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

📄 ixmlparser.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 5 页
字号:
static int
Parser_addNamespace( IN Parser * xmlParser )
{
    IXML_Node *pNode;
    IXML_ElementStack *pCur;
    char *namespaceUri;

    pNode = xmlParser->pNeedPrefixNode;
    pCur = xmlParser->pCurElement;

    if( pNode->prefix == NULL ) {   // element does not have prefix
        if( strcmp( pNode->nodeName, pCur->element ) != 0 ) {
            return IXML_FAILED;
        }
        if( pCur->namespaceUri != NULL ) {
            // it would be wrong that pNode->namespace != NULL.
            assert( pNode->namespaceURI == NULL );

            pNode->namespaceURI = strdup( pCur->namespaceUri );
            if( pNode->namespaceURI == NULL ) {
                return IXML_INSUFFICIENT_MEMORY;
            }
        }

        xmlParser->pNeedPrefixNode = NULL;

    } else {
        if( ( strcmp( pNode->nodeName, pCur->element ) != 0 ) &&
            ( strcmp( pNode->prefix, pCur->prefix ) != 0 ) ) {
            return IXML_FAILED;
        }

        namespaceUri = Parser_getNameSpace( xmlParser, pCur->prefix );
        if( namespaceUri != NULL ) {
            pNode->namespaceURI = strdup( namespaceUri );
            if( pNode->namespaceURI == NULL ) {
                return IXML_INSUFFICIENT_MEMORY;
            }

            xmlParser->pNeedPrefixNode = NULL;
        }
    }
    return IXML_SUCCESS;
}

/*==============================================================================*
*
*   Parser_setNodePrefixAndLocalName
*       set the node prefix and localName as defined by the nodeName
*       in the form of ns:name
*       Internal to parser only.			
*
*===============================================================================*/
int
Parser_setNodePrefixAndLocalName( IN IXML_Node * node )
{

    char *pStrPrefix = NULL;
    char *pLocalName;
    int nPrefix;

    assert( node != NULL );
    if( node == NULL ) {
        return IXML_FAILED;
    }

    pStrPrefix = strchr( node->nodeName, ':' );
    if( pStrPrefix == NULL ) {
        node->prefix = NULL;
        node->localName = strdup( node->nodeName );
        if( node->localName == NULL ) {
            return IXML_INSUFFICIENT_MEMORY;
        }

    } else {                    // fill in the local name and prefix

        pLocalName = ( char * )pStrPrefix + 1;
        nPrefix = pStrPrefix - node->nodeName;
        node->prefix = malloc( nPrefix + 1 );
        if( node->prefix == NULL ) {
            return IXML_INSUFFICIENT_MEMORY;
        }

        memset( node->prefix, 0, nPrefix + 1 );
        strncpy( node->prefix, node->nodeName, nPrefix );

        node->localName = strdup( pLocalName );
        if( node->localName == NULL ) {
            free( node->prefix );
            node->prefix = NULL;    //no need to free really, main loop will frees it
            //when return code is not success
            return IXML_INSUFFICIENT_MEMORY;
        }
    }

    return IXML_SUCCESS;
}

