⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparser.cpp

📁 upnpForWindows by microsoft
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                *pType = eTokenTagStart;                nSize = 1;            }            break;        // Check to see if we have a short hand type end tag ('/>').        case _T('/'):            // 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 == _T('>'))            {                // Set the type and ensure we point at the next character                getNextChar(pXML);                *pType = eTokenShortHandClose;                nSize = 2;                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;            nSize = 1;            nExit = FALSE;            while((nExit == FALSE) && (ch = getNextChar(pXML)))            {                switch(ch)                {                // Break when we find white space                case _T('\n'):                case _T(' '):                case _T('\t'):                case _T('\r'):                    nExit = TRUE;                    break;                // If we find a slash then this maybe text or a short hand end tag.                case _T('/'):                    // Peek at the next character to see it we have short hand end tag                    chTemp = pXML->lpXML[pXML->nIndex];                    // If we found a short hand end tag then we need to exit the loop                    if (chTemp == _T('>'))                    {                        pXML->nIndex--; //  03.02.2002                        nExit = TRUE;                    }                    else                    {                        nSize++;                    }                    break;                // Break when we find a terminator and decrement the index and                // column count so that we are pointing at the right character                // the next time we are called.                case _T('<'):                case _T('>'):                case _T('='):                    pXML->nIndex--;                    nExit = TRUE;                    break;                case 0:                    nExit = TRUE;                    break;                default:                    nSize++;                }            }        }        *pcbToken = nSize;    } else    {        // If we failed to obtain a valid character        *pcbToken = 0;        *pType = eTokenError;        result.pStr=NULL;    }    return result;}// Parse XML errors into a user friendly string.LPCTSTR XMLNode::getError(XMLError error){    switch (error)    {    case eXMLErrorNone:              return _T("No error");    case eXMLErrorMissingEndTag:     return _T("Warning: Unmatched end tag");    case eXMLErrorEmpty:             return _T("Error: No XML data");    case eXMLErrorFirstNotStartTag:  return _T("Error: First token not start tag");    case eXMLErrorMissingTagName:    return _T("Error: Missing start tag name");    case eXMLErrorMissingEndTagName: return _T("Error: Missing end tag name");    case eXMLErrorNoMatchingQuote:   return _T("Error: Unmatched quote");    case eXMLErrorUnmatchedEndTag:   return _T("Error: Unmatched end tag");    case eXMLErrorUnexpectedToken:   return _T("Error: Unexpected token found");    case eXMLErrorInvalidTag:        return _T("Error: Invalid tag found");    case eXMLErrorNoElements:        return _T("Error: No elements found");    case eXMLErrorFileNotFound:      return _T("Error: File not found");    case eXMLErrorTagNotFound:       return _T("Error: First Tag not found");    };    return _T("Unknown");}// private:XMLNode::XMLNode(XMLNode *pParent, LPCTSTR lpszName, int isDeclaration){    d=(XMLNodeData*)malloc(sizeof(XMLNodeData));    d->ref_count=1;    d->lpszName=lpszName;    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;}const int memoryIncrease=50;static void *myRealloc(void *p, int newsize, int memInc, int sizeofElem){    if (p==NULL) { return malloc(memInc*sizeofElem); }    if ((newsize%memInc)==0) p=realloc(p,(newsize+memInc)*sizeofElem);//    if (!p)
//    {
//        printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220);
//    }
    return p;}void XMLNode::addToOrder(int index, int type){    int n=nElement();    d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int));    d->pOrder[n]=(index<<2)+type;}// Add a child node to the given element.XMLNode XMLNode::addChild(LPCTSTR lpszName, int isDeclaration){    if (!lpszName) return emptyXMLNode;    int nc=d->nChild;    d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode));    d->pChild[nc].d=NULL;    d->pChild[nc]=XMLNode(this,lpszName,isDeclaration);    addToOrder(nc,eNodeChild);    d->nChild++;    return d->pChild[nc];}XMLNode XMLNode::createXMLTopNode() { return XMLNode(NULL,NULL,FALSE); }// Add an attribute to an element.XMLAttribute *XMLNode::addAttribute(LPCTSTR lpszName, LPCTSTR lpszValuev){    if (!lpszName) return &emptyXMLAttribute;    int na=d->nAttribute;    d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(na+1),memoryIncrease,sizeof(XMLAttribute));    XMLAttribute *pAttr=d->pAttribute+na;    pAttr->lpszName = lpszName;    pAttr->lpszValue = lpszValuev;    addToOrder(na,eNodeAttribute);    d->nAttribute++;    return pAttr;}// Add text to the element.LPCTSTR XMLNode::addText(LPCTSTR lpszValue){    if (!lpszValue) return NULL;    int nt=d->nText;    d->pText=(LPCTSTR*)myRealloc(d->pText,(nt+1),memoryIncrease,sizeof(LPTSTR));    d->pText[nt]=lpszValue;    addToOrder(nt,eNodeText);    d->nText++;    return d->pText[nt];}// Add clear (unformatted) text to the element.XMLClear *XMLNode::addClear(LPCTSTR lpszValue, LPCTSTR lpszOpen, LPCTSTR lpszClose){    if (!lpszValue) return &emptyXMLClear;    int nc=d->nClear;    d->pClear=(XMLClear *)myRealloc(d->pClear,(nc+1),memoryIncrease,sizeof(XMLClear));    XMLClear *pNewClear=d->pClear+nc;    pNewClear->lpszValue = lpszValue;    pNewClear->lpszOpenTag = lpszOpen;    pNewClear->lpszCloseTag = lpszClose;    addToOrder(nc,eNodeClear);    d->nClear++;    return pNewClear;}// Trim the end of the text to remove white space characters.static void FindEndOfText(LPCTSTR lpszToken, int *pcbText){    TCHAR   ch;    int     cbText;    assert(lpszToken);    assert(pcbText);    cbText = (*pcbText)-1;    while(TRUE)    {        assert(cbText >= 0);        ch = lpszToken[cbText];        switch(ch)        {        case _T('\r'):        case _T('\n'):        case _T('\t'):        case _T(' '): cbText--; break;        default: *pcbText = cbText+1; return;        }    }}// Duplicate a given string.LPTSTR stringDup(LPCTSTR lpszData, int cbData){    if (lpszData==NULL) return NULL;    LPTSTR lpszNew;    if (cbData==0) cbData=(int)_tcslen(lpszData);    lpszNew = (LPTSTR)malloc((cbData+1) * sizeof(TCHAR));    if (lpszNew)    {        memcpy(lpszNew, lpszData, (cbData) * sizeof(TCHAR));        lpszNew[cbData] = (TCHAR)NULL;    }    return lpszNew;}// private:// Parse a clear (unformatted) type node.int XMLNode::ParseClearTag(void *px, void *pa){    XML *pXML=(XML *)px;    ClearTag *pClear=(ClearTag *)pa;    int cbTemp = 0;    LPTSTR lpszTemp;    LPCTSTR lpszXML = &pXML->lpXML[pXML->nIndex];    // Find the closing tag    lpszTemp = _tcsstr(lpszXML, pClear->lpszClose);    // Iterate through the tokens until we find the closing tag.    if (lpszTemp)    {        // Cache the size and increment the index        cbTemp = (int)(lpszTemp - lpszXML);        pXML->nIndex += cbTemp;        pXML->nIndex += (int)_tcslen(pClear->lpszClose);        // Add the clear node to the current element        addClear(stringDup(lpszXML,cbTemp), pClear->lpszOpen, pClear->lpszClose);        return TRUE;    }    // If we failed to find the end tag    pXML->error = eXMLErrorUnmatchedEndTag;    return FALSE;}void XMLNode::exactMemory(XMLNodeData *d){
    if (memoryIncrease==1) return;    d->pOrder=(int*)realloc(d->pOrder,(d->nChild+d->nAttribute+d->nText+d->nClear)*sizeof(int));    d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*sizeof(XMLNode));    d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*sizeof(XMLAttribute));    d->pText=(LPCTSTR*)realloc(d->pText,d->nText*sizeof(LPTSTR));    d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*sizeof(XMLClear));}// private:// Recursively parse an XML element.int XMLNode::ParseXMLElement(void *pa){    XML *pXML=(XML *)pa;    int cbToken;    enum TokenTypeTag type;    NextToken token;    LPCTSTR lpszTemp;    int cbTemp;    int nDeclaration;    LPCTSTR lpszText = NULL;    XMLNode pNew;    enum Status status; // inside or outside a tag    enum Attrib attrib = eAttribName;    assert(pXML);    // If this is the first call to the function    if (pXML->nFirst)    {        // Assume we are outside of a tag definition        pXML->nFirst = FALSE;        status = eOutsideTag;    } else    {        // If this is not the first call then we should only be called when inside a tag.        status = eInsideTag;    }    // Iterate through the tokens in the document    while(TRUE)    {        // Obtain the next token        token = GetNextToken(pXML, &cbToken, &type);        if (type != eTokenError)        {            // Check the current status            switch(status)            {            // If we are outside of a tag definition            case eOutsideTag:                // Check what type of token we obtained                switch(type)                {                // If we have found text or quoted text                case eTokenText:                case eTokenQuotedText:                case eTokenEquals:                    if (!lpszText)                    {                        lpszText = token.pStr;                    }                    break;                // If we found a start tag '<' and declarations '<?'                case eTokenTagStart:                case eTokenDeclaration:                    // Cache whether this new element is a declaration or not                    nDeclaration = type == eTokenDeclaration;                    // If we have node text then add this to the element                    if (lpszText)                    {                        cbTemp = (int)(token.pStr - lpszText);                        FindEndOfText(lpszText, &cbTemp);                        addText(stringDup(lpszText,cbTemp));                        lpszText = NULL;                    }                    // Find the name of the tag                    token = GetNextToken(pXML, &cbToken, &type);                    // Return an error if we couldn't obtain the next token or                    // it wasnt text                    if (type != eTokenText)                    {                        pXML->error = eXMLErrorMissingTagName;                        return FALSE;                    }                    // If we found a new element which is the same as this                    // element then we need to pass this back to the caller..#ifdef APPROXIMATE_PARSING                    if (d->lpszName &&                        myTagCompare(d->lpszName, token.pStr) == 0)                    {                        // Indicate to the caller that it needs to create a                        // new element.                        pXML->lpNewElement = token.pStr;                        pXML->cbNewElement = cbToken;                        return TRUE;                    } else#endif                    {                        // If the name of the new element differs from the name of                        // the current element we need to add the new element to                        // the current one and recurse                        pNew = addChild(stringDup(token.pStr,cbToken), nDeclaration);                        while (!pNew.isEmpty())                        {                            // Callself to process the new node.  If we return                            // FALSE this means we dont have any more                            // processing to do...                            if (!pNew.ParseXMLElement(pXML)) return FALSE;                            else                            {                                // If the call to recurse this function                                // evented in a end tag specified in XML then                                // we need to unwind the calls to this                                // function until we find the appropriate node                                // (the element name and end tag name must                                // match)                                if (pXML->cbEndTag)                                {                                    // If we are back at the root node then we                                    // have an unmatched end tag                                    if (!d->lpszName)                                    {                                        pXML->error=eXMLErrorUnmatchedEndTag;                                        return FALSE;                                    }                                    // If the end tag matches the name of this                                    // element then we only need to unwind                                    // once more...                                    if (myTagCompare(d->lpszName, pXML->lpEndTag)==0)                                    {                                        pXML->cbEndTag = 0;                                    }                                    return TRUE;                                } else                                    if (pXML->cbNewElement)                                    {                                        // If the call indicated a new element is to                                        // be created on THIS element.                                        // If the name of this element matches the                                        // name of the element we need to create                                        // then we need to return to the caller                                        // and let it process the element.                                        if (myTagCompare(d->lpszName, pXML->lpNewElement)==0)                                        {                                            return TRUE;                                        }                                        // Add the new element and recurse                                        pNew = addChild(stringDup(pXML->lpNewElement,pXML->cbNewElement));                                        pXML->cbNewElement = 0;                                    }                                    else                                    {                                        // If we didn't have a new element to create                                        pNew = emptyXMLNode;                                    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -