📄 ilibparsers.c
字号:
Temp = *TheStack; *TheStack = ((struct ILibStackNode*)*TheStack)->Next; free(Temp); } return(RetVal);}/// <summary>/// Peeks at the item on the top of the stack/// </summary>/// <param name="TheStack">The stack to peek from</param>/// <returns>The item that is currently on the top of the stack</returns>void *ILibPeekStack(void **TheStack){ void *RetVal = NULL; if(*TheStack!=NULL) { RetVal = ((struct ILibStackNode*)*TheStack)->Data; } return(RetVal);}/// <summary>/// Clears all the items from the stack/// </summary>/// <param name="TheStack">The stack to clear</param>void ILibClearStack(void **TheStack){ void *Temp = *TheStack; do { ILibPopStack(&Temp); }while(Temp!=NULL); *TheStack = NULL;}/// <summary>/// Locks a HashTree/// </summary>/// <param name="hashtree">The HashTree to lock</param>void ILibHashTree_Lock(void *hashtree){}/// <summary>/// Unlocks a HashTree/// </summary>/// <param name="hashtree">The HashTree to unlock</param>void ILibHashTree_UnLock(void *hashtree){}/// <summary>/// Frees resources associated with a HashTree/// </summary>/// <param name="hashtree">The HashTree to free</param>void ILibDestroyHashTree(void *tree){ struct HashNode_Root *r = (struct HashNode_Root*)tree; struct HashNode *c = r->Root; struct HashNode *n; while(c!=NULL) { // // Iterate through each node, and free all the resources // n = c->Next; if(c->KeyValue!=NULL) {free(c->KeyValue);} free(c); c = n; } free(r);}/// <summary>/// Returns an Enumerator for a HashTree/// </summary>/// <para>/// Functionally identicle to a DictionaryEnumerator in .NET/// </para>/// <param name="tree">The HashTree to get an enumerator for</param>/// <returns>An enumerator</returns>void *ILibHashTree_GetEnumerator(void *tree){ // // The enumerator is basically a state machine that keeps track of which node we are at // in the tree. So initialize it to the root. // struct HashNodeEnumerator *en = (struct HashNodeEnumerator*)malloc(sizeof(struct HashNodeEnumerator)); en->node = ((struct HashNode_Root*)tree)->Root; return(en);}/// <summary>/// Frees resources associated with an Enumerator created by ILibHashTree_GetEnumerator/// </summary>/// <param name="tree_enumerator">The enumerator to free</param>void ILibHashTree_DestroyEnumerator(void *tree_enumerator){ // // The enumerator just contains a pointer, so we can just free the enumerator // free(tree_enumerator);}/// <summary>/// Advances an enumerator to the next item/// </summary>/// <para>/// Functionally identicle to a DictionaryEnumerator in .NET/// </para>/// <param name="tree_enumerator">The enumerator to advance</param>/// <returns>A zero value if successful, nonzero if no more items</returns>int ILibHashTree_MoveNext(void *tree_enumerator){ struct HashNodeEnumerator *en = (struct HashNodeEnumerator*)tree_enumerator; if(en->node!=NULL) { // // Advance the enumerator to point to the next node. If there is a node // return 0, else return 1 // en->node = en->node->Next; return(en->node!=NULL?0:1); } else { // // There are no more nodes, so just return 1 // return(1); }}/// <summary>/// Reads from the current item of an enumerator/// </summary>/// <param name="tree_enumerator">The enumerator to read from</param>/// <param name="key">The key of the current item</param>/// <param name="keyLength">The length of the key of the current item</param>/// <param name="data">The data of the current item</param>void ILibHashTree_GetValue(void *tree_enumerator, char **key, int *keyLength, void **data){ struct HashNodeEnumerator *en = (struct HashNodeEnumerator*)tree_enumerator; // // All we do, is just assign the pointers. // if(key!=NULL){*key = en->node->KeyValue;} if(keyLength!=NULL){*keyLength = en->node->KeyLength;} if(data!=NULL){*data = en->node->Data;}}/// <summary>/// Creates an empty ILibHashTree/// </summary>/// <returns>An empty ILibHashTree</returns>void* ILibInitHashTree(void){ struct HashNode_Root *Root = (struct HashNode_Root*)malloc(sizeof(struct HashNode_Root)); struct HashNode *RetVal = (struct HashNode*)malloc(sizeof(struct HashNode)); memset(RetVal,0,sizeof(struct HashNode)); Root->Root = RetVal; return(Root);}/// <summary>/// Calculates a numeric Hash from a given string/// </summary>/// <para>/// Used by ILibHashTree methods/// </para>/// <param name="key">The string to hash</param>/// <param name="keylength">The length of the string to hash</param>/// <returns>A hash value</returns>static int ILibGetHashValue(void *key, int keylength){ int HashValue=0; char TempValue[4]; if(keylength<=4) { // // If the key length is <= 4, the hash is just the key expressed as an integer // memset(TempValue,0,4); memcpy(TempValue,key,keylength); MEMCHECK(assert(keylength<=4);) HashValue = *((int*)TempValue); } else { // // If the key length is >4, the hash is the first 4 bytes XOR with the last 4 // memcpy(TempValue,key,4); HashValue = *((int*)TempValue); memcpy(TempValue,(char*)key+(keylength-4),4); HashValue = HashValue^(*((int*)TempValue)); // // If the key length is >= 10, the hash is also XOR with the middle 4 bytes // if(keylength>=10) { memcpy(TempValue,(char*)key+(keylength/2),4); HashValue = HashValue^(*((int*)TempValue)); } } return(HashValue);}/// <summary>/// Determines if a key entry exists in a HashTree, and creates it if requested/// </summary>/// <para>/// Used by ILibHashTree methods/// </para>/// <param name="hashtree">The HashTree to operate on</param>/// <param name="key">The key</param>/// <param name="keylength">The length of the key</param>/// <param name="create">0 if non-existing item is NOT to be created. Nonzero otherwise</param>/// <returns>A hash value</returns>static struct HashNode* ILibFindEntry(void *hashtree, void *key, int keylength, int create){ struct HashNode *current = ((struct HashNode_Root*)hashtree)->Root; int HashValue = ILibGetHashValue(key,keylength); int done = 0; if(keylength==0){return(NULL);} // // Iterate through our tree to see if we can find this key entry // while(done==0) { // // Integer compares are very fast, this will weed out most non-matches // if(current->KeyHash==HashValue) { // // Verify this is really a match // if(current->KeyLength==keylength && memcmp(current->KeyValue,key,keylength)==0) { return(current); } } if(current->Next!=NULL) { current = current->Next; } else if(create!=0) { // // If there is no match, and the create flag is set, we need to create an entry // current->Next = (struct HashNode*)malloc(sizeof(struct HashNode)); memset(current->Next,0,sizeof(struct HashNode)); current->Next->Prev = current; current->Next->KeyHash = HashValue; current->Next->KeyValue = (void*)malloc(keylength+1); memcpy(current->Next->KeyValue,key,keylength); current->Next->KeyValue[keylength]=0; current->Next->KeyLength = keylength; return(current->Next); } else { return(NULL); } } return(NULL);}/// <summary>/// Determines if a key entry exists in a HashTree/// </summary>/// <param name="hashtree">The HashTree to operate on</param>/// <param name="key">The key</param>/// <param name="keylength">The length of the key</param>/// <returns>0 if does not exist, nonzero otherwise</returns>int ILibHasEntry(void *hashtree, char* key, int keylength){ // // This can be duplicated by calling Find entry, but setting the create flag to false // return(ILibFindEntry(hashtree,key,keylength,0)!=NULL?1:0);}/// <summary>/// Adds an item to the HashTree/// </summary>/// <param name="hashtree">The HashTree to operate on</param>/// <param name="key">The key</param>/// <param name="keylength">The length of the key</param>/// <param name="value">The data to add into the HashTree</param>void ILibAddEntry(void* hashtree, char* key, int keylength, void *value){ // // This can be duplicated by calling FindEntry, and setting create to true // struct HashNode* n = ILibFindEntry(hashtree,key,keylength,1); n->Data = value;}/// <summary>/// Gets an item from a HashTree/// </summary>/// <param name="hashtree">The HashTree to operate on</param>/// <param name="key">The key</param>/// <param name="keylength">The length of the key</param>/// <returns>The data in the HashTree. NULL if key does not exist</returns>void* ILibGetEntry(void *hashtree, char* key, int keylength){ // // This can be duplicated by calling FindEntry and setting create to false. // If a match is found, just return the data // struct HashNode* n = ILibFindEntry(hashtree,key,keylength,0); if(n==NULL) { return(NULL); } else { return(n->Data); }}/// <summary>/// Deletes a keyed item from the HashTree/// </summary>/// <param name="hashtree">The HashTree to operate on</param>/// <param name="key">The key</param>/// <param name="keylength">The length of the key</param>void ILibDeleteEntry(void *hashtree, char* key, int keylength){ // // First find the entry // struct HashNode* n = ILibFindEntry(hashtree,key,keylength,0); if(n!=NULL) { // // Then remove it from the tree // n->Prev->Next = n->Next; if(n->Next!=NULL) { n->Next->Prev = n->Prev; } free(n->KeyValue); free(n); }}/// <summary>/// Reads a long value from a string, in a validating fashion/// </summary>/// <param name="TestValue">The string to read from</param>/// <param name="TestValueLength">The length of the string</param>/// <param name="NumericValue">The long value extracted from the string</param>/// <returns>0 if succesful, nonzero if there was an error</returns>int ILibGetLong(char *TestValue, int TestValueLength, long* NumericValue){ char* StopString; char* TempBuffer2 = (char*)malloc(1+sizeof(char)*19); char* TempBuffer = (char*)malloc(1+sizeof(char)*TestValueLength); memcpy(TempBuffer,TestValue,TestValueLength); TempBuffer[TestValueLength] = '\0'; *NumericValue = strtol(TempBuffer,&StopString,10); if(*StopString!='\0') { // // If strtol stopped somewhere other than the end, there was an error // free(TempBuffer); free(TempBuffer2); return(-1); } else { // // Now just check errno to see if there was an error reported // free(TempBuffer); free(TempBuffer2); if(errno!=ERANGE) { return(0); } else { return(-1); } }}/// <summary>/// Reads an unsigned long value from a string, in a validating fashion/// </summary>/// <param name="TestValue">The string to read from</param>/// <param name="TestValueLength">The length of the string</param>/// <param name="NumericValue">The unsigned long value extracted from the string</param>int ILibGetULong(const char *TestValue, const int TestValueLength, unsigned long* NumericValue){ char* StopString; char* TempBuffer2 = (char*)malloc(1+sizeof(char)*19); char* TempBuffer = (char*)malloc(1+sizeof(char)*TestValueLength); memcpy(TempBuffer,TestValue,TestValueLength); TempBuffer[TestValueLength] = '\0'; *NumericValue = strtoul(TempBuffer,&StopString,10); if(*StopString!='\0') { free(TempBuffer); free(TempBuffer2); return(-1); } else { free(TempBuffer); free(TempBuffer2);#ifdef _WIN32_WCE // Not Supported on PPC return(0);#else if(errno!=ERANGE) { if(memcmp(TestValue,"-",1)==0) { return(-1); } return(0); } else { return(-1); }#endif }}/// <summary>/// Determines if a buffer offset is a delimiter/// </summary>/// <para>/// Used by string parsing methods/// </para>/// <param name="buffer">The buffer to check</param>/// <param name="offset">The offset of the buffer to check</param>/// <param name="buffersize">The length of the buffer to check</param>/// <param name="Delimiter">The delimiter we are looking for</param>/// <param name="DelimiterLength">The length of the delimiter</param>/// <returns>0 if no match, nonzero otherwise</returns>static int ILibIsDelimiter(char* buffer, int offset, int buffersize, char* Delimiter, int DelimiterLength){ // // For simplicity sake, we'll assume a match unless proven otherwise // int i=0; int RetVal = 1; if(DelimiterLength>buffersize) { // // If the offset plus delimiter length is greater than the buffersize // There can't possible be a match, so don't bother looking // return(0); } for(i=0;i<DelimiterLength;++i) { if(buffer[offset+i]!=Delimiter[i]) { // // Uh oh! Can't possibly be a match now! // RetVal = 0; break; } } return(RetVal);}/// <summary>/// Parses a string into a linked list of tokens./// </summary>/// <para>/// Differs from ILibParseString, in that this method ignores characters contained within/// quotation marks, whereas ILibParseString does not./// </para>/// <param name="buffer">The buffer to parse</param>/// <param name="offset">The offset of the buffer to start parsing</param>/// <param name="length">The length of the buffer to parse</param>/// <param name="Delimiter">The delimiter</param>/// <param name="DelimiterLength">The length of the delimiter</param>/// <returns>A list of tokens</returns>struct parser_result* ILibParseStringAdv(char* buffer, int offset, int length, char* Delimiter, int DelimiterLength){ struct parser_result* RetVal = (struct parser_result*)malloc(sizeof(struct parser_result)); int i=0; char* Token = NULL; int TokenLength = 0; struct parser_result_field *p_resultfield; int Ignore = 0; char StringDelimiter=0; RetVal->FirstResult = NULL; RetVal->NumResults = 0; // // By default we will always return at least one token, which will be the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -