2 * Copyright (C) 2005-2011 Atsushi Konno All rights reserved.
3 * Copyright (C) 2005 QSDN,Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <qs_ignore_sp.h>
20 #include <qs_malloc.h>
21 #include <qs_parse_attr.h>
22 #include <qs_parse_file.h>
23 #include <qs_parse_string.h>
24 #include <qs_parse_tag.h>
25 #include "chxj_load_device_data.h"
26 #include "chxj_str_util.h"
29 static void s_set_devices_data(
32 mod_chxj_config *conf,
35 static void s_set_user_agent_data(
38 mod_chxj_config *conf,
41 static void s_set_device_data(
44 device_table_list *dtl,
47 static int s_sort_table_compare(const void *a, const void *b);
48 static void s_set_sort_table(Doc *doc, apr_pool_t *p, device_table_list *dtl);
53 s_debug_dump(device_table_list *dtl)
56 FILE *fp = fopen("/tmp/device_dump.log", "a");
57 fprintf(fp, "===================== %d\n", dtl->table_count);
59 for (ii=0; ii<dtl->table_count; ii++) {
60 if (dtl->sort_table == NULL) {
61 fprintf(fp, "sort_table is NULL\n");
64 if (dtl->sort_table[ii] == NULL) {
65 fprintf(fp, "sort_table[%d] is NULL\n", ii);
68 fprintf(fp, "[%s]\n", dtl->sort_table[ii]->device_id);
77 * load device_data.xml
80 chxj_load_device_data(Doc *doc, apr_pool_t *p, mod_chxj_config *conf)
83 s_set_devices_data(doc, p, conf,qs_get_root(doc));
91 s_set_devices_data(Doc *doc, apr_pool_t *p, mod_chxj_config *conf, Node *node)
95 for (child = qs_get_child_node(doc,node);
97 child = qs_get_next_node(doc,child)) {
98 char *name = qs_get_node_name(doc,child);
99 if (STRCASEEQ('d','D',"devices",name)) {
100 s_set_user_agent_data(doc, p, conf, child);
109 s_set_user_agent_data(Doc *doc, apr_pool_t *p, mod_chxj_config *conf, Node *node)
112 device_table_list *t;
114 for (child = qs_get_child_node(doc,node);
116 child = qs_get_next_node(doc,child)) {
117 char *name = qs_get_node_name(doc,child);
118 if (STRCASEEQ('u','U',"user_agent",name)) {
120 device_table_list *dtl;
122 if (! conf->devices) {
123 conf->devices = apr_pcalloc(p, sizeof(device_table_list));
124 conf->devices->next = NULL;
125 conf->devices->pattern = NULL;
126 conf->devices->table = NULL;
127 conf->devices->tail = NULL;
131 for (t = conf->devices; t ; t = t->next) {
135 t->next = apr_pcalloc(p, sizeof(device_table_list));
136 t->next->next = NULL;
137 t->next->pattern = NULL;
138 t->next->table = NULL;
139 t->next->tail = NULL;
143 for (attr = qs_get_attr(doc,child);
145 attr = qs_get_next_attr(doc,attr)) {
146 char *attr_name = qs_get_attr_name(doc,attr);
148 if (STRCASEEQ('p','P',"pattern",attr_name)) {
149 dtl->pattern = apr_pstrdup(p, qs_get_attr_value(doc,attr));
150 dtl->regexp = ap_pregcomp(p, (const char *)dtl->pattern, AP_REG_EXTENDED|AP_REG_ICASE);
153 dtl->table_count = 0;
154 s_set_device_data(doc, p, dtl, child);
155 s_set_sort_table(doc, p, dtl);
162 s_set_device_data(Doc *doc, apr_pool_t *p, device_table_list *dtl, Node *node)
167 dt = apr_pcalloc(p, sizeof(device_table));
169 dt->device_id = NULL;
170 dt->device_name = NULL;
171 dt->html_spec_type = CHXJ_SPEC_Chtml_3_0;
177 dt->emoji_type = NULL;
182 for (child = qs_get_child_node(doc,node);
184 child = qs_get_next_node(doc,child)) {
185 char *name = qs_get_node_name(doc,child);
189 if (strcasecmp(name, "device") == 0) {
190 s_set_device_data(doc,p, dtl, child);
193 if (strcasecmp(name, "device_id") == 0) {
194 Node* ch = qs_get_child_node(doc, child);
195 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
196 dt->device_id = apr_pstrdup(p, qs_get_node_value(doc, ch));
200 if (strcasecmp(name, "device_name") == 0) {
201 Node* ch = qs_get_child_node(doc, child);
202 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
203 dt->device_name = apr_pstrdup(p, qs_get_node_value(doc, ch));
207 if (strcasecmp(name, "dpi_width") == 0) {
208 Node* ch = qs_get_child_node(doc, child);
209 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
210 char *vv = qs_get_node_value(doc,ch);
212 for (ii=0; ii<strlen(vv); ii++) {
213 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
217 if (ii == strlen(vv))
218 dt->dpi_width = atoi(qs_get_node_value(doc,ch));
224 if (strcasecmp(name, "dpi_heigh") == 0) {
225 Node* ch = qs_get_child_node(doc, child);
226 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
227 char *vv = qs_get_node_value(doc,ch);
229 for (ii=0; ii<strlen(vv); ii++) {
230 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
235 if (ii == strlen(vv))
236 dt->dpi_heigh = atoi(qs_get_node_value(doc,ch));
245 if (strcasecmp(name, "html_spec_type") == 0) {
246 Node *ch = qs_get_child_node(doc, child);
247 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
248 char *vv = qs_get_node_value(doc, ch);
249 if (STRCASEEQ('x','X',"xhtml_mobile_1_0",vv)) {
250 dt->html_spec_type = CHXJ_SPEC_XHtml_Mobile_1_0;
252 else if (STRCASEEQ('c','C',"chtml_1_0",vv)) {
253 dt->html_spec_type = CHXJ_SPEC_Chtml_1_0;
255 else if (STRCASEEQ('c','C',"chtml_2_0",vv)) {
256 dt->html_spec_type = CHXJ_SPEC_Chtml_2_0;
258 else if (STRCASEEQ('c','C',"chtml_3_0",vv)) {
259 dt->html_spec_type = CHXJ_SPEC_Chtml_3_0;
261 else if (STRCASEEQ('c','C',"chtml_4_0",vv)) {
262 dt->html_spec_type = CHXJ_SPEC_Chtml_4_0;
264 else if (STRCASEEQ('c','C',"chtml_5_0",vv)) {
265 dt->html_spec_type = CHXJ_SPEC_Chtml_5_0;
267 else if (STRCASEEQ('c','C',"chtml_6_0",vv)) {
268 dt->html_spec_type = CHXJ_SPEC_Chtml_6_0;
270 else if (STRCASEEQ('c','C',"chtml_7_0",vv)) {
271 dt->html_spec_type = CHXJ_SPEC_Chtml_7_0;
273 else if (STRCASEEQ('h','H',"hdml",vv)) {
274 dt->html_spec_type = CHXJ_SPEC_Hdml;
276 else if (STRCASEEQ('j','J',"jhtml",vv)) {
277 dt->html_spec_type = CHXJ_SPEC_Jhtml;
279 else if (STRCASEEQ('j','J',"jxhtml",vv)) {
280 dt->html_spec_type = CHXJ_SPEC_Jxhtml;
285 if (strcasecmp(name, "heigh") == 0) {
286 Node* ch = qs_get_child_node(doc, child);
287 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
288 char *vv = qs_get_node_value(doc,ch);
290 for (ii=0; ii<strlen(vv); ii++) {
291 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
296 if (ii == strlen(vv))
297 dt->heigh = atoi(qs_get_node_value(doc,ch));
306 if (strcasecmp(name, "width") == 0) {
307 Node *ch = qs_get_child_node(doc, child);
308 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
309 char *vv = qs_get_node_value(doc,ch);
311 for (ii=0; ii<strlen(vv); ii++) {
312 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
316 if (ii == strlen(vv))
317 dt->width = atoi(qs_get_node_value(doc,ch));
323 if (strcasecmp(name, "wp_width") == 0) {
324 Node *ch = qs_get_child_node(doc, child);
325 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
326 char *vv = qs_get_node_value(doc,ch);
328 for (ii=0; ii<strlen(vv); ii++) {
329 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
334 if (ii == strlen(vv))
335 dt->wp_width = atoi(qs_get_node_value(doc,ch));
341 if (strcasecmp(name, "wp_heigh") == 0) {
342 Node *ch = qs_get_child_node(doc, child);
343 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
344 char *vv = qs_get_node_value(doc,ch);
346 for (ii=0; ii<strlen(vv); ii++) {
347 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
352 if (ii == strlen(vv))
353 dt->wp_heigh = atoi(qs_get_node_value(doc,ch));
362 if (strcasecmp(name, "gif") == 0) {
363 Node *ch = qs_get_child_node(doc, child);
364 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
365 char *vv = qs_get_node_value(doc,ch);
367 if (strcasecmp(vv, "true") == 0)
368 dt->available_gif = 1;
370 dt->available_gif = 0;
377 if (strcasecmp(name, "jpeg") == 0 || strcasecmp(name, "jpg") == 0) {
378 Node *ch = qs_get_child_node(doc, child);
379 if (ch != NULL && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
380 char *vv = qs_get_node_value(doc,ch);
382 if (strcasecmp(vv, "true") == 0)
383 dt->available_jpeg = 1;
385 dt->available_jpeg = 0;
392 if (strcasecmp(name, "png") == 0) {
393 Node *ch = qs_get_child_node(doc, child);
394 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
395 char *vv = qs_get_node_value(doc,ch);
397 if (strcasecmp(vv, "true") == 0)
398 dt->available_png = 1;
400 dt->available_png = 0;
407 if (strcasecmp(name, "bmp2") == 0) {
408 Node *ch = qs_get_child_node(doc, child);
409 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
410 char *vv = qs_get_node_value(doc,ch);
412 if (strcasecmp(vv, "true") == 0)
413 dt->available_bmp2 = 1;
415 dt->available_bmp2 = 0;
419 if (strcasecmp(name, "bmp4") == 0) {
420 Node *ch = qs_get_child_node(doc, child);
421 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
422 char *vv = qs_get_node_value(doc,ch);
424 if (strcasecmp(vv, "true") == 0)
425 dt->available_bmp4 = 1;
427 dt->available_bmp4 = 0;
434 if (strcasecmp(name, "color") == 0) {
435 Node *ch = qs_get_child_node(doc, child);
436 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
437 char *vv = qs_get_node_value(doc,ch);
439 if (chxj_chk_numeric(vv) != 0)
442 dt->color = chxj_atoi(vv);
446 if (strcasecmp(name, "cache") == 0) {
447 Node *ch = qs_get_child_node(doc, child);
448 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0) {
449 char *vv = qs_get_node_value(doc,ch);
451 for (ii=0; ii<strlen(vv); ii++) {
452 if ((vv[ii] >= '1' && vv[ii] <= '9') || vv[ii] == '0')
457 if (ii == strlen(vv))
458 dt->cache = atoi(qs_get_node_value(doc,ch));
467 if (strcasecmp(name, "emoji_type") == 0) {
468 Node *ch = qs_get_child_node(doc, child);
469 if (ch && strcasecmp(qs_get_node_name(doc,ch), "text") == 0)
470 dt->emoji_type = apr_pstrdup(p, qs_get_node_value(doc, ch));
484 dtl->tail->next = dt;
493 s_set_sort_table(Doc *doc, apr_pool_t *p, device_table_list *dtl)
495 device_table **sort_table;
499 sort_table = apr_palloc(p, sizeof(device_table) * dtl->table_count);
501 for (dt = dtl->table; dt; dt = dt->next) {
502 sort_table[ii++] = dt;
505 dtl->sort_table = sort_table;
508 qsort((void *)sort_table, (size_t)dtl->table_count, sizeof(*sort_table), s_sort_table_compare);
515 s_sort_table_compare(const void *a, const void *b)
517 device_table *aa = *(device_table **)a;
518 device_table *bb = *(device_table **)b;
519 /* not strcasecmp. for LOAD */
520 return strcmp(aa->device_id, bb->device_id);