OSDN Git Service

query-string function.
authorvisor <visor@users.sourceforge.jp>
Mon, 30 Jun 2014 12:49:09 +0000 (21:49 +0900)
committervisor <visor@users.sourceforge.jp>
Mon, 30 Jun 2014 12:49:09 +0000 (21:49 +0900)
lib/form.cc
lib/form.h
modules/ml-formvar.cc
modules/ml-formvar.h
modules/ml-xml.cc

index 4ecb562..f8f3854 100644 (file)
@@ -34,26 +34,25 @@ void  CGIForm::parseURLEncoded (const ustring& query) {
 }
 
 void  CGIForm::read_get () {
-    ustring  q = getenvString (kQUERY_STRING);
-    if (q.length () > 0) {
-       parseURLEncoded (q);
+    queryString = getenvString (kQUERY_STRING);
+    if (queryString.length () > 0) {
+       parseURLEncoded (queryString);
     }
 }
 
 void  CGIForm::read_post (size_t limit) {
     size_t  size;
-    ustring  q;
 
     size = postSize ();
     if (size == 0 || size > limit)
        return;
-    q.reserve (size);
-    q.resize (size);
-    assert (&q[0] == q.data ());
-    std::cin.read (&q[0], size);
-    q.resize (std::cin.gcount ());
-    if (q.length () == size) {
-       parseURLEncoded (q);
+    queryString.reserve (size);
+    queryString.resize (size);
+    assert (&queryString[0] == queryString.data ());
+    std::cin.read (&queryString[0], size);
+    queryString.resize (std::cin.gcount ());
+    if (queryString.length () == size) {
+       parseURLEncoded (queryString);
     }
 }
 
@@ -63,12 +62,12 @@ void  CGIForm::read_raw (size_t limit) {
     size = postSize ();
     if (size == 0 || size > limit)
        return;
-    postData.reserve (size);
-    postData.resize (size);
-    assert (&postData[0] == postData.data ());
-    std::cin.read (&postData[0], size);
-    postData.resize (std::cin.gcount ());
-    fix (postData);
+    queryString.reserve (size);
+    queryString.resize (size);
+    assert (&queryString[0] == queryString.data ());
+    std::cin.read (&queryString[0], size);
+    queryString.resize (std::cin.gcount ());
+    fix (queryString);
 }
 
 CGIForm::method_type  CGIForm::methodType () {
index 3f08a94..bb78ce2 100644 (file)
@@ -37,7 +37,7 @@ class  CGIForm {
     method_type  method;
     content_type  contentType;
     ustring  boundary;         /* multipart boundary */
-    ustring  postData;
+    ustring  queryString;
 
     CGIForm () {
        method = methodType ();
index 68a7dd7..2b465b0 100644 (file)
@@ -518,3 +518,22 @@ MNode*  ml_read_query_string (MNode* cell, MlEnv* mlenv) {
 
     return NULL;
 }
+
+/*DOC:
+===query-string===
+ (query-string) -> TEXT
+
+*/
+//#AFUNC       query-string    ml_query_string
+MNode*  ml_query_string (MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+
+    if (arg)
+       throw (uErrorWrongNumber);
+
+    if (mlenv->env && mlenv->env->form) {
+       return newMNode_str (new ustring (mlenv->env->form->queryString));
+    }
+
+    return NULL;
+}
index 1180f7b..a2a33e0 100644 (file)
@@ -47,5 +47,6 @@ MNode*  ml_formvar_input_bool (MNode* cell, MlEnv* mlenv);
 MNode*  ml_formvar_input_file (MNode* cell, MlEnv* mlenv);
 MNode*  ml_formvar_input_file_a (MNode* cell, MlEnv* mlenv);
 MNode*  ml_read_query_string (MNode* cell, MlEnv* mlenv);
+MNode*  ml_query_string (MNode* cell, MlEnv* mlenv);
 
 #endif /* ML_FORMVAR_H */
index 831d7ef..2f0ac6c 100644 (file)
@@ -11,6 +11,7 @@
 #include <expat.h>
 #include <exception>
 #include <vector>
+#include <memory>
 
 /*DOC:
 ==xml module==
@@ -72,17 +73,93 @@ public:
            ptr.pop_back ();
        }
     };
+
+    virtual void  newNode (const XML_Char* name, const XML_Char** atts) = 0;
+    virtual void  addText (const ustring& s) = 0;
+    virtual void  endNode () = 0;
+};
+
+class  xmlReaderData_rg: public xmlReaderData {
+public:
+    xmlReaderData_rg () {};
+    virtual  ~xmlReaderData_rg () {};
+
     virtual void  newNode (const XML_Char* name, const XML_Char** atts) {
        MNodeList  a;
        a.append (newMNode_sym (new ustring (fixUTF8 (ustring (name)))));
        a.append (NULL);
        for (; *atts; ) {
-#if 0
-           a.append (newMNode_sym (new ustring (fixUTF8 (ustring (*atts)))));
+           MNode*  c = new MNode;
+           c->set_car (newMNode_sym (new ustring (fixUTF8 (ustring (*atts)))));
            atts ++;
-           a.append (newMNode_str (new ustring (fixUTF8 (ustring (*atts)))));
+           c->set_cdr (newMNode_str (new ustring (fixUTF8 (ustring (*atts)))));
            atts ++;
-#endif
+           a.append (c);
+       }
+       ptr.push_back (a.release ());
+       mode.push_back (M_START);
+       text.resize (0);
+    };
+    virtual void  addText (const ustring& s) {
+       mode_t  m = mode.back ();
+
+       if (m == M_START || m == M_TEXT) {
+           text.append (s);
+           mode.back () = M_TEXT;
+       }
+    };
+    virtual void  endNode () {
+       MNode*  a = ptr.back ();
+       mode_t  m = mode.back ();
+
+       ptr.pop_back ();
+       mode.pop_back ();
+
+       switch (m) {
+       case M_START:
+           break;
+       case M_TEXT:
+           a->cdr ()->set_car (newMNode_str (new ustring (text)));
+           break;
+       case M_CHILD:
+           break;
+       default:;
+       }
+       if (ptr.size () == 0) {
+           ans = a;
+       } else {
+           if (! ptr.back ()->cdr ()->car ()) {
+               MNode*  c = new MNode;
+               c->set_car (a);
+               ptr.back ()->cdr ()->set_car (c);
+           } else if (ptr.back ()->cdr ()->car ()->isCons ()) {
+               MNode*  c = ptr.back ()->cdr ()->car ();
+               MNode*  d = new MNode;
+
+               while (c->cdr ()) {
+                   c = c->cdr ();
+               }
+               c->set_cdr (d);
+               d->set_car (a);
+           } else {
+               assert (0);
+           }
+           mode.back () = M_CHILD;
+       }
+    };
+};
+
+class  xmlReaderData_sxml: public xmlReaderData {
+public:
+    xmlReaderData_sxml () {};
+    virtual  ~xmlReaderData_sxml () {};
+
+    // ******
+    virtual void  newNode (const XML_Char* name, const XML_Char** atts) {
+       MNodeList  a;
+       a.append (newMNode_sym (new ustring (fixUTF8 (ustring (name)))));
+       a.append (NULL);
+       for (; *atts; ) {
            MNode*  c = new MNode;
            c->set_car (newMNode_sym (new ustring (fixUTF8 (ustring (*atts)))));
            atts ++;
@@ -160,7 +237,7 @@ static void  xmltext (void *data, const XML_Char *s, int len) {
 
 /*DOC:
 ===xml-read===
- (xml-read TEXT) -> LIST
+ (xml-read TEXT [#sxml | :sxml BOOL]) -> LIST
 
 */
 //#AFUNC       xml-read        ml_xml_read
@@ -168,19 +245,37 @@ static void  xmltext (void *data, const XML_Char *s, int len) {
 MNode*  ml_xml_read (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     ustring  text;
-    xmlReaderData  data;
+    bool  fsxml = false;
+//    xmlReaderData_rg  data;
+    std::auto_ptr<xmlReaderData>  data;
     expat  exp (false);
     int  rc;
+    std::vector<MNode*>  params;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("sxml"), true}, // 0
+       {NULL, 0, 0}
+    };
 
+#if 0
     if (! arg)
        throw (uErrorWrongNumber);
     text = eval_str (arg->car (), mlenv);
     nextNode (arg);
     if (arg)
        throw (uErrorWrongNumber);
-
+#endif
+    setParams (arg, 1, &params, kwlist, &keywords, NULL);
+    text = eval_str (params[0], mlenv);
+    if (keywords[0])
+       fsxml = eval_bool (keywords[0], mlenv);
+
+    if (fsxml)
+       data.reset (new xmlReaderData_sxml);
+    else
+       data.reset (new xmlReaderData_rg);
     exp.setElementHandler (xmlstart, xmlend, xmltext);
-    exp.setUserData (&data);
+    exp.setUserData (data.get ());
     rc = exp.parse (text.data (), text.length (), true);
 #ifdef DEBUG
     if (! rc) {
@@ -189,15 +284,15 @@ MNode*  ml_xml_read (MNode* cell, MlEnv* mlenv) {
 #endif /* DEBUG */
 
 #ifdef DEBUG2
-    std::cerr << data.ans ()->dump_string () << "\n";
+    std::cerr << data->ans ()->dump_string () << "\n";
 #endif /* DEBUG */
 
-    return data.ans.release ();
+    return data->ans.release ();
 }
 
 /*DOC:
 ===xml-read-file===
- (xml-read-file FILENAME) -> LIST
+ (xml-read-file FILENAME [#sxml | :sxml BOOL]) -> LIST
 
  Element ::= (list TagName ElementBody Attribute* )
  Attribute ::= (cons AttributeName AttributeValue )
@@ -214,25 +309,43 @@ MNode*  ml_xml_read (MNode* cell, MlEnv* mlenv) {
 MNode*  ml_xml_read_file (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     ustring  filename;
-    xmlReaderData  data;
+    bool  fsxml = false;
+//    xmlReaderData_rg  data;
+    std::auto_ptr<xmlReaderData>  data;
     expat  exp;
     FileMacro  fp;
     size_t  s;
+    std::vector<MNode*>  params;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("sxml"), true}, // 0
+       {NULL, 0, 0}
+    };
 
+#if 0
     if (! arg)
        throw (uErrorWrongNumber);
     filename = eval_str (arg->car (), mlenv);
     nextNode (arg);
     if (arg)
        throw (uErrorWrongNumber);
-
+#endif
+    setParams (arg, 1, &params, kwlist, &keywords, NULL);
+    filename = eval_str (params[0], mlenv);
+    if (keywords[0])
+       fsxml = eval_bool (keywords[0], mlenv);
+
+    if (fsxml)
+       data.reset (new xmlReaderData_sxml);
+    else
+       data.reset (new xmlReaderData_rg);
     if (mlenv->env->storedir.empty ())
        throw (uErrorNoStore);
     filename = mlenv->env->path_store_file (filename);
 
     if (fp.openRead (filename.c_str ())) {
        exp.setElementHandler (xmlstart, xmlend, xmltext);
-       exp.setUserData (&data);
+       exp.setUserData (data.get ());
        while (1) {
            s = fp.read (exp.buff, exp.buffsize);
            exp.parse (s, (s == 0));
@@ -243,10 +356,10 @@ MNode*  ml_xml_read_file (MNode* cell, MlEnv* mlenv) {
     }
 
 #ifdef DEBUG2
-    std::cerr << data.ans ()->dump_string () << "\n";
+    std::cerr << data->ans ()->dump_string () << "\n";
 #endif /* DEBUG */
 
-    return data.ans.release ();
+    return data->ans.release ();
 }
 
 static void  xmlWrite (MotorOutput* out, MNode* list) {
@@ -259,17 +372,6 @@ static void  xmlWrite (MotorOutput* out, MNode* list) {
            c = list->car ();
            d = list->cdr ();
            out->out_raw (CharConst ("<"))->out_toHTML_noCtrl (*name);
-#if 0
-           while (d && d->isCons ()
-                  && d->cdr () && d->cdr ()->isCons ()) {
-               out->out_raw (uSPC)
-                   ->out_toHTML (to_string (d->car ()))
-                   ->out_raw (CharConst ("=\""))
-                   ->out_toHTML (to_string (d->cdr ()->car ()))
-                   ->out_raw (uQ2);
-               d = d->cdr ()->cdr ();
-           }
-#endif
            while (d && d->isCons ()) {
                if (d->car () && d->car ()->isCons ()) {
                    out->out_raw (uSPC)
@@ -309,7 +411,7 @@ static void  xmlWrite (MotorOutput* out, MNode* list) {
 
 /*DOC:
 ===xml-output===
- (xml-output [#continue | :continue BOOL] LIST) -> NIL
+ (xml-output [#continue | :continue BOOL] [#sxml | :sxml BOOL] LIST) -> NIL
 
 */
 //#AFUNC       xml-output      ml_xml_output
@@ -317,17 +419,21 @@ MNode*  ml_xml_output (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     MNodePtr  xml;
     bool  cflag = false;
+    bool  fsxml = false;
     std::vector<MNode*>  params;
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
        {CharConst ("continue"), true},
+       {CharConst ("sxml"), true},
        {NULL, 0, 0}
     };
 
     setParams (arg, 1, &params, kwlist, &keywords, NULL);
     xml = eval (params[0], mlenv);
-    if (keywords[0] && eval_bool (keywords[0], mlenv))
-       cflag = true;
+    if (keywords[0])
+       cflag = eval_bool (keywords[0], mlenv);
+    if (keywords[1])
+       fsxml = eval_bool (keywords[1], mlenv);
 
     if (! mlenv->env->responseDone)
        mlenv->env->standardResponse (ustring (CharConst (kMIME_XML)), ustring (uUTF8), uEmpty, false);
@@ -345,7 +451,7 @@ MNode*  ml_xml_output (MNode* cell, MlEnv* mlenv) {
 
 /*DOC:
 ===xml-output-string===
- (xml-output LIST) -> STRING
+ (xml-output LIST [#sxml | :sxml BOOL]) -> STRING
 
 */
 //#AFUNC       xml-output-string       ml_xml_output_string
@@ -353,10 +459,18 @@ MNode*  ml_xml_output (MNode* cell, MlEnv* mlenv) {
 MNode*  ml_xml_output_string (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     MNodePtr  xml;
+    bool  fsxml = false;
     std::vector<MNode*>  params;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("sxml"), true}, // 0
+       {NULL, 0, 0}
+    };
 
-    setParams (arg, 1, &params, NULL, NULL, NULL);
+    setParams (arg, 1, &params, kwlist, &keywords, NULL);
     xml = eval (params[0], mlenv);
+    if (keywords[0])
+       fsxml = eval_bool (keywords[0], mlenv);
 
     if (! mlenv->env->responseDone)
        mlenv->env->standardResponse (ustring (CharConst (kMIME_XML)), ustring (uUTF8), uEmpty, false);
@@ -371,24 +485,39 @@ MNode*  ml_xml_output_string (MNode* cell, MlEnv* mlenv) {
 
 /*DOC:
 ===input-xml===
- (input-xml) -> LIST
+ (input-xml [#sxml | :sxml BOOL]) -> LIST
 
 */
 //#AFUNC       input-xml       ml_input_xml
 MNode*  ml_input_xml (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    xmlReaderData  data;
+    bool  fsxml = false;
+//    xmlReaderData_rg  data;
+    std::auto_ptr<xmlReaderData>  data;
     expat  exp (false);
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("sxml"), true}, // 0
+       {NULL, 0, 0}
+    };
 
-    if (arg)
-       throw (uErrorWrongNumber);
+//    if (arg)
+//     throw (uErrorWrongNumber);
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+    if (keywords[0])
+       fsxml = eval_bool (keywords[0], mlenv);
+
+    if (fsxml)
+       data.reset (new xmlReaderData_sxml);
+    else
+       data.reset (new xmlReaderData_rg);
     exp.setElementHandler (xmlstart, xmlend, xmltext);
-    exp.setUserData (&data);
-    exp.parse (mlenv->env->form->postData.data (), mlenv->env->form->postData.length (), true);
+    exp.setUserData (data.get ());
+    exp.parse (mlenv->env->form->queryString.data (), mlenv->env->form->queryString.length (), true);
 
 #ifdef DEBUG2
-    std::cerr << data.ans ()->dump_string () << "\n";
+    std::cerr << data->ans ()->dump_string () << "\n";
 #endif /* DEBUG */
 
-    return data.ans.release ();
+    return data->ans.release ();
 }