#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;
}