OSDN Git Service

* copy from old-trunk
[modchxj/mod_chxj.git] / src / chxj_tag_util.c
1 /*
2  * Copyright (C) 2005-2008 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 "chxj_tag_util.h"
18 #include "chxj_url_encode.h"
19 #include "chxj_str_util.h"
20
21
22 /**
23  * The value of the VALUE attribute that the object tag node maintains is
24  * acquired.
25  *
26  * @param doc  [i] The pointer to the Doc structure to be scanned is
27  *                 specified.
28  * @param node [i] The tag node to be scanned is specified.
29  * @param pool [i] To use POOL.
30  * @return The value of the VALUE attribute that the object tag node maintains
31  *         is returned. NULL is returned when not found.
32  */
33 char *
34 qs_get_value_attr(Doc *doc, Node *node, apr_pool_t *pool)
35 {
36   Attr *attr;
37
38   /*--------------------------------------------------------------------------*/
39   /* The object tag node is scanned.                                          */
40   /*--------------------------------------------------------------------------*/
41   for (attr = qs_get_attr(doc,node);
42        attr;
43        attr = qs_get_next_attr(doc,attr)) {
44     char *name  = qs_get_attr_name(doc,attr);
45     char *value = qs_get_attr_value(doc,attr);
46     if (STRCASEEQ('v','V',"value",name)) {
47       /*----------------------------------------------------------------------*/
48       /* The VALUE attribute was found.                                       */
49       /*----------------------------------------------------------------------*/
50       return apr_pstrdup(pool, value);
51     }
52   }
53   /*--------------------------------------------------------------------------*/
54   /* not found                                                                */
55   /*--------------------------------------------------------------------------*/
56   return NULL;
57 }
58
59
60 /**
61  * The value of the checked tag is acquired.
62  *
63  * @param doc  [i] The pointer to the Doc structure to be scanned is
64  *                 specified.
65  * @param tag  [i] The tag node to be scanned is specified.
66  * @param pool [i] To use POOL(unused).
67  * @return The value of the checked tag is returned. NULL is returned when
68  *         not found.
69  */
70 char *
71 qs_get_checked_attr(Doc *doc, Node *tag, apr_pool_t *UNUSED(pool))
72 {
73   Attr *attr;
74   /*--------------------------------------------------------------------------*/
75   /* The object tag node is scanned.                                          */
76   /*--------------------------------------------------------------------------*/
77   for (attr = qs_get_attr(doc,tag);
78        attr != NULL;
79        attr = qs_get_next_attr(doc,attr)) {
80     char *name  = qs_get_attr_name(doc,attr);
81     if (STRCASEEQ('c','C',"checked",name)) {
82       /*----------------------------------------------------------------------*/
83       /* The VALUE attribute was found.                                       */
84       /*----------------------------------------------------------------------*/
85       return name;
86     }
87   }
88   /*------------------------------------------------------------------------*/
89   /* not found                                                              */
90   /*------------------------------------------------------------------------*/
91   return NULL;
92 }
93
94
95 /**
96  * The value of the type attribute is acquired.
97  *
98  * @param doc  [i] The pointer to the Doc structure to be scanned is
99  *                 specified.
100  * @param tag  [i] The tag node to be scanned is specified.
101  * @param r    [i] To use POOL, the pointer to request_rec is specified.
102  * @return The value of the type attribute is returned. NULL is returned when
103  *         not found.
104  */
105 char *
106 qs_get_type_attr(Doc *doc, Node *tag, apr_pool_t *pool)
107 {
108   Attr *attr;
109   /*--------------------------------------------------------------------------*/
110   /* The object tag node is scanned.                                          */
111   /*--------------------------------------------------------------------------*/
112   for (attr = qs_get_attr(doc,tag);
113        attr != NULL;
114        attr = qs_get_next_attr(doc,attr)) {
115     char *name  = qs_get_attr_name(doc,attr);
116     char *value = qs_get_attr_value(doc,attr);
117     if (STRCASEEQ('t','T',"type",name)) {
118       /*----------------------------------------------------------------------*/
119       /* The VALUE attribute was found.                                       */
120       /*----------------------------------------------------------------------*/
121       return apr_pstrdup(pool, value);
122     }
123   }
124   /*--------------------------------------------------------------------------*/
125   /* not found                                                                */
126   /*--------------------------------------------------------------------------*/
127   return NULL;
128 }
129
130
131 /**
132  * The character string area in 0 bytes is allocated.
133  *
134  * @param pool    [i]   To use POOL.
135  * @return The allocated 0 byte character string is returned.
136  */
137 char *
138 qs_alloc_zero_byte_string(apr_pool_t *pool)
139 {
140   char *tgt;
141
142   if (! pool) {
143     return NULL;
144   }
145   tgt = apr_palloc(pool, 1);
146   tgt[0] = '\0';
147
148   return tgt;
149 }
150
151
152 /**
153  * A consecutive head and the last WHITESPACE are removed.
154  *
155  * @param p    [i]   To use POOL
156  * @param s    [i]   The character string that should be removed is specified.
157  * @return The character string that has been removed is returned.
158  */
159 char *
160 qs_trim_string(apr_pool_t *p, char *s)
161 {
162   char *ss;
163   int len;
164   int ii;
165
166   if (! s) return apr_pstrdup(p, "");
167
168   ss = apr_pstrdup(p, s);
169   len = strlen(s);
170   ii = 0;
171   for (ii = 0;is_white_space(*ss) && ii < len; ss++, ii++);
172
173   ii = strlen(ss);
174   for(;is_white_space(ss[ii-1]) && ii > 0; ii--);
175
176   ss[ii] = '\0';
177
178   return ss;
179 }
180
181
182 /**
183  * The value of child TEXT of tag that maintains the SELECTED attribute is 
184  * returned. 
185  *
186  * @param Doc  [i] The pointer to the Doc structure to be scanned is 
187  *                 specified. 
188  * @param node [i] The tag node to be scanned is specified.
189  * @param pool [i] To use POOL.
190  * @reutrn  The value of child TEXT of tag that maintains the SELECTED 
191  *          attribute is returned. NULL is returned when not found. 
192  */
193 char *
194 qs_get_selected_value_text(Doc *doc, Node *node, apr_pool_t *pool)
195 {
196   Node *child;
197   Node *selchild;
198   char *result   = NULL;
199
200   for (child = qs_get_child_node(doc,node);
201        child != NULL; 
202        child = qs_get_next_node(doc,child)) {
203     char *name = qs_get_node_name(doc,child);
204     /*------------------------------------------------------------------------*/
205     /* <OPTION> tag                                                           */
206     /*------------------------------------------------------------------------*/
207     if (STRCASEEQ('o','O',"option",name)) {
208       Attr *attr;
209       for (attr =  qs_get_attr(doc,child); 
210            attr != NULL; 
211            attr = qs_get_next_attr(doc,attr)) {
212         char *name2  = qs_get_attr_name(doc,attr);
213         if (STRCASEEQ('s','S',"selected",name2)) {
214           /*------------------------------------------------------------------*/
215           /* SELECTED Value Found                                             */
216           /*------------------------------------------------------------------*/
217           selchild = qs_get_child_node(doc, child);
218           if (! selchild) {
219             /* void value */
220             return apr_pstrdup(pool, "");
221           }
222           return qs_get_node_value(doc, selchild);
223         }
224       }
225     }
226
227     if ((result = qs_get_selected_value_text(doc, child, pool)) != NULL) {
228       return result;
229     }
230   }
231
232   /*--------------------------------------------------------------------------*/
233   /* not found                                                                */
234   /*--------------------------------------------------------------------------*/
235   return NULL;
236 }
237
238
239 /**
240  * The value of tag that maintains the SELECTED attribute is acquired. 
241  *
242  * @param doc    [i]  The pointer to the Doc structure to be scanned is 
243  *                    specified. 
244  * @param node   [i]  The SELECT tag node is specified.
245  * @param pool   [i] To use POOL.
246  * @return The value of tag that maintains the SELECTED attribute is 
247  *         returned. NULL is returned when not found. 
248  */
249 char *
250 qs_get_selected_value(Doc *doc, Node *node, apr_pool_t *pool)
251 {
252   Node *child;
253   char *result    = NULL;
254
255   for (child = qs_get_child_node(doc,node); 
256        child != NULL; 
257        child = qs_get_next_node(doc,child)) {
258     char *name = qs_get_node_name(doc,child);
259     /*------------------------------------------------------------------------*/
260     /* <OPTION> tag                                                           */
261     /*------------------------------------------------------------------------*/
262     if (STRCASEEQ('o','O',"option",name)) {
263       Attr *attr;
264       for (attr = qs_get_attr(doc,child); 
265            attr; 
266            attr = qs_get_next_attr(doc,attr)) {
267         char *name2  = qs_get_attr_name(doc,attr);
268         if (STRCASEEQ('s','S',"selected",name2)) {
269           /*------------------------------------------------------------------*/
270           /* SELECTED Value Found                                             */
271           /*------------------------------------------------------------------*/
272           return qs_get_value_attr(doc, child, doc->buf.pool);
273         }
274       }
275     }
276
277     if ((result = qs_get_selected_value(doc, child, pool)) != NULL) {
278       return result;
279     }
280   }
281
282   /*--------------------------------------------------------------------------*/
283   /* not found                                                                */
284   /*--------------------------------------------------------------------------*/
285   return NULL;
286 }
287
288
289 /**
290  * The value of the NAME attribute is acquired.
291  *
292  * @param doc  [i] The pointer to the Doc structure at the output
293  *                 destination is specified.
294  * @param tag  [i] The tag node to want to acquire the SIZE attribute
295  *                 is specified.
296  * @param pool [i] To use POOL.
297  * @return The value of the NAME attribute is returned. NULL is
298  *         returned when not is.
299  */
300 char *
301 qs_get_name_attr(Doc *doc, Node *tag, apr_pool_t *pool)
302 {
303   Attr *attr;
304   for (attr = qs_get_attr(doc,tag); 
305        attr; 
306        attr = qs_get_next_attr(doc,attr)) {
307     char *name  = qs_get_attr_name(doc,attr);
308     char *value = qs_get_attr_value(doc,attr);
309     if (STRCASEEQ('n','N',"name",name)) {
310       return apr_pstrdup(pool, (value ? value : ""));
311     }
312   }
313   return NULL;
314 }
315
316
317 /**
318  * The value of the SIZE attribute is acquired.
319  *
320  * @param doc  [i] The pointer to the Doc structure at the output
321  *                 destination is specified.
322  * @param tag  [i] The tag node to want to acquire the SIZE attribute
323  *                 is specified.
324  * @param pool [i] To use POOL.
325  * @return The value of the SIZE attribute is returned. NULL is
326  *         returned when not is.
327  */
328 char *
329 qs_get_size_attr(Doc *doc, Node *tag, apr_pool_t *pool)
330 {
331   Attr *attr;
332   for (attr = qs_get_attr(doc,tag); 
333        attr; 
334        attr = qs_get_next_attr(doc,attr)) {
335     char *name  = qs_get_attr_name(doc,attr);
336     char *value = qs_get_attr_value(doc,attr);
337     if (STRCASEEQ('s','S',"size",name)) {
338       return apr_pstrdup(pool, (value ? value : ""));
339     }
340   }
341   return NULL;
342 }
343
344
345 /**
346  * The value of the ACCESSKEY attribute is acquired.
347  *
348  * @param doc  [i] The pointer to the Doc structure at the output
349  *                 destination is specified.
350  * @param tag  [i] The tag node to want to acquire the ACCESSKEY attribute
351  *                 is specified.
352  * @param pool [i] To use POOL.
353  * @return The value of the ACCESSKEY attribute is returned. NULL is
354  *         returned when not is.
355  */
356 char *
357 qs_get_accesskey_attr(Doc *doc, Node *tag, apr_pool_t *pool)
358 {
359   Attr *attr;
360   for (attr = qs_get_attr(doc,tag); 
361        attr; 
362        attr = qs_get_next_attr(doc,attr)) {
363     char *name  = qs_get_attr_name(doc,attr);
364     char *value = qs_get_attr_value(doc,attr);
365     if (STRCASEEQ('a','A',"accesskey",name)) {
366       return apr_pstrdup(pool, value);
367     }
368   }
369   return NULL;
370 }
371
372
373 /**
374  * The value of the ISTYLE attribute is acquired.
375  *
376  * @param doc  [i] The pointer to the Doc structure at the output
377  *                 destination is specified.
378  * @param tag  [i] The tag node to want to acquire the ISTYLE attribute
379  *                 is specified.
380  * @param pool [i] To use POOL.
381  * @return The value of the ISTYLE attribute is returned. NULL is
382  *         returned when not is.
383  */
384 char *
385 qs_get_istyle_attr(Doc *doc, Node *tag, apr_pool_t *pool)
386 {
387   Attr *attr;
388   for (attr = qs_get_attr(doc,tag); 
389        attr != NULL; 
390        attr = qs_get_next_attr(doc,attr)) {
391     char *name  = qs_get_attr_name(doc,attr);
392     char *value = qs_get_attr_value(doc,attr);
393     if (STRCASEEQ('i','I',"istyle",name)) {
394       return apr_pstrdup(pool, value);
395     }
396   }
397   return NULL;
398 }
399
400
401 /**
402  * The value of the MAXLENGTH attribute is acquired from the tag node of the
403  * object.
404  *
405  * @param doc  [i] The pointer to the Doc structure at the output
406  *                 destination is specified.
407  * @param tag  [i] The tag node to want to acquire the MAXLENGTH attribute
408  *                 is specified.
409  * @param pool [i] To use POOL.
410  * @return The value of the MAXLENGTH attribute is returned. NULL is
411  *         returned when not is.
412  */
413 char *
414 qs_get_maxlength_attr(Doc *doc, Node *tag, apr_pool_t *pool)
415 {
416   Attr *attr;
417   for (attr = qs_get_attr(doc,tag);
418        attr; 
419        attr = qs_get_next_attr(doc,attr)) {
420     char *name  = qs_get_attr_name(doc,attr);
421     char *value = qs_get_attr_value(doc,attr);
422     if (STRCASEEQ('m','M',"maxlength",name)) {
423       return apr_pstrdup(pool, value);
424     }
425   }
426   return NULL;
427 }
428
429
430 /**
431  * It is scanned whether the CHECKBOX tag of the object is CHECKED. 
432  *
433  * @param doc  [i] The pointer to the Doc structure at the output
434  *                 destination is specified.
435  * @param tag  [i] The tag node to want to acquire the CHECKBOX attribute
436  *                 is specified.
437  * @param pool [i] To use POOL.
438  * @return 1 is returned when it is CHECKED and, additionally, 0 is returned. 
439  */
440 int
441 qs_is_checked_checkbox_attr(Doc *doc, Node *tag, apr_pool_t *UNUSED(pool))
442 {
443   Attr *attr;
444   for (attr = qs_get_attr(doc,tag);
445        attr; 
446        attr = qs_get_next_attr(doc,attr)) {
447     char *name  = qs_get_attr_name(doc,attr);
448     if (STRCASEEQ('c','C',"checked",name)) {
449       return 1;
450     }
451   }
452   return 0;
453 }
454
455
456 int
457 chxj_chxjif_is_mine(device_table *spec, Doc *doc, Node *tag)
458 {
459   request_rec *r = doc->r;
460   Attr        *attr;
461
462   for (attr = qs_get_attr(doc,tag);
463        attr; 
464        attr = qs_get_next_attr(doc,attr)) {
465     char *name  = qs_get_attr_name(doc,attr);
466     char *value = qs_get_attr_value(doc,attr);
467     if ((*name == 'l' || *name == 'L') && strcasecmp(name, "lang") == 0) {
468
469       DBG(r, "lang found [%s] spec [%d]", value, spec->html_spec_type);
470
471       if (STRCASEEQ('x','X',"xhtml",value)) {
472         if (spec->html_spec_type == CHXJ_SPEC_XHtml_Mobile_1_0) {
473           /* Yes , it is mine */
474           return 1;
475         }
476       }
477       else if (STRCASEEQ('h','H',"hdml",value)) {
478         if (spec->html_spec_type == CHXJ_SPEC_Hdml) {
479           /* Yes , it is mine */
480           return 1;
481         }
482       }
483       else if (STRCASEEQ('j','J',"jhtml",value)) {
484         if (spec->html_spec_type == CHXJ_SPEC_Jhtml) {
485           /* Yes , it is mine */
486           return 1;
487         }
488       }
489       else if (STRCASEEQ('j','J',"jxhtml",value)) {
490         if (spec->html_spec_type == CHXJ_SPEC_Jxhtml) {
491           /* Yes , it is mine */
492           return 1;
493         }
494       }
495       else if (STRCASEEQ('c','C',"chtml",value)) {
496         switch (spec->html_spec_type) {
497         case CHXJ_SPEC_Chtml_1_0:
498         case CHXJ_SPEC_Chtml_2_0:
499         case CHXJ_SPEC_Chtml_3_0:
500         case CHXJ_SPEC_Chtml_4_0:
501         case CHXJ_SPEC_Chtml_5_0:
502         case CHXJ_SPEC_Chtml_6_0:
503         case CHXJ_SPEC_Chtml_7_0:
504           return 1;
505         default:
506           break;
507         }
508       }
509       else if (STRCASEEQ('c','C',"cxhtml",value)) {
510         switch (spec->html_spec_type) {
511         case CHXJ_SPEC_Chtml_6_0:
512         case CHXJ_SPEC_Chtml_7_0:
513           return 1;
514         default:
515           break;
516         }
517       }
518     }
519   }
520
521   /* No, it is not mine. */
522   return 0;
523 }
524
525
526 /**
527  * The value of the DESTLANG attribute is acquired from the tag node of the
528  * object.
529  *
530  * @param doc  [i] The pointer to the Doc structure at the output
531  *                 destination is specified.
532  * @param tag  [i] The tag node to want to acquire the DESTLANG attribute
533  *                 is specified.
534  * @param pool [i] To use POOL.
535  * @return The value of the DESTLANG attribute is returned. NULL is
536  *         returned when not is.
537  */
538 char *
539 qs_get_destlang_attr(Doc *doc, Node *tag, apr_pool_t *pool)
540 {
541   Attr  *attr;
542   for (attr = qs_get_attr(doc,tag);
543        attr; 
544        attr = qs_get_next_attr(doc,attr)) {
545     char *name  = qs_get_attr_name(doc,attr);
546     char *value = qs_get_attr_value(doc,attr);
547     if (STRCASEEQ('d','D',"destlang",name)) {
548       return apr_pstrdup(pool, value);
549     }
550   }
551
552   return NULL;
553 }
554
555
556 /**
557  * The value of the PARSE attribute is acquired.
558  *
559  * @param doc  [i] The pointer to the Doc structure to be scanned is
560  *                 specified.
561  * @param tag  [i] The tag node to be scanned is specified.
562  * @param pool [i] To use POOL.
563  * @return The value of the PARSE attribute is returned. NULL is returned when
564  *         not found.
565  */
566 char *
567 qs_get_parse_attr(Doc *doc, Node *tag, apr_pool_t *pool)
568 {
569   Attr *attr;
570   /*--------------------------------------------------------------------------*/
571   /* The object tag node is scanned.                                          */
572   /*--------------------------------------------------------------------------*/
573   for (attr = qs_get_attr(doc,tag);
574        attr;
575        attr = qs_get_next_attr(doc,attr)) {
576     char *name  = qs_get_attr_name(doc,attr);
577     char *value = qs_get_attr_value(doc,attr);
578     if (STRCASEEQ('p','P',"parse",name)) {
579       /*----------------------------------------------------------------------*/
580       /* The VALUE attribute was found.                                       */
581       /*----------------------------------------------------------------------*/
582       return apr_pstrdup(pool, value);
583     }
584   }
585
586   /*--------------------------------------------------------------------------*/
587   /* not found                                                                */
588   /*--------------------------------------------------------------------------*/
589   return NULL;
590 }
591
592
593 char *
594 chxj_form_action_to_hidden_tag(request_rec *r, apr_pool_t *pool, const char *str, int xmlFlag, int post, char **new_query_string, int docomo)
595 {
596   char *s = apr_pstrdup(pool, str);
597   *new_query_string = NULL;
598   if (!s) return NULL;
599   if (chxj_starts_with(s, "http://") || chxj_starts_with(s, "https://")) {
600     apr_uri_t url;
601     apr_uri_parse(pool, s, &url);
602     if (url.hostname && strcasecmp(url.hostname, r->hostname) != 0) {
603       return NULL;
604     }
605   }
606   s = strchr(s, '?');
607   if (!s) return NULL;
608   s++;
609   char *result = NULL;
610
611   char *pstat;
612   char *pstat2;
613   for (;;) {
614     char *pair = apr_strtok(s, "&", &pstat);
615     if (! pair) break;
616     s = NULL;
617     char *key = apr_strtok(pair, "=",  &pstat2);
618     char *val = "";
619     if (key) {
620       val = apr_strtok(NULL, "=", &pstat2);
621       if (!val) val = "";
622     }
623     char *tmp = NULL;
624     if (post && strcasecmp(key, "guid") == 0 && docomo) {
625       *new_query_string = apr_psprintf(pool, "%s=%s", key, val);
626     }
627     else {
628       if (! post || strcasecmp(key, "_chxj_cc") == 0 || strcasecmp(key, "_chxj_nc") == 0) {
629         tmp = apr_psprintf(pool, "<input type=\"hidden\" name=\"%s\" value=\"%s\"%s>", key, chxj_url_decode(pool, val), (xmlFlag == 1) ? " /" : "");
630       }
631       else {
632         tmp = apr_psprintf(pool, "<input type=\"hidden\" name=\"_chxj_qs_%s\" value=\"%s\"%s>", key, chxj_url_decode(pool, val), (xmlFlag == 1) ? " /" : "");
633       }
634       if (result) {
635         result = apr_pstrcat(pool, result, tmp, NULL);
636       }
637       else {
638         result = tmp;
639       }
640     }
641   }
642   return result;
643 }
644 /*
645  * vim:ts=2 et
646  */