OSDN Git Service

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