00001
00002
00003 #if !defined(XmlParser_H)
00004 #define XmlParser_H
00005
00006 #include "XmlUtil.h"
00007
00008 #include <algorithm>
00009 #include <string>
00010 #include <sstream>
00011 #include <iostream>
00012 using namespace std;
00013
00014
00015
00017
00018
00019
00020
00021 class XmlParser
00022 {
00023 public:
00024
00025 static long _parseid;
00026
00027
00028 long _id;
00029
00030
00031 string _strParse;
00032
00033
00034 char * _buffer;
00035 long _parseLength;
00036
00037
00038 long _current;
00039
00040
00041 long _firstTagStart;
00042 long _firstTagEnd;
00043
00044 long _lastTagStart;
00045 long _lastTagEnd;
00046
00047 long _nameStart;
00048 long _nameEnd;
00049 long _attrStart;
00050 long _attrEnd;
00051 long _valueStart;
00052 long _valueEnd;
00053
00054
00055 XmlParser () :
00056 _strParse()
00057 {
00058 clear();
00059
00060
00061 _id = _parseid;
00062
00063
00064 _parseid++;
00065 }
00066
00067
00068 bool create ( const char * buffer, long parseStart, long parseEnd )
00069 {
00070
00071 if ( !buffer || parseStart < 0 || parseEnd < parseStart )
00072 return false;
00073
00074 return create( buffer + parseStart, getLength(parseStart,parseEnd) );
00075 }
00076
00077
00078
00079 bool create ( const char * buffer, long length )
00080 {
00081
00082 if ( !buffer || length <= 0 )
00083 return false;
00084
00085
00086 _buffer = (char *) buffer;
00087 _parseLength = length;
00088
00089
00090 _current = 0;
00091
00092 return true;
00093 }
00094
00095 void release ()
00096 {
00097
00098 }
00099
00100
00101 long getCurrent ()
00102 {
00103 return _current;
00104 }
00105
00106 long getParseLength ()
00107 {
00108 return _parseLength;
00109 }
00110
00111 long getCurLength ()
00112 {
00113 return getOffsetLength(_current);
00114 }
00115
00116 long getOffsetLength ( long offset )
00117 {
00118 return getLength(offset,_parseLength - 1);
00119 }
00120
00121
00122 char * getBufferPos ()
00123 {
00124 return _buffer;
00125 }
00126
00127 char * getLastBufferPos ()
00128 {
00129 return _buffer + _parseLength;
00130 }
00131
00132 char * getCurPos ()
00133 {
00134 if ( isValid() )
00135 return _buffer + _current;
00136 else
00137 return NULL;
00138 }
00139
00140 char * getParseState ( long & parseLength )
00141 {
00142
00143 if ( !isValid() )
00144 {
00145 parseLength = 0;
00146 return getCurPos();
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 parseLength = getCurLength();
00167
00168
00169 char * buffer = getCurPos();
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 return getCurPos();
00186
00187 }
00188
00189
00190 string & str ()
00191 {
00192 return _strParse;
00193 }
00194
00195
00196 void reset ()
00197 {
00198 resetTagPositions();
00199 }
00200
00201 bool isValid ()
00202 {
00203
00204 if ( !_buffer || _parseLength <= 0 )
00205 return false;
00206
00207
00208 if ( _current < 0 || _current > _parseLength )
00209 return false;
00210
00211 return true;
00212 }
00213
00214 void resetTagPositions ( long start=-1 )
00215 {
00216
00217 _firstTagStart = start;
00218 _firstTagEnd = start;
00219
00220 _lastTagStart = start;
00221 _lastTagEnd = start;
00222
00223 _nameStart = start;
00224 _nameEnd = start;
00225
00226 _attrStart = start;
00227 _attrEnd = start;
00228
00229 _valueStart = start;
00230 _valueEnd = start;
00231 }
00232
00233 void clear ()
00234 {
00235
00236 _buffer = 0;
00237 _parseLength = 0;
00238
00239
00240 _current = 0;
00241
00242
00243 reset();
00244 }
00245
00246
00247 bool parse ( const char * buffer, long parseStart, long parseEnd )
00248 {
00249
00250 if ( !create(buffer,parseStart,parseEnd) )
00251 return false;
00252
00253 return parse();
00254 }
00255
00256 bool parse ( const char * buffer, long parseLength )
00257 {
00258
00259 if ( !create(buffer,parseLength) )
00260 return false;
00261
00262 return parse();
00263 }
00264
00265 bool parse ()
00266 {
00267
00268 _firstTagStart = _current;
00269 _firstTagEnd = _current;
00270
00271 _lastTagStart = _current;
00272 _lastTagEnd = _current;
00273
00274
00275
00276 long first = find( idTagLeft, _current );
00277 if ( first == -1 )
00278 return false;
00279
00280
00281
00282 long last = find( idTagRight, first );
00283 if ( last == -1 )
00284 return false;
00285
00286
00287 _firstTagStart = first;
00288 _firstTagEnd = last;
00289
00290
00291 if ( !parseName() )
00292 return false;
00293
00294
00295 parseAttributes();
00296
00297
00298 if ( hasNullTag() )
00299 {
00300
00301 _current = _firstTagEnd + idTagRightLength;
00302
00303
00304 return true;
00305 }
00306
00307
00308 string endTag;
00309 endTag = idTagEnd;
00310 endTag += getName();
00311 endTag += idTagRight;
00312
00313
00314 first = find( endTag, last );
00315 if ( first == -1 )
00316 return false;
00317
00318
00319 _lastTagStart = first;
00320 _lastTagEnd = first + (long)endTag.size();
00321
00322
00323 if ( !hasNullTag() )
00324 parseValue();
00325
00326
00327
00328
00329
00330 long pos = find( idTagLeft, _lastTagEnd );
00331 if ( pos != -1 )
00332 _current = pos;
00333 else
00334 _current = _lastTagEnd;
00335
00336
00337 return true;
00338 }
00339
00340 bool parse ( string & name,
00341 string & value,
00342 string & attributes,
00343 long & current )
00344 {
00345
00346 return true;
00347 }
00348
00349
00350
00351
00352
00353 bool hasNullTag ()
00354 {
00355
00356 char * buffer = _buffer + _firstTagEnd - 1;
00357
00358
00359 if ( *buffer == '/' && *(buffer+1) == '>' )
00360 return true;
00361 else
00362 return false;
00363 }
00364
00366
00367
00368
00369
00370
00371 protected:
00372
00373
00374 bool parseName ()
00375 {
00376
00377 if ( _firstTagStart < 0 || _firstTagEnd < 0 ||
00378 _firstTagEnd <= _firstTagStart )
00379 {
00380 _nameStart = -1;
00381 _nameEnd = -1;
00382 return false;
00383 }
00384
00385
00386 _nameStart = _firstTagStart + idTagLeftLength;
00387 _nameEnd = _firstTagEnd - 1;
00388
00389
00390
00391 if ( hasNullTag() )
00392 _nameEnd -= 1;
00393
00394
00395 long last = find(' ',_nameStart, getNameLength());
00396 if ( last != -1 )
00397 {
00398
00399
00400 _nameEnd = last - 1;
00401 }
00402
00403 return true;
00404 }
00405
00406 bool parseName ( string & name )
00407 {
00408
00409 if ( !parseName() )
00410 return false;
00411
00412 name = getName();
00413
00414 return true;
00415 }
00416
00417
00418 bool parseAttributes ()
00419 {
00420
00421 _attrStart = -1;
00422 _attrEnd = -1;
00423
00424
00425 long tagLength = getTagLength();
00426 long nameLength = getNameLength();
00427 if ( tagLength <= 0 || nameLength <= 0 )
00428 return 0;
00429
00430
00431
00432
00433 long diff = getTagLength() - getNameLength();
00434
00435 switch ( diff )
00436 {
00437
00438 case 0:
00439 case 1:
00440 case 2:
00441 return false;
00442
00443
00444 case 3:
00445 return false;
00446 }
00447
00448
00449 _attrStart = _nameEnd + 2;
00450
00451
00452
00453 _attrEnd = _firstTagEnd - 1;
00454 if ( hasNullTag() )
00455 _attrEnd -= -1;
00456
00457 return true;
00458 }
00459
00460 bool parseAttributes ( string & attributes )
00461 {
00462
00463 if ( !parseAttributes() )
00464 return false;
00465
00466 attributes = getAttributes();
00467
00468 return true;
00469 }
00470
00471
00472
00473 bool parseValue ()
00474 {
00475
00476 if ( _firstTagStart < 0 || _lastTagEnd < 0 ||
00477 _lastTagEnd <= _firstTagStart )
00478 {
00479 _valueStart = -1;
00480 _valueEnd = -1;
00481 return false;
00482 }
00483
00484
00485 _valueStart = _firstTagEnd + 1;
00486 _valueEnd = _lastTagStart - 1;
00487
00488 return true;
00489 }
00490
00491
00492 bool parseValue ( string & value )
00493 {
00494
00495 if ( !parseValue() )
00496 return false;
00497
00498 value = getValue();
00499
00500 return true;
00501 }
00502
00503 public:
00504
00505
00506 char * getNamePos ()
00507 {
00508 if ( hasName() )
00509 return _buffer + _nameStart;
00510 else
00511 return NULL;
00512 }
00513
00514 bool hasName ()
00515 {
00516 if ( getNameLength() > 0 )
00517 return true;
00518 else
00519 return false;
00520 }
00521
00522 long getNameLength ()
00523 {
00524 long length = getLength(_nameStart,_nameEnd);
00525 return length;
00526 }
00527
00528
00529 string getName ()
00530 {
00531
00532 long length = getNameLength();
00533
00534
00535
00536 if ( length <= 0 )
00537 return string("");
00538 else
00539 return substr(_nameStart,length);
00540 }
00541
00542
00543
00544 char * getAttributesPos ()
00545 {
00546 if ( hasAttributes() )
00547 return _buffer + _attrStart;
00548 else
00549 return NULL;
00550 }
00551
00552 bool hasAttributes ()
00553 {
00554 if ( getValueLength() > 0 )
00555 return true;
00556 else
00557 return false;
00558 }
00559
00560 long getAttributesLength ()
00561 {
00562 long length = getLength(_attrStart,_attrEnd);
00563 return length;
00564 }
00565
00566 string getAttributes ()
00567 {
00568
00569 long length = getAttributesLength();
00570
00571
00572
00573 if ( length <= 0 )
00574 return string("");
00575 else
00576 return substr(_attrStart,length);
00577 }
00578
00579
00580 char * getValuePos ()
00581 {
00582 if ( hasValue() )
00583 return _buffer + _valueStart;
00584 else
00585 return NULL;
00586 }
00587
00588 bool hasValue ()
00589 {
00590 if ( getValueLength() > 0 )
00591 return true;
00592 else
00593 return false;
00594 }
00595
00596 long getValueLength ()
00597 {
00598 long length = getLength(_valueStart,_valueEnd);
00599 return length;
00600 }
00601
00602 string getValue ()
00603 {
00604
00605 long length = getValueLength();
00606
00607
00608
00609 if ( length <= 0 )
00610 return string("");
00611 else
00612 return substr(_valueStart,length);
00613 }
00614
00615 char * getValueState ( long & valueLength )
00616 {
00617
00618 valueLength = getValueLength();
00619
00620
00621 return _buffer + _valueStart;
00622 }
00623
00624 bool valueHasTag ()
00625 {
00626
00627 long pos = find( idTagLeft, _valueStart, getValueLength() );
00628
00629
00630 if ( pos != -1 )
00631 return true;
00632 else
00633 return false;
00634 }
00635
00636
00637 long getTagLength ()
00638 {
00639 long length = getLength( _firstTagStart, _firstTagEnd );
00640 return length;
00641 }
00642
00643 long getLastTagLength ()
00644 {
00645 long length = getLength( _lastTagStart, _lastTagEnd );
00646 return length;
00647 }
00648
00649 bool hasTag ()
00650 {
00651 if ( getTagLength() > 0 )
00652 return true;
00653 else
00654 return false;
00655 }
00656
00657 bool hasLastTag ()
00658 {
00659 if ( getLastTagLength() > 0 )
00660 return true;
00661 else
00662 return false;
00663 }
00664
00665 char * getTagPos ()
00666 {
00667 if ( hasTag() )
00668 return _buffer + _firstTagStart;
00669 else
00670 return NULL;
00671 }
00672
00673 char * getLastTagPos ()
00674 {
00675 if ( hasTag() )
00676 return _buffer + _lastTagStart;
00677 else
00678 return NULL;
00679 }
00680
00681 string getTag ()
00682 {
00683
00684 long length = getTagLength();
00685 return substr(_firstTagStart,length);
00686 }
00687
00688
00689 long getLength ( long startPos,
00690 long endPos )
00691 {
00692
00693 if ( startPos < 0 || endPos < 0 ||
00694 endPos < startPos )
00695 return 0;
00696
00697
00698 long length = endPos - startPos + 1;
00699 return length;
00700 }
00701
00702 string ::iterator begin ()
00703 {
00704 string::iterator buf = _buffer;
00705 return string::iterator(buf);
00706 }
00707
00708 string ::iterator end ()
00709 {
00710 string::iterator buf = _buffer + _parseLength;
00711 return string::iterator(buf);
00712 }
00713
00714 long find ( char srchChar, long offset, long length = -1 )
00715 {
00716
00717
00718 if ( length == -1 )
00719 length = getOffsetLength(offset);
00720
00721
00722 string::iterator start = _buffer + offset;
00723 string::iterator end = _buffer + (offset + length);
00724
00725
00726 string::iterator found = std::find( start, end, srchChar );
00727
00728
00729 if ( found >= end )
00730 {
00731 return -1;
00732 }
00733 else
00734 {
00735
00736 if ( found < start )
00737 return -1;
00738
00739
00740 long pos = (long)(found - start);
00741 pos += offset;
00742
00743 return pos;
00744 }
00745 }
00746
00747 long find ( char * srchStr, long offset, long length = -1 )
00748 {
00749
00750
00751 if ( length == -1 )
00752 length = getOffsetLength(offset);
00753
00754
00755 string::iterator start = _buffer + offset;
00756 string::iterator end = _buffer + (offset + length);
00757
00758
00759 string::iterator srchStart = srchStr;
00760 string::iterator srchEnd = srchStr + strlen(srchStr);
00761
00762
00763 string::iterator found = std::search( start, end, srchStart, srchEnd );
00764
00765
00766 if ( found >= end )
00767 {
00768 return -1;
00769 }
00770 else
00771 {
00772
00773 if ( found < start )
00774 return -1;
00775
00776
00777 long pos = (long)(found - start);
00778 pos += offset;
00779
00780 return pos;
00781 }
00782 }
00783
00784 long find ( string & srchStr, long offset, long length = -1 )
00785 {
00786
00787
00788 if ( length == -1 )
00789 length = getOffsetLength(offset);
00790
00791
00792 string::iterator start = _buffer + offset;
00793 string::iterator end = _buffer + (offset + length);
00794
00795
00796 string::iterator srchStart = srchStr.begin();
00797 string::iterator srchEnd = srchStr.end();
00798
00799
00800 string::iterator found = std::search( start, end, srchStart, srchEnd );
00801
00802
00803 if ( found >= end )
00804 {
00805 return -1;
00806 }
00807 else
00808 {
00809
00810 if ( found < start )
00811 return -1;
00812
00813
00814 long pos = (long)(found - start);
00815 pos += offset;
00816
00817 return pos;
00818 }
00819 }
00820
00821 long rfind ( char srchChar, long offset, long length )
00822 {
00823
00824 char srchStr[2];
00825 srchStr[0] = srchChar;
00826 srchStr[1] = '\0';
00827
00828 return rfind(srchStr,offset,length);
00829 }
00830
00831 long rfind ( char * srchStr, long offset, long length )
00832 {
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 long pos = 0;
00845
00846 return pos;
00847 }
00848
00849
00850 string substr ( long offset, long length )
00851 {
00852
00853 char * ptr = _buffer + offset;
00854
00855
00856 string str;
00857 str.assign( ptr, length );
00858
00859 return string(str);
00860 }
00861
00862
00863 };
00864
00865
00866 #endif