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

📄 ilibparsers.c

📁 解析xml格式的文件的好源码。解析xml格式的文件的好源码。解析xml格式的文件的好源码。解析xml格式的文件的好源码。解析xml格式的文件的好源码。
💻 C
📖 第 1 页 / 共 5 页
字号:


//
// Determines if a buffer offset is a delimiter
//
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);
}

/*! \fn ILibParseStringAdv(char* buffer, int offset, int length, char* Delimiter, int DelimiterLength)
	\brief Parses a string into a linked list of tokens.
	\para
	Differs from \a ILibParseString, in that this method ignores characters contained within
	quotation marks, whereas \a ILibParseString does not.
	\param buffer The buffer to parse
	\param offset The offset of the buffer to start parsing
	\param length The length of the buffer to parse
	\param Delimiter The delimiter
	\param DelimiterLength The length of the delimiter
	\returns A list of tokens
*/
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
	// entire string if the delimiter is not found.
	//
	// Iterate through the string to find delimiters
	//
	Token = buffer + offset;
	for(i=offset;i<(length+offset);++i)
	{
		if(StringDelimiter==0)
		{
			if(buffer[i]=='"') 
			{
				//
				// Ignore everything inside double quotes
				//
				StringDelimiter='"';
				Ignore=1;
			}
			else
			{
				if(buffer[i]=='\'')
				{
					//
					// Ignore everything inside single quotes
					//
					StringDelimiter='\'';
					Ignore=1;
				}
			}
		}
		else
		{
			//
			// Once we isolated everything inside double or single quotes, we can get
			// on with the real parsing
			//
			if(buffer[i]==StringDelimiter)
			{
				Ignore=((Ignore==0)?1:0);
			}
		}
		if(Ignore==0 && ILibIsDelimiter(buffer,i,length,Delimiter,DelimiterLength))
		{
			//
			// We found a delimiter in the string
			//
			p_resultfield = (struct parser_result_field*)malloc(sizeof(struct parser_result_field));
			p_resultfield->data = Token;
			p_resultfield->datalength = TokenLength;
			p_resultfield->NextResult = NULL;
			if(RetVal->FirstResult != NULL)
			{
				RetVal->LastResult->NextResult = p_resultfield;
				RetVal->LastResult = p_resultfield;
			}
			else
			{
				RetVal->FirstResult = p_resultfield;
				RetVal->LastResult = p_resultfield;
			}
			
			//
			// After we populate the values, we advance the token to after the delimiter
			// to prep for the next token
			//
			++RetVal->NumResults;
			i = i + DelimiterLength -1;
			Token = Token + TokenLength + DelimiterLength;
			TokenLength = 0;	
		}
		else
		{
			//
			// No match yet, so just increment this counter
			//
			++TokenLength;
		}
	}

	//
	// Create a result for the last token, since it won't be caught in the above loop
	// because if there are no more delimiters, than the entire last portion of the string since the 
	// last delimiter is the token
	//
	p_resultfield = (struct parser_result_field*)malloc(sizeof(struct parser_result_field));
	p_resultfield->data = Token;
	p_resultfield->datalength = TokenLength;
	p_resultfield->NextResult = NULL;
	if(RetVal->FirstResult != NULL)
	{
		RetVal->LastResult->NextResult = p_resultfield;
		RetVal->LastResult = p_resultfield;
	}
	else
	{
		RetVal->FirstResult = p_resultfield;
		RetVal->LastResult = p_resultfield;
	}	
	++RetVal->NumResults;
	
	return(RetVal);
}

/*! \fn ILibTrimString(char **theString, int length)
	\brief Trims leading and trailing whitespace characters
	\param theString The string to trim
	\param length Length of \a theString
	\returns Length of the trimmed string
*/
int ILibTrimString(char **theString, int length)
{
	int i;
	int flag1=0,flag2=0;
	for(i=0;i<length;++i)
	{
		if(!flag2 && (*theString)[length-i-1]!=8 && (*theString)[length-i-1]!=32)
		{
			length -= i;
			flag2=1;
			if(flag1 && flag2) {break;}
		}		
		if(!flag1 && (*theString)[i]!=8 && (*theString)[i]!=32)
		{
			*theString = *theString + i;
			length -= i;
			flag1=1;
			if(flag1 && flag2) {break;}
		}
	}
	return(length);
}

/*! \fn ILibParseString(char* buffer, int offset, int length, char* Delimiter, int DelimiterLength)
	\brief Parses a string into a linked list of tokens.
	\para
	Differs from \a ILibParseStringAdv, in that this method does not ignore characters contained within
	quotation marks, whereas \a ILibParseStringAdv does.
	\param buffer The buffer to parse
	\param offset The offset of the buffer to start parsing
	\param length The length of the buffer to parse
	\param Delimiter The delimiter
	\param DelimiterLength The length of the delimiter
	\returns A list of tokens
*/
struct parser_result* ILibParseString(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;
	
	RetVal->FirstResult = NULL;
	RetVal->NumResults = 0;
	
	//
	// By default we will always return at least one token, which will be the
	// entire string if the delimiter is not found.
	//
	// Iterate through the string to find delimiters
	//
	Token = buffer + offset;
	for(i=offset;i<length;++i)
	{
		if(ILibIsDelimiter(buffer,i,length,Delimiter,DelimiterLength))
		{
			//
			// We found a delimiter in the string
			//
			p_resultfield = (struct parser_result_field*)malloc(sizeof(struct parser_result_field));
			p_resultfield->data = Token;
			p_resultfield->datalength = TokenLength;
			p_resultfield->NextResult = NULL;
			if(RetVal->FirstResult != NULL)
			{
				RetVal->LastResult->NextResult = p_resultfield;
				RetVal->LastResult = p_resultfield;
			}
			else
			{
				RetVal->FirstResult = p_resultfield;
				RetVal->LastResult = p_resultfield;
			}
			
			//
			// After we populate the values, we advance the token to after the delimiter
			// to prep for the next token
			//
			++RetVal->NumResults;
			i = i + DelimiterLength -1;
			Token = Token + TokenLength + DelimiterLength;
			TokenLength = 0;	
		}
		else
		{
			//
			// No match yet, so just increment this counter
			//
			++TokenLength;
		}
	}

	//
	// Create a result for the last token, since it won't be caught in the above loop
	// because if there are no more delimiters, than the entire last portion of the string since the 
	// last delimiter is the token
	//
	p_resultfield = (struct parser_result_field*)malloc(sizeof(struct parser_result_field));
	p_resultfield->data = Token;
	p_resultfield->datalength = TokenLength;
	p_resultfield->NextResult = NULL;
	if(RetVal->FirstResult != NULL)
	{
		RetVal->LastResult->NextResult = p_resultfield;
		RetVal->LastResult = p_resultfield;
	}
	else
	{
		RetVal->FirstResult = p_resultfield;
		RetVal->LastResult = p_resultfield;
	}	
	++RetVal->NumResults;
	
	return(RetVal);
}

/*! \fn ILibDestructParserResults(struct parser_result *result)
	\brief Frees resources associated with the list of tokens returned from ILibParseString and ILibParseStringAdv.
	\param result The list of tokens to free
*/
void ILibDestructParserResults(struct parser_result *result)
{
	//
	// All of these nodes only contain pointers
	// so we just need to iterate through all the nodes and free them
	//
	struct parser_result_field *node = result->FirstResult;
	struct parser_result_field *temp;
	
	while(node!=NULL)
	{
		temp = node->NextResult;
		free(node);
		node = temp;
	}
	free(result);
}

/*! \fn ILibDestructPacket(struct packetheader *packet)
	\brief Frees resources associated with a Packet that was created either by \a ILibCreateEmptyPacket or \a ILibParsePacket
	\param packet The packet to free
*/
void ILibDestructPacket(struct packetheader *packet)
{
	struct packetheader_field_node *node = packet->FirstField;
	struct packetheader_field_node *nextnode;
	
	//
	// Iterate through all the headers
	//
	while(node!=NULL)
	{
		nextnode = node->NextField;
		if(node->UserAllocStrings!=0)
		{
			//
			// If the user allocated the string, then we need to free it.
			// Otherwise these are just pointers into others strings, in which
			// case we don't want to free them
			//
			free(node->Field);
			free(node->FieldData);
		}
		free(node);
		node = nextnode;
	}
	if(packet->UserAllocStrings!=0)
	{
		//
		// If this flag was set, it means the used ILibCreateEmptyPacket,
		// and set these fields manually, which means the string was copied.
		// In which case, we need to free the strings
		//
		if(packet->StatusData!=NULL) {free(packet->StatusData);}
		if(packet->Directive!=NULL) {free(packet->Directive);}
		if(packet->Reserved==NULL && packet->DirectiveObj!=NULL) {free(packet->DirectiveObj);}
		if(packet->Reserved!=NULL) {free(packet->Reserved);}
		if(packet->Body!=NULL) free(packet->Body);
	}
	if(packet->UserAllocVersion!=0)
	{
		free(packet->Version);
	}
	free(packet);
}

/*! \fn ILibHTTPEscape(char* outdata, const char* data)
	\brief Escapes a string according to HTTP Specifications.
	\para
	The string you would want to escape would typically be the string used in the Path portion
	of an HTTP request. eg:<br>
	GET foo/bar.txt HTTP/1.1<br>
	<br>
	\b Note: It should be noted that the output buffer needs to be allocated prior to calling this method.
	The required space can be determined by calling \a ILibHTTPEscapeLength.
	\param outdata The escaped string
	\param data The string to escape
	\returns The length of the escaped string
*/
int ILibHTTPEscape(char* outdata, const char* data)
{
	int i=0;
	int x=0;
	char hex[4];
	int hexLen;

	while(data[x]!=0)
	{
		if( (data[x]>=63 && data[x]<=90) || (data[x]>=97 && data[x]<=122) || (data[x]>=47 && data[x]<=57) \
			|| data[x]==59 || data[x]==47 || data[x]==63 || data[x]==58 || data[x]==64 || data[x]==61 \
			|| data[x]==43 || data[x]==36 || data[x]==45 || data[x]==95 || data[x]==46 || data[x]==42)
		{
			//
			// These are all the allowed values for HTTP. If it's one of these characters, we're ok
			//
			outdata[i] = data[x];
			++i;
		}
		else
		{
			//
			// If it wasn't one of these characters, then we need to escape it
			//
			hexLen = sprintf(hex,"%02X",(unsigned char)data[x]);
			outdata[i] = '%';
			outdata[i+1] = hex[0];
			outdata[i+2] = hex[1];
			i+=3;
		}
		++x;
	}
	outdata[i]=0;
	return(i+1);
}

/*! \fn ILibHTTPEscapeLength(const char* data)
	\brief Determines the buffer space required to HTTP escape a particular string.
	\param data Calculates the length requirements as if \a\b data was escaped
	\returns The minimum required length
*/
int ILibHTTPEscapeLength(const char* data)
{
	int i=0;
	int x=0;
	while(data[x]!=0)
	{
		if( (data[x]>=63 && data[x]<=90) || (data[x]>=97 && data[x]<=122) || (data[x]>=47 && data[x]<=57) \
			|| data[x]==59 || data[x]==47 || data[x]==63 || data[x]==58 || data[x]==64 || data[x]==61 \
			|| data[x]==43 || data[x]==36 || data[x]==45 || data[x]==95 || data[x]==46 || data[x]==42)
		{
			// No need to escape
			++i;
		}
		else
		{
			// Need to escape
			i+=3;
		}
		++x;
	}
	return(i+1);
}

/*! \fn ILibInPlaceHTTPUnEscape(char* data)
	\brief Unescapes a given string according to HTTP encoding rules
	\para
	The escaped representation of a string is always longer than the unescaped version
	so this method will overwrite the escaped string, with the unescaped result.
	\param data The buffer to unescape
	\returns The length of the unescaped string
*/
int ILibInPlaceHTTPUnEscape(char* data)
{
	char hex[3];
	char *stp;
	int src_x=0;
	int dst_x=0;

	int length = (int)strlen(data);
	hex[2]=0;

	while(src_x<length)
	{
		if(strncmp(data+src_x,"%",1)==0)
		{
			//
			// Since we encountered a '%' we know this is an escaped character
			//
			hex[0] = data[src_x+1];
			hex[1] = data[src_x+2];
			data[dst_x] = (char)strtol(hex,&stp,16);
			dst_x += 1;
			src_x += 3;
		}
		else if(src_x!=dst_x)
		{
			//
			// This doesn't need to be unescaped. If we didn't unescape anything previously
			// there is no need to copy the string either
			//
			data[dst_x] = data[src_x];
			src_x += 1;
			dst_x += 1;
		}
		else
		{
			//
			// This doesn't need to be unescaped, however we need to copy the string
			//
			src_x += 1;
			dst_x += 1;
		}
	}
	return(dst_x);
}

/*! \fn ILibParsePacketHeader(char* buffer, int offset, int length)
	\brief Parses the HTTP headers from a buffer, into a packetheader structure
	\param buffer The buffer to parse
	\param offset The offset of the buffe

⌨️ 快捷键说明

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