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