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
208   em->imode->hex1byte = 0;
209   em->imode->hex2byte = 0;
210   em->imode->string = NULL;
211   em->imode->description = NULL;
212
213   for (child = qs_get_child_node(doc, node);
214        child ;
215        child = qs_get_next_node(doc, child))
216   {
217     char* name  = qs_get_node_name(doc, child);
218     if (strcasecmp(name, "hex1") == 0) 
219     {
220       Node* hex1node = qs_get_child_node(doc, child);
221       if (hex1node != NULL)
222       {
223         char* cname = qs_get_node_name(doc, hex1node);
224         char* cvalue = qs_get_node_value(doc, hex1node);
225         if (strcasecmp(cname, "text") == 0)
226         {
227           em->imode->hex1byte = s_hexstring_to_byte(cvalue);
228         }
229       }
230       else
231       {
232         em->imode->hex1byte    = 0;
233       }
234     }
235     else
236     if (strcasecmp(name, "hex2") == 0)
237     {
238       Node* hex2node = qs_get_child_node(doc, child);
239       if (hex2node != NULL)
240       {
241         char* cname = qs_get_node_name(doc, hex2node);
242         char* cvalue = qs_get_node_value(doc, hex2node);
243         if (strcasecmp(cname, "text") == 0)
244         {
245           em->imode->hex2byte = s_hexstring_to_byte(cvalue);
246         }
247       }
248       else
249       {
250         em->imode->hex2byte    = 0;
251       }
252     }
253     else
254     if (strcasecmp(name, "string") == 0)
255     {
256       Node* string_node = qs_get_child_node(doc, child);
257       if (string_node != NULL)
258       {
259         char* cname = qs_get_node_name(doc, string_node);
260         char* cvalue = qs_get_node_value(doc, string_node);
261         if (strcasecmp(cname, "text") == 0)
262         {
263           em->imode->string = apr_pstrdup(p, cvalue);
264         }
265       }
266       else
267       {
268         em->imode->string    = apr_palloc(p, 1);
269         em->imode->string[0] = 0;
270       }
271     }
272     else
273     if (strcasecmp(name, "description") == 0)
274     {
275       Node* description_node = qs_get_child_node(doc, child);
276       if (description_node != NULL)
277       {
278         char* cname = qs_get_node_name(doc, description_node);
279         char* cvalue = qs_get_node_value(doc, description_node);
280         if (strcasecmp(cname, "text") == 0)
281         {
282           em->imode->description = apr_pstrdup(p, cvalue);
283         }
284       }
285       else
286       {
287         em->imode->description    = apr_palloc(p, 1);
288         em->imode->description[0] = 0;
289       }
290     }
291   }
292   return NULL;
293 }
294
295 static char*
296 s_load_emoji_ezweb_tag(
297   Doc* doc,
298   apr_pool_t* p,
299   emoji_t* em,
300   Node* node)
301 {
302   Node* child;
303
304
305   em->ezweb->typeA = NULL;
306   em->ezweb->typeB = NULL;
307   em->ezweb->typeC = NULL;
308   em->ezweb->typeD = NULL;
309
310   for (child = qs_get_child_node(doc, node);
311        child ;
312        child = qs_get_next_node(doc, child))
313   {
314     char* name  = qs_get_node_name(doc, child);
315     if (strcasecmp(name, "A") == 0) 
316     {
317       Node* typeAnode = qs_get_child_node(doc, child);
318
319       if (typeAnode != NULL)
320       {
321         char* cname = qs_get_node_name(doc, typeAnode);
322         char* cvalue = qs_get_node_value(doc, typeAnode);
323         if (strcasecmp(cname, "text") == 0)
324         {
325           em->ezweb->typeA = apr_pstrdup(p,cvalue);
326         }
327       }
328       else
329       {
330         em->ezweb->typeA    = apr_palloc(p, 1);
331         em->ezweb->typeA[0] = 0;
332       }
333     }
334     else
335     if (strcasecmp(name, "B") == 0) 
336     {
337       Node* typeBnode = qs_get_child_node(doc, child);
338
339       if (typeBnode != NULL)
340       {
341         char* cname = qs_get_node_name(doc, typeBnode);
342         char* cvalue = qs_get_node_value(doc, typeBnode);
343         if (strcasecmp(cname, "text") == 0)
344         {
345           em->ezweb->typeB = apr_pstrdup(p,cvalue);
346         }
347       }
348       else
349       {
350         em->ezweb->typeB    = apr_palloc(p, 1);
351         em->ezweb->typeB[0] = 0;
352       }
353     }
354     else
355     if (strcasecmp(name, "C") == 0) 
356     {
357       Node* typeCnode = qs_get_child_node(doc, child);
358
359       if (typeCnode != NULL)
360       {
361         char* cname = qs_get_node_name(doc, typeCnode);
362         char* cvalue = qs_get_node_value(doc, typeCnode);
363         if (strcasecmp(cname, "text") == 0)
364         {
365           em->ezweb->typeC = apr_pstrdup(p,cvalue);
366         }
367       }
368       else
369       {
370         em->ezweb->typeC = apr_palloc(p, 1);
371         em->ezweb->typeC[0] = 0;
372       }
373     }
374     else
375     if (strcasecmp(name, "D") == 0) 
376     {
377       Node* typeDnode = qs_get_child_node(doc, child);
378
379       if (typeDnode != NULL)
380       {
381         char* cname = qs_get_node_name(doc, typeDnode);
382         char* cvalue = qs_get_node_value(doc, typeDnode);
383         if (strcasecmp(cname, "text") == 0)
384         {
385           em->ezweb->typeD = apr_pstrdup(p,cvalue);
386         }
387       }
388       else
389       {
390         em->ezweb->typeD = apr_palloc(p, 1);
391         em->ezweb->typeD[0] = 0;
392       }
393     }
394   }
395   return NULL;
396 }
397
398 static char*
399 s_load_emoji_jphone_tag(
400   Doc* doc,
401   apr_pool_t* p,
402   emoji_t* em,
403   Node* node)
404 {
405   Node* child;
406
407
408   em->jphone->string = NULL;
409
410   for (child = qs_get_child_node(doc, node);
411        child ;
412        child = qs_get_next_node(doc, child))
413   {
414     char* name  = qs_get_node_name(doc, child);
415     if (strcasecmp(name, "string") == 0) 
416     {
417       Node* stringnode = qs_get_child_node(doc, child);
418       if (stringnode != NULL)
419       {
420         char* cname = qs_get_node_name(doc, stringnode);
421         char* cvalue = qs_get_node_value(doc, stringnode);
422         if (strcasecmp(cname, "text") == 0)
423         {
424           int ii;
425           int jj;
426           char* tmp = apr_palloc(p, strlen(cvalue)+1);
427           memset(tmp, 0, strlen(cvalue)+1);
428
429           for (jj=0,ii=0; ii< strlen(cvalue); ii++) 
430           {
431             if (strncasecmp(&cvalue[ii] , ESCAPE_CHAR_LT, strlen(ESCAPE_CHAR_LT)) == 0)
432             {
433               tmp[jj] = '<';
434               jj++;
435               ii += (strlen(ESCAPE_CHAR_LT) - 1);
436             }
437             else
438             if (strncasecmp(&cvalue[ii] , ESCAPE_CHAR_GT, strlen(ESCAPE_CHAR_GT)) == 0)
439             {
440               tmp[jj] = '>';
441               jj++;
442               ii += (strlen(ESCAPE_CHAR_GT) - 1);
443             }
444             else
445             {
446               tmp[jj] = cvalue[ii];
447               jj++;
448             }
449           }
450           em->jphone->string = apr_pstrdup(p,tmp);
451         }
452       }
453       else
454       {
455         em->jphone->string    = apr_palloc(p, 1);
456         em->jphone->string[0] = 0;
457       }
458     }
459   }
460   return NULL;
461 }
462
463 static void
464 s_emoji_add_to_tail(
465   mod_chxj_config* conf,
466   emoji_t* emoji)
467 {
468   emoji->next = NULL;
469   if (conf->emoji == NULL) {
470     conf->emoji      = emoji;
471     conf->emoji_tail = emoji;
472     return;
473   }
474
475   conf->emoji_tail->next = emoji;
476   conf->emoji_tail = emoji;
477 }
478
479 static char 
480 s_hexstring_to_byte(char* s)
481 {
482   int len;
483   int ii;
484   char one_byte = 0;
485
486   len = strlen(s);
487   for (ii=0; ii<len; ii++)
488   {
489     switch(s[ii]) 
490     {
491     case '1':
492     case '2':
493     case '3':
494     case '4':
495     case '5':
496     case '6':
497     case '7':
498     case '8':
499     case '9':
500     case '0':
501       one_byte |= (0xFF & (((s[ii] - '0') & 0xFF) << ((1-ii)*4)));
502       break;
503     case 'A':
504     case 'a':
505       one_byte |= (0xFF & ((0x0A & 0xFF) << ((1-ii)*4)));
506       break;
507     case 'B':
508     case 'b':
509       one_byte |= (0xFF & ((0x0B & 0xFF) << ((1-ii)*4)));
510       break;
511     case 'C':
512     case 'c':
513       one_byte |= (0xFF & ((0x0C & 0xFF) << ((1-ii)*4)));
514       break;
515     case 'D':
516     case 'd':
517       one_byte |= (0xFF & ((0x0d & 0xFF) << ((1-ii)*4)));
518       break;
519     case 'E':
520     case 'e':
521       one_byte |= (0xFF & ((0x0e & 0xFF) << ((1-ii)*4)));
522       break;
523     case 'F':
524     case 'f':
525       one_byte |= (0xFF & ((0x0f & 0xFF) << ((1-ii)*4)));
526       break;
527     default:
528       break;
529     }
530   }
531   return one_byte;
532 }
533 /*
534  * vim:ts=2 et
535  */