OSDN Git Service

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