OSDN Git Service

* use BUFFERRING for JHTML converter.
authorkonn <konn@1a406e8e-add9-4483-a2c8-d8cac5b7c224>
Fri, 4 Apr 2008 10:30:17 +0000 (10:30 +0000)
committerkonn <konn@1a406e8e-add9-4483-a2c8-d8cac5b7c224>
Fri, 4 Apr 2008 10:30:17 +0000 (10:30 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/modchxj/mod_chxj/trunk@1980 1a406e8e-add9-4483-a2c8-d8cac5b7c224

src/chxj_jhtml.c

index 8a0cc02..215f851 100644 (file)
 #include "chxj_qr_code.h"
 #include "chxj_encoding.h"
 #include "chxj_jreserved_tag.h"
+#include "chxj_buffered_write.h"
 
+#define BUFFERED 1
 #define GET_JHTML(X) ((jhtml_t*)(X))
+#define W_L(X)  do { jhtml->out = BUFFERED_WRITE_LITERAL(jhtml->out, &doc->buf, (X)); } while(0)
+#define W_V(X)  do { jhtml->out = (X) ? BUFFERED_WRITE_VALUE(jhtml->out, &doc->buf, (X))  \
+                                      : BUFFERED_WRITE_LITERAL(jhtml->out, &doc->buf, ""); } while(0)
+
 
 static char *s_jhtml_start_html_tag     (void *pdoc, Node *node);
 static char *s_jhtml_end_html_tag       (void *pdoc, Node *node);
@@ -89,7 +95,7 @@ static void  s_init_jhtml(
   request_rec *r, 
   device_table *spec);
 
-static char *chxj_istyle_to_mode(request_rec *r, const char *s);
+static char *chxj_istyle_to_mode(Doc *doc, const char *s);
 
 
 
@@ -402,20 +408,31 @@ chxj_convert_jhtml(
 
   qs_parse_string(&doc,ss,strlen(ss));
 
+  if (! chxj_buffered_write_init(r->pool, &doc.buf)) {
+    ERR(r, "failed: chxj_buffered_write_init()");
+    DBG(r, "end chxj_convert_jhtml()");
+    return apr_pstrdup(r->pool, ss);
+  }
+
   /*--------------------------------------------------------------------------*/
   /* It converts it from CHTML to JHTML.                                      */
   /*--------------------------------------------------------------------------*/
   chxj_node_convert(spec,r,(void*)&jhtml, &doc, qs_get_root(&doc), 0);
-  dst = jhtml.out;
+  /*--------------------------------------------------------------------------*/
+  /* flush buffer AND terminate.                                              */
+  /*--------------------------------------------------------------------------*/
+  jhtml.out = chxj_buffered_write_flush(jhtml.out, &doc.buf);
+  dst = apr_pstrdup(r->pool, jhtml.out);
+  chxj_buffered_write_terminate(&doc.buf);
 
   qs_all_free(&doc,QX_LOGMARK);
-
-  if (! dst) 
+  if (! dst) {
     return apr_pstrdup(r->pool,ss);
+  }
 
-  if (! strlen(dst)) 
+  if (! strlen(dst))  {
     dst = apr_psprintf(r->pool, "\n");
-
+  }
   *dstlen = strlen(dst);
 
 #ifdef DUMP_LOG
@@ -471,11 +488,14 @@ s_jhtml_start_html_tag(void *pdoc, Node *UNUSED(node))
   doc    = jhtml->doc;
   r      = doc->r;
   DBG(r, "start s_jhtml_start_html_tag()");
-
   /*--------------------------------------------------------------------------*/
   /* start HTML tag                                                           */
   /*--------------------------------------------------------------------------*/
+#if BUFFERED
+  W_L("<html>\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<html>\n", NULL);
+#endif
 
   DBG(r, "end s_jhtml_start_html_tag()[%s]", jhtml->out);
 
@@ -499,8 +519,11 @@ s_jhtml_end_html_tag(void *pdoc, Node *UNUSED(child))
   request_rec   *r   = doc->r;
 
   DBG(r, "start s_jhtml_end_html_tag()");
-
+#if BUFFERED
+  W_L("</html>\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</html>\n", NULL);
+#endif
 
   DBG(r, "end s_jhtml_end_html_tag() OUT:[%s]", jhtml->out);
 
@@ -532,21 +555,21 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
   refresh_flag      = 0;
   content_type_flag = 0;
 
+#if BUFFERED
+  W_L("<meta");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<meta", NULL);
-
+#endif
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
   /*--------------------------------------------------------------------------*/
   for (attr = qs_get_attr(doc,node);
        attr;
        attr = qs_get_next_attr(doc,attr)) {
-
     char *name;
     char *value;
-
     name   = qs_get_attr_name(doc,attr);
     value  = qs_get_attr_value(doc,attr);
-
     switch(*name) {
     case 'h':
     case 'H':
@@ -554,12 +577,18 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
         /*----------------------------------------------------------------------*/
         /* CHTML 2.0                                                            */
         /*----------------------------------------------------------------------*/
+#if BUFFERED
+        W_L(" http-equiv=\"");
+        W_V(value);
+        W_L("\"");
+#else
         jhtml->out = apr_pstrcat(r->pool, 
                         jhtml->out, 
                         " http-equiv=\"", 
                         value,
                         "\"",
                         NULL);
+#endif
         if (STRCASEEQ('c','C',"content-type", value)) {
           content_type_flag = 1;
         }
@@ -577,6 +606,12 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
         /*----------------------------------------------------------------------*/
         if (content_type_flag)  {
           if (IS_SJIS_STRING(GET_SPEC_CHARSET(jhtml->spec))) {
+#if BUFFERED
+            W_L(" ");
+            W_V(name);
+            W_L("=\"");
+            W_L("text/html; charset=Windows-31J");
+#else
             jhtml->out = apr_pstrcat(r->pool,
                                     jhtml->out,
                                     " ",
@@ -585,8 +620,15 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
                                     "text/html; charset=Windows-31J",
                                     "\"",
                                     NULL);
+#endif
           }
           else {
+#if BUFFERED
+            W_L(" ");
+            W_V(name);
+            W_L("=\"");
+            W_L("text/html; charset=UTF-8");
+#else
             jhtml->out = apr_pstrcat(r->pool,
                                     jhtml->out,
                                     " ",
@@ -595,6 +637,7 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
                                     "text/html; charset=UTF-8",
                                     "\"",
                                     NULL);
+#endif
           }
         }
         else
@@ -602,16 +645,23 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
           char* buf;
           char* sec;
           char* url;
-  
-          buf = apr_pstrdup(r->pool, value);
-  
+          buf = apr_pstrdup(doc->buf.pool, value);
           url = strchr(buf, ';');
           if (url) {
-            sec = apr_pstrdup(r->pool, buf);
+            sec = apr_pstrdup(doc->buf.pool, buf);
             sec[url-buf] = 0;
             url++;
             url = chxj_encoding_parameter(r, url);
             url = chxj_add_cookie_parameter(r, url, jhtml->cookie);
+#if BUFFERED
+            W_L(" ");
+            W_V(name);
+            W_L("=\"");
+            W_V(sec);
+            W_L(";");
+            W_V(url);
+            W_L("\"");
+#else
             jhtml->out = apr_pstrcat(r->pool,
                                      jhtml->out,
                                      " ",
@@ -622,9 +672,16 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
                                      url,
                                      "\"",
                                      NULL);
+#endif
           }
         }
-        else
+        else {
+#if BUFFERED
+          W_L(" ");
+          W_V(name);
+          W_L("=\"");
+          W_V(value);
+#else
           jhtml->out = apr_pstrcat(r->pool,
                                    jhtml->out,
                                    " ",
@@ -633,6 +690,8 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
                                    value,
                                    "\"",
                                    NULL);
+#endif
+        }
       }
       break;
     
@@ -641,7 +700,11 @@ s_jhtml_start_meta_tag(void *pdoc, Node *node)
     }
   }
 
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -685,7 +748,11 @@ s_jhtml_start_head_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<head>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<head>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -710,7 +777,11 @@ s_jhtml_end_head_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</head>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</head>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -735,7 +806,11 @@ s_jhtml_start_title_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<title>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<title>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -760,7 +835,11 @@ s_jhtml_end_title_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</title>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</title>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -786,8 +865,11 @@ s_jhtml_start_base_tag(void *pdoc, Node *node)
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<base");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<base", NULL);
-
+#endif
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
   /*--------------------------------------------------------------------------*/
@@ -801,18 +883,26 @@ s_jhtml_start_base_tag(void *pdoc, Node *node)
     name  = qs_get_attr_name(doc,attr);
     value = qs_get_attr_value(doc,attr);
 
-    if ((*name == 'h' || *name == 'H') && strcasecmp(name, "href") == 0) {
+    if (STRCASEEQ('h','H',"href",name)) {
+#if BUFFERED
+      W_L(" href=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " href=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
   }
-
+#if BUFFERED
+  W_L(" >\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, " >\r\n", NULL);
-
+#endif
   return jhtml->out;
 }
 
@@ -856,8 +946,11 @@ s_jhtml_start_body_tag(void *pdoc, Node *node)
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<body");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<body", NULL);
-
+#endif
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
   /*--------------------------------------------------------------------------*/
@@ -867,54 +960,67 @@ s_jhtml_start_body_tag(void *pdoc, Node *node)
 
     char *name;
     char *value;
-
     name   = qs_get_attr_name(doc,attr);
     value  = qs_get_attr_value(doc,attr);
 
-    if ((*name == 'b' || *name == 'B') && strcasecmp(name, "bgcolor") == 0) {
+    if (STRCASEEQ('b','B',"bgcolor",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 2.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" bgcolor=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " bgcolor=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 't' || *name == 'T') && strcasecmp(name, "text") == 0) {
+    else if (STRCASEEQ('t','T',"text",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 2.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" text=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " text=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'l' || *name == 'L') && strcasecmp(name, "link") == 0) {
+    else if (STRCASEEQ('l','L',"link",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 2.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" link=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                               jhtml->out, 
                               " link=\"", 
                               value, 
                               "\"", 
                               NULL);
+#endif
     }
-    else
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "alink") == 0) {
+    else if (STRCASEEQ('a','A',"alink",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 4.0                                                            */
       /*----------------------------------------------------------------------*/
       /* ignore */
     }
-    else
-    if ((*name == 'v' || *name == 'V') && strcasecmp(name, "vlink") == 0) {
+    else if (STRCASEEQ('v','V',"vlink",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 4.0                                                            */
       /*----------------------------------------------------------------------*/
@@ -922,7 +1028,11 @@ s_jhtml_start_body_tag(void *pdoc, Node *node)
     }
   }
 
+#if BUFFERED
+  W_L(">\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -947,7 +1057,11 @@ s_jhtml_end_body_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</body>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</body>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -973,8 +1087,11 @@ s_jhtml_start_a_tag(void *pdoc, Node *node)
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<a");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<a", NULL);
-
+#endif
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
   /*--------------------------------------------------------------------------*/
@@ -988,117 +1105,133 @@ s_jhtml_start_a_tag(void *pdoc, Node *node)
     name  = qs_get_attr_name(doc,attr);
     value = qs_get_attr_value(doc,attr);
 
-    if ((*name == 'n' || *name == 'N') && strcasecmp(name, "name") == 0) {
+    if (STRCASEEQ('n','N',"name",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML1.0                                                             */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" name=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " name=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'h' || *name == 'H') && strcasecmp(name, "href") == 0) {
+    else if (STRCASEEQ('h','H',"href",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML1.0                                                             */
       /*----------------------------------------------------------------------*/
       value = chxj_encoding_parameter(r, value);
       value = chxj_add_cookie_parameter(r, value, jhtml->cookie);
+#if BUFFERED
+      W_L(" href=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " href=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "accesskey") == 0) {
+    else if (STRCASEEQ('a','A',"accesskey",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML1.0                                                             */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" accesskey=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " accesskey=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'c' || *name == 'C') && strcasecmp(name, "cti") == 0) {
+    else if (STRCASEEQ('c','C',"cti",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 2.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" cti=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " cti=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'i' || *name == 'I') && strcasecmp(name, "ijam") == 0) {
+    else if (STRCASEEQ('i','I',"ijam",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 3.0                                                            */
       /*----------------------------------------------------------------------*/
       /* ignore */
     }
-    else
-    if ((*name == 'u' || *name == 'U') && strcasecmp(name, "utn") == 0) {
+    else if (STRCASEEQ('u','U',"utn",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 3.0                                                            */
       /* It is special only for CHTML.                                        */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" utn ");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " utn ", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 't' || *name == 'T') && strcasecmp(name, "telbook") == 0) {
+    else if (STRCASEEQ('t','T',"telbook",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 3.0                                                            */
       /*----------------------------------------------------------------------*/
       /* not support */
     }
-    else
-    if ((*name == 'k' || *name == 'K') && strcasecmp(name, "kana") == 0) {
+    else if (STRCASEEQ('k','K',"kana",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 3.0                                                            */
       /*----------------------------------------------------------------------*/
       /* not support */
     }
-    else
-    if ((*name == 'e' || *name == 'E') && strcasecmp(name, "email") == 0) {
+    else if (STRCASEEQ('e','E',"email",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 3.0                                                            */
       /*----------------------------------------------------------------------*/
       /* not support */
     }
-    else
-    if ((*name == 'i' || *name == 'I') && strcasecmp(name, "ista") == 0) {
+    else if (STRCASEEQ('i','I',"ista",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 4.0                                                            */
       /*----------------------------------------------------------------------*/
       /* ignore */
     }
-    else
-    if ((*name == 'i' || *name == 'I') && strcasecmp(name, "ilet") == 0) {
+    else if (STRCASEEQ('i','I',"ilet",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 5.0                                                            */
       /*----------------------------------------------------------------------*/
       /* ignore */
     }
-    else
-    if ((*name == 'i' || *name == 'I') && strcasecmp(name, "iswf") == 0) {
+    else if (STRCASEEQ('i','I',"iswf",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 5.0                                                            */
       /*----------------------------------------------------------------------*/
       /* ignore */
     }
-    else
-    if ((*name == 'i' || *name == 'I') && strcasecmp(name, "irst") == 0) {
+    else if (STRCASEEQ('i','I',"irst",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 5.0                                                            */
       /*----------------------------------------------------------------------*/
@@ -1106,7 +1239,11 @@ s_jhtml_start_a_tag(void *pdoc, Node *node)
     }
   }
 
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1131,7 +1268,11 @@ s_jhtml_end_a_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</a>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</a>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1156,7 +1297,11 @@ s_jhtml_start_br_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<br>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<br>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1200,7 +1345,11 @@ s_jhtml_start_tr_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<br>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<br>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1245,31 +1394,36 @@ s_jhtml_start_font_tag(void *pdoc, Node *node)
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<font");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<font", NULL);
-
+#endif
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
   /*--------------------------------------------------------------------------*/
   for (attr = qs_get_attr(doc,node);
        attr; 
        attr = qs_get_next_attr(doc,attr)) {
-
     char *name;
     char *value;
-
     name  = qs_get_attr_name(doc,attr);
     value = qs_get_attr_value(doc,attr);
-
-    if ((*name == 'c' || *name == 'C') && strcasecmp(name, "color") == 0) {
+    if (STRCASEEQ('c','C',"color",name)) {
+#if BUFFERED
+      W_L(" color=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " color=\"", 
                                value, 
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 's' || *name == 'S') && strcasecmp(name, "size") == 0) {
+    else if (STRCASEEQ('s','S',"size",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 5.0                                                            */
       /*----------------------------------------------------------------------*/
@@ -1277,7 +1431,11 @@ s_jhtml_start_font_tag(void *pdoc, Node *node)
     }
   }
 
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1295,12 +1453,18 @@ static char *
 s_jhtml_end_font_tag(void *pdoc, Node *UNUSED(child)) 
 {
   jhtml_t      *jhtml;
+  Doc          *doc;
   request_rec  *r;
 
   jhtml = GET_JHTML(pdoc);
-  r     = jhtml->doc->r;
+  doc   = jhtml->doc;
+  r     = doc->r;
 
+#if BUFFERED
+  W_L("</font>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</font>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1326,64 +1490,89 @@ s_jhtml_start_form_tag(void *pdoc, Node *node)
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<form");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<form", NULL);
-
+#endif
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
   /*--------------------------------------------------------------------------*/
   for (attr = qs_get_attr(doc,node);
        attr;
        attr = qs_get_next_attr(doc,attr)) {
-
     char *name;
     char *value;
-
     name  = qs_get_attr_name(doc,attr);
     value = qs_get_attr_value(doc,attr);
-
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "action") == 0) {
+    if (STRCASEEQ('a','A',"action",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" action=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " action=\"",
                                value,
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'm' || *name == 'M') && strcasecmp(name, "method") == 0) {
+    else if (STRCASEEQ('m','M',"method",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" method=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " method=\"",
                                value,
                                "\"", 
                                NULL);
+#endif
     }
-    else
-    if ((*name == 'u' || *name == 'U') && strcasecmp(name, "utn") == 0) {
+    else if (STRCASEEQ('u','U',"utn",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 3.0                                                            */
       /* It is special only for CHTML.                                        */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" utn ");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, 
                       " utn ", 
                       NULL);
+#endif
     }
   }
 
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   if (jhtml->cookie && jhtml->cookie->cookie_id) {
+#if BUFFERED
+    char *vv = apr_psprintf(r->pool, "<input type='hidden' name='%s' value='%s'>",
+                             CHXJ_COOKIE_PARAM,
+                             jhtml->cookie->cookie_id);
+    W_V(vv);
+#else
     jhtml->out = apr_psprintf(r->pool, "%s<input type='hidden' name='%s' value='%s'>",
                              jhtml->out, 
                              CHXJ_COOKIE_PARAM,
                              jhtml->cookie->cookie_id);
+#endif
   }
 
   return jhtml->out;
@@ -1403,9 +1592,12 @@ s_jhtml_end_form_tag(void *pdoc, Node *UNUSED(child))
 {
   jhtml_t      *jhtml = GET_JHTML(pdoc);
   Doc          *doc   = jhtml->doc;
-  request_rec  *r     = doc->r;
 
+#if BUFFERED
+  W_L("</form>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</form>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1446,7 +1638,11 @@ s_jhtml_start_input_tag(void *pdoc, Node *node)
   checked     = NULL;
   accesskey   = NULL;
 
+#if BUFFERED
+  W_L("<input");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<input", NULL);
+#endif
 
   /*--------------------------------------------------------------------------*/
   /* Get Attributes                                                           */
@@ -1462,95 +1658,157 @@ s_jhtml_start_input_tag(void *pdoc, Node *node)
   size       = qs_get_size_attr(doc, node, r);
 
   if (type) {
+#if BUFFERED
+    W_L(" type=\"");
+    W_V(type);
+    W_L("\" ");
+#else
     jhtml->out = apr_pstrcat(r->pool,
                     jhtml->out, 
                     " type=\"", 
                     type, 
                     "\" ", 
                     NULL);
+#endif
   }
   if (size) {
+#if BUFFERED
+    W_L(" size=\"");
+    W_V(size);
+    W_L("\" ");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                     jhtml->out, 
                     " size=\"", 
                     size, 
                     "\" ", 
                     NULL);
+#endif
   }
   if (name) {
+#if BUFFERED
+    char *vv = chxj_jreserved_to_safe_tag(r, name);
+    W_L(" name=\"");
+    W_V(vv);
+    W_L("\" ");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                     jhtml->out, 
                     " name=\"", 
                     chxj_jreserved_to_safe_tag(r, name),
                     "\" ", 
                     NULL);
+#endif
   }
   if (value) {
+#if BUFFERED
+    W_L(" value=\"");
+    W_V(value);
+    W_L("\" ");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                     jhtml->out, 
                     " value=\"", 
                     value, 
                     "\" ", 
                     NULL);
+#endif
   }
   if (accesskey) {
+#if BUFFERED
+    W_L(" accesskey=\"");
+    W_V(accesskey);
+    W_L("\" ");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                     jhtml->out, 
                     " accesskey=\"", 
                     accesskey, "\" ", 
                     NULL);
+#endif
   }
   if (istyle) {
     /*------------------------------------------------------------------------*/
     /* CHTML 2.0                                                              */
     /*------------------------------------------------------------------------*/
-    if (type && (*type == 'p' || *type == 'P') && strcasecmp(type, "password") == 0
-    && ! jhtml->entryp->pc_flag ) {
+    if (type && STRCASEEQ('p','P',"password", type) && ! jhtml->entryp->pc_flag ) {
+#if BUFFERED
+      W_L(" mode=\"");
+      W_L("numeric");
+      W_L("\" ");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " mode=\"", 
                                "numeric", 
                                "\" ", 
                                NULL);
+#endif
     }
     else {
+#if BUFFERED
+      char *vv = chxj_istyle_to_mode(doc,istyle);
+      W_L(" mode=\"");
+      W_V(vv);
+      W_L("\" ");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                                jhtml->out, 
                                " mode=\"", 
-                               chxj_istyle_to_mode(r,istyle), 
+                               chxj_istyle_to_mode(doc,istyle), 
                                "\" ", 
                                NULL);
+#endif
     }
   }
-  else
-  if (istyle == NULL && type != NULL && strcasecmp(type, "password") == 0) {
+  else if (istyle == NULL && type && STRCASEEQ('p','P',"password", type)) {
+#if BUFFERED
+    W_L(" mode=\"");
+    W_L("numeric");
+    W_L("\" ");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                              jhtml->out, 
                              " mode=\"", 
                              "numeric", 
                              "\" ", 
                              NULL);
+#endif
   }
   /*--------------------------------------------------------------------------*/
   /* The figure is default for the password.                                  */
   /*--------------------------------------------------------------------------*/
   if (max_length) {
+#if BUFFERED
+    W_L(" maxlength=\"");
+    W_V(max_length);
+    W_L("\"");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                              jhtml->out, 
                              " maxlength=\"", 
                              max_length, 
                              "\"", 
                              NULL);
+#endif
   }
 
   if (checked) {
+#if BUFFERED
+    W_L(" checked ");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                              jhtml->out,
                              " checked ",
                              NULL);
+#endif
   }
 
+#if BUFFERED
+  W_L(" >");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, " >", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1586,9 +1844,12 @@ s_jhtml_start_center_tag(void *pdoc, Node *UNUSED(node))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
+#if BUFFERED
+  W_L("<center>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<center>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1613,7 +1874,11 @@ s_jhtml_end_center_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</center>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</center>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1638,7 +1903,11 @@ s_jhtml_start_li_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<li>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<li>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1663,7 +1932,11 @@ s_jhtml_end_li_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</li>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</li>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1688,7 +1961,11 @@ s_jhtml_start_ol_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<ol>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<ol>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1713,7 +1990,11 @@ s_jhtml_end_ol_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</ol>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</ol>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1738,7 +2019,11 @@ s_jhtml_start_p_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<p>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<p>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1757,9 +2042,12 @@ s_jhtml_end_p_tag(void *pdoc, Node *UNUSED(child))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
+#if BUFFERED
+  W_L("</p>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</p>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1778,10 +2066,13 @@ s_jhtml_start_pre_tag(void *pdoc, Node *UNUSED(node))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
   jhtml->pre_flag++;
+#if BUFFERED
+  W_L("<pre>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<pre>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1800,9 +2091,12 @@ s_jhtml_end_pre_tag(void *pdoc, Node *UNUSED(child))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
+#if BUFFERED
+  W_L("</pre>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</pre>", NULL);
+#endif
   jhtml->pre_flag--;
 
   return jhtml->out;
@@ -1822,9 +2116,12 @@ s_jhtml_start_ul_tag(void *pdoc, Node *UNUSED(node))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
+#if BUFFERED
+  W_L("<ul>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<ul>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1843,9 +2140,12 @@ s_jhtml_end_ul_tag(void *pdoc, Node *UNUSED(child))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
+#if BUFFERED
+  W_L("</ul>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</ul>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1864,60 +2164,85 @@ s_jhtml_start_hr_tag(void *pdoc, Node *node)
 {
   jhtml_t      *jhtml = GET_JHTML(pdoc);
   Doc          *doc   = jhtml->doc;
-  request_rec  *r     = doc->r;
   Attr         *attr;
 
+#if BUFFERED
+  W_L("<hr ");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<hr ", NULL);
+#endif
  
   for (attr = qs_get_attr(doc,node);
        attr; 
        attr = qs_get_next_attr(doc,attr)) {
     char *name = qs_get_attr_name(doc,attr);
     char *value = qs_get_attr_value(doc,attr);
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "align") == 0) {
+    if (STRCASEEQ('a','A',"align",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" align=\"");
+      W_V(value);
+      W_L("\" ");
+#else
       jhtml->out = apr_pstrcat(r->pool,
                         jhtml->out, 
                         " align=\"", value, "\" ", NULL);
+#endif
     }
-    else
-    if ((*name == 's' || *name == 'S') && strcasecmp(name, "size") == 0) {
+    else if (STRCASEEQ('s','S',"size",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" size=\"");
+      W_V(value);
+      W_L("\" ");
+#else
       jhtml->out = apr_pstrcat(r->pool,
                         jhtml->out, 
                         " size=\"", value, "\" ", NULL);
+#endif
     }
-    else
-    if ((*name == 'w' || *name == 'W') && strcasecmp(name, "width") == 0) {
+    else if (STRCASEEQ('w','W',"width",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" width=\"");
+      W_V(value);
+      W_L("\" ");
+#else
       jhtml->out = apr_pstrcat(r->pool,
                         jhtml->out, 
                         " width=\"", value, "\" ", NULL);
+#endif
     }
-    else
-    if ((*name == 'n' || *name == 'N') && strcasecmp(name, "noshade") == 0) {
+    else if (STRCASEEQ('n','N',"noshade",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" noshade ");
+#else
       jhtml->out = apr_pstrcat(r->pool,
                         jhtml->out, 
                         " noshade ", NULL);
+#endif
     }
-    else
-    if ((*name == 'c' || *name == 'C') && strcasecmp(name, "color") == 0) {
+    else if (STRCASEEQ('c','C',"color",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 4.0                                                            */
       /*----------------------------------------------------------------------*/
       /* ignore */
     }
   }
+#if BUFFERED
+  W_L(" >");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, " >", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -1959,7 +2284,11 @@ s_jhtml_start_img_tag(void *pdoc, Node *node)
   device_table  *spec = jhtml->spec;
 #endif
 
+#if BUFFERED
+  W_L("<img");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<img", NULL);
+#endif
  
 
   /*--------------------------------------------------------------------------*/
@@ -1971,7 +2300,7 @@ s_jhtml_start_img_tag(void *pdoc, Node *node)
     char *name  = qs_get_attr_name(doc,attr);
     char *value = qs_get_attr_value(doc,attr);
 
-    if ((*name == 's' || *name == 'S') && strcasecmp(name, "src") == 0) {
+    if (STRCASEEQ('s','S',"src",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
@@ -1979,80 +2308,120 @@ s_jhtml_start_img_tag(void *pdoc, Node *node)
       value = chxj_encoding_parameter(r, value);
       value = chxj_add_cookie_parameter(r, value, jhtml->cookie);
       if (value) {
-        value = apr_psprintf(r->pool,
+        value = apr_psprintf(doc->buf.pool,
                              "%s%c%s=true",
                              value,
                              (strchr(value, '?')) ? '&' : '?',
                              CHXJ_COOKIE_NOUPDATE_PARAM);
       }
+#if BUFFERED
+      W_L(" src=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " src=\"",value,"\"", NULL);
+#endif
 #else
       value = chxj_img_conv(r, spec, value);
       value = chxj_encoding_parameter(r, value);
       value = chxj_add_cookie_parameter(r, value, jhtml->cookie);
       if (value) {
-        value = apr_psprintf(r->pool,
+        value = apr_psprintf(doc->buf.pool,
                              "%s%c%s=true",
                              value,
                              (strchr(value, '?')) ? '&' : '?',
                              CHXJ_COOKIE_NOUPDATE_PARAM);
       }
+#if BUFFERED
+      W_L(" src=\"");
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " src=\"", value, NULL);
       jhtml->out = apr_pstrcat(r->pool, jhtml->out, "\"", NULL);
 #endif
+#endif
     }
-    else
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "align" ) == 0) {
+    else if (STRCASEEQ('a','A',"align",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" align=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " align=\"",value,"\"", NULL);
+#endif
     }
-    else
-    if ((*name == 'w' || *name == 'W') && strcasecmp(name, "width" ) == 0) {
+    else if (STRCASEEQ('w','W',"width",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" width=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " width=\"",value,"\"", NULL);
+#endif
     }
-    else
-    if ((*name == 'h' || *name == 'H') && strcasecmp(name, "height") == 0) {
+    else if (STRCASEEQ('h','H',"height",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" height=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " height=\"",value,"\"", NULL);
+#endif
     }
-    else
-    if ((*name == 'h' || *name == 'H') && strcasecmp(name, "hspace") == 0) {
+    else if (STRCASEEQ('h','H',"hspace",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" hspace=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " hspace=\"",value,"\"", NULL);
+#endif
     }
-    else
-    if ((*name == 'v' || *name == 'V') && strcasecmp(name, "vspace") == 0) {
+    else if (STRCASEEQ('v','V',"vspace",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" vspace=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " vspace=\"",value,"\"", NULL);
+#endif
     }
-    else
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "alt"   ) == 0) {
+    else if (STRCASEEQ('a','A',"alt",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0                                                            */
       /*----------------------------------------------------------------------*/
+#if BUFFERED
+      W_L(" alt=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, 
                       jhtml->out, " alt=\"",value,"\"", NULL);
+#endif
     }
-    else
-    if ((*name == 'a' || *name == 'A') && strcasecmp(name, "align" ) == 0) {
+    else if (STRCASEEQ('a','A',"align",name)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 4.0                                                            */
       /*----------------------------------------------------------------------*/
@@ -2060,7 +2429,11 @@ s_jhtml_start_img_tag(void *pdoc, Node *node)
     }
   }
 
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2096,34 +2469,34 @@ s_jhtml_start_select_tag(void *pdoc, Node *child)
 {
   jhtml_t     *jhtml = GET_JHTML(pdoc);
   Doc         *doc   = jhtml->doc;
-  request_rec *r     = doc->r;
   Attr        *attr;
 
   char *size      = NULL;
   char *name      = NULL;
 
+#if BUFFERED
+  W_L("<select");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<select", NULL);
+#endif
   for (attr = qs_get_attr(doc,child);
        attr;
        attr = qs_get_next_attr(doc,attr)) {
     char *nm  = qs_get_attr_name(doc,attr);
     char *val = qs_get_attr_value(doc,attr);
-
-    if ((*nm == 's' || *nm == 'S') && strcasecmp(nm, "size") == 0) {
+    if (STRCASEEQ('s','S',"size",nm)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0 version 2.0                                                */
       /*----------------------------------------------------------------------*/
-      size = apr_pstrdup(r->pool, val);
+      size = apr_pstrdup(doc->buf.pool, val);
     }
-    else
-    if ((*nm == 'n' || *nm == 'N') && strcasecmp(nm, "name") == 0) {
+    else if (STRCASEEQ('n','N',"name",nm)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0 version 2.0                                                */
       /*----------------------------------------------------------------------*/
-      name = apr_pstrdup(r->pool, val);
+      name = apr_pstrdup(doc->buf.pool, val);
     }
-    else
-    if ((*nm == 'm' || *nm == 'M') && strcasecmp(nm, "multiple") == 0) {
+    else if (STRCASEEQ('m','M',"multiple",nm)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0 version 2.0                                                */
       /*----------------------------------------------------------------------*/
@@ -2131,13 +2504,31 @@ s_jhtml_start_select_tag(void *pdoc, Node *child)
     }
   }
 
-  if (size)
+  if (size) {
+#if BUFFERED
+    W_L(" size=\"");
+    W_V(size);
+    W_L("\"");
+#else
     jhtml->out = apr_pstrcat(r->pool, jhtml->out, " size=\"",size,"\"", NULL);
+#endif
+  }
 
-  if (name)
+  if (name) {
+#if BUFFERED
+    W_L(" name=\"");
+    W_V(name);
+    W_L("\"");
+#else
     jhtml->out = apr_pstrcat(r->pool, jhtml->out, " name=\"",name,"\"", NULL);
+#endif
+  }
 
+#if BUFFERED
+  W_L(">\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2155,9 +2546,12 @@ s_jhtml_end_select_tag(void *pdoc, Node *UNUSED(child))
 {
   jhtml_t      *jhtml = GET_JHTML(pdoc);
   Doc          *doc   = jhtml->doc;
-  request_rec  *r     = doc->r;
 
+#if BUFFERED
+  W_L("</select>\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</select>\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2175,43 +2569,65 @@ s_jhtml_start_option_tag(void *pdoc, Node *child)
 {
   jhtml_t      *jhtml = GET_JHTML(pdoc);
   Doc          *doc   = jhtml->doc;
-  request_rec  *r     = doc->r;
   Attr         *attr;
 
   char         *selected   = NULL;
   char         *value      = NULL;
 
+#if BUFFERED
+  W_L("<option");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<option", NULL);
+#endif
   for (attr = qs_get_attr(doc,child);
        attr;
        attr = qs_get_next_attr(doc,attr)) {
     char *nm  = qs_get_attr_name(doc,attr);
     char *val = qs_get_attr_value(doc,attr);
-
-    if ((*nm == 's' || *nm == 'S') && strcasecmp(nm, "selected") == 0) {
+    if (STRCASEEQ('s','S',"selected",nm)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0 version 2.0                                                */
       /*----------------------------------------------------------------------*/
-      selected = apr_pstrdup(r->pool, val);
+      selected = apr_pstrdup(doc->buf.pool, val);
     }
-    else
-    if ((*nm == 'v' || *nm == 'V') && strcasecmp(nm, "value") == 0) {
+    else if (STRCASEEQ('v','V',"value",nm)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0 version 2.0                                                */
       /*----------------------------------------------------------------------*/
-      value = apr_pstrdup(r->pool, val);
+      value = apr_pstrdup(doc->buf.pool, val);
     }
   }
 
-  if (value) 
+  if (value) {
+#if BUFFERED
+    W_L(" value=\"");
+    W_V(value);
+    W_L("\"");
+#else
     jhtml->out = apr_pstrcat(r->pool, jhtml->out, " value=\"",value,"\"", NULL);
-  else
+#endif
+  }
+  else {
+#if BUFFERED
+    W_L(" value=\"\"");
+#else
     jhtml->out = apr_pstrcat(r->pool, jhtml->out, " value=\"\"", NULL);
+#endif
+  }
 
-  if (selected)
+  if (selected) {
+#if BUFFERED
+    W_L(" selected ");
+#else
     jhtml->out = apr_pstrcat(r->pool, jhtml->out, " selected ", NULL);
+#endif
+  }
 
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2262,30 +2678,41 @@ s_jhtml_start_div_tag(void *pdoc, Node *child)
 
   align = NULL;
 
+#if BUFFERED
+  W_L("<div");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<div", NULL);
+#endif
   for (attr = qs_get_attr(doc,child);
        attr;
        attr = qs_get_next_attr(doc,attr)) {
-
     char *nm;
     char *val;
-
     nm  = qs_get_attr_name(doc,attr);
     val = qs_get_attr_value(doc,attr);
-
-    if ((*nm == 'a' || *nm == 'A') && strcasecmp(nm, "align") == 0) {
+    if (STRCASEEQ('a','A',"align",nm)) {
       /*----------------------------------------------------------------------*/
       /* CHTML 1.0 (W3C version 3.2)                                          */
       /*----------------------------------------------------------------------*/
-      align = apr_pstrdup(r->pool, val);
+      align = apr_pstrdup(doc->buf.pool, val);
     }
   }
 
-  if (align)
+  if (align) {
+#if BUFFERED
+    W_L(" align=\"");
+    W_V(align);
+    W_L("\"");
+#else
     jhtml->out = apr_pstrcat(r->pool, 
                     jhtml->out, " align=\"", align, "\"", NULL);
-
+#endif
+  }
+#if BUFFERED
+  W_L(">");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2310,33 +2737,37 @@ s_jhtml_end_div_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</div>\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</div>\n", NULL);
+#endif
 
   return jhtml->out;
 }
 
 
 static char *
-chxj_istyle_to_mode(request_rec *r, const char *s)
+chxj_istyle_to_mode(Doc *doc, const char *s)
 {
   char *tmp;
 
   if (s) {
     switch (s[0]) {
-    case '1': return apr_psprintf(r->pool, "hiragana");
-    case '2': return apr_psprintf(r->pool, "hankakukana");
-    case '3': return apr_psprintf(r->pool, "alphabet");
-    case '4': return apr_psprintf(r->pool, "numeric");
+    case '1': return apr_psprintf(doc->buf.pool, "hiragana");
+    case '2': return apr_psprintf(doc->buf.pool, "hankakukana");
+    case '3': return apr_psprintf(doc->buf.pool, "alphabet");
+    case '4': return apr_psprintf(doc->buf.pool, "numeric");
     default: 
-      tmp = apr_palloc(r->pool, 1);
+      tmp = apr_palloc(doc->buf.pool, 1);
       tmp[0] = '\0';
-      return apr_pstrdup(r->pool, tmp);
+      return apr_pstrdup(doc->buf.pool, tmp);
     }
   }
 
-  tmp = apr_palloc(r->pool, 1);
+  tmp = apr_palloc(doc->buf.pool, 1);
   tmp[0] = '\0';
-  return apr_pstrdup(r->pool,tmp);
+  return apr_pstrdup(doc->buf.pool,tmp);
 }
 
 
@@ -2355,7 +2786,11 @@ s_jhtml_chxjif_tag(void *pdoc, Node *node)
   for (child = qs_get_child_node(doc, node);
        child;
        child = qs_get_next_node(doc, child)) {
+#if BUFFERED
+    W_V(child->otext);
+#else
     jhtml->out = apr_pstrcat(r->pool, jhtml->out, child->otext, NULL);
+#endif
     s_jhtml_chxjif_tag(jhtml, child);
   }
   return NULL;
@@ -2383,31 +2818,53 @@ s_jhtml_start_textarea_tag(void *pdoc, Node *node)
   r     = doc->r;
 
   jhtml->textarea_flag++;
+#if BUFFERED
+  W_L("<textarea ");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<textarea ", NULL);
-
+#endif
   for (attr = qs_get_attr(doc,node);
        attr;
        attr = qs_get_next_attr(doc,attr)) {
     char *name;
     char *value;
-
     name  = qs_get_attr_name(doc,attr);
     value = qs_get_attr_value(doc,attr);
-
-    if ((*name == 'n' || *name == 'N') && strcasecmp(name, "name") == 0) {
+    if (STRCASEEQ('n','N',"name",name)) {
+#if BUFFERED
+      char *vv = chxj_jreserved_to_safe_tag(r, value);
+      W_L(" name=\"");
+      W_V(vv);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, jhtml->out, " name=\"",chxj_jreserved_to_safe_tag(r, value),"\"", NULL);
+#endif
     }
-    else 
-    if ((*name == 'r' || *name == 'R') && strcasecmp(name, "rows") == 0) {
+    else if (STRCASEEQ('r','R',"rows",name)) {
+#if BUFFERED
+      W_L(" rows=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, jhtml->out, " rows=\"",value,"\"", NULL);
+#endif
     }
-    else 
-    if ((*name == 'c' || *name == 'C') && strcasecmp(name, "cols") == 0) {
+    else if (STRCASEEQ('c','C',"cols",name)) {
+#if BUFFERED
+      W_L(" cols=\"");
+      W_V(value);
+      W_L("\"");
+#else
       jhtml->out = apr_pstrcat(r->pool, jhtml->out, " cols=\"",value,"\"", NULL);
+#endif
     }
   }
 
+#if BUFFERED
+  W_L(">\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, ">\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2432,7 +2889,11 @@ s_jhtml_end_textarea_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</textarea>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</textarea>\r\n", NULL);
+#endif
   jhtml->textarea_flag--;
 
   return jhtml->out;
@@ -2458,7 +2919,11 @@ s_jhtml_start_b_tag(void *pdoc, Node *UNUSED(node))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<b>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<b>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2477,9 +2942,12 @@ s_jhtml_end_b_tag(void *pdoc, Node *UNUSED(child))
 {
   jhtml_t       *jhtml = GET_JHTML(pdoc);
   Doc           *doc   = jhtml->doc;
-  request_rec   *r     = doc->r;
 
+#if BUFFERED
+  W_L("</b>\r\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</b>\r\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2503,8 +2971,9 @@ s_jhtml_text_tag(void *pdoc, Node *child)
 
   textval = qs_get_node_value(doc,child);
   textval = qs_trim_string(r->pool, textval);
-  if (strlen(textval) == 0)
+  if (strlen(textval) == 0) {
     return jhtml->out;
+  }
 
   tmp = apr_palloc(r->pool, qs_get_node_size(doc,child)+1);
   memset(tmp, 0, qs_get_node_size(doc,child)+1);
@@ -2538,7 +3007,11 @@ s_jhtml_text_tag(void *pdoc, Node *child)
       }
     }
   }
+#if BUFFERED
+  W_V(tdst);
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, tdst, NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2565,7 +3038,11 @@ s_jhtml_start_dl_tag(void *pdoc, Node *UNUSED(child))
   r     = doc->r;
 
 
+#if BUFFERED
+  W_L("<dl>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<dl>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2590,7 +3067,11 @@ s_jhtml_end_dl_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("</dl>\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "</dl>\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2615,8 +3096,11 @@ s_jhtml_start_dt_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
-
+#if BUFFERED
+  W_L("<dt>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<dt>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2642,7 +3126,11 @@ s_jhtml_end_dt_tag(void *pdoc, Node *UNUSED(child))
   r     = doc->r;
 
 
+#if BUFFERED
+  W_L("\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "\n", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2667,7 +3155,11 @@ s_jhtml_start_dd_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("<dd>");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "<dd>", NULL);
+#endif
 
   return jhtml->out;
 }
@@ -2692,7 +3184,11 @@ s_jhtml_end_dd_tag(void *pdoc, Node *UNUSED(child))
   doc   = jhtml->doc;
   r     = doc->r;
 
+#if BUFFERED
+  W_L("\n");
+#else
   jhtml->out = apr_pstrcat(r->pool, jhtml->out, "\n", NULL);
+#endif
 
   return jhtml->out;
 }