📄 ixmlparser.c
字号:
if( c <= 127 ) { // if c<=127, c is just the character. *len = 1; return c; } else if( ( c & 0xE0 ) == 0xC0 && ( s[1] & 0xc0 ) == 0x80 ) { // a sequence of 110xxxxx and 10xxxxxx? *len = 2; return ( ( ( c & 0x1f ) << 6 ) | ( s[1] & 0x3f ) ); } else if( ( c & 0xF0 ) == 0xE0 && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 ) { // a sequence of 1110xxxx,10xxxxxx and 10xxxxxx ? *len = 3; return ( ( ( c & 0xf ) << 12 ) | ( ( s[1] & 0x3f ) << 6 ) | ( s[2] & 0x3f ) ); } else if( ( c & 0xf8 ) == 0xf0 && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 && ( s[3] & 0xc0 ) == 0x80 ) { // a sequence of 11110xxx,10xxxxxx,10xxxxxx and 10xxxxxx ? *len = 4; return ( ( ( c & 0x7 ) << 18 ) | ( ( s[1] & 0x3f ) << 12 ) | ( ( s[2] & 0x3f ) << 6 ) | ( s[3] & 0x3f ) ); } else if( ( c & 0xfc ) == 0xf8 && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 && ( s[3] & 0xc0 ) == 0x80 && ( s[4] & 0xc0 ) == 0x80 ) { // a sequence of 111110xx,10xxxxxx,10xxxxxx,10xxxxxx,10xxxxxx ? *len = 5; return ( ( ( c & 0x3 ) << 24 ) | ( ( s[1] & 0x3f ) << 18 ) | ( ( s[2] & 0x3f ) << 12 ) | ( ( s[3] & 0x3f ) << 6 ) | ( s[4] & 0x3f ) ); } else if( ( c & 0xfe ) == 0xfc && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 && ( s[3] & 0xc0 ) == 0x80 && ( s[4] & 0xc0 ) == 0x80 && ( s[5] & 0xc0 ) == 0x80 ) { // a sequence of 1111110x,10xxxxxx,10xxxxxx,10xxxxxx,10xxxxxx and 10xxxxxx ? *len = 6; return ( ( ( c & 0x1 ) << 30 ) | ( ( s[1] & 0x3f ) << 24 ) | ( ( s[2] & 0x3f ) << 18 ) | ( ( s[3] & 0x3f ) << 12 ) | ( ( s[4] & 0x3f ) << 6 ) | ( s[5] & 0x3f ) ); } else { // none of above, error *len = 0; return -1; }}/*==============================================================================** Parser_init* Initializes a xml parser.* Internal to parser only* *===============================================================================*/static Parser *Parser_init( ){ Parser *newParser = NULL; newParser = ( Parser * ) malloc( sizeof( Parser ) ); if( newParser == NULL ) { return NULL; } memset( newParser, 0, sizeof( Parser ) ); ixml_membuf_init( &( newParser->tokenBuf ) ); ixml_membuf_init( &( newParser->lastElem ) ); return newParser;}/*================================================================* Parser_isValidEndElement* check if a new node->nodeName matches top of element stack.* Internal to parser only.**=================================================================*/static intParser_isValidEndElement( IN Parser * xmlParser, IN IXML_Node * newNode ){ return ( strcmp( xmlParser->pCurElement->element, newNode->nodeName ) == 0 );}/*===============================================================* Parser_pushElement* push a new element onto element stack* Internal to parser only.**=================================================================*/static intParser_pushElement( IN Parser * xmlParser, IN IXML_Node * newElement ){ IXML_ElementStack *pCurElement = NULL; IXML_ElementStack *pNewStackElement = NULL; assert( newElement ); if( newElement != NULL ) { // push new element pNewStackElement = ( IXML_ElementStack * ) malloc( sizeof( IXML_ElementStack ) ); if( pNewStackElement == NULL ) { return IXML_INSUFFICIENT_MEMORY; } memset( pNewStackElement, 0, sizeof( IXML_ElementStack ) ); // the element member includes both prefix and name pNewStackElement->element = strdup( newElement->nodeName ); if( pNewStackElement->element == NULL ) { free( pNewStackElement ); return IXML_INSUFFICIENT_MEMORY; } if( newElement->prefix != 0 ) { pNewStackElement->prefix = strdup( newElement->prefix ); if( pNewStackElement->prefix == NULL ) { Parser_freeElementStackItem( pNewStackElement ); free( pNewStackElement ); return IXML_INSUFFICIENT_MEMORY; } } if( newElement->namespaceURI != 0 ) { pNewStackElement->namespaceUri = strdup( newElement->namespaceURI ); if( pNewStackElement->namespaceUri == NULL ) { Parser_freeElementStackItem( pNewStackElement ); free( pNewStackElement ); return IXML_INSUFFICIENT_MEMORY; } } pCurElement = xmlParser->pCurElement; // insert the new element into the top of the stack pNewStackElement->nextElement = pCurElement; xmlParser->pCurElement = pNewStackElement; } return IXML_SUCCESS;}/*================================================================* Parser_popElement* Remove element from element stack.* Internal to parser only. **=================================================================*/static voidParser_popElement( IN Parser * xmlParser ){ IXML_ElementStack *pCur = NULL; IXML_NamespaceURI *pnsUri = NULL, *pNextNS = NULL; pCur = xmlParser->pCurElement; if( pCur != NULL ) { xmlParser->pCurElement = pCur->nextElement; Parser_freeElementStackItem( pCur ); pnsUri = pCur->pNsURI; while( pnsUri != NULL ) { pNextNS = pnsUri->nextNsURI; Parser_freeNsURI( pnsUri ); free( pnsUri ); pnsUri = pNextNS; } free( pCur ); }}/*================================================================* Parser_readFileOrBuffer* read a xml file or buffer contents into xml parser.* Internal to parser only.**=================================================================*/static intParser_readFileOrBuffer( IN Parser * xmlParser, IN char *xmlFileName, IN BOOL file ){ int fileSize = 0; int bytesRead = 0; FILE *xmlFilePtr = NULL; if( file ) { xmlFilePtr = fopen( xmlFileName, "rb" ); if( xmlFilePtr == NULL ) { return IXML_NO_SUCH_FILE; } else { fseek( xmlFilePtr, 0, SEEK_END ); fileSize = ftell( xmlFilePtr ); if( fileSize == 0 ) { fclose( xmlFilePtr ); return IXML_SYNTAX_ERR; } xmlParser->dataBuffer = ( char * )malloc( fileSize + 1 ); if( xmlParser->dataBuffer == NULL ) { fclose( xmlFilePtr ); return IXML_INSUFFICIENT_MEMORY; } fseek( xmlFilePtr, 0, SEEK_SET ); bytesRead = fread( xmlParser->dataBuffer, 1, fileSize, xmlFilePtr ); xmlParser->dataBuffer[bytesRead] = '\0'; // append null fclose( xmlFilePtr ); } } else { xmlParser->dataBuffer = strdup( xmlFileName ); if( xmlParser->dataBuffer == NULL ) { return IXML_INSUFFICIENT_MEMORY; } } return IXML_SUCCESS;}/*================================================================* Parser_LoadDocument* parses a xml file and return the DOM tree.* Internal to parser only**=================================================================*/intParser_LoadDocument( OUT IXML_Document ** retDoc, IN char *xmlFileName, IN BOOL file ){ int rc = IXML_SUCCESS; Parser *xmlParser = NULL; xmlParser = Parser_init( ); if( xmlParser == NULL ) { return IXML_INSUFFICIENT_MEMORY; } rc = Parser_readFileOrBuffer( xmlParser, xmlFileName, file ); if( rc != IXML_SUCCESS ) { Parser_free( xmlParser ); return rc; } xmlParser->curPtr = xmlParser->dataBuffer; rc = Parser_parseDocument( retDoc, xmlParser ); return rc;}/*================================================================* isTopLevelElement* decides whether we have top level element already.* Internal to parser only.**=================================================================*/static intisTopLevelElement( IN Parser * xmlParser ){ assert( xmlParser ); return ( xmlParser->pCurElement == NULL );}/*================================================================* isDuplicateAttribute* Decide whether the new attribute is the same as an* existing one.* Internal to parser only.**=================================================================*/static intisDuplicateAttribute( IN Parser * xmlParser, IN IXML_Node * newAttrNode ){ IXML_Node *elementNode = NULL; IXML_Node *attrNode = NULL; elementNode = xmlParser->currentNodePtr; attrNode = elementNode->firstAttr; while( attrNode != NULL ) { if( strcmp( attrNode->nodeName, newAttrNode->nodeName ) == 0 ) { return TRUE; } attrNode = attrNode->nextSibling; } return FALSE;}/*================================================================* Parser_processAttributeName* processes the attribute name.* Internal to parser only.**=================================================================*/static intParser_processAttributeName( IN IXML_Document * rootDoc, IN Parser * xmlParser, IN IXML_Node * newNode ){ IXML_Attr *attr = NULL; int rc = IXML_SUCCESS; if( isDuplicateAttribute( xmlParser, newNode ) == TRUE ) { return IXML_SYNTAX_ERR; } rc = ixmlDocument_createAttributeEx( rootDoc, newNode->nodeName, &attr ); if( rc != IXML_SUCCESS ) { return rc; } rc = ixmlNode_setNodeProperties( ( IXML_Node * ) attr, newNode ); if( rc != IXML_SUCCESS ) { return rc; } rc = ixmlElement_setAttributeNode( ( IXML_Element * ) xmlParser-> currentNodePtr, attr, NULL ); return rc;}/*================================================================* Parser_processElementName* Processes element name * Internal to parser only.**=================================================================*/static intParser_processElementName( IN IXML_Document * rootDoc, IN Parser * xmlParser, IN IXML_Node * newNode ){ IXML_Element *newElement = NULL; char *nsURI = NULL; int rc = IXML_SUCCESS; if( xmlParser->bHasTopLevel == TRUE ) { if( isTopLevelElement( xmlParser ) == TRUE ) { return IXML_SYNTAX_ERR; } } else { xmlParser->bHasTopLevel = TRUE; } xmlParser->savePtr = xmlParser->curPtr; rc = ixmlDocument_createElementEx( rootDoc, newNode->nodeName, &newElement ); if( rc != IXML_SUCCESS ) { return rc; } rc = ixmlNode_setNodeProperties( ( IXML_Node * ) newElement, newNode ); if( rc != IXML_SUCCESS ) { ixmlElement_free( newElement ); return rc; } if( newNode->prefix != NULL ) { // element has namespace prefix if( Parser_ElementPrefixDefined( xmlParser, newNode, &nsURI ) != TRUE ) { // read next node to see whether it includes namespace definition xmlParser->pNeedPrefixNode = ( IXML_Node * ) newElement; } else { // fill in the namespace Parser_setElementNamespace( newElement, nsURI ); } } else // does element has default namespace { // the node may have default namespace definition if( Parser_hasDefaultNamespace( xmlParser, newNode, &nsURI ) == TRUE ) { Parser_setElementNamespace( newElement, nsURI ); } else if( xmlParser->state == eATTRIBUTE ) { // the default namespace maybe defined later xmlParser->pNeedPrefixNode = ( IXML_Node * ) newElement; } } rc = ixmlNode_appendChild( xmlParser->currentNodePtr, ( IXML_Node * ) newElement ); if( rc != IXML_SUCCESS ) { ixmlElement_free( newElement ); return rc; } xmlParser->currentNodePtr = ( IXML_Node * ) newElement; // push element to stack rc = Parser_pushElement( xmlParser, ( IXML_Node * ) newElement ); return rc;}/*================================================================* Parser_eTagVerification* Verifies endof element tag is the same as the openning * element tag.* Internal to parser only.**=================================================================*/static intParser_eTagVerification( IN Parser * xmlParser, IN IXML_Node * newNode ){ assert( newNode->nodeName ); assert( xmlParser->currentNodePtr ); if( newNode->nodeType == eELEMENT_NODE ) { if( Parser_isValidEndElement( xmlParser, newNode ) == TRUE ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -