📄 xmlparser.cpp
字号:
ss++; while (*ss!=_X(';')) { if ((*ss>=_X('0'))&&(*ss<=_X('9'))) j=(j<<4)+*ss-_X('0'); else if ((*ss>=_X('A'))&&(*ss<=_X('F'))) j=(j<<4)+*ss-_X('A')+10; else if ((*ss>=_X('a'))&&(*ss<=_X('f'))) j=(j<<4)+*ss-_X('a')+10; else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;} ss++; } } else { while (*ss!=_X(';')) { if ((*ss>=_X('0'))&&(*ss<=_X('9'))) j=(j*10)+*ss-_X('0'); else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;} ss++; } } (*d++)=(XMLCHAR)j; ss++; } else { entity=XMLEntities; do { if (xstrnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l; break; } entity++; } while(entity->s); } } else {#ifdef _XMLWIDECHAR *(d++)=*(ss++);#else switch(XML_ByteTable[(unsigned char)*ss]) { case 4: *(d++)=*(ss++); ll--; case 3: *(d++)=*(ss++); ll--; case 2: *(d++)=*(ss++); ll--; case 1: *(d++)=*(ss++); }#endif } } *d=0; return (XMLSTR)s;}#define XML_isSPACECHAR(ch) ((ch==_X('\n'))||(ch==_X(' '))||(ch== _X('\t'))||(ch==_X('\r')))// private:char myTagCompare(XMLCSTR cclose, XMLCSTR copen)// !!!! WARNING strange convention&:// return 0 if equals// return 1 if different{ if (!cclose) return 1; int l=(int)xstrlen(cclose); if (xstrnicmp(cclose, copen, l)!=0) return 1; const XMLCHAR c=copen[l]; if (XML_isSPACECHAR(c)|| (c==_X('/' ))|| (c==_X('<' ))|| (c==_X('>' ))|| (c==_X('=' ))) return 0; return 1;}// Obtain the next character from the string.static inline XMLCHAR getNextChar(XML *pXML){ XMLCHAR ch = pXML->lpXML[pXML->nIndex];#ifdef _XMLWIDECHAR if (ch!=0) pXML->nIndex++;#else pXML->nIndex+=XML_ByteTable[(unsigned char)ch];#endif return ch;}// Find the next token in a string.// pcbToken contains the number of characters that have been read.static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType){ NextToken result; XMLCHAR ch; XMLCHAR chTemp; int indexStart,nFoundMatch,nIsText=FALSE; result.pClr=NULL; // prevent warning // Find next non-white space character do { indexStart=pXML->nIndex; ch=getNextChar(pXML); } while XML_isSPACECHAR(ch); if (ch) { // Cache the current string pointer result.pStr = &pXML->lpXML[indexStart]; // First check whether the token is in the clear tag list (meaning it // does not need formatting). ALLXMLClearTag *ctag=XMLClearTags; do { if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0) { result.pClr=ctag; pXML->nIndex+=ctag->openTagLen-1; *pType=eTokenClear; return result; } ctag++; } while(ctag->lpszOpen); // If we didn't find a clear tag then check for standard tokens switch(ch) { // Check for quotes case _X('\''): case _X('\"'): // Type of token *pType = eTokenQuotedText; chTemp = ch; // Set the size nFoundMatch = FALSE; // Search through the string to find a matching quote while((ch = getNextChar(pXML))) { if (ch==chTemp) { nFoundMatch = TRUE; break; } if (ch==_X('<')) break; } // If we failed to find a matching quote if (nFoundMatch == FALSE) { pXML->nIndex=indexStart+1; nIsText=TRUE; break; }// 4.02.2002// if (FindNonWhiteSpace(pXML)) pXML->nIndex--; break; // Equals (used with attribute values) case _X('='): *pType = eTokenEquals; break; // Close tag case _X('>'): *pType = eTokenCloseTag; break; // Check for tag start and tag end case _X('<'): // Peek at the next character to see if we have an end tag '</', // or an xml declaration '<?' chTemp = pXML->lpXML[pXML->nIndex]; // If we have a tag end... if (chTemp == _X('/')) { // Set the type and ensure we point at the next character getNextChar(pXML); *pType = eTokenTagEnd; } // If we have an XML declaration tag else if (chTemp == _X('?')) { // Set the type and ensure we point at the next character getNextChar(pXML); *pType = eTokenDeclaration; } // Otherwise we must have a start tag else { *pType = eTokenTagStart; } break; // Check to see if we have a short hand type end tag ('/>'). case _X('/'): // Peek at the next character to see if we have a short end tag '/>' chTemp = pXML->lpXML[pXML->nIndex]; // If we have a short hand end tag... if (chTemp == _X('>')) { // Set the type and ensure we point at the next character getNextChar(pXML); *pType = eTokenShortHandClose; break; } // If we haven't found a short hand closing tag then drop into the // text process // Other characters default: nIsText = TRUE; } // If this is a TEXT node if (nIsText) { // Indicate we are dealing with text *pType = eTokenText; while((ch = getNextChar(pXML))) { if XML_isSPACECHAR(ch) { indexStart++; break; } else if (ch==_X('/')) { // If we find a slash then this maybe text or a short hand end tag // Peek at the next character to see it we have short hand end tag ch=pXML->lpXML[pXML->nIndex]; // If we found a short hand end tag then we need to exit the loop if (ch==_X('>')) { pXML->nIndex--; break; } } else if ((ch==_X('<'))||(ch==_X('>'))||(ch==_X('='))) { pXML->nIndex--; break; } } } *pcbToken = pXML->nIndex-indexStart; } else { // If we failed to obtain a valid character *pcbToken = 0; *pType = eTokenError; result.pStr=NULL; } return result;}XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName){ if (!d) { free(lpszName); return NULL; } if (d->lpszName&&(lpszName!=d->lpszName)) free((void*)d->lpszName); d->lpszName=lpszName; return lpszName;}// private:XMLNode::XMLNode(struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; }XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration){ d=(XMLNodeData*)malloc(sizeof(XMLNodeData)); d->ref_count=1; d->lpszName=NULL; d->nChild= 0; d->nText = 0; d->nClear = 0; d->nAttribute = 0; d->isDeclaration = isDeclaration; d->pParent = pParent; d->pChild= NULL; d->pText= NULL; d->pClear= NULL; d->pAttribute= NULL; d->pOrder= NULL; updateName_WOSD(lpszName);}XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { return XMLNode(NULL,lpszName,isDeclaration); }XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,stringDup(lpszName),isDeclaration); }#define MEMORYINCREASE 50static inline void myFree(void *p) { if (p) free(p); };static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem){ if (p==NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); } if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem);// if (!p)// {// printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220);// } return p;}// private:int XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xtype){ if (index<0) return -1; int i=0,j=(int)((index<<2)+xtype),*o=d->pOrder; while (o[i]!=j) i++; return i;}// private:// update "order" information when deleting a content of a XMLNodeint XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index){ int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t); memmove(o+i, o+i+1, (n-i)*sizeof(int)); for (;i<n;i++) if ((o[i]&3)==(int)t) o[i]-=4; // We should normally do: // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int)); // but we skip reallocation because it's too time consuming. // Anyway, at the end, it will be free'd completely at once. return i;}void *XMLNode::addToOrder(int memoryIncrease,int *_pos, int nc, void *p, int size, XMLElementType xtype){ // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") // out: *_pos is the index inside p p=myRealloc(p,(nc+1),memoryIncrease,size); int n=d->nChild+d->nText+d->nClear; d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int)); int pos=*_pos,*o=d->pOrder; if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; } int i=pos; memmove(o+i+1, o+i, (n-i)*sizeof(int)); while ((pos<n)&&((o[pos]&3)!=(int)xtype)) pos++; if (pos==n) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; } o[i]=o[pos]; for (i=pos+1;i<=n;i++) if ((o[i]&3)==(int)xtype) o[i]+=4; *_pos=pos=o[pos]>>2; memmove(((char*)p)+(pos+1)*size,((char*)p)+pos*size,(nc-pos)*size); return p;}// Add a child node to the given element.XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, char isDeclaration, int pos){ if (!lpszName) return emptyXMLNode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -