User:Antigng-bot/zhconvert

#include <stdio.h>
#include <string.h>
#include "mem.h"
#include "struct.h"
#include "network.h"
#include "convert.h"
typedef struct _node
{
	unsigned int depth;
	unsigned int unicode;
	unsigned int *dest_str;
	struct _node *return_addr;
	unsigned int return_depth;
	struct _node *next_node;
	struct _node *other_node;
} match_node;
struct hashlist *matchtree=0;
struct hashlist* matchlistini()
{
	return hashini();
}
static int add_item_to_list(const unsigned int *source,const unsigned int *dest,int dest_length)
{
	match_node *tree_node;
	unsigned int ch;
	int depth=0;
	ch=*source;
	if(!int_hashquery(matchtree,ch,&tree_node))
	{
		tree_node=(match_node *)s_calloc(sizeof(struct _node),1);
		tree_node->unicode=ch;
		int_hashadd(matchtree,ch,tree_node);
		for(depth=1,source++;ch=*source;depth++,source++)
		{
			tree_node->next_node=(match_node *)s_calloc(sizeof(struct _node),1);
			tree_node=tree_node->next_node;
			tree_node->unicode=ch;
			tree_node->return_depth=depth;
			tree_node->depth=depth;
		}
		tree_node->dest_str=(unsigned int *)s_calloc(4*(dest_length+1),1);
		{
			int count;
			for(count=0;dest[count];count++)
			{
				tree_node->dest_str[count]=dest[count];
			}
			tree_node->dest_str[count]=0;
		}
	}
	else
	{
		int state=0;
		match_node *addr;
		int base_depth;
		int pre_depth;
		source++;
		while(1)
		{
			ch=*source;
			if(ch==0)
			{
				state=1;
				break;
			}
			if(!tree_node->next_node) 
			{
				state=2;
				break;
			}
			tree_node=tree_node->next_node;
			if(ch!=tree_node->unicode) 
			{
				while(1)
				{
					if(!tree_node->other_node)
					{
						state=3;
						break;
					}
					else
					{
						tree_node=tree_node->other_node;
						if(ch==tree_node->unicode) break;
					}
				}
				if(state==3) break;				
			}
			source++;
		}
		switch(state)
		{
		case 1:
			{
				struct queue *node_queue;
				if(tree_node->dest_str!=0) return -1;
				tree_node->dest_str=(unsigned int *)s_calloc(4*(dest_length+1),1);
				{
					int count;
					for(count=0;dest[count];count++) tree_node->dest_str[count]=dest[count];
					tree_node->dest_str[count]=0;
				}
				base_depth=tree_node->depth;
				addr=tree_node;
				node_queue=queueini();
				queuepush(node_queue,tree_node);
				do
				{
					queuepop(node_queue,&tree_node);
					tree_node=tree_node->next_node;
					while(tree_node)
					{
						tree_node->return_addr=addr;
						tree_node->return_depth=tree_node->depth-base_depth;
						queuepush(node_queue,tree_node);
						tree_node=tree_node->other_node;
					}
				}while(!queueisnull(node_queue));
				s_free(node_queue);
			}
			break;
		case 2:
			addr=tree_node;
			pre_depth=0;
			base_depth=tree_node->depth;
			for(depth=1;ch=*source;depth++,source++)
			{
				tree_node->next_node=(match_node *)s_calloc(sizeof(struct _node),1);
				tree_node=tree_node->next_node;
				tree_node->unicode=ch;
				tree_node->return_depth=depth+pre_depth;
				tree_node->depth=depth+base_depth;
				tree_node->return_addr=addr;
			}
			tree_node->dest_str=(unsigned int *)s_calloc(4*(dest_length+1),1);
			{
				int count;
				for(count=0;dest[count];count++) tree_node->dest_str[count]=dest[count];
				tree_node->dest_str[count]=0;
			}
			break;
		case 3:
			addr=tree_node->return_addr;
			pre_depth=tree_node->return_depth;
			base_depth=tree_node->depth;
			tree_node->other_node=(match_node *)s_calloc(sizeof(struct _node),1);
			tree_node=tree_node->other_node;
			tree_node->unicode=ch;
			tree_node->return_depth=pre_depth;
			tree_node->return_depth=base_depth;
			tree_node->depth=pre_depth;
			tree_node->return_addr=addr;
			for(depth=1,source++;ch=*source;depth++,source++)
			{
				tree_node->next_node=(match_node *)s_calloc(sizeof(struct _node),1);
				tree_node=tree_node->next_node;
				tree_node->unicode=ch;
				tree_node->return_depth=depth+pre_depth;
				tree_node->depth=depth+base_depth;
				tree_node->return_addr=addr;
			}
			tree_node->dest_str=(unsigned int *)s_calloc(4*(dest_length+1),1);
			{
				int count;
				for(count=0;dest[count];count++) tree_node->dest_str[count]=dest[count];
				tree_node->dest_str[count]=0;
			}
			break;
		}

	}
	return 0;
}
int zhconverter(const unsigned int *source,unsigned int *dest)
{
	int sourcepos=0;
	int state=0;
	int cur_depth=0;
	unsigned int ch=0;
	unsigned int *base_dest=dest;
	unsigned int *replace_str=0;
	match_node *tree_node=0;
	while(1)
	{
		switch(state)
		{
		case 0:
			ch=source[sourcepos];
			if(cur_depth==0)
			{
				if(ch==0) break;
				else if(int_hashquery(matchtree,ch,&tree_node))
				{
					cur_depth++;
				}
				else
				{
					*dest++=ch;
				}
				sourcepos++;
			}
			else
			{
				if(tree_node->next_node)
				{
					tree_node=tree_node->next_node;
					if(ch!=tree_node->unicode) state=1;
					else 
					{
						cur_depth++;
						sourcepos++;
					}
				}
				else
				{
					replace_str=tree_node->dest_str;
					while(*dest=*replace_str)
					{
						dest++;
						replace_str++;
					}
					cur_depth=0;
				}
			}
			break;
		case 1:
			while(tree_node->other_node!=0)
			{
				tree_node=tree_node->other_node;
				if(ch==tree_node->unicode)
				{
					cur_depth++;
					sourcepos++;
					state=0;
					break;
				}				
			}
			if(state==1)
			{
				cur_depth-=tree_node->return_depth;
				sourcepos-=tree_node->return_depth;
				ch=source[sourcepos];
				tree_node=tree_node->return_addr;
				if(tree_node==0)
				{
					*dest++=ch;
				}
				else
				{
					replace_str=tree_node->dest_str;
					while(*dest=*replace_str)
					{
						dest++;
						replace_str++;
					}
					cur_depth=0;
				}
				state=0;
				sourcepos++;
			}
		}
		if(ch==0&&state==0) break;
	}
	*dest=0;
	return dest-base_dest;
}