📄 ilibparsers.c
字号:
int flags;#endif // // Use this thread as if it's our own. Keep looping until we are signaled to stop // FD_ZERO(&readset); FD_ZERO(&errorset); FD_ZERO(&writeset); #if !defined(WIN32) && !defined(_WIN32_WCE) // // For posix, we need to use a pipe to force unblock the select loop // pipe(TerminatePipe); flags = fcntl(TerminatePipe[0],F_GETFL,0); // // We need to set the pipe to nonblock, so we can blindly empty the pipe // fcntl(TerminatePipe[0],F_SETFL,O_NONBLOCK|flags); ((struct ILibBaseChain*)Chain)->TerminateReadPipe = fdopen(TerminatePipe[0],"r"); ((struct ILibBaseChain*)Chain)->TerminateWritePipe = fdopen(TerminatePipe[1],"w");#endif while(((struct ILibBaseChain*)Chain)->TerminateFlag==0) { slct = 0; FD_ZERO(&readset); FD_ZERO(&errorset); FD_ZERO(&writeset); tv.tv_sec = UPNP_MAX_WAIT; tv.tv_usec = 0; #if defined(WIN32) || defined(_WIN32_WCE) // // Check the fake socket, for ILibForceUnBlockChain // if(((struct ILibBaseChain*)Chain)->Terminate==~0) { slct = -1; } else { FD_SET(((struct ILibBaseChain*)Chain)->Terminate,&errorset); }#else // // Put the Read end of the Pipe in the FDSET, for ILibForceUnBlockChain // FD_SET(TerminatePipe[0],&readset);#endif // // Iterate through all the PreSelect function pointers in the chain // c = (struct ILibBaseChain*)Chain; while(c!=NULL && c->Object!=NULL) { if(((struct ILibChain*)c->Object)->PreSelect!=NULL) {#ifdef MEMORY_CHECK#ifdef WIN32 _CrtCheckMemory();#endif#endif v = (tv.tv_sec*1000) + (tv.tv_usec/1000); ((struct ILibChain*)c->Object)->PreSelect(c->Object,&readset,&writeset,&errorset,&v); tv.tv_sec = v/1000; tv.tv_usec = 1000*(v%1000);#ifdef MEMORY_CHECK#ifdef WIN32 _CrtCheckMemory();#endif#endif } c = c->Next; } // // If this flag is set, force the max block time to be zero // if(slct!=0) { tv.tv_sec = 0; tv.tv_usec = 0; } // // The actual Select Statement // slct = select(FD_SETSIZE,&readset,&writeset,&errorset,&tv); if(slct==-1) { // // If the select simply timed out, we need to clear these sets // FD_ZERO(&readset); FD_ZERO(&writeset); FD_ZERO(&errorset); } #if defined(WIN32) || defined(_WIN32_WCE) // // Reinitialise our fake socket if necessary // if(((struct ILibBaseChain*)Chain)->Terminate==~0) { ((struct ILibBaseChain*)Chain)->Terminate = socket(AF_INET,SOCK_DGRAM,0); }#else if(FD_ISSET(TerminatePipe[0],&readset)) { // // Empty the pipe // while(fgetc(((struct ILibBaseChain*)Chain)->TerminateReadPipe)!=EOF) { } }#endif // // Iterate through all of the PostSelect in the chain // c = (struct ILibBaseChain*)Chain; while(c!=NULL && c->Object!=NULL) { if(((struct ILibChain*)c->Object)->PostSelect!=NULL) {#ifdef MEMORY_CHECK#ifdef WIN32 _CrtCheckMemory();#endif#endif ((struct ILibChain*)c->Object)->PostSelect(c->Object,slct,&readset,&writeset,&errorset);#ifdef MEMORY_CHECK#ifdef WIN32 _CrtCheckMemory();#endif#endif } c = c->Next; } } // // This loop will start, when the Chain was signaled to quit. Clean up the chain // by iterating through all the Destroy. // c = (struct ILibBaseChain*)Chain; while(c!=NULL && c->Object!=NULL) { if(((struct ILibChain*)c->Object)->Destroy!=NULL) { ((struct ILibChain*)c->Object)->Destroy(c->Object); } // // After calling the Destroy, we free the link // free(c->Object); c = c->Next; } // // Now we actually free the chain // c = (struct ILibBaseChain*)Chain;#if !defined(WIN32) && !defined(_WIN32_WCE) // // Free the pipe resources // fclose(c->TerminateReadPipe); fclose(c->TerminateWritePipe);#endif while(c!=NULL) { temp = c->Next; free(c); c = temp; }#ifdef WIN32 WSACleanup();#endif if(ILibChainLock_RefCounter==1) { } --ILibChainLock_RefCounter;}/// <summary>/// Stops a chain/// <para>/// This will signal the microstack thread to shutdown. When the chain cleans itself up, /// the thread that is blocked on ILibStartChain will return./// </para>/// </summary>/// <param name="Chain">The Chain to stop</param>void ILibStopChain(void *Chain){ ((struct ILibBaseChain*)Chain)->TerminateFlag = 1; ILibForceUnBlockChain(Chain);}/// <summary>/// Frees resources from an XMLNodeList tree that was returned from ILibParseXML/// </summary>/// <param name="node">The XML Tree to clean up</param>void ILibDestructXMLNodeList(struct ILibXMLNode *node){ struct ILibXMLNode *temp; while(node!=NULL) { temp = node->Next; if(node->Reserved2!=NULL) { // If there was a namespace table, delete it ILibDestroyHashTree(node->Reserved2); } free(node); node = temp; }}/// <summary>/// Frees resources from an AttributeList that was returned from ILibGetXMLAttributes/// </summary>/// <param name="attribute">The Attribute Tree to clean up</param>void ILibDestructXMLAttributeList(struct ILibXMLAttribute *attribute){ struct ILibXMLAttribute *temp; while(attribute!=NULL) { temp = attribute->Next; free(attribute); attribute = temp; }}/// <summary>/// Checks XML for validity, while at the same time populate helper properties on each node/// <para>/// This method call will populate various helper properties such as Parent, Peer, etc, to aid/// in XML parsing./// </para>/// </summary>/// <param name="nodeList">The XML Tree to process</param>/// <returns>0 if the XML is valid, nonzero otherwise</returns>int ILibProcessXMLNodeList(struct ILibXMLNode *nodeList){ int RetVal = 0; struct ILibXMLNode *current = nodeList; struct ILibXMLNode *temp; void *TagStack; ILibCreateStack(&TagStack); // // Iterate through the node list, and setup all the pointers // such that all StartElements have pointers to EndElements, // And all StartElements have pointers to siblings and parents. // while(current!=NULL) { if(current->StartTag!=0) { // Start Tag current->Parent = ILibPeekStack(&TagStack); ILibPushStack(&TagStack,current); } else { // Close Tag // // Check to see if there is supposed to be an EndElement // temp = (struct ILibXMLNode*)ILibPopStack(&TagStack); if(temp!=NULL) { // // Checking to see if this EndElement is correct in scope // if(temp->NameLength==current->NameLength && memcmp(temp->Name,current->Name,current->NameLength)==0) { // // Now that we know this EndElement is correct, set the Peer // pointers of the previous sibling // if(current->Next!=NULL) { if(current->Next->StartTag!=0) { temp->Peer = current->Next; } } temp->ClosingTag = current; current->StartingTag = temp; } else { // Illegal Close Tag Order RetVal = -2; break; } } else { // Illegal Close Tag RetVal = -1; break; } } current = current->Next; } // // If there are still elements in the stack, that means not all the StartElements // have associated EndElements, which means this XML is not valid XML. // if(TagStack!=NULL) { // Incomplete XML RetVal = -3; ILibClearStack(&TagStack); } return(RetVal);}/// <summary>/// Resolves a namespace prefix from the scope of the given node/// </summary>/// <param name="currentLocation">The node used to start the resolve</param>/// <param name="prefix">The namespace prefix to resolve</param>/// <param name="prefixLength">The lenght of the prefix</param>/// <returns>The resolved namespace. NULL if unable to resolve</returns>char* ILibXML_LookupNamespace(struct ILibXMLNode *currentLocation, char *prefix, int prefixLength){ struct ILibXMLNode *temp = currentLocation; int done=0; char* RetVal = ""; // // If the specified Prefix is zero length, we interpret that to mean // they want to lookup the default namespace // if(prefixLength==0) { // // This is the default namespace prefix // prefix = "xmlns"; prefixLength = 5; } // // From the current node, keep traversing up the parents, until we find a match. // Each step we go up, is a step wider in scope. // do { if(temp->Reserved2!=NULL) { if(ILibHasEntry(temp->Reserved2,prefix,prefixLength)!=0) { // // As soon as we find the namespace declaration, stop // iterating the tree, as it would be a waste of time // RetVal = (char*)ILibGetEntry(temp->Reserved2,prefix,prefixLength); done=1; } } temp = temp->Parent; }while(temp!=NULL && done==0); return(RetVal);}/// <summary>/// Builds the lookup table used by ILibXML_LookupNamespace/// </summary>/// <param name="node">This node will be the highest scoped</param>void ILibXML_BuildNamespaceLookupTable(struct ILibXMLNode *node){ struct ILibXMLAttribute *attr,*currentAttr; struct ILibXMLNode *current = node; // // Iterate through all the StartElements, and build a table of the declared namespaces // while(current!=NULL) { if(current->StartTag!=0) { // // Reserved2 is the HashTable containing the fully qualified namespace // keyed by the namespace prefix // current->Reserved2 = ILibInitHashTree(); currentAttr = attr = ILibGetXMLAttributes(current); if(attr!=NULL) { // // Iterate through all the attributes to find namespace declarations // while(currentAttr!=NULL) { if(currentAttr->NameLength==5 && memcmp(currentAttr->Name,"xmlns",5)==0) { // Default Namespace Declaration currentAttr->Value[currentAttr->ValueLength]=0; ILibAddEntry(current->Reserved2,"xmlns",5,currentAttr->Value); } else if(currentAttr->PrefixLength==5 && memcmp(currentAttr->Prefix,"xmlns",5)==0) { // Other Namespace Declaration currentAttr->Value[currentAttr->ValueLength]=0; ILibAddEntry(current->Reserved2,currentAttr->Name,currentAttr->NameLength,currentAttr->Value); } currentAttr=currentAttr->Next; } ILibDestructXMLAttributeList(attr); } } current = current->Next; }}/// <summary>/// Reads the data segment from an ILibXMLNode/// </summary>/// <para>/// The data is a pointer into the original string that the XML was read from./// </para>/// <param name="node">The node to read the data from</param>/// <param name="RetVal">The data</param>/// <returns>The length of the data read</returns>int ILibReadInnerXML(struct ILibXMLNode *node, char **RetVal){ struct ILibXMLNode *x = node; int length = 0; void *TagStack; *RetVal = NULL; // // Starting with the current StartElement, we use this stack to find the matching // EndElement, so we can figure out what we need to return // ILibCreateStack(&TagStack); do { if(x->StartTag!=0) {ILibPushStack(&TagStack,x);} if(x!=NULL) { x = x->Next; } else { return(0); } }while(!(x->StartTag==0 && ILibPopStack(&TagStack)==node && x->NameLength==node->NameLength && memcmp(x->Name,node->Name,node->NameLength)==0)); // // The Reserved fields of the StartElement and EndElement are used as pointers representing // the data segment of the XML // length = (int)((char*)x->Reserved - (char*)node->Reserved - 1); if(length<0) {length=0;} *RetVal = (char*)node->Reserved; return(length);}/// <summary>/// Reads the attributes from an XML node/// </summary>/// <param name="node">The node to read the attributes from</param>/// <returns>A linked list of attributes</returns>struct ILibXMLAttribute *ILibGetXMLAttributes(struct ILibXMLNode *node){ struct ILibXMLAttribute *RetVal = NULL; struct ILibXMLAttribute *current = NULL; char *c; int EndReserved = (node->EmptyTag==0)?1:2; int i; int CheckName = node->Name[node->NameLength]==0?1:0; struct parser_result *xml; struct parser_result_field *field; struct parser_result *temp2; struct parser_result *temp3; // // The reserved field is used to show where the data segments start and stop. We // can also use them to figure out where the attributes start and stop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -