OSDN Git Service

edcc4b7a3d945badf31a040102001737b728f1da
[bbk/bchan.git] / src / tadimf.c
1 /*
2  * tadimf.c
3  *
4  * Copyright (c) 2010 project bchan
5  *
6  * This software is provided 'as-is', without any express or implied
7  * warranty. In no event will the authors be held liable for any damages
8  * arising from the use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not
15  *    claim that you wrote the original software. If you use this software
16  *    in a product, an acknowledgment in the product documentation would be
17  *    appreciated but is not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  *    misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source
23  *    distribution.
24  *
25  */
26
27 #include        <basic.h>
28 #include        <tcode.h>
29
30 #include    "tadimf.h"
31 #include    "tadlib.h"
32
33 /* like internet message format. rfc5322. */
34
35 EXPORT VOID timfparser_clear(timfparser_t *timf)
36 {
37         //taditerator_initialize(&timf->iterator);
38         tctokenchecker_clear(&timf->headerchecker);
39         timf->state = TIMFPARSER_STATE_SEARCH_HEADER;
40         timf->ishankaku = False;
41 }
42
43 LOCAL Bool is_chratio_fusen(LTADSEG *seg, RATIO *w_ratio)
44 {
45         UB *data;
46         UB subid;
47
48         if ((seg->id & 0xFF) != TS_TFONT) {
49                 return False;
50         }
51         if (seg->len != 6) {
52                 return False;
53         }
54         data = ((UB*)seg) + 4;
55         subid = *(UH*)data >> 8;
56         if (subid != 3) {
57                 return False;
58         }
59         *w_ratio = *(RATIO*)(data + 4);
60         return True;
61 }
62
63 EXPORT W timfparser_next(timfparser_t *timf, W *headername, UB **bin, W *len)
64 {
65         W segsize, ret, val, ratio_a, ratio_b;
66         TC ch;
67         UB *data;
68         LTADSEG *seg;
69         TADITERATOR_RESULT_T result;
70         Bool is_chratio;
71         RATIO w_ratio;
72
73         for (;;) {
74                 result = taditerator_next(&timf->iterator, NULL, &ch, &seg, &segsize, &data);
75                 if (result == TADITERATOR_RESULT_END) {
76                         return TIMFPARSER_RESULT_END;
77                 }
78                 if (result == TADITERATOR_RESULT_CHARCTOR) {
79                         switch (timf->state) {
80                         case TIMFPARSER_STATE_SEARCH_HEADER:
81                                 if (ch == TK_NL) {
82                                         timf->state = TIMFPARSER_STATE_READ_VALUE_MESSAGE;
83                                         if (timf->ishankaku == True) {
84                                                 *bin = (UB*)timf->chratio;
85                                                 *len = 10;
86                                                 return TIMFPARSER_RESULT_BODY;
87                                         }
88                                         break;
89                                 }
90                                 tctokenchecker_clear(&timf->headerchecker);
91                                 timf->state = TIMFPARSER_STATE_READ_HEADER_FIELDNAME;
92                                 ret = tctokenchecker_inputchar(&timf->headerchecker, ch, &val);
93                                 if (ret == TCTOKENCHECKER_DETERMINE) {
94                                         timf->state = TIMFPARSER_STATE_READ_HEADER_FIELDVALUE;
95                                         timf->headertype = val;
96                                 } else if (ret != TCTOKENCHECKER_CONTINUE) {
97                                         timf->state = TIMFPARSER_STATE_SKIP_HEADER;
98                                 } else {
99                                         timf->state = TIMFPARSER_STATE_SEARCH_HEADER_FIELDVALUE;
100                                 }
101                                 break;
102                         case TIMFPARSER_STATE_SKIP_HEADER:
103                                 if (ch == TK_NL) {
104                                         timf->state = TIMFPARSER_STATE_SEARCH_HEADER;
105                                 }
106                                 break;
107                         case TIMFPARSER_STATE_READ_HEADER_FIELDNAME:
108                                 ret = tctokenchecker_inputchar(&timf->headerchecker, ch, &val);
109                                 if (ret == TCTOKENCHECKER_DETERMINE) {
110                                         timf->state = TIMFPARSER_STATE_READ_HEADER_FIELDVALUE;
111                                         timf->headertype = val;
112                                 } else if (ret != TCTOKENCHECKER_CONTINUE) {
113                                         timf->state = TIMFPARSER_STATE_SKIP_HEADER;
114                                 } else {
115                                         timf->state = TIMFPARSER_STATE_SEARCH_HEADER_FIELDVALUE;
116                                 }
117                                 break;
118                         case TIMFPARSER_STATE_SEARCH_HEADER_FIELDVALUE:
119                                 if (ch == TK_KSP) {
120                                         break;
121                                 }
122                                 timf->state = TIMFPARSER_STATE_READ_HEADER_FIELDNAME;
123                                 *headername = timf->headertype;
124                                 if (timf->ishankaku == True) {
125                                         memcpy(timf->buf, timf->chratio, 10);
126                                         timf->buf[5] = ch;
127                                         *bin = (UB*)timf->buf;
128                                         *len = 6;
129                                 } else {
130                                         timf->buf[0] = ch;
131                                         *bin = (UB*)timf->buf;
132                                         *len = 2;
133                                 }
134                                 return TIMFPARSER_RESULT_HEADERVALUE;
135                         case TIMFPARSER_STATE_READ_HEADER_FIELDVALUE:
136                                 if (ch == TK_NL) {
137                                         timf->state = TIMFPARSER_STATE_SEARCH_HEADER;
138                                         break;
139                                 }
140                                 timf->buf[0] = ch;
141                                 *headername = timf->headertype;
142                                 *bin = (UB*)timf->buf;
143                                 *len = 2;
144                                 return TIMFPARSER_RESULT_HEADERVALUE;
145                         case TIMFPARSER_STATE_READ_VALUE_MESSAGE:
146                                 timf->buf[0] = ch;
147                                 *bin = (UB*)timf->buf;
148                                 *len = 2;
149                                 return TIMFPARSER_RESULT_BODY;
150                         }
151                 } else if (result == TADITERATOR_RESULT_SEGMENT) {
152                         is_chratio = is_chratio_fusen(seg, &w_ratio);
153                         if (is_chratio == False) {
154                                 continue;
155                         }
156
157                         switch (timf->state) {
158                         case TIMFPARSER_STATE_SEARCH_HEADER:
159                         case TIMFPARSER_STATE_SKIP_HEADER:
160                         case TIMFPARSER_STATE_READ_HEADER_FIELDNAME:
161                         case TIMFPARSER_STATE_SEARCH_HEADER_FIELDVALUE:
162                                 memcpy(timf->chratio, seg, 10);
163                                 ratio_a = w_ratio >> 8;
164                                 ratio_b = w_ratio & 0xFF;
165                                 if ((ratio_a * 2 > ratio_b)||(ratio_b == 0)) {
166                                         timf->ishankaku = False;
167                                 } else {
168                                         timf->ishankaku = True;
169                                 }
170                                 break;
171                         case TIMFPARSER_STATE_READ_HEADER_FIELDVALUE:
172                                 memcpy(timf->chratio, seg, 10);
173                                 ratio_a = w_ratio >> 8;
174                                 ratio_b = w_ratio & 0xFF;
175                                 if ((ratio_a * 2 > ratio_b)||(ratio_b == 0)) {
176                                         timf->ishankaku = False;
177                                 } else {
178                                         timf->ishankaku = True;
179                                 }
180                                 *headername = timf->headertype;
181                                 *bin = (UB*)timf->chratio;
182                                 *len = 5;
183                                 return TIMFPARSER_RESULT_HEADERVALUE;
184                         case TIMFPARSER_STATE_READ_VALUE_MESSAGE:
185                                 *bin = (UB*)timf->chratio;
186                                 *len = 5;
187                                 return TIMFPARSER_RESULT_BODY;
188                         }
189                 }
190         }
191
192         return TIMFPARSER_RESULT_END;
193 }
194
195 LOCAL TC timfparser_headerend[] = {TK_COLN, TNULL};
196
197 EXPORT VOID timfparser_initialize(timfparser_t *timf, tctokenchecker_valuetuple_t *val, W val_len, TC *bin, W strlen)
198 {
199         taditerator_initialize(&timf->iterator, bin, strlen);
200         tctokenchecker_initialize(&timf->headerchecker, val, val_len, timfparser_headerend);
201         timf->state = TIMFPARSER_STATE_SEARCH_HEADER;
202         timf->ishankaku = False;
203 }
204
205 EXPORT VOID timfparser_finalize(timfparser_t *timf)
206 {
207         tctokenchecker_finalize(&timf->headerchecker);
208         taditerator_finalize(&timf->iterator);
209 }