OSDN Git Service

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