OSDN Git Service

* updated copyright.
[modchxj/mod_chxj.git] / src / chxj_specified_device.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 "mod_chxj.h"
18 #include "chxj_add_device_env.h"
19
20 static device_table  UNKNOWN_DEVICE      = {
21   .next = NULL,
22   .device_id = "",
23   .device_name = "UNKNOWN",
24   .html_spec_type = CHXJ_SPEC_UNKNOWN,
25   .width = 640,
26   .heigh = 480,
27   /*--------------------------------------------------------------------------*/
28   /* Walll Paper Size                                                         */
29   /*--------------------------------------------------------------------------*/
30   .wp_width = 640,
31   .wp_heigh = 480,
32   /*--------------------------------------------------------------------------*/
33   /* Cache Size                                                               */
34   /*--------------------------------------------------------------------------*/
35   .cache    = 10000000,
36   /*--------------------------------------------------------------------------*/
37   /* Correspondence image format                                              */
38   /* 1: It is possible to display it.                                         */
39   /* 0: It is not possible to display it.                                     */
40   /*--------------------------------------------------------------------------*/
41   .available_gif = 1,
42   .available_jpeg = 1,
43   .available_png = 1,
44   .available_bmp2 = 1,
45   .available_bmp4 = 1,
46   .dpi_width = 96,
47   .dpi_heigh = 96,
48   /*--------------------------------------------------------------------------*/
49   /* Color number type                                                        */
50   /* 2       : 2        Colors                                                */
51   /* 4       : 4        Colors                                                */
52   /* 256     : 256      Colors                                                */
53   /* 4096    : 4096     Colors                                                */
54   /* 65536   : 65536    Colors                                                */
55   /* 262144  : 262144   Colors                                                */
56   /* 15680000: 15680000 over colors                                           */
57   /*--------------------------------------------------------------------------*/
58   .color = 15680000,
59   .emoji_type = NULL,
60 };
61 static __thread device_table *v_spec = NULL;
62 static device_table * s_get_device_data(request_rec *r, const char *device_id, device_table_list *dtl);
63
64 /**
65  * The device is specified from UserAgent. 
66  * @param r Request_rec is appointed.
67  * @param userAgent UserAgent is appointed here,
68  * @return The style which corresponds is returned.
69  */
70 device_table *
71 chxj_specified_device(request_rec *r, const char *user_agent) 
72 {
73   ap_regmatch_t        match[10];
74   device_table         *returnType = &UNKNOWN_DEVICE;
75   device_table_list    *dtl;
76   mod_chxj_config      *conf; 
77   char                 *device_id;
78   char                 *spec_check = NULL;
79
80   DBG(r,"REQ[%x] start %s()", TO_ADDR(r), __func__ );
81
82   if (! user_agent) {
83     DBG(r,"REQ[%x] end %s() (User-Agent is NULL)", TO_ADDR(r),__func__);
84     return returnType;
85   }
86
87
88
89   spec_check = (char *)apr_table_get(r->headers_in, "X-Chxj-Spec-Check");
90   if (spec_check && STRCASEEQ('d','D',"done",spec_check)) {
91     DBG(r,"REQ[%x] Use spec cache.", (unsigned int)(apr_size_t)r);
92     returnType = v_spec;
93     DBG(r,"REQ[%x] end %s() (Spec-Check-Done)", TO_ADDR(r),__func__);
94     return returnType;
95   }
96
97   conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
98   if (! conf->devices) {
99     ERR(r,"REQ[%X] device_data.xml load failure", TO_ADDR(r));
100     DBG(r,"REQ[%x] end %s() (Spec-Check-Done)", TO_ADDR(r),__func__);
101     return returnType;
102   }
103
104   for (dtl = conf->devices; dtl; dtl = dtl->next) {
105     if (! dtl->pattern) {
106       /* DBG(r, "REQ[%X] pattern is null", TO_ADDR(r)); */
107       continue;
108     }
109
110     /* DBG(r, "REQ[%X] pattern is [%s]", TO_ADDR(r), dtl->pattern); */
111     if (! dtl->regexp) {
112       ERR(r,"REQ[%X] compile failed.", TO_ADDR(r));
113       DBG(r,"REQ[%x] end %s() (Spec-Check-Done)", TO_ADDR(r),__func__);
114       return returnType;
115     }
116
117     if (ap_regexec((const ap_regex_t *)dtl->regexp, user_agent, (apr_size_t)dtl->regexp->re_nsub + 1, match, 0) == 0) {
118       device_id = ap_pregsub(r->pool, "$1", user_agent, dtl->regexp->re_nsub + 1, match);
119       DBG(r,"REQ[%X] device_id:[%s]", TO_ADDR(r), device_id);
120       returnType = s_get_device_data(r, device_id, dtl);
121       if (! returnType) {
122         if (dtl->tail) {
123           returnType = dtl->tail;
124         }
125         else {
126           returnType = &UNKNOWN_DEVICE;
127         }
128       }
129       v_spec = returnType;
130       apr_table_setn(r->headers_in, "X-Chxj-Spec-Check", "done");
131       DBG(r,"REQ[%X] end %s() (Found User-Agent Type)", TO_ADDR(r),__func__);
132       return returnType;
133     }
134   }
135
136   v_spec = &UNKNOWN_DEVICE;
137   apr_table_setn(r->headers_in, "X-Chxj-Spec-Check", "done");
138   DBG(r,"REQ[%X] end %s() (Not Found User-Agent Type) [%s]",TO_ADDR(r), __func__,user_agent);
139
140   return &UNKNOWN_DEVICE;
141 }
142
143 void
144 chxj_specified_cleanup(request_rec *r) 
145 {
146   DBG(r,"REQ[%X] start %s()",TO_ADDR(r), __func__);
147   v_spec = NULL;
148   DBG(r,"REQ[%X] end %s()",TO_ADDR(r), __func__);
149 }
150
151
152 #include <stdlib.h>
153 static int 
154 s_compar(const void *a, const void *b)
155 {
156   device_table *aa = *(device_table **)a;
157   device_table *bb = *(device_table **)b;
158   /* Not strcasecmp. for LOAD */
159   return strcmp(aa->device_id, bb->device_id);
160 }
161 static device_table *
162 s_get_device_data(request_rec *r, const char *device_id, device_table_list *dtl)
163 {
164   device_table dt;
165   device_table *_dt;
166   dt.device_id = device_id;
167   _dt = &dt;
168   device_table **ret = bsearch(&_dt, dtl->sort_table, dtl->table_count, sizeof(device_table *), s_compar);
169   if (ret && *ret) {
170     return *ret;
171   }
172   return NULL;
173 }
174 /*
175  * vim:ts=2 et
176  */
177