OSDN Git Service

Merge branch 'branch_0.12.0-tmp' into branch_0.12.0
authorAtsushi Konno <konn@users.sourceforge.jp>
Sun, 27 Feb 2011 12:30:15 +0000 (21:30 +0900)
committerAtsushi Konno <konn@users.sourceforge.jp>
Sun, 27 Feb 2011 12:30:15 +0000 (21:30 +0900)
configure
configure.ac
include/chxj_add_device_env.h
include/chxj_specified_device.h
include/config.h
src/chxj_add_device_env.c
src/chxj_img_conv_format.c
src/chxj_load_device_data.c
src/chxj_specified_device.c
src/mod_chxj.c
support/centos/mod-chxj.spec

index 5ca5597..deb9081 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for mod_chxj 0.12.38rc8.
+# Generated by GNU Autoconf 2.61 for mod_chxj 0.12.38rc9.
 #
 # Report bugs to <konn@users.sourceforge.jp>.
 #
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='mod_chxj'
 PACKAGE_TARNAME='mod_chxj'
-PACKAGE_VERSION='0.12.38rc8'
-PACKAGE_STRING='mod_chxj 0.12.38rc8'
+PACKAGE_VERSION='0.12.38rc9'
+PACKAGE_STRING='mod_chxj 0.12.38rc9'
 PACKAGE_BUGREPORT='konn@users.sourceforge.jp'
 
 ac_unique_file="src/mod_chxj.c"
