wldcrd_mtchr.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2008-2009.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00015 #include <ders/wldcrd_mtchr.hpp>
00016 #include <ders/mem.hpp>
00017 
00018 namespace ders {  // ::ders
00019 
00020 using namespace std;
00021 
00022 void wldcrd_mtchr::add_sg()
00023 {
00024  sav_sgs.push_back(segm());
00025  sgs.push_back(&sav_sgs.back());
00026 }
00027 
00028 bool wldcrd_mtchr::eq(const char* str, const segm& sg, int beg) const
00029 {
00030  for (int i=beg, end=sg.wds.size(); i<end; i++) {
00031      const ch_rng& wstr=sg.wds[i].str;
00032      if (memcmp(str+sg.wds[i].off, wstr.beg, wstr.size())) return false;
00033  }
00034 
00035  return true;
00036 }
00037 
00038 const char* wldcrd_mtchr::fnd(const ch_rng& str, const segm& sg) const
00039 {
00040  if (sg.wds.size()==0) return (str.size()>=sg.len) ? str.beg : 0;
00041 
00042  const word& wd=sg.wds.front();
00043  for (ch_rng s=str; s.size()>=sg.len; ) {
00044      const char* ptr=static_cast<const char*>(mem_find(s.beg+wd.off, s.size()-
00045        sg.len+wd.str.size(), wd.str.beg, wd.str.size()));
00046      if (!ptr) return 0;
00047 
00048      ptr-=wd.off;
00049      if (eq(ptr, sg, 1)) return ptr;
00050 
00051      s.beg=ptr+1;
00052  }
00053 
00054  return 0;
00055 }
00056 
00057 wldcrd_mtchr::wldcrd_mtchr(mem_pool& m, const ch_rng& mask) :
00058   mp(m), len(0), sav_msk(nt(m, mask)), sav_sgs(stl_allocator<segm>(mp))
00059 {
00060  for (char* ptr=sav_msk->begin(); ptr<sav_msk->end(); ptr++) {
00061      switch (*ptr) {
00062             case '*': {
00063                  if (sgs.size()==0 || sgs.back()) sgs.push_back(0);
00064                  break;
00065             }
00066             case '?': {
00067                  if (sgs.size()==0 || !sgs.back()) add_sg();
00068                  sgs.back()->len++;
00069 
00070                  break;
00071             }
00072             default: {
00073                      if (sgs.size()==0 || !sgs.back()) add_sg();
00074                      segm& bs=*sgs.back();
00075 
00076                      if (*ptr=='\\' && ptr+1<sav_msk->end()) {
00077                         ptr++;
00078                         bs.wds.push_back(word(bs.len, ch_rng(ptr, ptr+1)));
00079                      }
00080                      else {
00081                           if (bs.wds.size()==0 || bs.len!=bs.wds.back().off+
00082                               bs.wds.back().str.size())
00083                              bs.wds.push_back(word(bs.len, ch_rng(ptr, ptr+1)));
00084                           else bs.wds.back().str.end++;
00085                      }
00086 
00087                      bs.len++;
00088             }
00089      }
00090  }
00091 
00092  for (int i=0, end=sgs.size(); i<end; i++)
00093      if (sgs[i]) len+=sgs[i]->len;
00094 }
00095 
00096 bool wldcrd_mtchr::match(const ch_rng& str) const
00097 {
00098  if (str.size()<len) return false;
00099 
00100  int sgfr=0, sgbk=sgs.size()-1;
00101  if (sgfr>sgbk) return true;
00102 
00103  ch_rng s=str;
00104  if (sgs[sgfr]) {
00105     if (!eq(s.beg, *sgs[sgfr])) return false;
00106 
00107     s.beg+=sgs[sgfr]->len;
00108     sgfr++;
00109  }
00110 
00111  if (sgfr<=sgbk && sgs[sgbk]) {
00112     if (!eq(s.end-sgs[sgbk]->len, *sgs[sgbk])) return false;
00113 
00114     s.end-=sgs[sgbk]->len;
00115     sgbk--;
00116  }
00117 
00118  if (sgfr>sgbk) return s.beg==s.end;
00119 
00120  assert(!sgs[sgbk]);
00121  for (int i=sgfr; i<sgbk; i++) {
00122      if (sgs[i]) {
00123         s.beg=fnd(s, *sgs[i]);
00124         if (!s.beg) return false;
00125 
00126         s.beg+=sgs[i]->len;
00127      }
00128  }
00129 
00130  return true;
00131 }
00132 
00133 sh_wldcrd_mtchr new_wldcrd_mtchr(mem_pool& mp, const ch_rng& mask)
00134 {
00135  mp_newbuf<wldcrd_mtchr> buf(mp);
00136  return sh_wldcrd_mtchr(buf.pool(), buf.rls(::new(buf.get()) wldcrd_mtchr(mp,
00137    mask)));
00138 }
00139 
00140 }  // namespace ::ders
00141 

Generated on Tue Dec 8 11:35:32 2009 for derslib by  doxygen 1.5.5