73 #ifndef _CRT_SECURE_NO_DEPRECATE
74 #define _CRT_SECURE_NO_DEPRECATE
77 #include "xml_parser.h"
83 #define WIN32_LEAN_AND_MEAN
97 XMLCSTR XMLNode::getVersion() {
return _X(
"v2.30"); }
98 void freeXMLString(XMLSTR t){free(t);}
100 static XMLNode::XMLCharEncoding characterEncoding=XMLNode::encoding_UTF8;
101 static char guessWideCharChars=1, dropWhiteSpace=1;
103 inline int mmin(
const int t1,
const int t2 ) {
return t1 < t2 ? t1 : t2; }
109 typedef struct { XMLCSTR lpszOpen;
int openTagLen; XMLCSTR lpszClose;}
ALLXMLClearTag;
112 { _X(
"<![CDATA["),9, _X(
"]]>") },
113 { _X(
"<!DOCTYPE"),9, _X(
">") },
114 { _X(
"<PRE>") ,5, _X(
"</PRE>") },
115 { _X(
"<Script>") ,8, _X(
"</Script>")},
116 { _X(
"<!--") ,4, _X(
"-->") },
127 { _X(
"&" ), 5, _X(
'&' )},
128 { _X(
"<" ), 4, _X(
'<' )},
129 { _X(
">" ), 4, _X(
'>' )},
130 { _X(
"""), 6, _X(
'\"')},
131 { _X(
"'"), 6, _X(
'\'')},
138 #define INDENTCHAR _X('\t')
142 XMLCSTR XMLNode::getError(XMLError xerror)
146 case eXMLErrorNone:
return _X(
"No error");
147 case eXMLErrorMissingEndTag:
return _X(
"Warning: Unmatched end tag");
148 case eXMLErrorNoXMLTagFound:
return _X(
"Warning: No XML tag found");
149 case eXMLErrorEmpty:
return _X(
"> Error: No XML data");
150 case eXMLErrorMissingTagName:
return _X(
"> Error: Missing start tag name");
151 case eXMLErrorMissingEndTagName:
return _X(
"> Error: Missing end tag name");
152 case eXMLErrorUnmatchedEndTag:
return _X(
"> Error: Unmatched end tag");
153 case eXMLErrorUnmatchedEndClearTag:
return _X(
"> Error: Unmatched clear tag end");
154 case eXMLErrorUnexpectedToken:
return _X(
"> Error: Unexpected token found");
155 case eXMLErrorNoElements:
return _X(
"> Error: No elements found");
156 case eXMLErrorFileNotFound:
return _X(
"> Error: File not found");
157 case eXMLErrorFirstTagNotFound:
return _X(
"> Error: First Tag not found");
158 case eXMLErrorUnknownCharacterEntity:
return _X(
"> Error: Unknown character entity");
159 case eXMLErrorCharConversionError:
return _X(
"> Error: unable to convert between WideChar and MultiByte chars");
160 case eXMLErrorCannotOpenWriteFile:
return _X(
"> Error: unable to open file for writing");
161 case eXMLErrorCannotWriteFile:
return _X(
"> Error: cannot write into file");
163 case eXMLErrorBase64DataSizeIsNotMultipleOf4:
return _X(
"Warning: Base64-string length is not a multiple of 4");
164 case eXMLErrorBase64DecodeTruncatedData:
return _X(
"Warning: Base64-string is truncated");
165 case eXMLErrorBase64DecodeIllegalCharacter:
return _X(
"> Error: Base64-string contains an illegal character");
166 case eXMLErrorBase64DecodeBufferTooSmall:
return _X(
"> Error: Base64 decode output buffer is too small");
168 return _X(
"Unknown");
180 #ifdef XML_NO_WIDE_CHAR
181 char myIsTextWideChar(
const void *b,
int len) {
return FALSE; }
183 #if defined (UNDER_CE) || !defined(_XMLWINDOWS)
184 char myIsTextWideChar(
const void *b,
int len)
188 if ((((
unsigned long)b)%
sizeof(
wchar_t))!=0)
return FALSE;
190 const wchar_t *s=(
const wchar_t*)b;
193 if (len<(
int)
sizeof(wchar_t))
return FALSE;
196 if (len&1)
return FALSE;
199 len=mmin(256,len/
sizeof(
wchar_t));
202 if (*((
unsigned short*)s) == 0xFFFE)
return TRUE;
203 if (*((
unsigned short*)s) == 0xFEFF)
return TRUE;
207 for (i=0; i<len; i++)
if (s[i]<=(
unsigned short)255) stats++;
208 if (stats>len/2)
return TRUE;
211 for (i=0; i<len; i++)
if (!s[i])
return TRUE;
216 char myIsTextWideChar(
const void *b,
int l) {
return (
char)IsTextUnicode((CONST LPVOID)b,l,NULL); };
223 wchar_t *myMultiByteToWideChar(
const char *s)
226 if (characterEncoding==XMLNode::encoding_UTF8) i=(int)MultiByteToWideChar(CP_UTF8,0 ,s,-1,NULL,0);
227 else i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,-1,NULL,0);
228 if (i<0)
return NULL;
229 wchar_t *d=(
wchar_t *)malloc((i+1)*
sizeof(XMLCHAR));
230 if (characterEncoding==XMLNode::encoding_UTF8) i=(int)MultiByteToWideChar(CP_UTF8,0 ,s,-1,d,i);
231 else i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,-1,d,i);
235 static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) {
return _wfopen(filename,mode); }
236 static inline int xstrlen(XMLCSTR c) {
return (
int)wcslen(c); }
237 static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return _wcsnicmp(c1,c2,l);}
238 static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return wcsncmp(c1,c2,l);}
239 static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) {
return _wcsicmp(c1,c2); }
240 static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) {
return (XMLSTR)wcsstr(c1,c2); }
241 static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) {
return (XMLSTR)wcscpy(c1,c2); }
243 char *myWideCharToMultiByte(
const wchar_t *s)
245 UINT codePage=CP_ACP;
if (characterEncoding==XMLNode::encoding_UTF8) codePage=CP_UTF8;
246 int i=(int)WideCharToMultiByte(codePage,
255 if (i<0)
return NULL;
256 char *d=(
char*)malloc(i+1);
257 WideCharToMultiByte(codePage,
269 static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) {
return fopen(filename,mode); }
270 static inline int xstrlen(XMLCSTR c) {
return (
int)strlen(c); }
271 static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return _strnicmp(c1,c2,l);}
272 static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return strncmp(c1,c2,l);}
273 static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) {
return _stricmp(c1,c2); }
274 static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) {
return (XMLSTR)strstr(c1,c2); }
275 static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) {
return (XMLSTR)strcpy(c1,c2); }
278 static inline int _strnicmp(
char *c1,
char *c2,
int l){
return strnicmp(c1,c2,l);}
282 #ifdef XML_NO_WIDE_CHAR
283 char *myWideCharToMultiByte(
const wchar_t *s) {
return NULL; }
285 char *myWideCharToMultiByte(
const wchar_t *s)
288 int i=(int)wcsrtombs(NULL,&ss,0,NULL);
289 if (i<0)
return NULL;
290 char *d=(
char *)malloc(i+1);
291 wcsrtombs(d,&s,i,NULL);
297 wchar_t *myMultiByteToWideChar(
const char *s)
300 int i=(int)mbsrtowcs(NULL,&ss,0,NULL);
301 if (i<0)
return NULL;
302 wchar_t *d=(
wchar_t *)malloc((i+1)*
sizeof(wchar_t));
303 mbsrtowcs(d,&s,i,NULL);
307 int xstrlen(XMLCSTR c) {
return wcslen(c); }
311 static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return wsncasecmp(c1,c2,l);}
312 static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return wsncmp(c1,c2,l);}
313 static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) {
return wscasecmp(c1,c2); }
316 static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return wcsncasecmp(c1,c2,l);}
317 static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return wcsncmp(c1,c2,l);}
318 static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) {
return wcscasecmp(c1,c2); }
320 static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) {
return (XMLSTR)wcsstr(c1,c2); }
321 static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) {
return (XMLSTR)wcscpy(c1,c2); }
322 static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode)
324 char *filenameAscii=myWideCharToMultiByte(filename);
326 if (mode[0]==_X(
'r')) f=fopen(filenameAscii,
"rb");
327 else f=fopen(filenameAscii,
"wb");
332 static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) {
return fopen(filename,mode); }
333 static inline int xstrlen(XMLCSTR c) {
return strlen(c); }
334 static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return strncasecmp(c1,c2,l);}
335 static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2,
int l) {
return strncmp(c1,c2,l);}
336 static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) {
return strcasecmp(c1,c2); }
337 static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) {
return (XMLSTR)strstr(c1,c2); }
338 static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) {
return (XMLSTR)strcpy(c1,c2); }
340 static inline int _strnicmp(
const char *c1,
const char *c2,
int l) {
return strncasecmp(c1,c2,l);}
349 XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag)
353 FILE *f=xfopen(filename,_X(
"rb"));
357 int l=(int)fread(bb,1,200,f);
358 setGlobalOptions(guessCharEncoding(bb,l),guessWideCharChars,dropWhiteSpace);
364 XMLNode xnode=XMLNode::parseFile(filename,tag,&pResults);
367 if (pResults.error != eXMLErrorNone)
370 char message[2000],*s1=(
char*)
"",*s3=(
char*)
""; XMLCSTR s2=_X(
"");
371 if (pResults.error==eXMLErrorFirstTagNotFound) { s1=(
char*)
"First Tag should be '"; s2=tag; s3=(
char*)
"'.\n"; }
374 "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s"
376 "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s"
378 ,filename,XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn,s1,s2,s3);
381 #if defined(_XMLWINDOWS) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_)
382 MessageBoxA(NULL,message,
"XML Parsing error",MB_OK|MB_ICONERROR|MB_TOPMOST);
384 printf(
"%s",message);
404 static const char XML_utf8ByteTable[256] =
407 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
408 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
409 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
410 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
411 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
412 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
413 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
414 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
415 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
416 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
417 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
418 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
419 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
420 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
421 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
422 4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1
424 static const char XML_asciiByteTable[256] =
426 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
427 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
428 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
429 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
430 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
431 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
433 static const char XML_sjisByteTable[256] =
436 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
437 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
438 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
439 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
440 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
441 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
442 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
443 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
444 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
445 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
446 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
447 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
448 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
449 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
450 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
451 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
453 static const char *XML_ByteTable=(
const char *)XML_utf8ByteTable;
457 XMLNode XMLNode::emptyXMLNode;
458 XMLClear XMLNode::emptyXMLClear={ NULL, NULL, NULL};
459 XMLAttribute XMLNode::emptyXMLAttribute={ NULL, NULL};
462 typedef enum XMLTokenTypeTag
471 eTokenShortHandClose,
481 int nIndex,nIndexMissigEndTag;
485 XMLCSTR lpNewElement;
512 XMLError XMLNode::writeToFile(XMLCSTR filename,
const char *encoding,
char nFormat)
const
514 if (!d)
return eXMLErrorNone;
515 FILE *f=xfopen(filename,_X(
"wb"));
516 if (!f)
return eXMLErrorCannotOpenWriteFile;
518 unsigned char h[2]={ 0xFF, 0xFE };
519 if (!fwrite(h,2,1,f))
return eXMLErrorCannotWriteFile;
520 if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration())))
522 if (!fwrite(_X(
"<?xml version=\"1.0\" encoding=\"utf-16\"?>\n"),
sizeof(
wchar_t)*40,1,f))
523 return eXMLErrorCannotWriteFile;
526 if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration())))
528 if (characterEncoding==encoding_UTF8)
531 unsigned char h[3]={0xEF,0xBB,0xBF};
if (!fwrite(h,3,1,f))
return eXMLErrorCannotWriteFile;
533 }
else if (characterEncoding==encoding_ShiftJIS) encoding=
"SHIFT-JIS";
535 if (!encoding) encoding=
"ISO-8859-1";
536 if (fprintf(f,
"<?xml version=\"1.0\" encoding=\"%s\"?>\n",encoding)<0)
return eXMLErrorCannotWriteFile;
539 if (characterEncoding==encoding_UTF8)
541 unsigned char h[3]={0xEF,0xBB,0xBF};
if (!fwrite(h,3,1,f))
return eXMLErrorCannotWriteFile;
546 XMLSTR t=createXMLString(nFormat,&i);
547 if (!fwrite(t,
sizeof(XMLCHAR)*i,1,f))
return eXMLErrorCannotWriteFile;
548 if (fclose(f)!=0)
return eXMLErrorCannotWriteFile;
550 return eXMLErrorNone;
554 XMLSTR stringDup(XMLCSTR lpszData,
int cbData)
556 if (lpszData==NULL)
return NULL;
559 if (cbData==0) cbData=(int)xstrlen(lpszData);
560 lpszNew = (XMLSTR)malloc((cbData+1) *
sizeof(XMLCHAR));
563 memcpy(lpszNew, lpszData, (cbData) *
sizeof(XMLCHAR));
564 lpszNew[cbData] = (XMLCHAR)NULL;
569 XMLSTR toXMLStringUnSafe(XMLSTR dest,XMLCSTR source)
573 XMLCharacterEntity *entity;
579 if (ch==entity->c) {xstrcpy(dest,entity->s); dest+=entity->l; source++;
goto out_of_loop1; }
583 *(dest++)=*(source++);
585 switch(XML_ByteTable[(
unsigned char)ch])
587 case 4: *(dest++)=*(source++);
588 case 3: *(dest++)=*(source++);
589 case 2: *(dest++)=*(source++);
590 case 1: *(dest++)=*(source++);
601 int lengthXMLString(XMLCSTR source)
604 XMLCharacterEntity *entity;
611 if (ch==entity->c) { r+=entity->l; source++;
goto out_of_loop1; }
617 ch=XML_ByteTable[(
unsigned char)ch]; r+=ch; source+=ch;
625 ToXMLStringTool::~ToXMLStringTool(){ freeBuffer(); }
626 void ToXMLStringTool::freeBuffer(){
if (buf) free(buf); buf=NULL; buflen=0; }
627 XMLSTR ToXMLStringTool::toXML(XMLCSTR source)
629 int l=lengthXMLString(source)+1;
630 if (l>buflen) { buflen=l; buf=(XMLSTR)realloc(buf,l*
sizeof(XMLCHAR)); }
631 return toXMLStringUnSafe(buf,source);
635 XMLSTR fromXMLString(XMLCSTR s,
int lo, XML *pXML)
649 XMLCharacterEntity *entity;
654 if ((lo>2)&&(s[1]==_X(
'#')))
657 if ((*s==_X(
'X'))||(*s==_X(
'x'))) { s++; lo--; }
658 while ((*s)&&(*s!=_X(
';'))&&((lo--)>0)) s++;
661 pXML->error=eXMLErrorUnknownCharacterEntity;
670 if ((lo>=entity->l)&&(xstrnicmp(s,entity->s,entity->l)==0)) { s+=entity->l; lo-=entity->l;
break; }
675 pXML->error=eXMLErrorUnknownCharacterEntity;
684 j=XML_ByteTable[(
unsigned char)*s]; s+=j; lo-=j; ll+=j-1;
690 d=(XMLSTR)malloc((ll+1)*
sizeof(XMLCHAR));
699 if ((*ss==_X(
'X'))||(*ss==_X(
'x')))
704 if ((*ss>=_X(
'0'))&&(*ss<=_X(
'9'))) j=(j<<4)+*ss-_X(
'0');
705 else if ((*ss>=_X(
'A'))&&(*ss<=_X(
'F'))) j=(j<<4)+*ss-_X(
'A')+10;
706 else if ((*ss>=_X(
'a'))&&(*ss<=_X(
'f'))) j=(j<<4)+*ss-_X(
'a')+10;
707 else { free((
void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;
return NULL;}
714 if ((*ss>=_X(
'0'))&&(*ss<=_X(
'9'))) j=(j*10)+*ss-_X(
'0');
715 else { free((
void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;
return NULL;}
719 (*d++)=(XMLCHAR)j; ss++;
725 if (xstrnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l;
break; }
734 switch(XML_ByteTable[(
unsigned char)*ss])
736 case 4: *(d++)=*(ss++); ll--;
737 case 3: *(d++)=*(ss++); ll--;
738 case 2: *(d++)=*(ss++); ll--;
739 case 1: *(d++)=*(ss++);
748 #define XML_isSPACECHAR(ch) ((ch==_X('\n'))||(ch==_X(' '))||(ch== _X('\t'))||(ch==_X('\r')))
751 char myTagCompare(XMLCSTR cclose, XMLCSTR copen)
756 if (!cclose)
return 1;
757 int l=(int)xstrlen(cclose);
758 if (xstrnicmp(cclose, copen, l)!=0)
return 1;
759 const XMLCHAR c=copen[l];
760 if (XML_isSPACECHAR(c)||
764 (c==_X(
'=' )))
return 0;
769 static inline XMLCHAR getNextChar(XML *pXML)
771 XMLCHAR ch = pXML->lpXML[pXML->nIndex];
773 if (ch!=0) pXML->nIndex++;
775 pXML->nIndex+=XML_ByteTable[(
unsigned char)ch];
782 static NextToken GetNextToken(XML *pXML,
int *pcbToken,
enum XMLTokenTypeTag *pType)
787 int indexStart,nFoundMatch,nIsText=FALSE;
791 do { indexStart=pXML->nIndex; ch=getNextChar(pXML); }
while XML_isSPACECHAR(ch);
796 result.pStr = &pXML->lpXML[indexStart];
800 ALLXMLClearTag *ctag=XMLClearTags;
803 if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0)
806 pXML->nIndex+=ctag->openTagLen-1;
811 }
while(ctag->lpszOpen);
820 *pType = eTokenQuotedText;
827 while((ch = getNextChar(pXML)))
829 if (ch==chTemp) { nFoundMatch = TRUE;
break; }
830 if (ch==_X(
'<'))
break;
834 if (nFoundMatch == FALSE)
836 pXML->nIndex=indexStart+1;
848 *pType = eTokenEquals;
853 *pType = eTokenCloseTag;
861 chTemp = pXML->lpXML[pXML->nIndex];
864 if (chTemp == _X(
'/'))
868 *pType = eTokenTagEnd;
872 else if (chTemp == _X(
'?'))
877 *pType = eTokenDeclaration;
883 *pType = eTokenTagStart;
891 chTemp = pXML->lpXML[pXML->nIndex];
894 if (chTemp == _X(
'>'))
898 *pType = eTokenShortHandClose;
915 while((ch = getNextChar(pXML)))
917 if XML_isSPACECHAR(ch)
921 }
else if (ch==_X(
'/'))
925 ch=pXML->lpXML[pXML->nIndex];
927 if (ch==_X(
'>')) { pXML->nIndex--;
break; }
929 }
else if ((ch==_X(
'<'))||(ch==_X(
'>'))||(ch==_X(
'=')))
931 pXML->nIndex--;
break;
935 *pcbToken = pXML->nIndex-indexStart;
940 *pType = eTokenError;
947 XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName)
949 if (!d) { free(lpszName);
return NULL; }
950 if (d->lpszName&&(lpszName!=d->lpszName)) free((
void*)d->lpszName);
951 d->lpszName=lpszName;
956 XMLNode::XMLNode(
struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; }
957 XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName,
char isDeclaration)
959 d=(XMLNodeData*)malloc(
sizeof(XMLNodeData));
968 d->isDeclaration = isDeclaration;
970 d->pParent = pParent;
977 updateName_WOSD(lpszName);
980 XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName,
char isDeclaration) {
return XMLNode(NULL,lpszName,isDeclaration); }
981 XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName,
char isDeclaration) {
return XMLNode(NULL,stringDup(lpszName),isDeclaration); }
983 #define MEMORYINCREASE 50
985 static inline void myFree(
void *p) {
if (p) free(p); };
986 static inline void *myRealloc(
void *p,
int newsize,
int memInc,
int sizeofElem)
988 if (p==NULL) {
if (memInc)
return malloc(memInc*sizeofElem);
return malloc(sizeofElem); }
989 if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem);
998 int XMLNode::findPosition(XMLNodeData *d,
int index, XMLElementType xtype)
1000 if (index<0)
return -1;
1001 int i=0,j=(int)((index<<2)+xtype),*o=d->pOrder; while (o[i]!=j) i++;
return i;
1006 int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t,
int index)
1008 int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t);
1009 memmove(o+i, o+i+1, (n-i)*
sizeof(
int));
1011 if ((o[i]&3)==(
int)t) o[i]-=4;
1019 void *XMLNode::addToOrder(
int memoryIncrease,
int *_pos,
int nc,
void *p,
int size, XMLElementType xtype)
1023 p=myRealloc(p,(nc+1),memoryIncrease,size);
1024 int n=d->nChild+d->nText+d->nClear;
1025 d->pOrder=(
int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,
sizeof(
int));
1026 int pos=*_pos,*o=d->pOrder;
1028 if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype);
return p; }
1031 memmove(o+i+1, o+i, (n-i)*
sizeof(
int));
1033 while ((pos<n)&&((o[pos]&3)!=(
int)xtype)) pos++;
1034 if (pos==n) { *_pos=nc; o[n]=(int)((nc<<2)+xtype);
return p; }
1037 for (i=pos+1;i<=n;i++)
if ((o[i]&3)==(int)xtype) o[i]+=4;
1039 *_pos=pos=o[pos]>>2;
1040 memmove(((
char*)p)+(pos+1)*size,((
char*)p)+pos*size,(nc-pos)*size);
1046 XMLNode XMLNode::addChild_priv(
int memoryIncrease, XMLSTR lpszName,
char isDeclaration,
int pos)
1048 if (!lpszName)
return emptyXMLNode;
1049 d->pChild=(XMLNode*)addToOrder(memoryIncrease,&pos,d->nChild,d->pChild,
sizeof(XMLNode),eNodeChild);
1050 d->pChild[pos].d=NULL;
1051 d->pChild[pos]=XMLNode(d,lpszName,isDeclaration);
1053 return d->pChild[pos];
1057 XMLAttribute *XMLNode::addAttribute_priv(
int memoryIncrease,XMLSTR lpszName, XMLSTR lpszValuev)
1059 if (!lpszName)
return &emptyXMLAttribute;
1060 if (!d) { myFree(lpszName); myFree(lpszValuev);
return &emptyXMLAttribute; }
1061 int nc=d->nAttribute;
1062 d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(nc+1),memoryIncrease,
sizeof(XMLAttribute));
1063 XMLAttribute *pAttr=d->pAttribute+nc;
1064 pAttr->lpszName = lpszName;
1065 pAttr->lpszValue = lpszValuev;
1071 XMLCSTR XMLNode::addText_priv(
int memoryIncrease, XMLSTR lpszValue,
int pos)
1073 if (!lpszValue)
return NULL;
1074 if (!d) { myFree(lpszValue);
return NULL; }
1075 d->pText=(XMLCSTR*)addToOrder(memoryIncrease,&pos,d->nText,d->pText,
sizeof(XMLSTR),eNodeText);
1076 d->pText[pos]=lpszValue;
1082 XMLClear *XMLNode::addClear_priv(
int memoryIncrease, XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose,
int pos)
1084 if (!lpszValue)
return &emptyXMLClear;
1085 if (!d) { myFree(lpszValue);
return &emptyXMLClear; }
1086 d->pClear=(XMLClear *)addToOrder(memoryIncrease,&pos,d->nClear,d->pClear,
sizeof(XMLClear),eNodeClear);
1087 XMLClear *pNewClear=d->pClear+pos;
1088 pNewClear->lpszValue = lpszValue;
1089 if (!lpszOpen) lpszOpen=XMLClearTags->lpszOpen;
1090 if (!lpszClose) lpszClose=XMLClearTags->lpszClose;
1091 pNewClear->lpszOpenTag = lpszOpen;
1092 pNewClear->lpszCloseTag = lpszClose;
1099 char XMLNode::parseClearTag(
void *px,
void *_pClear)
1101 XML *pXML=(XML *)px;
1102 ALLXMLClearTag pClear=*((ALLXMLClearTag*)_pClear);
1104 XMLCSTR lpszTemp=NULL;
1105 XMLCSTR lpXML=&pXML->lpXML[pXML->nIndex];
1106 static XMLCSTR docTypeEnd=_X(
"]>");
1110 if (pClear.lpszOpen==XMLClearTags[1].lpszOpen)
1115 if (*pCh==_X(
'<')) { pClear.lpszClose=docTypeEnd; lpszTemp=xstrstr(lpXML,docTypeEnd);
break; }
1116 else if (*pCh==_X(
'>')) { lpszTemp=pCh;
break; }
1120 pCh+=XML_ByteTable[(
unsigned char)(*pCh)];
1123 }
else lpszTemp=xstrstr(lpXML, pClear.lpszClose);
1128 cbTemp = (int)(lpszTemp - lpXML);
1130 pXML->nIndex += cbTemp+(int)xstrlen(pClear.lpszClose);
1133 addClear_priv(MEMORYINCREASE,stringDup(lpXML,cbTemp), pClear.lpszOpen, pClear.lpszClose,-1);
1138 pXML->error = eXMLErrorUnmatchedEndClearTag;
1142 void XMLNode::exactMemory(XMLNodeData *d)
1144 if (d->pOrder) d->pOrder=(
int*)realloc(d->pOrder,(d->nChild+d->nText+d->nClear)*
sizeof(int));
1145 if (d->pChild) d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*
sizeof(XMLNode));
1146 if (d->pAttribute) d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*
sizeof(XMLAttribute));
1147 if (d->pText) d->pText=(XMLCSTR*)realloc(d->pText,d->nText*
sizeof(XMLSTR));
1148 if (d->pClear) d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*
sizeof(XMLClear));
1151 char XMLNode::maybeAddTxT(
void *pa, XMLCSTR tokenPStr)
1153 XML *pXML=(XML *)pa;
1154 XMLCSTR lpszText=pXML->lpszText;
1155 if (!lpszText)
return 0;
1156 if (dropWhiteSpace)
while (XML_isSPACECHAR(*lpszText)&&(lpszText!=tokenPStr)) lpszText++;
1157 int cbText = (int)(tokenPStr - lpszText);
1158 if (!cbText) { pXML->lpszText=NULL;
return 0; }
1159 if (dropWhiteSpace) { cbText--;
while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; }
1160 if (!cbText) { pXML->lpszText=NULL;
return 0; }
1161 XMLSTR lpt=fromXMLString(lpszText,cbText,pXML);
1163 addText_priv(MEMORYINCREASE,lpt,-1);
1164 pXML->lpszText=NULL;
1169 int XMLNode::ParseXMLElement(
void *pa)
1171 XML *pXML=(XML *)pa;
1173 enum XMLTokenTypeTag xtype;
1175 XMLCSTR lpszTemp=NULL;
1180 enum Attrib attrib = eAttribName;
1188 pXML->nFirst = FALSE;
1189 status = eOutsideTag;
1193 status = eInsideTag;
1200 token = GetNextToken(pXML, &cbToken, &xtype);
1202 if (xtype != eTokenError)
1216 case eTokenCloseTag:
1217 case eTokenShortHandClose:
1218 case eTokenQuotedText:
1223 case eTokenTagStart:
1224 case eTokenDeclaration:
1227 nDeclaration = (xtype == eTokenDeclaration);
1230 if (maybeAddTxT(pXML,token.pStr))
return FALSE;
1233 token = GetNextToken(pXML, &cbToken, &xtype);
1237 if (xtype != eTokenText)
1239 pXML->error = eXMLErrorMissingTagName;
1246 #ifdef APPROXIMATE_PARSING
1248 myTagCompare(d->lpszName, token.pStr) == 0)
1252 pXML->lpNewElement = token.pStr;
1253 pXML->cbNewElement = cbToken;
1261 pNew = addChild_priv(MEMORYINCREASE,stringDup(token.pStr,cbToken), nDeclaration,-1);
1263 while (!pNew.isEmpty())
1269 if (!pNew.ParseXMLElement(pXML))
return FALSE;
1284 pXML->error=eXMLErrorUnmatchedEndTag;
1292 if (myTagCompare(d->lpszName, pXML->lpEndTag)==0)
1299 if (pXML->cbNewElement)
1309 if (myTagCompare(d->lpszName, pXML->lpNewElement)==0)
1315 pNew = addChild_priv(MEMORYINCREASE,stringDup(pXML->lpNewElement,pXML->cbNewElement),0,-1);
1316 pXML->cbNewElement = 0;
1321 pNew = emptyXMLNode;
1333 if (maybeAddTxT(pXML,token.pStr))
return FALSE;
1336 token = GetNextToken(pXML, &cbTemp, &xtype);
1339 if (xtype != eTokenText)
1341 pXML->error = eXMLErrorMissingEndTagName;
1344 lpszTemp = token.pStr;
1347 token = GetNextToken(pXML, &cbToken, &xtype);
1348 if (xtype != eTokenCloseTag)
1350 pXML->error = eXMLErrorMissingEndTagName;
1353 pXML->lpszText=pXML->lpXML+pXML->nIndex;
1358 if (myTagCompare(d->lpszName, lpszTemp) != 0)
1359 #ifdef STRICT_PARSING
1361 pXML->error=eXMLErrorUnmatchedEndTag;
1362 pXML->nIndexMissigEndTag=pXML->nIndex;
1367 pXML->error=eXMLErrorMissingEndTag;
1368 pXML->nIndexMissigEndTag=pXML->nIndex;
1369 pXML->lpEndTag = lpszTemp;
1370 pXML->cbEndTag = cbTemp;
1381 if (maybeAddTxT(pXML,token.pStr))
return FALSE;
1382 if (parseClearTag(pXML, token.pClr))
return FALSE;
1383 pXML->lpszText=pXML->lpXML+pXML->nIndex;
1409 lpszTemp = token.pStr;
1411 attrib = eAttribEquals;
1416 case eTokenCloseTag:
1418 status = eOutsideTag;
1419 pXML->lpszText=pXML->lpXML+pXML->nIndex;
1424 case eTokenShortHandClose:
1426 pXML->lpszText=pXML->lpXML+pXML->nIndex;
1430 case eTokenQuotedText:
1431 case eTokenTagStart:
1434 case eTokenDeclaration:
1436 pXML->error = eXMLErrorUnexpectedToken;
1451 addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
1454 lpszTemp = token.pStr;
1460 case eTokenShortHandClose:
1461 case eTokenCloseTag:
1464 pXML->lpszText=pXML->lpXML+pXML->nIndex;
1466 if (d->isDeclaration &&
1467 (lpszTemp[cbTemp-1]) == _X(
'?'))
1475 addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
1479 if (xtype == eTokenShortHandClose)
1486 status = eOutsideTag;
1494 attrib = eAttribValue;
1498 case eTokenQuotedText:
1499 case eTokenTagStart:
1501 case eTokenDeclaration:
1503 pXML->error = eXMLErrorUnexpectedToken;
1518 case eTokenQuotedText:
1521 if (d->isDeclaration &&
1522 (token.pStr[cbToken-1]) == _X(
'?'))
1530 if (xtype==eTokenQuotedText) { token.pStr++; cbToken-=2; }
1531 XMLSTR attrVal=(XMLSTR)token.pStr;
1534 attrVal=fromXMLString(attrVal,cbToken,pXML);
1535 if (!attrVal)
return FALSE;
1537 addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal);
1541 attrib = eAttribName;
1545 case eTokenTagStart:
1547 case eTokenCloseTag:
1548 case eTokenShortHandClose:
1550 case eTokenDeclaration:
1552 pXML->error = eXMLErrorUnexpectedToken;
1563 if ((!d->isDeclaration)&&(d->pParent))
1565 #ifdef STRICT_PARSING
1566 pXML->error=eXMLErrorUnmatchedEndTag;
1568 pXML->error=eXMLErrorMissingEndTag;
1570 pXML->nIndexMissigEndTag=pXML->nIndex;
1572 maybeAddTxT(pXML,pXML->lpXML+pXML->nIndex);
1579 static void CountLinesAndColumns(XMLCSTR lpXML,
int nUpto, XMLResults *pResults)
1585 struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
1587 pResults->nLine = 1;
1588 pResults->nColumn = 1;
1589 while (xml.nIndex<nUpto)
1591 ch = getNextChar(&xml);
1592 if (ch != _X(
'\n')) pResults->nColumn++;
1596 pResults->nColumn=1;
1602 XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults)
1608 pResults->error=eXMLErrorNoElements;
1610 pResults->nColumn=0;
1612 return emptyXMLNode;
1615 XMLNode xnode(NULL,NULL,FALSE);
1616 struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
1619 xnode.ParseXMLElement(&xml);
1620 enum XMLError error = xml.error;
1621 if (!xnode.nChildNode()) error=eXMLErrorNoXMLTagFound;
1622 if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode();
1625 if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag)||(error==eXMLErrorNoXMLTagFound))
1627 XMLCSTR name=xnode.getName();
1628 if (tag&&xstrlen(tag)&&((!name)||(xstricmp(xnode.getName(),tag))))
1632 while (i<xnode.nChildNode())
1634 nodeTmp=xnode.getChildNode(i);
1635 if (xstricmp(nodeTmp.getName(),tag)==0)
break;
1636 if (nodeTmp.isDeclaration()) { xnode=nodeTmp; i=0; }
else i++;
1638 if (i>=xnode.nChildNode())
1642 pResults->error=eXMLErrorFirstTagNotFound;
1644 pResults->nColumn=0;
1646 return emptyXMLNode;
1653 xnode = emptyXMLNode;
1660 pResults->error = error;
1663 if (error!=eXMLErrorNone)
1665 if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag;
1667 CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults);
1673 XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults)
1675 if (pResults) { pResults->nLine=0; pResults->nColumn=0; }
1676 FILE *f=xfopen(filename,_X(
"rb"));
1677 if (f==NULL) {
if (pResults) pResults->error=eXMLErrorFileNotFound;
return emptyXMLNode; }
1678 fseek(f,0,SEEK_END);
1679 int l=ftell(f),headerSz=0;
1680 if (!l) {
if (pResults) pResults->error=eXMLErrorEmpty; fclose(f);
return emptyXMLNode; }
1681 fseek(f,0,SEEK_SET);
1682 unsigned char *buf=(
unsigned char*)malloc(l+4);
1685 buf[l]=0;buf[l+1]=0;buf[l+2]=0;buf[l+3]=0;
1687 if (guessWideCharChars)
1689 if (!myIsTextWideChar(buf,l))
1691 if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
1692 XMLSTR b2=myMultiByteToWideChar((
const char*)(buf+headerSz));
1693 free(buf); buf=(
unsigned char*)b2; headerSz=0;
1696 if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
1697 if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
1701 if (guessWideCharChars)
1703 if (myIsTextWideChar(buf,l))
1706 if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
1707 if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
1708 char *b2=myWideCharToMultiByte((
const wchar_t*)(buf+headerSz));
1709 free(buf); buf=(
unsigned char*)b2; headerSz=0;
1712 if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
1717 if (!buf) {
if (pResults) pResults->error=eXMLErrorCharConversionError;
return emptyXMLNode; }
1718 XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults);
1723 static inline void charmemset(XMLSTR dest,XMLCHAR c,
int l) {
while (l--) *(dest++)=c; }
1730 int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker,
int nFormat)
1735 int nChildFormat=-1;
1736 int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear;
1741 #define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0)
1744 cbElement = (int)LENSTR(pEntry->lpszName);
1749 cb = nFormat == -1 ? 0 : nFormat;
1753 if (cb) charmemset(lpszMarker, INDENTCHAR,
sizeof(XMLCHAR)*cb);
1755 lpszMarker[nResult++]=_X(
'<');
1756 if (pEntry->isDeclaration) lpszMarker[nResult++]=_X(
'?');
1757 xstrcpy(&lpszMarker[nResult], pEntry->lpszName);
1759 lpszMarker[nResult++]=_X(
' ');
1763 nResult+=cbElement+2+cb;
1764 if (pEntry->isDeclaration) nResult++;
1768 XMLAttribute *pAttr=pEntry->pAttribute;
1769 for (i=0; i<pEntry->nAttribute; i++)
1772 cb = (int)LENSTR(pAttr->lpszName);
1775 if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName);
1778 if (pAttr->lpszValue)
1780 cb=(int)lengthXMLString(pAttr->lpszValue);
1783 lpszMarker[nResult]=_X(
'=');
1784 lpszMarker[nResult+1]=_X(
'"');
1785 if (cb) toXMLStringUnSafe(&lpszMarker[nResult+2],pAttr->lpszValue);
1786 lpszMarker[nResult+cb+2]=_X(
'"');
1790 if (lpszMarker) lpszMarker[nResult] = _X(
' ');
1796 if (pEntry->isDeclaration)
1800 lpszMarker[nResult-1]=_X(
'?');
1801 lpszMarker[nResult]=_X(
'>');
1806 if (lpszMarker) lpszMarker[nResult]=_X(
'\n');
1813 if (lpszMarker) lpszMarker[nResult-1]=_X(
'>');
1816 if (lpszMarker) lpszMarker[nResult]=_X(
'\n');
1826 if (cbElement&&(!pEntry->isDeclaration)) nChildFormat=nFormat+1;
1827 else nChildFormat=nFormat;
1831 for (i=0; i<nElementI; i++)
1833 j=pEntry->pOrder[i];
1834 switch((XMLElementType)(j&3))
1840 XMLCSTR pChild=pEntry->pText[j>>2];
1841 cb = (int)lengthXMLString(pChild);
1848 charmemset(&lpszMarker[nResult],INDENTCHAR,
sizeof(XMLCHAR)*(nFormat + 1));
1849 toXMLStringUnSafe(&lpszMarker[nResult+nFormat+1],pChild);
1850 lpszMarker[nResult+nFormat+1+cb]=_X(
'\n');
1852 nResult+=cb+nFormat+2;
1855 if (lpszMarker) toXMLStringUnSafe(&lpszMarker[nResult], pChild);
1865 XMLClear *pChild=pEntry->pClear+(j>>2);
1867 cb = (int)LENSTR(pChild->lpszOpenTag);
1874 charmemset(&lpszMarker[nResult], INDENTCHAR,
sizeof(XMLCHAR)*(nFormat + 1));
1875 xstrcpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag);
1877 nResult+=cb+nFormat+1;
1881 if (lpszMarker)xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag);
1887 cb = (int)LENSTR(pChild->lpszValue);
1890 if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue);
1895 cb = (int)LENSTR(pChild->lpszCloseTag);
1898 if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag);
1904 if (lpszMarker) lpszMarker[nResult] = _X(
'\n');
1914 nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat);
1921 if ((cbElement)&&(!pEntry->isDeclaration))
1934 charmemset(&lpszMarker[nResult], INDENTCHAR,
sizeof(XMLCHAR)*nFormat);
1939 xstrcpy(&lpszMarker[nResult], _X(
"</"));
1941 xstrcpy(&lpszMarker[nResult], pEntry->lpszName);
1942 nResult += cbElement;
1946 xstrcpy(&lpszMarker[nResult], _X(
">"));
1950 xstrcpy(&lpszMarker[nResult], _X(
">\n"));
1955 if (nFormat != -1) nResult+=cbElement+4+nFormat;
1956 else nResult+=cbElement+3;
1967 xstrcpy(&lpszMarker[nResult], _X(
"/>"));
1972 xstrcpy(&lpszMarker[nResult], _X(
"/>\n"));
1978 nResult += nFormat == -1 ? 2 : 3;
1997 XMLSTR XMLNode::createXMLString(
int nFormat,
int *pnSize)
const
1999 if (!d) {
if (pnSize) *pnSize=0;
return NULL; }
2001 XMLSTR lpszResult = NULL;
2005 if (!dropWhiteSpace) nFormat=0;
2006 nFormat = nFormat ? 0 : -1;
2007 cbStr = CreateXMLStringR(d, 0, nFormat);
2011 lpszResult=(XMLSTR)malloc((cbStr+1)*
sizeof(XMLCHAR));
2012 CreateXMLStringR(d, lpszResult, nFormat);
2013 if (pnSize) *pnSize = cbStr;
2017 int XMLNode::detachFromParent(XMLNodeData *d)
2019 XMLNode *pa=d->pParent->pChild;
2021 while (((
void*)(pa[i].d))!=((
void*)d)) i++;
2022 d->pParent->nChild--;
2023 if (d->pParent->nChild) memmove(pa+i,pa+i+1,(d->pParent->nChild-i)*
sizeof(XMLNode));
2024 else { free(pa); d->pParent->pChild=NULL; }
2025 return removeOrderElement(d->pParent,eNodeChild,i);
2028 XMLNode::~XMLNode() { deleteNodeContent_priv(1,0); }
2029 void XMLNode::deleteNodeContent(){ deleteNodeContent_priv(0,1); }
2030 void XMLNode::deleteNodeContent_priv(
char isInDestuctor,
char force)
2033 if (isInDestuctor) (d->ref_count)--;
2034 if ((d->ref_count==0)||force)
2037 if (d->pParent) detachFromParent(d);
2038 for(i=0; i<d->nChild; i++) { d->pChild[i].d->pParent=NULL; d->pChild[i].deleteNodeContent_priv(1,force); }
2040 for(i=0; i<d->nText; i++) free((
void*)d->pText[i]);
2042 for(i=0; i<d->nClear; i++) free((
void*)d->pClear[i].lpszValue);
2044 for(i=0; i<d->nAttribute; i++)
2046 free((
void*)d->pAttribute[i].lpszName);
2047 if (d->pAttribute[i].lpszValue) free((
void*)d->pAttribute[i].lpszValue);
2049 myFree(d->pAttribute);
2051 myFree((
void*)d->lpszName);
2052 d->nChild=0; d->nText=0; d->nClear=0; d->nAttribute=0;
2053 d->pChild=NULL; d->pText=NULL; d->pClear=NULL; d->pAttribute=NULL;
2054 d->pOrder=NULL; d->lpszName=NULL; d->pParent=NULL;
2056 if (d->ref_count==0)
2063 XMLNode XMLNode::addChild(XMLNode childNode,
int pos)
2065 XMLNodeData *dc=childNode.d;
2066 if ((!dc)||(!d))
return childNode;
2067 if (dc->pParent) {
if ((detachFromParent(dc)<=pos)&&(dc->pParent==d)) pos--; }
else dc->ref_count++;
2071 d->pChild=(XMLNode*)addToOrder(0,&pos,d->nChild,d->pChild,
sizeof(XMLNode),eNodeChild);
2072 d->pChild[pos].d=dc;
2077 void XMLNode::deleteAttribute(
int i)
2079 if ((!d)||(i<0)||(i>=d->nAttribute))
return;
2081 XMLAttribute *p=d->pAttribute+i;
2082 free((
void*)p->lpszName);
2083 if (p->lpszValue) free((
void*)p->lpszValue);
2084 if (d->nAttribute) memmove(p,p+1,(d->nAttribute-i)*
sizeof(XMLAttribute));
else { free(p); d->pAttribute=NULL; }
2087 void XMLNode::deleteAttribute(XMLAttribute *a){
if (a) deleteAttribute(a->lpszName); }
2088 void XMLNode::deleteAttribute(XMLCSTR lpszName)
2091 getAttribute(lpszName,&j);
2092 if (j) deleteAttribute(j-1);
2095 XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,
int i)
2097 if (!d) {
if (lpszNewValue) free(lpszNewValue);
if (lpszNewName) free(lpszNewName);
return NULL; }
2098 if (i>=d->nAttribute)
2100 if (lpszNewName)
return addAttribute_WOSD(lpszNewName,lpszNewValue);
2103 XMLAttribute *p=d->pAttribute+i;
2104 if (p->lpszValue&&p->lpszValue!=lpszNewValue) free((
void*)p->lpszValue);
2105 p->lpszValue=lpszNewValue;
2106 if (lpszNewName&&p->lpszName!=lpszNewName) { free((
void*)p->lpszName); p->lpszName=lpszNewName; };
2110 XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
2112 if (oldAttribute)
return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue,(XMLSTR)newAttribute->lpszName,oldAttribute->lpszName);
2113 return addAttribute_WOSD((XMLSTR)newAttribute->lpszName,(XMLSTR)newAttribute->lpszValue);
2116 XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName)
2119 getAttribute(lpszOldName,&j);
2120 if (j)
return updateAttribute_WOSD(lpszNewValue,lpszNewName,j-1);
2123 if (lpszNewName)
return addAttribute_WOSD(lpszNewName,lpszNewValue);
2124 else return addAttribute_WOSD(stringDup(lpszOldName),lpszNewValue);
2128 int XMLNode::indexText(XMLCSTR lpszValue)
const
2132 if (!lpszValue) {
if (l)
return 0;
return -1; }
2133 XMLCSTR *p=d->pText;
2134 for (i=0; i<l; i++)
if (lpszValue==p[i])
return i;
2138 void XMLNode::deleteText(
int i)
2140 if ((!d)||(i<0)||(i>=d->nText))
return;
2142 XMLCSTR *p=d->pText+i;
2144 if (d->nText) memmove(p,p+1,(d->nText-i)*
sizeof(XMLCSTR));
else { free(p); d->pText=NULL; }
2145 removeOrderElement(d,eNodeText,i);
2148 void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); }
2150 XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue,
int i)
2152 if (!d) {
if (lpszNewValue) free(lpszNewValue);
return NULL; }
2153 if (i>=d->nText)
return addText_WOSD(lpszNewValue);
2154 XMLCSTR *p=d->pText+i;
2155 if (*p!=lpszNewValue) { free((
void*)*p); *p=lpszNewValue; }
2156 return lpszNewValue;
2159 XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue)
2161 if (!d) {
if (lpszNewValue) free(lpszNewValue);
return NULL; }
2162 int i=indexText(lpszOldValue);
2163 if (i>=0)
return updateText_WOSD(lpszNewValue,i);
2164 return addText_WOSD(lpszNewValue);
2167 void XMLNode::deleteClear(
int i)
2169 if ((!d)||(i<0)||(i>=d->nClear))
return;
2171 XMLClear *p=d->pClear+i;
2172 free((
void*)p->lpszValue);
2173 if (d->nClear) memmove(p,p+1,(d->nClear-i)*
sizeof(XMLClear));
else { free(p); d->pClear=NULL; }
2174 removeOrderElement(d,eNodeClear,i);
2177 int XMLNode::indexClear(XMLCSTR lpszValue)
const
2181 if (!lpszValue) {
if (l)
return 0;
return -1; }
2182 XMLClear *p=d->pClear;
2183 for (i=0; i<l; i++)
if (lpszValue==p[i].lpszValue)
return i;
2187 void XMLNode::deleteClear(XMLCSTR lpszValue) { deleteClear(indexClear(lpszValue)); }
2188 void XMLNode::deleteClear(XMLClear *a) {
if (a) deleteClear(a->lpszValue); }
2190 XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent,
int i)
2192 if (!d) {
if (lpszNewContent) free(lpszNewContent);
return NULL; }
2193 if (i>=d->nClear)
return addClear_WOSD(lpszNewContent);
2194 XMLClear *p=d->pClear+i;
2195 if (lpszNewContent!=p->lpszValue) { free((
void*)p->lpszValue); p->lpszValue=lpszNewContent; }
2199 XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, XMLCSTR lpszOldValue)
2201 if (!d) {
if (lpszNewContent) free(lpszNewContent);
return NULL; }
2202 int i=indexClear(lpszOldValue);
2203 if (i>=0)
return updateClear_WOSD(lpszNewContent,i);
2204 return addClear_WOSD(lpszNewContent);
2207 XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP,XMLClear *oldP)
2209 if (oldP)
return updateClear_WOSD((XMLSTR)newP->lpszValue,(XMLSTR)oldP->lpszValue);
2213 XMLNode& XMLNode::operator=(
const XMLNode& A )
2218 deleteNodeContent_priv(1,0);
2220 if (d) (d->ref_count) ++ ;
2225 XMLNode::XMLNode(
const XMLNode &A)
2229 if (d) (d->ref_count)++ ;
2232 int XMLNode::nChildNode(XMLCSTR name)
const
2235 int i,j=0,n=d->nChild;
2236 XMLNode *pc=d->pChild;
2239 if (xstricmp(pc->d->lpszName, name)==0) j++;
2245 XMLNode XMLNode::getChildNode(XMLCSTR name,
int *j)
const
2247 if (!d)
return emptyXMLNode;
2248 int i=0,n=d->nChild;
2250 XMLNode *pc=d->pChild+i;
2253 if (xstricmp(pc->d->lpszName, name)==0)
2260 return emptyXMLNode;
2263 XMLNode XMLNode::getChildNode(XMLCSTR name,
int j)
const
2265 if (!d)
return emptyXMLNode;
2267 while (j-->0) getChildNode(name,&i);
2268 return getChildNode(name,&i);
2271 int XMLNode::positionOfText (
int i)
const {
if (i>=d->nText ) i=d->nText-1;
return findPosition(d,i,eNodeText ); }
2272 int XMLNode::positionOfClear (
int i)
const {
if (i>=d->nClear) i=d->nClear-1;
return findPosition(d,i,eNodeClear); }
2273 int XMLNode::positionOfChildNode(
int i)
const {
if (i>=d->nChild) i=d->nChild-1;
return findPosition(d,i,eNodeChild); }
2274 int XMLNode::positionOfText (XMLCSTR lpszValue)
const {
return positionOfText (indexText (lpszValue)); }
2275 int XMLNode::positionOfClear(XMLCSTR lpszValue)
const {
return positionOfClear(indexClear(lpszValue)); }
2276 int XMLNode::positionOfClear(XMLClear *a)
const {
if (a)
return positionOfClear(a->lpszValue);
return positionOfClear(); }
2277 int XMLNode::positionOfChildNode(XMLNode x)
const
2279 if ((!d)||(!x.d))
return -1;
2280 XMLNodeData *dd=x.d;
2281 XMLNode *pc=d->pChild;
2283 while (i--)
if (pc[i].d==dd)
return findPosition(d,i,eNodeChild);
2286 int XMLNode::positionOfChildNode(XMLCSTR name,
int count)
const
2288 if (!name)
return positionOfChildNode(count);
2290 do { getChildNode(name,&j);
if (j<0)
return -1; }
while (count--);
2291 return findPosition(d,j-1,eNodeChild);
2294 XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name,XMLCSTR attributeName,XMLCSTR attributeValue,
int *k)
const
2302 x=getChildNode(name,&i);
2310 t=x.getAttribute(attributeName,&j);
2311 if (t&&(xstricmp(attributeValue,t)==0)) {
if (k) *k=i+1;
return x; }
2315 if (x.isAttributeSet(attributeName)) {
if (k) *k=i+1;
return x; }
2318 }
while (!x.isEmpty());
2319 return emptyXMLNode;
2323 XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib,
int *j)
const
2325 if (!d)
return NULL;
2326 int i=0,n=d->nAttribute;
2328 XMLAttribute *pAttr=d->pAttribute+i;
2331 if (xstricmp(pAttr->lpszName, lpszAttrib)==0)
2334 return pAttr->lpszValue;
2341 char XMLNode::isAttributeSet(XMLCSTR lpszAttrib)
const
2343 if (!d)
return FALSE;
2344 int i,n=d->nAttribute;
2345 XMLAttribute *pAttr=d->pAttribute;
2348 if (xstricmp(pAttr->lpszName, lpszAttrib)==0)
2357 XMLCSTR XMLNode::getAttribute(XMLCSTR name,
int j)
const
2359 if (!d)
return NULL;
2361 while (j-->0) getAttribute(name,&i);
2362 return getAttribute(name,&i);
2365 XMLNodeContents XMLNode::enumContents(
int i)
const
2368 if (!d) { c.type=eNodeNULL;
return c; }
2369 if (i<d->nAttribute)
2371 c.type=eNodeAttribute;
2372 c.attrib=d->pAttribute[i];
2376 c.type=(XMLElementType)(d->pOrder[i]&3);
2377 i=(d->pOrder[i])>>2;
2380 case eNodeChild: c.child = d->pChild[i];
break;
2381 case eNodeText: c.text = d->pText[i];
break;
2382 case eNodeClear: c.clear = d->pClear[i];
break;
2388 XMLCSTR XMLNode::getName()
const {
if (!d)
return NULL;
return d->lpszName; }
2389 int XMLNode::nText()
const {
if (!d)
return 0;
return d->nText; }
2390 int XMLNode::nChildNode()
const {
if (!d)
return 0;
return d->nChild; }
2391 int XMLNode::nAttribute()
const {
if (!d)
return 0;
return d->nAttribute; }
2392 int XMLNode::nClear()
const {
if (!d)
return 0;
return d->nClear; }
2393 int XMLNode::nElement()
const {
if (!d)
return 0;
return d->nAttribute+d->nChild+d->nText+d->nClear; }
2394 XMLClear XMLNode::getClear (
int i)
const {
if ((!d)||(i>=d->nClear ))
return emptyXMLClear;
return d->pClear[i]; }
2395 XMLAttribute XMLNode::getAttribute (
int i)
const {
if ((!d)||(i>=d->nAttribute))
return emptyXMLAttribute;
return d->pAttribute[i]; }
2396 XMLCSTR XMLNode::getAttributeName (
int i)
const {
if ((!d)||(i>=d->nAttribute))
return NULL;
return d->pAttribute[i].lpszName; }
2397 XMLCSTR XMLNode::getAttributeValue(
int i)
const {
if ((!d)||(i>=d->nAttribute))
return NULL;
return d->pAttribute[i].lpszValue; }
2398 XMLCSTR XMLNode::getText (
int i)
const {
if ((!d)||(i>=d->nText ))
return NULL;
return d->pText[i]; }
2399 XMLNode XMLNode::getChildNode (
int i)
const {
if ((!d)||(i>=d->nChild ))
return emptyXMLNode;
return d->pChild[i]; }
2400 XMLNode XMLNode::getParentNode ( )
const {
if ((!d)||(!d->pParent ))
return emptyXMLNode;
return XMLNode(d->pParent); }
2401 char XMLNode::isDeclaration ( )
const {
if (!d)
return 0;
return d->isDeclaration; }
2402 char XMLNode::isEmpty ( )
const {
return (d==NULL); }
2403 XMLNode XMLNode::emptyNode ( ) {
return XMLNode::emptyXMLNode; }
2405 XMLNode XMLNode::addChild(XMLCSTR lpszName,
char isDeclaration,
int pos)
2406 {
return addChild_priv(0,stringDup(lpszName),isDeclaration,pos); }
2407 XMLNode XMLNode::addChild_WOSD(XMLSTR lpszName,
char isDeclaration,
int pos)
2408 {
return addChild_priv(0,lpszName,isDeclaration,pos); }
2409 XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue)
2410 {
return addAttribute_priv(0,stringDup(lpszName),stringDup(lpszValue)); }
2411 XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev)
2412 {
return addAttribute_priv(0,lpszName,lpszValuev); }
2413 XMLCSTR XMLNode::addText(XMLCSTR lpszValue,
int pos)
2414 {
return addText_priv(0,stringDup(lpszValue),pos); }
2415 XMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue,
int pos)
2416 {
return addText_priv(0,lpszValue,pos); }
2417 XMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose,
int pos)
2418 {
return addClear_priv(0,stringDup(lpszValue),lpszOpen,lpszClose,pos); }
2419 XMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose,
int pos)
2420 {
return addClear_priv(0,lpszValue,lpszOpen,lpszClose,pos); }
2421 XMLCSTR XMLNode::updateName(XMLCSTR lpszName)
2422 {
return updateName_WOSD(stringDup(lpszName)); }
2423 XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
2424 {
return updateAttribute_WOSD(stringDup(newAttribute->lpszValue),stringDup(newAttribute->lpszName),oldAttribute->lpszName); }
2425 XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,
int i)
2426 {
return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),i); }
2427 XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName)
2428 {
return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),lpszOldName); }
2429 XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue,
int i)
2430 {
return updateText_WOSD(stringDup(lpszNewValue),i); }
2431 XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
2432 {
return updateText_WOSD(stringDup(lpszNewValue),lpszOldValue); }
2433 XMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent,
int i)
2434 {
return updateClear_WOSD(stringDup(lpszNewContent),i); }
2435 XMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
2436 {
return updateClear_WOSD(stringDup(lpszNewValue),lpszOldValue); }
2437 XMLClear *XMLNode::updateClear(XMLClear *newP,XMLClear *oldP)
2438 {
return updateClear_WOSD(stringDup(newP->lpszValue),oldP->lpszValue); }
2440 char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding,
char _guessWideCharChars,
char _dropWhiteSpace)
2442 guessWideCharChars=_guessWideCharChars; dropWhiteSpace=_dropWhiteSpace;
2444 if (_characterEncoding) characterEncoding=_characterEncoding;
2446 switch(_characterEncoding)
2448 case encoding_UTF8: characterEncoding=_characterEncoding; XML_ByteTable=XML_utf8ByteTable;
break;
2449 case encoding_ascii: characterEncoding=_characterEncoding; XML_ByteTable=XML_asciiByteTable;
break;
2450 case encoding_ShiftJIS: characterEncoding=_characterEncoding; XML_ByteTable=XML_sjisByteTable;
break;
2457 XMLNode::XMLCharEncoding XMLNode::guessCharEncoding(
void *buf,
int l,
char useXMLEncodingAttribute)
2460 return (XMLCharEncoding)0;
2462 if (l<25)
return (XMLCharEncoding)0;
2463 if (guessWideCharChars&&(myIsTextWideChar(buf,l)))
return (XMLCharEncoding)0;
2464 unsigned char *b=(
unsigned char*)buf;
2465 if ((b[0]==0xef)&&(b[1]==0xbb)&&(b[2]==0xbf))
return encoding_UTF8;
2468 XMLCharEncoding bestGuess=encoding_UTF8;
2471 switch (XML_utf8ByteTable[b[i]])
2473 case 4: i++;
if ((i<l)&&(b[i]& 0xC0)!=0x80) { bestGuess=encoding_ascii; i=l; }
2474 case 3: i++;
if ((i<l)&&(b[i]& 0xC0)!=0x80) { bestGuess=encoding_ascii; i=l; }
2475 case 2: i++;
if ((i<l)&&(b[i]& 0xC0)!=0x80) { bestGuess=encoding_ascii; i=l; }
2479 if (!useXMLEncodingAttribute)
return bestGuess;
2486 b=(
unsigned char*)strstr(bb,
"encoding");
2487 if (!b)
return bestGuess;
2488 b+=8;
while XML_isSPACECHAR(*b) b++;
if (*b!=
'=')
return bestGuess;
2489 b++;
while XML_isSPACECHAR(*b) b++;
if ((*b!=
'\'')&&(*b!=
'"'))
return bestGuess;
2490 b++;
while XML_isSPACECHAR(*b) b++;
2492 if ((_strnicmp((
char*)b,
"utf-8",5)==0)||
2493 (_strnicmp((
char*)b,
"utf8",4)==0))
2495 if (bestGuess==encoding_ascii)
return (XMLCharEncoding)0;
2496 return encoding_UTF8;
2499 if ((_strnicmp((
char*)b,
"shiftjis",8)==0)||
2500 (_strnicmp((
char*)b,
"shift-jis",9)==0)||
2501 (_strnicmp((
char*)b,
"sjis",4)==0))
return encoding_ShiftJIS;
2503 return encoding_ascii;
2506 #undef XML_isSPACECHAR
2512 static const char base64Fillchar = _X(
'=');
2515 XMLCSTR base64EncodeTable=_X(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
2519 const unsigned char base64DecodeTable[] = {
2520 99,98,98,98,98,98,98,98,98,97, 97,98,98,97,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98,
2521 98,98,97,98,98,98,98,98,98,98, 98,98,98,62,98,98,98,63,52,53, 54,55,56,57,58,59,60,61,98,98,
2522 98,96,98,98,98, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,
2523 25,98,98,98,98,98,98,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46,47,48,
2524 49,50,51,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98,
2525 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98,
2526 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98,
2527 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98,98,98,98,98,
2528 98,98,98,98,98,98,98,98,98,98, 98,98,98,98,98,98
2531 XMLParserBase64Tool::~XMLParserBase64Tool(){ freeBuffer(); }
2533 void XMLParserBase64Tool::freeBuffer(){
if (buf) free(buf); buf=NULL; buflen=0; }
2535 int XMLParserBase64Tool::encodeLength(
int inlen,
char formatted)
2537 unsigned int i=((inlen-1)/3*4+4+1);
2538 if (formatted) i+=inlen/54;
2542 XMLSTR XMLParserBase64Tool::encode(
unsigned char *inbuf,
unsigned int inlen,
char formatted)
2544 int i=encodeLength(inlen,formatted),k=17,eLen=inlen/3,j;
2545 alloc(i*
sizeof(XMLCHAR));
2546 XMLSTR curr=(XMLSTR)buf;
2550 j=(inbuf[0]<<16)|(inbuf[1]<<8)|inbuf[2]; inbuf+=3;
2552 *(curr++)=base64EncodeTable[ j>>18 ];
2553 *(curr++)=base64EncodeTable[(j>>12)&0x3f];
2554 *(curr++)=base64EncodeTable[(j>> 6)&0x3f];
2555 *(curr++)=base64EncodeTable[(j )&0x3f];
2556 if (formatted) {
if (!k) { *(curr++)=_X(
'\n'); k=18; } k--; }
2561 *(curr++)=base64EncodeTable[ inbuf[0]>>2 ];
2562 *(curr++)=base64EncodeTable[(inbuf[0]<<4)&0x3F];
2563 *(curr++)=base64Fillchar;
2564 *(curr++)=base64Fillchar;
2567 j=(inbuf[0]<<8)|inbuf[1];
2568 *(curr++)=base64EncodeTable[ j>>10 ];
2569 *(curr++)=base64EncodeTable[(j>> 4)&0x3f];
2570 *(curr++)=base64EncodeTable[(j<< 2)&0x3f];
2571 *(curr++)=base64Fillchar;
2577 unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data,XMLError *xe)
2579 if (xe) *xe=eXMLErrorNone;
2586 if (*data>255) {
if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter;
return 0; }
2588 c=base64DecodeTable[(
unsigned char)(*data)];
2590 else if (c==98) {
if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter;
return 0; }
2593 if (xe&&(size%4!=0)) *xe=eXMLErrorBase64DataSizeIsNotMultipleOf4;
2594 if (size==0)
return 0;
2595 do { data--; size--; }
while(*data==base64Fillchar); size++;
2596 return (
unsigned int)((size*3)/4);
2599 unsigned char XMLParserBase64Tool::decode(XMLCSTR data,
unsigned char *buf,
int len, XMLError *xe)
2601 if (xe) *xe=eXMLErrorNone;
2608 #define BASE64DECODE_READ_NEXT_CHAR(c) \
2610 if (data[i]>255){ c=98; break; } \
2611 c=base64DecodeTable[(unsigned char)data[i++]]; \
2613 if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
2615 #define BASE64DECODE_READ_NEXT_CHAR(c) \
2616 do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97); \
2617 if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
2620 BASE64DECODE_READ_NEXT_CHAR(c)
2621 if (c==99) {
return 2; }
2624 if (p==(
int)len)
return 2;
2625 if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
2629 BASE64DECODE_READ_NEXT_CHAR(d)
2630 if ((d==99)||(d==96)) {
if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
return 1; }
2631 if (p==(
int)len) {
if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
return 0; }
2632 buf[p++]=(
unsigned char)((c<<2)|((d>>4)&0x3));
2634 BASE64DECODE_READ_NEXT_CHAR(c)
2635 if (c==99) {
if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
return 1; }
2638 if (c==96)
return 2;
2639 if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
2642 if (c==96) {
if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
return 1; }
2643 buf[p++]=(
unsigned char)(((d<<4)&0xf0)|((c>>2)&0xf));
2645 BASE64DECODE_READ_NEXT_CHAR(d)
2646 if (d==99 ) {
if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
return 1; }
2649 if (d==96)
return 2;
2650 if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
2653 if (d==96) {
if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
return 1; }
2654 buf[p++]=(
unsigned char)(((c<<6)&0xc0)|d);
2657 #undef BASE64DECODE_READ_NEXT_CHAR
2659 void XMLParserBase64Tool::alloc(
int newsize)
2661 if ((!buf)&&(newsize)) { buf=malloc(newsize); buflen=newsize;
return; }
2662 if (newsize>buflen) { buf=realloc(buf,newsize); buflen=newsize; }
2665 unsigned char *XMLParserBase64Tool::decode(XMLCSTR data,
int *outlen, XMLError *xe)
2667 if (xe) *xe=eXMLErrorNone;
2668 unsigned int len=decodeSize(data,xe);
2669 if (outlen) *outlen=len;
2670 if (!len)
return NULL;
2672 if(!decode(data,(
unsigned char*)buf,len,xe)){
return NULL; }
2673 return (
unsigned char*)buf;