/*==============================================================================*
*
*   Parser_xmlNamespace
*       add namespace definition. 
*       internal to parser only.			
*
*===============================================================================*/
static int
Parser_xmlNamespace( IN Parser * xmlParser,
                     IN IXML_Node * newNode )
{

    IXML_ElementStack *pCur = xmlParser->pCurElement;
    IXML_NamespaceURI *pNewNs = NULL,
     *pNs = NULL,
     *pPrevNs = NULL;
    int rc;

    // if the newNode contains a namespace definition
    assert( newNode->nodeName != NULL );

    if( strcmp( newNode->nodeName, "xmlns" ) == 0 ) // default namespace def.
    {
        if( pCur->namespaceUri != NULL ) {
            free( pCur->namespaceUri );
        }

        pCur->namespaceUri = strdup( newNode->nodeValue );
        if( pCur->namespaceUri == NULL ) {
            return IXML_INSUFFICIENT_MEMORY;
        }

    } else if( strncmp( newNode->nodeName, "xmlns:", strlen( "xmlns:" ) ) == 0 ) {  // namespace definition
        rc = Parser_setNodePrefixAndLocalName( newNode );
        if( rc != IXML_SUCCESS ) {
            return rc;
        }

        assert( newNode->localName != NULL );

        if( pCur == NULL ) {
            return IXML_FAILED;
        }

        if( ( pCur->prefix != NULL )
            && ( strcmp( pCur->prefix, newNode->localName ) == 0 ) ) {
            pCur->namespaceUri = strdup( newNode->nodeValue );
            if( pCur->namespaceUri == NULL ) {
                return IXML_INSUFFICIENT_MEMORY;
            }
        } else {
            pPrevNs = pCur->pNsURI;
            pNs = pPrevNs;
            while( pNs != NULL ) {
                if( ( pNs->prefix != NULL ) &&
                    ( strcmp( pNs->prefix, newNode->localName ) == 0 ) ) {
                    break;      // replace namespace definition
                } else {
                    pPrevNs = pNs;
                    pNs = pNs->nextNsURI;
                }
            }

            if( pNs == NULL )   // a new definition
            {
                pNewNs =
                    ( IXML_NamespaceURI * )
                    malloc( sizeof( IXML_NamespaceURI ) );
                if( pNewNs == NULL ) {
                    return IXML_INSUFFICIENT_MEMORY;
                }
                memset( pNewNs, 0, sizeof( IXML_NamespaceURI ) );

                pNewNs->prefix = strdup( newNode->localName );
                if( pNewNs->prefix == NULL ) {
                    free( pNewNs );
                    return IXML_INSUFFICIENT_MEMORY;
                }

                pNewNs->nsURI = strdup( newNode->nodeValue );
                if( pNewNs->nsURI == NULL ) {
                    Parser_freeNsURI( pNewNs );
                    free( pNewNs );
                    return IXML_INSUFFICIENT_MEMORY;
                }

                if( pCur->pNsURI == NULL ) {
                    pCur->pNsURI = pNewNs;
                } else {
                    pPrevNs->nextNsURI = pNewNs;
                }
            } else              // udpate the namespace
            {
                if( pNs->nsURI != NULL ) {
                    free( pNs->nsURI );
                }

                pNs->nsURI = strdup( newNode->nodeValue );
                if( pNs->nsURI == NULL ) {
                    return IXML_INSUFFICIENT_MEMORY;
                }
            }
        }
    }

    if( xmlParser->pNeedPrefixNode != NULL ) {
        rc = Parser_addNamespace( xmlParser );
        return rc;
    } else {
        return IXML_SUCCESS;
    }

}

/*==============================================================================*
*
*   Parser_processSTag:	
*       Processes the STag as defined by XML spec. 
*       Internal to parser only.			
*
*===============================================================================*/
static int
Parser_processSTag( IN Parser * xmlParser,
                    IN IXML_Node * node )
{
    char *pCurToken = NULL;
    int rc;

    if( Parser_getNextToken( xmlParser ) == 0 ) {
        return IXML_SYNTAX_ERR;
    }

    pCurToken = ( xmlParser->tokenBuf ).buf;
    if( pCurToken != NULL ) {
        node->nodeName = strdup( pCurToken );
        if( node->nodeName == NULL ) {
            return IXML_INSUFFICIENT_MEMORY;
        }
    } else {
        return IXML_SYNTAX_ERR;
    }

    rc = Parser_setLastElem( xmlParser, node->nodeName );
    if( rc != IXML_SUCCESS ) {  // no need to free node->nodeName, main loop will free it
        return IXML_FAILED;
    }

    rc = Parser_setNodePrefixAndLocalName( node );
    if( rc != IXML_SUCCESS ) {  // no need to free node->nodeName, main loop will free it
        return IXML_FAILED;
    }

    node->nodeValue = NULL;
    node->nodeType = eELEMENT_NODE;

    xmlParser->savePtr = xmlParser->curPtr;
    if( Parser_getNextToken( xmlParser ) == 0 ) {   // no need to free node->nodeName, main loop will free it
        return IXML_SYNTAX_ERR;
    }

    pCurToken = ( xmlParser->tokenBuf ).buf;
    // check to see what is the next token
    if( strcmp( pCurToken, "/>" ) == 0 )    // empty element 
    {
        xmlParser->state = eELEMENT;
        xmlParser->curPtr = xmlParser->savePtr; // backup to /> 
    } else if( strcmp( pCurToken, ">" ) == 0 )  // expecting text node
    {
        xmlParser->state = eCONTENT;
    } else {
        xmlParser->state = eATTRIBUTE;
        xmlParser->curPtr = xmlParser->savePtr;
    }

    return IXML_SUCCESS;
}

