OSDN Git Service

* change writting.
[modchxj/mod_chxj.git] / src / chxj_load_emoji_data.c
1 /*
2  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
3  * Copyright (C) 2005 Atsushi Konno All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <stdio.h>
18 #include "mod_chxj.h"
19 #include "chxj_load_emoji_data.h"
20
21 static char* s_load_emoji_set_tag(
22   Doc*             doc,
23   apr_pool_t*      p,
24   mod_chxj_config* conf,
25   Node*            node);
26
27 static char* s_set_emoji_data(
28   Doc*             doc,
29   apr_pool_t*      p,
30   mod_chxj_config* conf,
31   Node*            node);
32
33 static char* s_load_emoji_emoji_tag(
34   Doc*             doc,
35   apr_pool_t*      p,
36   mod_chxj_config* conf,
37   Node*            node);
38
39 static void  
40 s_emoji_add_to_tail( mod_chxj_config* conf, emoji_t* emoji);
41
42 static char* s_load_emoji_no_tag( Doc* doc, apr_pool_t* p, emoji_t* em, Node* node);
43 static char* s_load_emoji_imode_tag( Doc* doc, apr_pool_t* p, emoji_t* em, Node* node);
44 static char* s_load_emoji_ezweb_tag( Doc* doc, apr_pool_t* p, emoji_t* em, Node* node);
45 static char* s_load_emoji_jphone_tag( Doc* doc, apr_pool_t* p, emoji_t* em, Node* node);
46 static char  s_hexstring_to_byte(char* s);
47
48
49 /**
50  * load emoji.xml
51  */
52 char* 
53 chxj_load_emoji_data(
54   Doc* doc,
55   apr_pool_t *p,
56   mod_chxj_config* conf) 
57 {
58   char* rtn;
59
60   conf->emoji      = NULL;
61   conf->emoji_tail = NULL;
62
63   if ((rtn = s_set_emoji_data(doc, p, conf,qs_get_root(doc))) != NULL)
64     return rtn;
65
66   return NULL;
67 }
68
69 /**
70  * <emoji>
71  */
72 static char*
73 s_set_emoji_data(
74   Doc* doc,
75   apr_pool_t* p,
76   mod_chxj_config* conf,
77   Node* node) 
78 {
79   Node* child;
80   char* rtn;
81
82   for (child = qs_get_child_node(doc,node);
83        child;
84        child = qs_get_next_node(doc,child)) {
85
86     char* name = qs_get_node_name(doc,child);
87
88     if ((*name == 'e' || *name == 'E') && strcasecmp(name, "emoji") == 0) {
89       if ((rtn = s_load_emoji_emoji_tag(doc, p, conf, child)))
90         return rtn;
91     }
92   }
93   return NULL;
94 }
95
96 static char* 
97 s_load_emoji_emoji_tag(
98   Doc* doc,
99   apr_pool_t* p,
100   mod_chxj_config* conf,
101   Node* node)
102 {
103   Node* child;
104   char* rtn;
105
106   for (child = qs_get_child_node(doc, node);
107        child ;
108        child = qs_get_next_node(doc, child)) {
109
110     char* name = qs_get_node_name(doc, child);
111
112     if ((*name == 's' || *name == 'S') && strcasecmp(name, "set") == 0) {
113       if ((rtn = s_load_emoji_set_tag(doc, p, conf, child)) != NULL) 
114         return rtn;
115     }
116   }
117
118   return NULL;
119 }
120
121
122 static char*
123 s_load_emoji_set_tag(
124   Doc*             doc,
125   apr_pool_t*      p,
126   mod_chxj_config* conf,
127   Node*            node)
128 {
129   Node*    child;
130   emoji_t* em;
131   char*    rtn;
132
133   em         = apr_palloc(p, sizeof(emoji_t));
134   em->imode  = apr_palloc(p, sizeof(imode_emoji_t));
135   em->ezweb  = apr_palloc(p, sizeof(ezweb_emoji_t));
136   em->jphone = apr_palloc(p, sizeof(jphone_emoji_t));
137   
138   for (child = qs_get_child_node(doc, node);
139        child;
140        child = qs_get_next_node(doc, child)) {
141
142     char* name  = qs_get_node_name(doc, child);
143
144     switch (*name) {
145     case 'n':
146     case 'N':
147       if (strcasecmp(name, "no") == 0) {
148         if ((rtn = s_load_emoji_no_tag(doc, p, em, child)) != NULL)
149           return rtn;
150       }
151       break;
152     
153     case 'i':
154     case 'I':
155       if (strcasecmp(name, "imode") == 0) {
156         if ((rtn = s_load_emoji_imode_tag(doc, p, em, child)) != NULL)
157           return rtn;
158       }
159       break;
160
161     case 'e':
162     case 'E':
163       if (strcasecmp(name, "ezweb") == 0) {
164         if ((rtn = s_load_emoji_ezweb_tag(doc, p, em, child)) != NULL)
165           return rtn;
166       }
167       break;
168
169     case 'j':
170     case 'J':
171       if (strcasecmp(name, "jphone") == 0) {
172         if ((rtn = s_load_emoji_jphone_tag(doc, p, em, child)) != NULL)
173           return rtn;
174       }
175       break;
176
177     default:
178       break;
179     }
180   }
181
182   s_emoji_add_to_tail(conf, em);
183
184   return NULL;
185 }
186
187
188 static char*
189 s_load_emoji_no_tag(
190   Doc*        doc,
191   apr_pool_t* p,
192   emoji_t*    em,
193   Node*       node)
194 {
195   int len;
196   int ii;
197
198   Node* child = qs_get_child_node(doc,node);
199   char* name  = qs_get_node_name(doc,  child);
200   char* value = qs_get_node_value(doc, child);
201
202   if ((*name == 't' || *name == 'T') && strcasecmp(name, "text") == 0) {
203     len = strlen(value);
204
205     for (ii=0; ii<len; ii++) {
206       if (value[ii] < '0' || value[ii] > '9')
207         return apr_psprintf(p, "invalid data <no> tag [%s]", value);
208     }
209     em->no = atoi(value);
210   }
211
212   return NULL;
213 }
214
215 static char*
216 s_load_emoji_imode_tag(
217   Doc*        doc,
218   apr_pool_t* p,
219   emoji_t*    em,
220   Node*       node)
221 {
222   Node* child;
223
224   em->imode->hex1byte    = 0;
225   em->imode->hex2byte    = 0;
226   em->imode->string      = NULL;
227   em->imode->description = NULL;
228
229   for (child = qs_get_child_node(doc, node);
230        child ;
231        child = qs_get_next_node(doc, child)) {
232
233     char* name  = qs_get_node_name(doc, child);
234
235     switch (*name) {
236     case 'h':
237     case 'H':
238       if (strcasecmp(name, "hex1") == 0) {
239         Node* hex1node = qs_get_child_node(doc, child);
240         if (hex1node) {
241   
242           char* cname  = qs_get_node_name(doc, hex1node);
243           char* cvalue = qs_get_node_value(doc, hex1node);
244   
245           if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
246             em->imode->hex1byte = s_hexstring_to_byte(cvalue);
247         }
248         else {
249           em->imode->hex1byte    = 0;
250         }
251       }
252       else
253       if ((*name == 'h' || *name == 'H') && strcasecmp(name, "hex2") == 0) {
254         Node* hex2node = qs_get_child_node(doc, child);
255         if (hex2node) {
256           char* cname  = qs_get_node_name(doc, hex2node);
257           char* cvalue = qs_get_node_value(doc, hex2node);
258
259           if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
260             em->imode->hex2byte = s_hexstring_to_byte(cvalue);
261         }
262         else {
263           em->imode->hex2byte    = 0;
264         }
265       }
266       break;
267
268     case 's':
269     case 'S':
270       if (strcasecmp(name, "string") == 0) {
271         Node* string_node = qs_get_child_node(doc, child);
272
273         if (string_node) {
274           char* cname = qs_get_node_name(doc, string_node);
275           char* cvalue = qs_get_node_value(doc, string_node);
276
277           if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
278             em->imode->string = apr_pstrdup(p, cvalue);
279         }
280         else {
281           em->imode->string    = apr_palloc(p, 1);
282           em->imode->string[0] = 0;
283         }
284       }
285       break;
286     
287     case 'd':
288     case 'D':
289       if (strcasecmp(name, "description") == 0) {
290         Node* description_node = qs_get_child_node(doc, child);
291   
292         if (description_node) {
293           char* cname = qs_get_node_name(doc, description_node);
294           char* cvalue = qs_get_node_value(doc, description_node);
295   
296           if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
297             em->imode->description = apr_pstrdup(p, cvalue);
298         }
299         else {
300           em->imode->description    = apr_palloc(p, 1);
301           em->imode->description[0] = 0;
302         }
303       }
304       break;
305
306     default:
307       break;
308     }
309   }
310
311   return NULL;
312 }
313
314
315 static char*
316 s_load_emoji_ezweb_tag(
317   Doc*        doc,
318   apr_pool_t* p,
319   emoji_t*    em,
320   Node*       node)
321 {
322   Node* child;
323
324
325   em->ezweb->typeA = NULL;
326   em->ezweb->typeB = NULL;
327   em->ezweb->typeC = NULL;
328   em->ezweb->typeD = NULL;
329
330   for (child = qs_get_child_node(doc, node);
331        child ;
332        child = qs_get_next_node(doc, child)) {
333
334     char* name  = qs_get_node_name(doc, child);
335
336     if ((*name == 'a' || *name == 'A') && strcasecmp(name, "A") == 0) {
337
338       Node* typeAnode = qs_get_child_node(doc, child);
339
340       if (typeAnode) {
341
342         char* cname = qs_get_node_name(doc, typeAnode);
343         char* cvalue = qs_get_node_value(doc, typeAnode);
344
345         if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
346           em->ezweb->typeA = apr_pstrdup(p,cvalue);
347       }
348       else {
349         em->ezweb->typeA    = apr_palloc(p, 1);
350         em->ezweb->typeA[0] = 0;
351       }
352
353     }
354     else
355     if ((*name == 'b' || *name == 'B') && strcasecmp(name, "B") == 0) {
356
357       Node* typeBnode = qs_get_child_node(doc, child);
358
359       if (typeBnode) {
360
361         char* cname = qs_get_node_name(doc, typeBnode);
362         char* cvalue = qs_get_node_value(doc, typeBnode);
363
364         if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
365           em->ezweb->typeB = apr_pstrdup(p,cvalue);
366
367       }
368       else {
369         em->ezweb->typeB    = apr_palloc(p, 1);
370         em->ezweb->typeB[0] = 0;
371       }
372     }
373     else
374     if ((*name == 'c' || *name == 'C') && strcasecmp(name, "C") == 0) {
375
376       Node* typeCnode = qs_get_child_node(doc, child);
377
378       if (typeCnode) {
379
380         char* cname  = qs_get_node_name(doc, typeCnode);
381         char* cvalue = qs_get_node_value(doc, typeCnode);
382
383         if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
384           em->ezweb->typeC = apr_pstrdup(p,cvalue);
385       }
386       else {
387         em->ezweb->typeC = apr_palloc(p, 1);
388         em->ezweb->typeC[0] = 0;
389       }
390     }
391     else
392     if ((*name == 'd' || *name == 'D') && strcasecmp(name, "D") == 0) {
393
394       Node* typeDnode = qs_get_child_node(doc, child);
395
396       if (typeDnode) {
397
398         char* cname  = qs_get_node_name(doc, typeDnode);
399         char* cvalue = qs_get_node_value(doc, typeDnode);
400
401         if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0)
402           em->ezweb->typeD = apr_pstrdup(p,cvalue);
403
404       }
405       else {
406         em->ezweb->typeD = apr_palloc(p, 1);
407         em->ezweb->typeD[0] = 0;
408       }
409     }
410   }
411
412   return NULL;
413 }
414
415
416 static char*
417 s_load_emoji_jphone_tag(
418   Doc*        doc,
419   apr_pool_t* p,
420   emoji_t*    em,
421   Node*       node)
422 {
423   Node* child;
424
425
426   em->jphone->string = NULL;
427
428   for (child = qs_get_child_node(doc, node);
429        child ;
430        child = qs_get_next_node(doc, child)) {
431
432     char* name  = qs_get_node_name(doc, child);
433
434     if ((*name == 's' || *name == 'S') && strcasecmp(name, "string") == 0) {
435
436       Node* stringnode = qs_get_child_node(doc, child);
437
438       if (stringnode) {
439
440         char* cname  = qs_get_node_name(doc, stringnode);
441         char* cvalue = qs_get_node_value(doc, stringnode);
442
443         if ((*cname == 't' || *cname == 'T') && strcasecmp(cname, "text") == 0) {
444           int   ii;
445           int   jj;
446           char* tmp;
447  
448           tmp = apr_palloc(p, strlen(cvalue)+1);
449           memset(tmp, 0, strlen(cvalue)+1);
450
451           for (jj=0,ii=0; ii< strlen(cvalue); ii++) {
452             if (strncasecmp(&cvalue[ii] , ESCAPE_CHAR_LT, strlen(ESCAPE_CHAR_LT)) == 0) {
453               tmp[jj] = '<';
454               jj++;
455               ii += (strlen(ESCAPE_CHAR_LT) - 1);
456             }
457             else
458             if (strncasecmp(&cvalue[ii] , ESCAPE_CHAR_GT, strlen(ESCAPE_CHAR_GT)) == 0) {
459               tmp[jj] = '>';
460               jj++;
461               ii += (strlen(ESCAPE_CHAR_GT) - 1);
462             }
463             else {
464               tmp[jj] = cvalue[ii];
465               jj++;
466             }
467           }
468           em->jphone->string = apr_pstrdup(p,tmp);
469         }
470       }
471       else {
472         em->jphone->string    = apr_palloc(p, 1);
473         em->jphone->string[0] = 0;
474       }
475     }
476   }
477
478   return NULL;
479 }
480
481
482
483 static void
484 s_emoji_add_to_tail(
485   mod_chxj_config* conf,
486   emoji_t*         emoji)
487 {
488   emoji->next = NULL;
489
490   if (conf->emoji == NULL) {
491     conf->emoji      = emoji;
492     conf->emoji_tail = emoji;
493     return;
494   }
495
496   conf->emoji_tail->next = emoji;
497   conf->emoji_tail       = emoji;
498 }
499
500
501
502 static char 
503 s_hexstring_to_byte(char* s)
504 {
505   int  len;
506   int  ii;
507   char one_byte = 0;
508
509   len = strlen(s);
510
511   for (ii=0; ii<len; ii++) {
512     switch(s[ii]) {
513     case '1':
514     case '2':
515     case '3':
516     case '4':
517     case '5':
518     case '6':
519     case '7':
520     case '8':
521     case '9':
522     case '0':
523       one_byte |= (0xFF & (((s[ii] - '0') & 0xFF) << ((1-ii)*4)));
524       break;
525     case 'A':
526     case 'a':
527       one_byte |= (0xFF & ((0x0A & 0xFF) << ((1-ii)*4)));
528       break;
529     case 'B':
530     case 'b':
531       one_byte |= (0xFF & ((0x0B & 0xFF) << ((1-ii)*4)));
532       break;
533     case 'C':
534     case 'c':
535       one_byte |= (0xFF & ((0x0C & 0xFF) << ((1-ii)*4)));
536       break;
537     case 'D':
538     case 'd':
539       one_byte |= (0xFF & ((0x0d & 0xFF) << ((1-ii)*4)));
540       break;
541     case 'E':
542     case 'e':
543       one_byte |= (0xFF & ((0x0e & 0xFF) << ((1-ii)*4)));
544       break;
545     case 'F':
546     case 'f':
547       one_byte |= (0xFF & ((0x0f & 0xFF) << ((1-ii)*4)));
548       break;
549     default:
550       break;
551     }
552   }
553
554   return one_byte;
555 }
556 /*
557  * vim:ts=2 et
558  */