From 1b52e3534abc05d0549295de669eaaf358f4a799 Mon Sep 17 00:00:00 2001 From: visor Date: Mon, 30 Jun 2014 21:49:09 +0900 Subject: [PATCH] query-string function. --- lib/form.cc | 33 ++++---- lib/form.h | 2 +- modules/ml-formvar.cc | 19 +++++ modules/ml-formvar.h | 1 + modules/ml-xml.cc | 209 ++++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 206 insertions(+), 58 deletions(-) diff --git a/lib/form.cc b/lib/form.cc index 4ecb562..f8f3854 100644 --- a/lib/form.cc +++ b/lib/form.cc @@ -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 () { diff --git a/lib/form.h b/lib/form.h index 3f08a94..bb78ce2 100644 --- a/lib/form.h +++ b/lib/form.h @@ -37,7 +37,7 @@ class CGIForm { method_type method; content_type contentType; ustring boundary; /* multipart boundary */ - ustring postData; + ustring queryString; CGIForm () { method = methodType (); diff --git a/modules/ml-formvar.cc b/modules/ml-formvar.cc index 68a7dd7..2b465b0 100644 --- a/modules/ml-formvar.cc +++ b/modules/ml-formvar.cc @@ -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; +} diff --git a/modules/ml-formvar.h b/modules/ml-formvar.h index 1180f7b..a2a33e0 100644 --- a/modules/ml-formvar.h +++ b/modules/ml-formvar.h @@ -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 */ diff --git a/modules/ml-xml.cc b/modules/ml-xml.cc index 831d7ef..2f0ac6c 100644 --- a/modules/ml-xml.cc +++ b/modules/ml-xml.cc @@ -11,6 +11,7 @@ #include #include #include +#include /*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 data; expat exp (false); int rc; + std::vector params; + std::vector 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, ¶ms, 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 data; expat exp; FileMacro fp; size_t s; + std::vector params; + std::vector 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, ¶ms, 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 params; std::vector keywords; static paramList kwlist[] = { {CharConst ("continue"), true}, + {CharConst ("sxml"), true}, {NULL, 0, 0} }; setParams (arg, 1, ¶ms, 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 params; + std::vector keywords; + static paramList kwlist[] = { + {CharConst ("sxml"), true}, // 0 + {NULL, 0, 0} + }; - setParams (arg, 1, ¶ms, NULL, NULL, NULL); + setParams (arg, 1, ¶ms, 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 data; expat exp (false); + std::vector 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 (); } -- 2.11.0