SourceForge.jp

dkutilParser.h

説明を見る。
00001 
00002 
00003 #ifndef _dkutilParser__
00004 #define _dkutilParser__
00005 
00006 #include "dkutilString.h"
00007 #include "dkutilDefined.h"
00008 #include "dkutilStdio.h"
00009 
00010 namespace dkutil{
00011 
00013 typedef std::list<std::string> PARSE_STRING_CONTAINER;
00014 
00026 
00027 inline bool ParseStringUpToDoubleNull(PARSE_STRING_CONTAINER &c,
00028                                                                 const char *str,
00029                                                                 size_t permitsize)
00030 {
00031     bool isPush=false;
00032     std::string buff;
00033     if(permitsize == 0){return false;}
00034     permitsize--;//-1にしておく
00035     for(size_t i=0;i<permitsize/*permitsize - 1*/;i++)
00036     {
00037         if(str[i] != NULL){
00038             buff.push_back(str[i]);
00039         }else{
00040             if(!buff.empty()){
00041                 c.push_back(buff);
00042                 buff.clear();
00043                 isPush = true;
00044             }
00045             if(str[i + 1] == NULL){
00046                 
00047                 break;
00048             }
00049         }
00050     }
00051     return isPush;
00052 
00053 }
00059 
00060 inline bool ParseStringDirectoryName(PARSE_STRING_CONTAINER &c,
00061                                                                          const char *directory,
00062                                                                          size_t length
00063                                                                          )
00064 {
00065     bool isPush =false;
00066     std::string buff;
00067     if(length == 0){return false;}
00068         
00069     for(size_t i=0;i<length;i++)
00070     {
00071         if(directory[i] != '\\'){
00072             buff.push_back(directory[i]);
00073         }else{
00074             if(!buff.empty()){
00075                 c.push_back(buff);
00076                 buff.clear();
00077                 isPush = true;
00078             }
00079         }
00080     }
00081     return isPush;
00082 }
00083     
00084 
00085 
00086 
00087 
00088 namespace private_{
00089 
00090 
00091 
00092 
00093 
00094 class counter{
00095     int mc;
00096     void check(){
00097         DK_TRUE_ASSERT_OR_THROW(
00098             mc <= 0,
00099             std::logic_error("private_::counter decrement error");
00100         );
00101     }
00102 public:
00103     counter(){mc=0;}
00104     ~counter(){check();}
00105     int operator++(){
00106         mc++;
00107     }
00108     int operator--(){
00109         check();
00110     
00111         mc--;
00112     }
00113     int get(){return mc;}
00114 };
00115 
00116 
00118 extern int GetParsedStringType(const char *s);
00124 
00125 extern bool ParsedStringToGeneralPurposeVariable(const char *s,GeneralPurposeVariable *v);
00126 
00127 
00128 
00129 
00130 
00131 class CommandLineParser{
00132 public:
00133     typedef std::string::size_type size_type;
00134     struct DATA_TYPE{
00135         std::string str;//コマンドラインの文字列
00136         std::string sig;//シグネチャ
00137     };
00138     typedef std::list<DATA_TYPE> CONTAINER_TYPE;
00139     //typedef CONTAINER_TYPE::iterator iterator;
00140     typedef CONTAINER_TYPE::const_iterator const_iterator;
00141 
00142     
00143         
00144 private:
00145     std::string mbuf;
00146     int mNum;//コマンドラインにぶち込んだ数。
00147     CONTAINER_TYPE mList;
00148     
00149     std::string::const_iterator ParsingOption(
00150         std::string::const_iterator ch,const std::string &buf,
00151         int num,CONTAINER_TYPE &c)
00152     {
00153 
00154         if( ch == buf.end() || *ch=='\0'){ return ch;}
00155         DATA_TYPE data;
00156         //search logic
00157         {
00158             
00159             //search signature
00160             for(;ch != buf.end();ch++){
00161                 if(*ch==' ' || *ch=='\0' || *ch=='"'){
00162                     break;
00163                 }else 
00164                 data.sig += (*ch);
00165             }
00166             if( ch == buf.end()){ goto end;}
00167             if(*ch=='-' || *ch=='/'){
00168                 ch--;
00169                 goto end;
00170             }
00171             ch++;
00172             if( ch == buf.end()){ goto end;}
00173             if(*ch=='-' || *ch=='/'){
00174                 ch--;
00175                 goto end;
00176             }
00177             //search data
00178             for(;ch != buf.end();ch++){
00179                 if(//*ch==' ' ||
00180                     *ch=='\0' || *ch=='"'){
00181                     break;
00182                 }
00183                 data.str += (*ch);
00184             }
00185             
00186         }
00187     end:
00188         c.push_back(data);
00189         //元に戻す
00190         return ch;
00191     }
00192     std::string::const_iterator ParsingNormal(
00193         std::string::const_iterator ch,const std::string &buf,
00194         int num,CONTAINER_TYPE &c)
00195     {
00196         if(*ch=='\0') return ch;
00197         DATA_TYPE data;
00198         for(;ch != buf.end();ch++)
00199         {
00200             if(*ch==' '){
00201                     break;
00202             }
00203             data.str += (*ch);
00204         }
00205         c.push_back(data);
00206         return ch;
00207     }
00208 
00209     void Parsing(const std::string &buf,int num,CONTAINER_TYPE &c){
00210         typedef std::string::const_iterator it_type;
00211         for(it_type it=buf.begin();it != buf.end();it++)
00212         {
00213             if( (*it) == '\0') break;
00214             if( isSpace((*it)) ) continue;
00215             if( (*it) == '-' || (*it) == '/'){
00216                 it++;
00217                 //指定して、サーチ後のイテレータを貰う
00218                 it = ParsingOption(it,buf,num,c);
00219 
00220             }else{
00221                 it = ParsingNormal(it,buf,num,c);
00222             }
00223             if(it == buf.end() || (*it) == '\0') break;
00224         }
00225 
00226     }
00227     
00228 public:
00229     CommandLineParser(const char *str=NULL,int num=0){
00230         if(str==NULL && num==0){return;}
00231             reset(str,num);
00232         
00233     }
00234     virtual ~CommandLineParser(){}
00235     void reset(const char *str,int num){
00236         mbuf = str;
00237         mNum = num;
00238         mList.clear();
00239         Parsing(mbuf,mNum,mList);
00240     }
00241     const_iterator begin()const{return mList.begin();}
00242     const_iterator end()const{return mList.end();}
00243     void clear(){mbuf.clear();mList.clear();}
00244 };
00245 
00246 inline bool is0x(const char *s){
00247     if(s[0]=='0' && s[1]=='x'){
00248         return true;
00249     }
00250     return false;
00251 }
00252 
00253 inline bool ParsedStringToBoostAny(const char *s,boost::any *Any)
00254 {
00255     radix_convert conv;
00256     int r=GetParsedStringType( s );
00257     
00258     switch(r)
00259     {
00260     case enuDU2CSV_STRING:
00261     case enuDU2CSV_STRING_32MORE:
00262         *Any = s;
00263         break;
00264     case enuDU2CSV_DOUBLE:
00265         //DOUBLE(浮動小数点)だった
00266         double d;
00267         d = ::atof( s );
00268         *Any = d;
00269         break;
00270     case enuDU2CSV_INT:
00271         {//INTだった
00272             int t;
00273             if(is0x(s)){
00274                 t = conv.a16toi(s);
00275             }else{
00276                 t = ::atoi(s);
00277             }
00278             *Any = t;
00279             break;
00280         }
00281     case enuDU2CSV_LONGLONG:
00282         {//LONGLONGだった
00283             LONGLONG t;
00284             if(is0x(s )){
00285                 t = conv.a16toll(s) ;
00286             }else{
00287                 t =  ::_atoi64(s);
00288             }
00289             *Any = t;
00290             break;
00291         }
00292     case enuDU2CSV_ULONGLONG:
00293         {//ULONGLONGだった
00294             ULONGLONG t;
00295             if(is0x(s)){
00296                 t = conv.a16toull( s );
00297             }else{
00298                 t = atoull( s ) ;
00299             }
00300             *Any = t;
00301             break;
00302         }
00303     default:
00304         return false;
00305     }//end of switch
00306     return true;
00307 }
00308 
00309 
00310 
00311 
00312 
00313 class CSVParser{
00314 public:
00315     typedef std::string::size_type size_type;
00316     struct DATA_TYPE{
00317         std::string str;
00318     };
00319     typedef std::deque<DATA_TYPE> CONTAINER_TYPE;
00320     typedef CONTAINER_TYPE::const_iterator const_iterator;
00321 private:
00322     CONTAINER_TYPE mC;
00323     std::string mbuf;
00324 
00325     bool CheckEnd(std::string::iterator &it,std::string &buf){
00326         if(buf.end() != it) return false;
00327         return true;
00328     }
00329     bool CheckBegin(std::string::iterator &it,std::string &buf){
00330         if(buf.begin() != it) return false;
00331         return true;
00332     }
00333     bool CheckChar(std::string::iterator it,char d){
00334         if((*it) != d) return false;
00335         return true;
00336     }
00337     bool CheckBreak(std::string::iterator &it,std::string &buf){
00338         if((*it) == '\0' || it == buf.end() ) return true;
00339         return false;
00340     }
00341     void Parsing(std::string &buf,CONTAINER_TYPE &container){
00342         typedef std::string::iterator it_type;
00343 
00344         it_type it = buf.begin();
00345 
00346         //これでパーシングミスのチェックをする。
00347         //counter c;
00348         DATA_TYPE data;
00349         
00350         for(;it != buf.end();it++)
00351         {
00352             if(CheckBreak(it,buf))
00353             {
00354                 break; 
00355             }else if(CheckChar(it,',') || CheckChar(it,'\n'))
00356             {
00357                 if(data.str.empty()){
00358                     //if(CheckBegin(it,buf)){ continue;}
00359                     continue;
00360                 }
00361                 container.push_back(data);
00362                 data.str.clear();
00363                 continue;
00364             }else
00365             {
00366                 if(CheckBegin(it,buf)){
00367                 }else{
00368                     if(CheckChar(it - 1,'\n') && CheckChar(it,',')){ continue;}
00369                 }
00370                 if((*it) != '\n'){
00371                     data.str += (*it);
00372                 }
00373             }
00374         }
00375         if(!data.str.empty()){
00376             container.push_back(data);
00377         }
00378     }
00379 
00380 public:
00381     CSVParser(const char *str=NULL){
00382         if(str){
00383             reset(str);
00384         }
00385     }
00386     virtual ~CSVParser(){}
00390 
00391     void reset(const char *str){
00392         mbuf = str;
00393         Parsing(mbuf,mC);
00394     }
00396     void clear(){mbuf.clear();mC.clear();}
00398     const_iterator begin()const{return mC.begin();}
00400     const_iterator end()const{return mC.end();}
00401 
00402 };
00403 
00404 
00442 class CSVAnalyzer{
00443 public:
00444     typedef dkutil::GeneralPurposeVariable DATA_TYPE;
00445     typedef std::deque<DATA_TYPE> CONTAINER_TYPE;
00446     typedef CONTAINER_TYPE::const_iterator const_iterator;
00447     typedef CONTAINER_TYPE::const_reverse_iterator const_reverse_iterator;
00448     explicit CSVAnalyzer(const CSVParser &parser){
00449         reset(parser);
00450     }
00451     CSVAnalyzer(){}
00453     void reset(const CSVParser &parser){
00454         reset(parser.begin(),parser.end());
00455     }
00460     void reset(CSVParser::const_iterator be,
00461         CSVParser::const_iterator en){
00462 
00463         Analyzing(mc,be,en);
00464 
00465     }
00467     const_iterator begin()const{    return mc.begin();}
00468     const_iterator end()const{return mc.end();}
00470     const_reverse_iterator rbegin()const{return mc.rbegin();}
00471     const_reverse_iterator rend()const{return mc.rend();}
00472 
00473 
00474 
00475 protected:
00476 
00477 
00478     static void Analyzing(CONTAINER_TYPE &container,
00479         CSVParser::const_iterator be,CSVParser::const_iterator en)
00480 
00481     {
00482         CSVParser::const_iterator it=be;
00483         //radix_convert conv;
00484         //スレッドロックする
00485         for(;it != en;it++)
00486         {
00487             DATA_TYPE data;
00488             if(false==ParsedStringToGeneralPurposeVariable(
00489                 (*it).str.c_str(),
00490                 &data)
00491                 )
00492             {
00493                 throw std::logic_error("Analizingでエラりました!!");
00494             }
00495             /*
00496             int r=GetParsedStringType( (*it).str.c_str() );
00497             
00498             switch(r)
00499             {
00500             case enuDU2CSV_STRING:
00501             case enuDU2CSV_STRING_32MORE:
00502                 data.insert((*it).str);
00503                 break;
00504             case enuDU2CSV_DOUBLE:
00505                 //DOUBLE(浮動小数点)だった
00506                 data.insert( ::atof( (*it).str.c_str() ) );
00507                 break;
00508             case enuDU2CSV_INT:
00509                 {//INTだった
00510                     if(private_::is0x((*it).str.c_str())){
00511                         data.insert(  conv.a16toi((*it).str.c_str()) );
00512                     }else{
00513                         data.insert(  ::atoi((*it).str.c_str()) );
00514                     }
00515                     break;
00516                 }
00517             case enuDU2CSV_LONGLONG:
00518                 {//LONGLONGだった
00519                     if(private_::is0x((*it).str.c_str())){
00520                         data.insert( conv.a16toll((*it).str.c_str()) );
00521                     }else{
00522                         data.insert( ::_atoi64((*it).str.c_str()) );
00523                     }
00524                     break;
00525                 }
00526             case enuDU2CSV_ULONGLONG:
00527                 {//ULONGLONGだった
00528                     if(private_::is0x((*it).str.c_str())){
00529                         data.insert( conv.a16toull( (*it).str.c_str() ) );
00530                     }else{
00531                         data.insert( atoull( (*it).str.c_str() ) );
00532                     }
00533                     break;
00534                 }
00535             default:
00536                 throw std::logic_error("Analizingでエラりました!!");
00537             }//end of switch
00538             */
00539 
00540             container.push_back(data);
00541         }//end of for
00542         //ここでアンロック
00543 
00544     }
00545     CONTAINER_TYPE mc;
00546 };
00547 
00548 }//end of private_ namespace
00549 
00550 //typedef private_::CommandLineParser CommandLineParser;
00551 
00552 //typedef private_::CSVParser CSVParser;
00553 
00554 //typedef private_::CSVAnalyzer CSVAnalyzer;
00555 
00556 /*
00557 struct GeneralPurposeVariableScanEx : public private_::GeneralPurposeVariable{
00558     GeneralPurposeVariableEx(boost::any){
00559     }
00560 
00561 
00562 };
00563 */
00564 
00565 }//end of namespace
00566 
00567 #endif//end of include once

dkutil 1.02リリース前 d金魚専用マニュアルバージョンに対してSun Dec 28 21:23:08 2003に生成されました。 doxygen 1.3.5