/*==============================================================================*
*
*   Parser_hasDefaultNamespace   	
*       decide whether the current element has default namespace
*       Internal to parser only.       			
*
*===============================================================================*/
static BOOL
Parser_hasDefaultNamespace( IN Parser * xmlParser,
                            IN IXML_Node * newNode,
                            IN char **nsURI )
{
    IXML_ElementStack *pCur = xmlParser->pCurElement;

    while( pCur != NULL ) {
        if( ( pCur->prefix == NULL ) && ( pCur->namespaceUri != NULL ) ) {
            *nsURI = pCur->namespaceUri;
            return TRUE;
        } else {
            pCur = pCur->nextElement;
        }
    }

    return FALSE;

}

/*==============================================================================*
*
*   Parser_ElementPrefixDefined
*       decides whether element's prefix is already defined.
*       Internal to parser only. 
*
*===============================================================================*/
static BOOL
Parser_ElementPrefixDefined( IN Parser * xmlParser,
                             IN IXML_Node * newNode,
                             IN char **nsURI )
{

    IXML_ElementStack *pCur = xmlParser->pCurElement;
    IXML_NamespaceURI *pNsUri;

    while( pCur != NULL ) {
        if( ( pCur->prefix != NULL )
            && ( strcmp( pCur->prefix, newNode->prefix ) == 0 ) ) {
            *nsURI = pCur->namespaceUri;
            return TRUE;
        } else {
            pNsUri = pCur->pNsURI;

            while( pNsUri != NULL ) {
                if( strcmp( pNsUri->prefix, newNode->prefix ) == 0 ) {
                    *nsURI = pNsUri->nsURI;
                    return TRUE;
                } else {
                    pNsUri = pNsUri->nextNsURI;
                }
            }
        }

        pCur = pCur->nextElement;

    }

    return FALSE;

}

/*==============================================================================*
*
*   Parser_processCDSect   
*       Processes CDSection as defined by XML spec.
*       Internal to parser only.
*
*===============================================================================*/
static int
Parser_processCDSect( IN char **pSrc,
                      IN IXML_Node * node )
{

    char *pEnd;
    int tokenLength = 0;
    char *pCDataStart;

    if( *pSrc == NULL ) {
        return IXML_FAILED;
    }

    pCDataStart = *pSrc + strlen( CDSTART );
    pEnd = pCDataStart;
    while( ( Parser_isXmlChar( *pEnd ) == TRUE ) && ( *pEnd != '0' ) ) {
        if( strncmp( pEnd, CDEND, strlen( CDEND ) ) == 0 ) {
            break;
        } else {
            pEnd++;
        }
    }

    if( ( pEnd - pCDataStart > 0 ) && ( *pEnd != '0' ) ) {
        tokenLength = pEnd - pCDataStart;
        node->nodeValue = ( char * )malloc( tokenLength + 1 );
        if( node->nodeValue == NULL ) {
            return IXML_INSUFFICIENT_MEMORY;
        }
        strncpy( node->nodeValue, pCDataStart, tokenLength );
        node->nodeValue[tokenLength] = '\0';

        node->nodeName = strdup( CDATANODENAME );
        if( node->nodeName == NULL ) {
            // no need to free node->nodeValue at all, bacause node contents
            // will be freed by the main loop.
            return IXML_INSUFFICIENT_M

⌨️ 快捷键说明

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