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 "chxj_str_util.h"
19 #include "chxj_add_device_env.h"
21 static device_table UNKNOWN_DEVICE = {
23 .provider = CHXJ_PROVIDER_UNKNOWN,
25 .device_name = "UNKNOWN",
26 .html_spec_type = CHXJ_SPEC_UNKNOWN,
29 /*--------------------------------------------------------------------------*/
30 /* Walll Paper Size */
31 /*--------------------------------------------------------------------------*/
34 /*--------------------------------------------------------------------------*/
36 /*--------------------------------------------------------------------------*/
38 /*--------------------------------------------------------------------------*/
39 /* Correspondence image format */
40 /* 1: It is possible to display it. */
41 /* 0: It is not possible to display it. */
42 /*--------------------------------------------------------------------------*/
50 /*--------------------------------------------------------------------------*/
51 /* Color number type */
54 /* 256 : 256 Colors */
55 /* 4096 : 4096 Colors */
56 /* 65536 : 65536 Colors */
57 /* 262144 : 262144 Colors */
58 /* 15680000: 15680000 over colors */
59 /*--------------------------------------------------------------------------*/
62 .output_encoding = "Shift_JIS",
65 static device_table *s_get_device_data(request_rec *r, const char *device_id, device_table_list *dtl);
66 static device_table *s_specified_device_from_xml(request_rec *r, mod_chxj_config * conf, const char *user_agent);
67 static device_table *s_specified_device_from_tsv(request_rec *r,device_table *spec,const char *user_agent);
71 get_boolean_value(request_rec *r,const char *val){
92 * The device is specified from UserAgent.
93 * @param r Request_rec is appointed.
94 * @param userAgent UserAgent is appointed here,
95 * @return The style which corresponds is returned.
98 chxj_specified_device(request_rec *r, const char *user_agent)
100 device_table *dt = &UNKNOWN_DEVICE;
101 mod_chxj_config *conf;
102 mod_chxj_req_config *request_conf;
104 DBG(r, "REQ[%X] start %s()", TO_ADDR(r),__func__);
106 request_conf = (mod_chxj_req_config *)chxj_get_module_config(r->request_config, &chxj_module);
108 request_conf->user_agent = apr_pstrdup(r->pool, user_agent);
111 request_conf->user_agent = "";
114 conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
116 request_conf->spec = dt;
117 DBG(r, "REQ[%X] end %s() %d", TO_ADDR(r), __func__,conf->detect_device_type);
121 dt = s_specified_device_from_xml(r,conf, user_agent);
123 if (conf->detect_device_type == CHXJ_ADD_DETECT_DEVICE_TYPE_TSV ){
124 s_specified_device_from_tsv(r,dt,user_agent);
126 /* save to spec cache */
127 request_conf->spec = dt;
129 DBG(r, "REQ[%X] end %s() %d",TO_ADDR(r), __func__,conf->detect_device_type);
134 * The device is specified from UserAgent.
135 * @param r Request_rec is appointed.
136 * @param userAgent UserAgent is appointed here,
137 * @return The style which corresponds is returned.
139 static device_table *
140 s_specified_device_from_xml(request_rec *r, mod_chxj_config * conf, const char *user_agent)
142 ap_regmatch_t match[10];
143 device_table *returnType = &UNKNOWN_DEVICE;
144 device_table_list *dtl;
148 DBG(r, "REQ[%X] start %s()", TO_ADDR(r),__func__);
150 DBG(r, "REQ[%X] end %s() (user_agent is not set)", TO_ADDR(r),__func__);
156 if (! conf->devices) {
157 ERR(r, "REQ[%X] device_data.xml load failure", TO_ADDR(r));
158 DBG(r, "REQ[%X] end %s()", TO_ADDR(r), __func__);
162 for (dtl = conf->devices; dtl; dtl = dtl->next) {
163 if (! dtl->pattern) {
167 /* DBG(r, "pattern is [%s]", dtl->pattern); */
169 ERR(r,"REQ[%X] compile failed.", TO_ADDR(r));
170 DBG(r, "REQ[%X] %s()", TO_ADDR(r),__func__);
174 if (ap_regexec((const ap_regex_t *)dtl->regexp, user_agent, (apr_size_t)dtl->regexp->re_nsub + 1, match, 0) == 0) {
175 device_id = ap_pregsub(r->pool, "$1", user_agent, dtl->regexp->re_nsub + 1, match);
176 DBG(r, "REQ[%X] device_id:[%s]", TO_ADDR(r), device_id);
178 dt = s_get_device_data(r, device_id, dtl);
182 if (conf->detect_device_type > CHXJ_ADD_DETECT_DEVICE_TYPE_NONE ){
183 dt->device_id = device_id;
185 DBG(r,"REQ[%X] end %s() (Not Found) use [%s]", TO_ADDR(r), __func__, dt->device_id);
189 DBG(r,"REQ[%X] end %s() (Found) use [%s]", TO_ADDR(r), __func__, dt->device_id);
194 DBG(r,"REQ[%X] end %s()", TO_ADDR(r), __func__);
202 s_compar(const void *a, const void *b)
204 device_table *aa = *(device_table **)a;
205 device_table *bb = *(device_table **)b;
208 * Don't use strcasecmp for LOAD!!
210 return strcmp(aa->device_id, bb->device_id);
214 static device_table *
215 s_get_device_data(request_rec *r, const char *device_id, device_table_list *dtl)
219 dt.device_id = device_id;
221 device_table **ret = bsearch(&_dt, dtl->sort_table, dtl->table_count, sizeof(device_table *), s_compar);
230 * The device is specified from TSV file.
231 * @param r Request_rec is appointed.
232 * @param userAgent UserAgent is appointed here,
233 * @return The style which corresponds is returned.
235 static device_table *
236 s_specified_device_from_tsv(request_rec *r,device_table *spec,const char *user_agent)
238 if(spec->device_id == NULL){
242 DBG(r, "REQ[%X] start %s() device_id:[%s]", TO_ADDR(r), __func__,spec->device_id);
243 mod_chxj_config *conf;
245 conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
247 if(conf->device_hash == NULL){
248 DBG(r, "REQ[%X] end %s()", TO_ADDR(r),__func__);
251 char *key = apr_psprintf(r->pool,"%d.%s",spec->provider,spec->device_id);
253 apr_table_t *ht = apr_hash_get(conf->device_hash,key,APR_HASH_KEY_STRING);
256 DBG(r, "REQ[%X] found ! %s() %s", TO_ADDR(r), __func__,key);
258 for ( i=0; i< conf->device_keys->nelts; i++){
259 const char *k = ((const char**)conf->device_keys->elts)[i];
260 char *val = (char *)apr_table_get(ht,k);
264 DBG(r, "REQ[%X] start chxj_specified_device_from_tsv() [%s] = [%s]:[%s]",TO_ADDR(r),spec->device_id,k,val);
265 if (STRCASEEQ('d','D',"device_name",k)){
266 spec->device_name = apr_pstrdup(r->pool,val);
268 if (STRCASEEQ('w','W',"width",k)){
269 if(chxj_chk_numeric(val) == 0){
270 spec->width = chxj_atoi(val);
273 else if (STRCASEEQ('h','H',"heigh",k)){
274 if(chxj_chk_numeric(val) == 0){
275 spec->heigh = chxj_atoi(val);
278 else if (STRCASEEQ('h','H',"height",k)){
279 if(chxj_chk_numeric(val) == 0){
280 spec->heigh = chxj_atoi(val);
283 else if (STRCASEEQ('w','W',"wp_width",k)){
284 if(chxj_chk_numeric(val) == 0){
285 spec->wp_width = chxj_atoi(val);
288 else if (STRCASEEQ('w','W',"wp_heigh",k)){
289 if(chxj_chk_numeric(val) == 0){
290 spec->wp_heigh = chxj_atoi(val);
293 else if (STRCASEEQ('w','W',"wp_height",k)){
294 if(chxj_chk_numeric(val) == 0){
295 spec->wp_heigh = chxj_atoi(val);
298 else if (STRCASEEQ('c','C',"cache",k)){
299 if(chxj_chk_numeric(val) == 0){
300 spec->cache = chxj_atoi(val);
303 else if (STRCASEEQ('g','G',"gif",k)){
304 int tmp = get_boolean_value(r,val);
306 spec->available_gif = tmp;
309 else if (STRCASEEQ('j','J',"jpeg",k)){
310 int tmp = get_boolean_value(r,val);
312 spec->available_jpeg = tmp;
315 else if (STRCASEEQ('p','P',"png",k)){
316 int tmp = get_boolean_value(r,val);
318 spec->available_png = tmp;
321 else if (STRCASEEQ('b','B',"bmp2",k)){
322 int tmp = get_boolean_value(r,val);
324 spec->available_bmp2 = tmp;
327 else if (STRCASEEQ('b','B',"bmp4",k)){
328 int tmp = get_boolean_value(r,val);
330 spec->available_bmp4 = tmp;
333 else if (STRCASEEQ('c','C',"color",k)){
334 if(chxj_chk_numeric(val) == 0){
335 spec->color = chxj_atoi(val);
338 else if (STRCASEEQ('e','E',"emoji_type",k)){
339 spec->emoji_type = apr_pstrdup(r->pool,val);
341 else if (STRCASEEQ('h','H',"html_spec_type",k)){
342 if (STRCASEEQ('x','X',"xhtml_mobile_1_0",val)) {
343 spec->html_spec_type = CHXJ_SPEC_XHtml_Mobile_1_0;
345 else if (STRCASEEQ('c','C',"chtml_1_0",val)) {
346 spec->html_spec_type = CHXJ_SPEC_Chtml_1_0;
348 else if (STRCASEEQ('c','C',"chtml_2_0",val)) {
349 spec->html_spec_type = CHXJ_SPEC_Chtml_2_0;
351 else if (STRCASEEQ('c','C',"chtml_3_0",val)) {
352 spec->html_spec_type = CHXJ_SPEC_Chtml_3_0;
354 else if (STRCASEEQ('c','C',"chtml_4_0",val)) {
355 spec->html_spec_type = CHXJ_SPEC_Chtml_4_0;
357 else if (STRCASEEQ('c','C',"chtml_5_0",val)) {
358 spec->html_spec_type = CHXJ_SPEC_Chtml_5_0;
360 else if (STRCASEEQ('c','C',"chtml_6_0",val)) {
361 spec->html_spec_type = CHXJ_SPEC_Chtml_6_0;
363 else if (STRCASEEQ('c','C',"chtml_7_0",val)) {
364 spec->html_spec_type = CHXJ_SPEC_Chtml_7_0;
366 else if (STRCASEEQ('h','H',"hdml",val)) {
367 spec->html_spec_type = CHXJ_SPEC_Hdml;
369 else if (STRCASEEQ('i','I',"ixhtml",val)) {
370 spec->html_spec_type = CHXJ_SPEC_Chtml_7_0;
372 else if (STRCASEEQ('j','J',"jhtml",val)) {
373 spec->html_spec_type = CHXJ_SPEC_Jhtml;
375 else if (STRCASEEQ('j','J',"jxhtml",val)) {
376 spec->html_spec_type = CHXJ_SPEC_Jxhtml;
379 else if (STRCASEEQ('o','O',"output_encoding",k)){
380 spec->output_encoding = apr_pstrdup(r->pool,val);
385 DBG(r, "REQ[%X] end %s() [%d]",TO_ADDR(r),__func__,spec->provider);