1 #include "../../src/bsdconv.h"
2 
3 #include "_NF-CCC.h"
4 
5 struct my_s {
6 	struct bsdconv_instance *map;
7 	size_t *err;
8 	int status;
9 	struct data_rt *starter;
10 	int ccc;
11 	struct data_rt *pending_head;
12 	struct data_rt *pending_tail;
13 };
14 
cbcreate(struct bsdconv_instance * ins,struct bsdconv_hash_entry * arg)15 int cbcreate(struct bsdconv_instance *ins, struct bsdconv_hash_entry *arg){
16 	struct my_s *r=THIS_CODEC(ins)->priv=malloc(sizeof(struct my_s));
17 	r->map=bsdconv_create("_NFC-MAP,COUNT#ERR");
18 	r->err=bsdconv_counter(r->map, "ERR");
19 	r->starter=NULL;
20 	r->pending_tail=r->pending_head=malloc(sizeof(struct data_rt));
21 	r->pending_head->flags=0;
22 	r->pending_tail->next=NULL;
23 	return 0;
24 }
25 
cbinit(struct bsdconv_instance * ins)26 void cbinit(struct bsdconv_instance *ins){
27 	struct my_s *r=THIS_CODEC(ins)->priv;
28 	r->status=0;
29 	struct data_rt *t;
30 	if(r->starter){
31 		DATUM_FREE(ins, r->starter);
32 	}
33 	while(r->pending_head->next){
34 		t=r->pending_head->next->next;
35 		DATUM_FREE(ins, r->pending_head->next);
36 		r->pending_head->next=t;
37 	}
38 	r->pending_tail=r->pending_head;
39 }
40 
cbconv(struct bsdconv_instance * ins)41 void cbconv(struct bsdconv_instance *ins){
42 	struct my_s *r=THIS_CODEC(ins)->priv;
43 	unsigned char *data;
44 	struct bsdconv_phase *this_phase=THIS_PHASE(ins);
45 	struct bsdconv_phase *prev_phase=&ins->phase[ins->phase_index-1];
46 	data=this_phase->curr->data;
47 	int i;
48 	uint32_t ucs=0;
49 	int ccc=0;
50 	int max=sizeof(ccc_table) / sizeof(struct ccc_interval) - 1;
51 	int min = 0;
52 	int mid;
53 	struct data_rt *t;
54 
55 	if(data[0]==0x1){
56 		for(i=1;i<this_phase->curr->len;++i){
57 			ucs<<=8;
58 			ucs|=data[i];
59 		}
60 		if (ucs < ccc_table[0].beg || ucs > ccc_table[max].end){
61 			//noop
62 		}else while (max >= min) {
63 			mid = (min + max) / 2;
64 			if (ucs > ccc_table[mid].end)
65 				min = mid + 1;
66 			else if (ucs < ccc_table[mid].beg)
67 				max = mid - 1;
68 			else{
69 				ccc=ccc_table[mid].ccc;
70 				break;
71 			}
72 		}
73 		switch(r->status){
74 			case 0:
75 				r->ccc=0;
76 				if(ccc==0){ //first starters
77 					if(r->starter){
78 						DATUM_FREE(ins, r->starter);
79 					}
80 					r->status=1;
81 					r->starter=dup_data_rt(ins, this_phase->curr);
82 					this_phase->state.status=SUBMATCH;
83 				}else{ //non-starters
84 					this_phase->state.status=DEADEND;
85 				}
86 				return;
87 			case 1:
88 				if(ccc==0){ //following starter
89 					r->ccc=0;
90 					if(r->pending_head->next==NULL){ //adjacent starters
91 						bsdconv_init(r->map);
92 						bsdconv_counter_reset(r->map, NULL);
93 						r->map->input=*(r->starter);
94 						r->map->input.flags &= ~F_FREE;
95 						DATA_MALLOC(ins, r->map->input.next);
96 						*(r->map->input.next)=*(this_phase->curr);
97 						r->map->input.next->flags &= ~F_FREE;
98 						r->map->input.next->next=NULL;
99 						r->map->flush=1;
100 						bsdconv(r->map);
101 						if(*(r->err)==0){
102 							DATUM_FREE(ins, r->starter);
103 							r->status=1;
104 							r->starter=r->map->phase[r->map->phasen].data_head->next;
105 							r->map->phase[r->map->phasen].data_head->next=NULL;
106 						}else{
107 							cbflush(ins);
108 							r->status=1;
109 							r->starter=dup_data_rt(ins, this_phase->curr);
110 						}
111 					}else{ //replace first starters
112 						cbflush(ins);
113 						r->status=1;
114 						r->starter=dup_data_rt(ins, this_phase->curr);
115 					}
116 				}else{ //following non-starters
117 					if(ccc <= r->ccc){ //blocked
118 						r->ccc=ccc;
119 						r->pending_tail->next=dup_data_rt(ins, this_phase->curr);
120 						r->pending_tail=r->pending_tail->next;
121 						r->pending_tail->next=NULL;
122 					}else{ //try to combine
123 						bsdconv_init(r->map);
124 						bsdconv_counter_reset(r->map, NULL);
125 						r->map->input=*(r->starter);
126 						r->map->input.flags &= ~F_FREE;
127 						DATA_MALLOC(ins, r->map->input.next);
128 						*(r->map->input.next)=*(this_phase->curr);
129 						r->map->input.next->flags &= ~F_FREE;
130 						r->map->input.next->next=NULL;
131 						r->map->flush=1;
132 
133 						bsdconv(r->map);
134 						if(*(r->err)==0){ //combinable
135 							DATUM_FREE(ins, r->starter);
136 							r->status=1;
137 							r->starter=r->map->phase[r->map->phasen].data_head->next;
138 							r->map->phase[r->map->phasen].data_head->next=NULL;
139 
140 							if(r->pending_head->next){
141 								t=this_phase->curr->next;
142 								this_phase->curr->next=r->pending_head->next;
143 								r->pending_tail->next=t;
144 								r->pending_tail=r->pending_head;
145 								r->pending_head->next=NULL;
146 								while(prev_phase->data_tail->next){
147 									prev_phase->data_tail=prev_phase->data_tail->next;
148 								}
149 							}
150 							r->ccc=0;
151 						}else{ //not combinable
152 							r->ccc=ccc;
153 							r->pending_tail->next=dup_data_rt(ins, this_phase->curr);
154 							r->pending_tail=r->pending_tail->next;
155 							r->pending_tail->next=NULL;
156 						}
157 					}
158 				}
159 				this_phase->state.status=SUBMATCH;
160 				return;
161 		}
162 	}else{ //not unicode
163 		r->ccc=0;
164 		cbflush(ins);
165 		this_phase->data_tail->next=dup_data_rt(ins, this_phase->curr);
166 		this_phase->data_tail=this_phase->data_tail->next;
167 		this_phase->data_tail->next=NULL;
168 	}
169 	return;
170 }
171 
cbdestroy(struct bsdconv_instance * ins)172 void cbdestroy(struct bsdconv_instance *ins){
173 	struct my_s *r=THIS_CODEC(ins)->priv;
174 	struct data_rt *t;
175 	bsdconv_destroy(r->map);
176 	if(r->status){
177 		DATUM_FREE(ins, r->starter);
178 	}
179 	while(r->pending_head){
180 		t=r->pending_head->next;
181 		DATUM_FREE(ins, r->pending_head);
182 		r->pending_head=t;
183 	}
184 	free(r);
185 }
186 
cbflush(struct bsdconv_instance * ins)187 void cbflush(struct bsdconv_instance *ins){
188 	struct bsdconv_phase *this_phase=THIS_PHASE(ins);
189 	struct my_s *r=THIS_CODEC(ins)->priv;
190 	struct data_rt *t;
191 
192 	this_phase->state.status=NEXTPHASE;
193 
194 	if(r->status==0)
195 		return;
196 
197 	this_phase->data_tail->next=r->starter;
198 	this_phase->data_tail=this_phase->data_tail->next;
199 	this_phase->data_tail->next=NULL;
200 
201 	r->starter=NULL;
202 
203 	while(r->pending_head->next){
204 		t=r->pending_head->next->next;
205 		this_phase->data_tail->next=r->pending_head->next;
206 		this_phase->data_tail=this_phase->data_tail->next;
207 		this_phase->data_tail->next=NULL;
208 		r->pending_head->next=t;
209 	}
210 	r->pending_tail=r->pending_head;
211 
212 	r->status=0;
213 }
214