@@ -1411,7 +1411,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures mod_chxj 0.12.38rc8 to adapt to many kinds of systems.
+\`configure' configures mod_chxj 0.12.38rc9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1482,7 +1482,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of mod_chxj 0.12.38rc8:";;
+     short | recursive ) echo "Configuration of mod_chxj 0.12.38rc9:";;
    esac
   cat <<\_ACEOF
 
@@ -1600,7 +1600,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-mod_chxj configure 0.12.38rc8
+mod_chxj configure 0.12.38rc9
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1614,7 +1614,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by mod_chxj $as_me 0.12.38rc8, which was
+It was created by mod_chxj $as_me 0.12.38rc9, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2432,7 +2432,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=mod_chxj
- VERSION=0.12.38rc8
+ VERSION=0.12.38rc9
 
 
 cat >>confdefs.h <<_ACEOF
@@ -22602,7 +22602,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by mod_chxj $as_me 0.12.38rc8, which was
+This file was extended by mod_chxj $as_me 0.12.38rc9, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -22655,7 +22655,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-mod_chxj config.status 0.12.38rc8
+mod_chxj config.status 0.12.38rc9
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index 2271b86..bb02117 100644 (file)
@@ -1,6 +1,6 @@
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
-AC_INIT([mod_chxj],[0.12.38rc8],[konn@users.sourceforge.jp])
+AC_INIT([mod_chxj],[0.12.38rc9],[konn@users.sourceforge.jp])
 AC_PREREQ(2.59)
 AC_CONFIG_SRCDIR([src/mod_chxj.c])
 AC_CANONICAL_TARGET
index 82cae00..278d727 100644 (file)
 /* "X-Chxj-Cache"        => { <cache> } */
 #define HTTP_X_CHXJ_CACHE    "X-Chxj-Cache"
 
+/* "X-Chxj-Dpi-Width"        => { <dpi_width> } */
+#define HTTP_X_CHXJ_DPI_WIDTH "X-Chxj-Dpi-Width"
+
+/* "X-Chxj-Dpi-Height"       => { <dpi_heigh> } */
+#define HTTP_X_CHXJ_DPI_HEIGHT "X-Chxj-Dpi-Height"
+
+/* "X-Chxj-Color"       => { <color> } */
+#define HTTP_X_CHXJ_COLOR "X-Chxj-Color"
+
+/* "X-Chxj-Emoji-Type"  => { <emoji_type> } */
+#define HTTP_X_CHXJ_EMOJI_TYPE "X-Chxj-Emoji-Type"
+
 #define HTTP_X_CHXJ_VERSION  "X-Chxj-Version"
 
 extern void chxj_add_device_env(request_rec *r, device_table *spec);
+extern device_table *chxj_get_device_env(request_rec *r);
 
 #endif
 /*
index 9d6abd9..a591a1b 100644 (file)
@@ -96,6 +96,9 @@ struct device_table_list_t {
   ap_regex_t                  *regexp;
   device_table                *table;
   device_table                *tail;
+
+  device_table                **sort_table;
+  size_t                      table_count;
 };
 
 typedef struct converter_t converter_t;
index eb3db8e..6864537 100644 (file)
 #define PACKAGE_NAME "mod_chxj"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "mod_chxj 0.12.38rc8"
+#define PACKAGE_STRING "mod_chxj 0.12.38rc9"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "mod_chxj"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.12.38rc8"
+#define PACKAGE_VERSION "0.12.38rc9"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.12.38rc8"
+#define VERSION "0.12.38rc9"
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
index 4fa865f..7448be1 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include "mod_chxj.h"
 #include "chxj_add_device_env.h"
+#include "chxj_str_util.h"
 
 void
 chxj_add_device_env(request_rec *r, device_table *spec)
@@ -78,7 +79,195 @@ chxj_add_device_env(request_rec *r, device_table *spec)
   apr_table_setn(r->headers_in, HTTP_X_CHXJ_WP_HEIGHT,apr_psprintf(r->pool, "%d", spec->wp_heigh));
   apr_table_setn(r->headers_in, HTTP_X_CHXJ_CACHE,    apr_psprintf(r->pool, "%d", spec->cache));
 
+  /* for LOAD */
+  apr_table_setn(r->headers_in, HTTP_X_CHXJ_DPI_WIDTH,    apr_psprintf(r->pool, "%d", spec->dpi_width));
+  apr_table_setn(r->headers_in, HTTP_X_CHXJ_DPI_HEIGHT,   apr_psprintf(r->pool, "%d", spec->dpi_heigh));
+  apr_table_setn(r->headers_in, HTTP_X_CHXJ_EMOJI_TYPE,   spec->emoji_type);
+
   apr_table_setn(r->headers_in, HTTP_X_CHXJ_VERSION,  apr_pstrdup(r->pool, PACKAGE_VERSION));
 
   DBG(r, "REQ[%X] end chxj_add_device_env()", (unsigned int)(apr_size_t)r);
 }
+
+
+device_table *
+chxj_get_device_env(request_rec *r)
+{
+  device_table *spec;
+  char *tmp;
+  DBG(r, "REQ[%X] start chxj_get_device_env()", (unsigned int)(apr_size_t)r);
+
+  spec = apr_palloc(r->pool, sizeof(device_table));
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_HTMLSPECTYPE);
+  if (! tmp) {
+    DBG(r, "REQ[%X] end chxj_get_device_env()", (unsigned int)(apr_size_t)r);
+    return NULL;
+  }
+  if (STRCASEEQ('c','C', "CHTML1.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_1_0;
+  }
+  else if (STRCASEEQ('c','C', "CHTML2.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_2_0;
+  }
+  else if (STRCASEEQ('c','C', "CHTML3.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_3_0;
+  }
+  else if (STRCASEEQ('c','C', "CHTML4.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_4_0;
+  }
+  else if (STRCASEEQ('c','C', "CHTML5.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_5_0;
+  }
+  else if (STRCASEEQ('c','C', "CHTML6.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_6_0;
+  }
+  else if (STRCASEEQ('c','C', "CHTML7.0", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Chtml_7_0;
+  }
+  else if (STRCASEEQ('x','X', "XHTML", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_XHtml_Mobile_1_0;
+  }
+  else if (STRCASEEQ('h','H', "HDML", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Hdml;
+  }
+  else if (STRCASEEQ('j','j', "JHTML", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Jhtml;
+  }
+  else if (STRCASEEQ('j','j', "JXHTML", tmp)) {
+    spec->html_spec_type = CHXJ_SPEC_Jxhtml;
+  }
+  else {
+    spec->html_spec_type = CHXJ_SPEC_UNKNOWN;
+  }
+  
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_DEVICEID);
+  if (tmp) {
+    spec->device_id = apr_pstrdup(r->pool, tmp);
+  }
+  else {
+    spec->device_id = apr_pstrdup(r->pool, "");
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_DEVICENAME);
+  if (tmp) {
+    spec->device_name = apr_pstrdup(r->pool, tmp);
+  }
+  else {
+    spec->device_name = apr_pstrdup(r->pool, "UNKNOWN");
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_WIDTH);
+  if (tmp) {
+    spec->width = chxj_atoi(tmp); 
+  }
+  else {
+    spec->width = 640;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_HEIGHT);
+  if (tmp) {
+    spec->heigh = chxj_atoi(tmp); 
+  }
+  else {
+    spec->heigh = 480; 
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_GIF);
+  if (STRCASEEQ('t','T',"true",tmp)) {
+    spec->available_gif = 1;
+  }
+  else {
+    spec->available_gif = 0;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_JPEG);
+  if (STRCASEEQ('t','T',"true",tmp)) {
+    spec->available_jpeg = 1;
+  }
+  else {
+    spec->available_jpeg = 0;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_PNG);
+  if (STRCASEEQ('t','T',"true",tmp)) {
+    spec->available_png = 1;
+  }
+  else {
+    spec->available_png = 0;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_BMP2);
+  if (STRCASEEQ('t','T',"true",tmp)) {
+    spec->available_bmp2 = 1;
+  }
+  else {
+    spec->available_bmp2 = 0;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_BMP4);
+  if (STRCASEEQ('t','T',"true",tmp)) {
+    spec->available_bmp4 = 1;
+  }
+  else {
+    spec->available_bmp4 = 0;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_COLOR);
+  if (tmp) {
+    spec->color = chxj_atoi(tmp); 
+  }
+  else {
+    spec->color = 15680000; 
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_WP_WIDTH);
+  if (tmp) {
+    spec->wp_width = chxj_atoi(tmp); 
+  }
+  else {
+    spec->wp_width = 640; 
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_WP_HEIGHT);
+  if (tmp) {
+    spec->wp_heigh = chxj_atoi(tmp); 
+  }
+  else {
+    spec->wp_heigh = 480; 
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_CACHE);
+  if (tmp) {
+    spec->cache = chxj_atoi(tmp); 
+  }
+  else {
+    spec->cache = 10000000; 
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_DPI_WIDTH);
+  if (tmp) {
+    spec->dpi_width = chxj_atoi(tmp); 
+  }
+  else {
+    spec->dpi_width = 96;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_DPI_HEIGHT);
+  if (tmp) {
+    spec->dpi_heigh = chxj_atoi(tmp); 
+  }
+  else {
+    spec->dpi_heigh = 96;
+  }
+
+  tmp = (char *)apr_table_get(r->headers_in, HTTP_X_CHXJ_EMOJI_TYPE);
+  if (tmp) {
+    spec->emoji_type = apr_pstrdup(r->pool, tmp);
+  }
+  else {
+    spec->emoji_type = apr_pstrdup(r->pool, "");
+  }
+
+  DBG(r, "REQ[%X] end chxj_get_device_env()", (unsigned int)(apr_size_t)r);
+  return spec;
+}
index 3139f4a..b6b9387 100644 (file)
@@ -511,7 +511,7 @@ s_create_cache_file(request_rec          *r,
     /*------------------------------------------------------------------------*/
     rv = apr_file_open(&fin, 
                     r->filename, 
-                    APR_READ|APR_BINARY ,
+                    APR_FOPEN_READ | APR_FOPEN_BINARY | APR_FOPEN_BUFFERED | APR_FOPEN_SHARELOCK | APR_FOPEN_SENDFILE_ENABLED,
                     APR_OS_DEFAULT, 
                     r->pool);
     if (rv != APR_SUCCESS) {
@@ -808,8 +808,8 @@ s_create_cache_file(request_rec          *r,
 
   /* to cache */
   rv = apr_file_open(&fout, tmpfile,
-                  APR_WRITE| APR_CREATE | APR_BINARY | APR_SHARELOCK ,APR_OS_DEFAULT,
-                  r->pool);
+                  APR_FOPEN_WRITE| APR_FOPEN_CREATE | APR_FOPEN_BINARY | APR_SHARELOCK ,
+                  APR_OS_DEFAULT, r->pool);
   if (rv != APR_SUCCESS) {
     DestroyMagickWand(magick_wand);
     ERR(r,"file open error.[%s]", tmpfile);
@@ -1675,7 +1675,8 @@ s_send_cache_file(device_table *spec, query_string_param_t *query_string, reques
       }
     }
     rv = apr_file_open(&fout, tmpfile, 
-      APR_READ | APR_BINARY, APR_OS_DEFAULT, r->pool);
+      APR_FOPEN_READ | APR_FOPEN_BINARY | APR_FOPEN_BUFFERED | APR_FOPEN_SHARELOCK | APR_FOPEN_SENDFILE_ENABLED, 
+      APR_OS_DEFAULT, r->pool);
     if (rv != APR_SUCCESS) {
       DBG(r, "cache file open failed[%s]", tmpfile);
       return HTTP_NOT_FOUND;
@@ -1731,7 +1732,8 @@ s_send_cache_file(device_table *spec, query_string_param_t *query_string, reques
       DBG(r, "Content-Length:[%d]", (int)st.size);
 
       rv = apr_file_open(&fout, tmpfile, 
-        APR_READ | APR_BINARY, APR_OS_DEFAULT, r->pool);
+        APR_FOPEN_READ | APR_FOPEN_BINARY | APR_FOPEN_BUFFERED | APR_FOPEN_SHARELOCK | APR_FOPEN_SENDFILE_ENABLED, 
+        APR_OS_DEFAULT, r->pool);
 
       if (rv != APR_SUCCESS) {
         DBG(r,"tmpfile open failed[%s]", tmpfile);
@@ -1770,7 +1772,8 @@ s_send_original_file(request_rec *r, const char *originalfile)
   }
 
   rv = apr_file_open(&fout, originalfile, 
-    APR_READ | APR_BINARY, APR_OS_DEFAULT, r->pool);
+    APR_FOPEN_READ | APR_FOPEN_BINARY | APR_FOPEN_BUFFERED | APR_FOPEN_SHARELOCK | APR_FOPEN_SENDFILE_ENABLED, 
+    APR_OS_DEFAULT, r->pool);
   if (rv != APR_SUCCESS) {
     DBG(r, "originalfile open failed[%s]", originalfile);
     return HTTP_NOT_FOUND;
index 72bb193..48f15ef 100644 (file)
@@ -44,6 +44,34 @@ static void s_set_device_data(
   device_table_list *dtl, 
   Node              *node) ;
 
+static int s_sort_table_compare(const void *a, const void *b);
+static void s_set_sort_table(Doc *doc, apr_pool_t *p, device_table_list *dtl);
+
+#if 0
+#include <stdio.h>
+static void
+s_debug_dump(device_table_list *dtl) 
+{
+  size_t ii=0;
+  FILE *fp = fopen("/tmp/device_dump.log", "a");
+  fprintf(fp, "===================== %d\n", dtl->table_count);
+  fflush(fp);
+  for (ii=0; ii<dtl->table_count; ii++) {
+    if (dtl->sort_table == NULL) {
+      fprintf(fp, "sort_table is NULL\n"); 
+      fflush(fp);
+    }
+    if (dtl->sort_table[ii] == NULL) {
+      fprintf(fp, "sort_table[%d] is NULL\n", ii);
+      fflush(fp);
+    }
+    fprintf(fp, "[%s]\n", dtl->sort_table[ii]->device_id); 
+  }
+  fclose(fp);
+}
+#endif
+#define DBG_DUMP(X) 
+
 
 /**
  * load device_data.xml
@@ -122,7 +150,9 @@ s_set_user_agent_data(Doc *doc, apr_pool_t *p, mod_chxj_config *conf, Node *node
             dtl->regexp = ap_pregcomp(p, (const char *)dtl->pattern, AP_REG_EXTENDED|AP_REG_ICASE);
         }
       }
+      dtl->table_count = 0;
       s_set_device_data(doc, p, dtl, child);
+      s_set_sort_table(doc, p, dtl);
     }
   }
 }
@@ -454,8 +484,42 @@ s_set_device_data(Doc *doc, apr_pool_t *p, device_table_list *dtl, Node *node)
       dtl->tail->next = dt;
       dtl->tail = dt;
     }
+    dtl->table_count++;
   }
 }
+
+
+static void
+s_set_sort_table(Doc *doc, apr_pool_t *p, device_table_list *dtl)
+{
+  device_table **sort_table;
+  device_table *dt;
+  size_t ii=0;
+
+  sort_table = apr_palloc(p, sizeof(device_table) * dtl->table_count);
+
+  for (dt = dtl->table; dt; dt = dt->next) {
+    sort_table[ii++] = dt;
+  }
+
+  dtl->sort_table = sort_table;
+  DBG_DUMP(dtl);
+
+  qsort((void *)sort_table, (size_t)dtl->table_count, sizeof(*sort_table), s_sort_table_compare);
+
+
+  DBG_DUMP(dtl);
+}
+
+static int
+s_sort_table_compare(const void *a, const void *b)
+{
+  device_table *aa = *(device_table **)a;
+  device_table *bb = *(device_table **)b;
+  /* not strcasecmp. for LOAD */
+  return strcmp(aa->device_id, bb->device_id);
+}
+
 /*
  * vim:ts=2 et
  */
index 68247ec..e92ff59 100644 (file)
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 #include "mod_chxj.h"
+#include "chxj_add_device_env.h"
 
 static device_table  UNKNOWN_DEVICE      = {
   .next = NULL,
@@ -57,6 +58,8 @@ static device_table  UNKNOWN_DEVICE      = {
   .color = 15680000,
   .emoji_type = NULL,
 };
+static __thread device_table *v_spec = NULL;
+static device_table * s_get_device_data(request_rec *r, const char *device_id, device_table_list *dtl);
 
 /**
  * The device is specified from UserAgent. 
@@ -70,19 +73,31 @@ chxj_specified_device(request_rec *r, const char *user_agent)
   ap_regmatch_t        match[10];
   device_table         *returnType = &UNKNOWN_DEVICE;
   device_table_list    *dtl;
-  device_table         *dt;
   mod_chxj_config      *conf; 
   char                 *device_id;
+  char                 *spec_check = NULL;
 
-  if (! user_agent) 
+  DBG(r, "REQ[%x] start chxj_specified_device()", (unsigned int)(apr_size_t)r);
+
+  if (! user_agent) {
+    DBG(r, "REQ[%x] end chxj_specified_device() (User-Agent is NULL)", (unsigned int)(apr_size_t)r);
     return returnType;
-            
+  }
+
 
-  DBG(r, "start chxj_specified_device()");
+
+  spec_check = (char *)apr_table_get(r->headers_in, "X-Chxj-Spec-Check");
+  if (spec_check && STRCASEEQ('d','D',"done",spec_check)) {
+    DBG(r, "REQ[%x] Use spec cache.", (unsigned int)(apr_size_t)r);
+    returnType = v_spec;
+    DBG(r, "REQ[%x] end chxj_specified_device() (Spec-Check-Done)", (unsigned int)(apr_size_t)r);
+    return returnType;
+  }
 
   conf = chxj_get_module_config(r->per_dir_config, &chxj_module);
   if (! conf->devices) {
-    DBG(r, "device_data.xml load failure");
+    ERR(r, "device_data.xml load failure");
+    DBG(r, "REQ[%x] end chxj_specified_device() (Spec-Check-Done)", (unsigned int)(apr_size_t)r);
     return returnType;
   }
 
@@ -94,43 +109,74 @@ chxj_specified_device(request_rec *r, const char *user_agent)
 
     /* DBG(r, "pattern is [%s]", dtl->pattern); */
     if (! dtl->regexp) {
-      DBG(r,"compile failed.");
+      ERR(r,"compile failed.");
+      DBG(r, "REQ[%x] end chxj_specified_device() (Spec-Check-Done)", (unsigned int)(apr_size_t)r);
       return returnType;
     }
 
     if (ap_regexec((const ap_regex_t *)dtl->regexp, user_agent, (apr_size_t)dtl->regexp->re_nsub + 1, match, 0) == 0) {
       device_id = ap_pregsub(r->pool, "$1", user_agent, dtl->regexp->re_nsub + 1, match);
       DBG(r, "device_id:[%s]", device_id);
-      for (dt = dtl->table; dt; dt = dt->next) {
-        if (strcasecmp(device_id, dt->device_id) == 0) {
-          DBG(r, "device_name:[%s]", dt->device_name);
-          returnType = dt;
-          break;
+      returnType = s_get_device_data(r, device_id, dtl);
+      if (! returnType) {
+        if (dtl->tail) {
+          returnType = dtl->tail;
         }
-      }
-
-      if (! dt) {
-        for (dt = dtl->table; dt; dt = dt->next) {
-          if (dt->next == NULL)
-            break;
+        else {
+          returnType = &UNKNOWN_DEVICE;
         }
-
-        if (dt)
-          returnType = dt;
       }
-    }
-
-    if (returnType != &UNKNOWN_DEVICE) {
-      DBG(r,"end chxj_specified_device()");
+      v_spec = returnType;
+      apr_table_setn(r->headers_in, "X-Chxj-Spec-Check", "done");
+      DBG(r,"REQ[%X] end chxj_specified_device() (Found User-Agent Type)", (unsigned int)(apr_size_t)r);
       return returnType;
     }
   }
 
-  DBG(r,"end chxj_specified_device()");
+  v_spec = &UNKNOWN_DEVICE;
+  apr_table_setn(r->headers_in, "X-Chxj-Spec-Check", "done");
+  DBG(r,"REQ[%X] end chxj_specified_device() (Not Found User-Agent Type) [%s]",(unsigned int)(apr_size_t)r, user_agent);
 
-  return returnType;
+  return &UNKNOWN_DEVICE;
 }
 
+
+#include <stdlib.h>
+static int 
+s_compar(const void *a, const void *b)
+{
+  device_table *aa = *(device_table **)a;
+  device_table *bb = *(device_table **)b;
+#if 0
+{FILE *fp=fopen("/tmp/erer.log","a");fprintf(fp, "aa[%s] vs bb[%s]\n", aa->device_id, bb->device_id); fclose(fp);}
+#endif
+  /* Not strcasecmp. for LOAD */
+  return strcmp(aa->device_id, bb->device_id);
+}
+static device_table *
+s_get_device_data(request_rec *r, const char *device_id, device_table_list *dtl)
+{
+#if 0
+  device_table *dt;
+  for (dt = dtl->table; dt; dt = dt->next) {
+    if (strcasecmp(device_id, dt->device_id) == 0) {
+      DBG(r, "device_name:[%s]", dt->device_name);
+      return dt;
+    }
+  }
+  return NULL;
+#else
+  device_table dt;
+  device_table *_dt;
+  dt.device_id = device_id;
+  _dt = &dt;
+  device_table **ret = bsearch(&_dt, dtl->sort_table, dtl->table_count, sizeof(device_table *), s_compar);
+  if (ret && *ret) {
+    return *ret;
+  }
+  return NULL;
+#endif
+}
 /*
  * vim:ts=2 et
  */
index c241eb5..4505b1c 100644 (file)
@@ -257,7 +257,7 @@ chxj_headers_fixup(request_rec *r)
 
   }
 
-  char *x_client_type = apr_table_get(r->headers_out, "X-Client-Type");
+  char *x_client_type = (char *)apr_table_get(r->headers_out, "X-Client-Type");
   apr_table_unset(r->headers_out, "X-Client-Type");
   if (x_client_type) {
     apr_table_setn(r->headers_in, "X-Client-Type", x_client_type);
index ff65b13..3ebad63 100644 (file)
@@ -1,4 +1,4 @@
-%define version 0.12.38rc8
+%define version 0.12.38rc9
 
 Summary: CHTML to HDML,XHTML,JHTML convert module for Apache HTTPD.
 Name:  mod_chxj