Diff for /parser3/src/classes/xdoc.C between versions 1.149 and 1.167

version 1.149, 2005/12/16 10:15:12 version 1.167, 2011/05/25 03:54:46
Line 1 Line 1
 /** @file  /** @file
         Parser: @b xdoc parser class.          Parser: @b xdoc parser class.
   
         Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
Line 33  static const char * const IDENT_XDOC_C=" Line 33  static const char * const IDENT_XDOC_C="
   
 #define XDOC_CLASS_NAME "xdoc"  #define XDOC_CLASS_NAME "xdoc"
   
 #define XDOC_OUTPUT_METHOD_OPTION_NAME "method"  
 #define XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "xml"  
 #define XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "html"  
 #define XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "text"  
   
 // class  // class
   
 class MXdoc: public MXnode {  class MXdoc: public MXnode {
 public: // VStateless_class  public: // VStateless_class
         Value* create_new_value(Pool&, HashStringValue&) { return new VXdoc(); }          Value* create_new_value(Pool&) { return new VXdoc(); }
   
 public:  public:
         MXdoc();          MXdoc();
Line 158  private: Line 153  private:
   
 static void writeNode(Request& r, VXdoc& xdoc, xmlNode* node) {  static void writeNode(Request& r, VXdoc& xdoc, xmlNode* node) {
         if(!node)          if(!node)
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         0,                          0,
                         "error creating node"); // OOM, bad name, things like that                          "error creating node"); // OOM, bad name, things like that
   
Line 237  static void _createElementNS(Request& r, Line 232  static void _createElementNS(Request& r,
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         // namespaceURI;localName          // namespaceURI;localName
         xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         xmlChar* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string");          xmlChar* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string");
   
         xmlChar* prefix=0;          xmlChar* prefix=0;
Line 266  static void _createTextNode(Request& r, Line 261  static void _createTextNode(Request& r,
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         xmlChar* data=as_xmlchar(r, params, 0, "data must be string");          xmlChar* data=as_xmlchar(r, params, 0, DATA_MUST_BE_STRING);
   
         xmlNode *node=xmlNewDocText(&xmldoc, data);          xmlNode *node=xmlNewDocText(&xmldoc, data);
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
Line 276  static void _createTextNode(Request& r, Line 271  static void _createTextNode(Request& r,
 static void _createComment(Request& r, MethodParams& params) {  static void _createComment(Request& r, MethodParams& params) {
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
   
         xmlChar* data=as_xmlchar(r, params, 0, "data must be string");          xmlChar* data=as_xmlchar(r, params, 0, DATA_MUST_BE_STRING);
   
         xmlNode *node=xmlNewComment(data);          xmlNode *node=xmlNewComment(data);
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
Line 287  static void _createCDATASection(Request& Line 282  static void _createCDATASection(Request&
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         xmlChar* data=as_xmlchar(r, params, 0, "data must be string");          xmlChar* data=as_xmlchar(r, params, 0, DATA_MUST_BE_STRING);
   
         xmlNode *node=xmlNewCDataBlock(&xmldoc, data, strlen((const char*)data));          xmlNode *node=xmlNewCDataBlock(&xmldoc, data, strlen((const char*)data));
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
Line 298  static void _createProcessingInstruction Line 293  static void _createProcessingInstruction
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         xmlChar* target=as_xmlchar(r, params, 0, "data must be string");          xmlChar* target=as_xmlchar(r, params, 0, DATA_MUST_BE_STRING);
         xmlChar* data=as_xmlchar(r, params, 1, "data must be string");          xmlChar* data=as_xmlchar(r, params, 1, DATA_MUST_BE_STRING);
   
         xmlNode *node=xmlNewDocPI(&xmldoc, target, data);          xmlNode *node=xmlNewDocPI(&xmldoc, target, data);
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
Line 310  static void _createAttribute(Request& r, Line 305  static void _createAttribute(Request& r,
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         xmlChar* name=as_xmlchar(r, params, 0, "name must be string");          xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         xmlNode *node=(xmlNode*)xmlNewDocProp(&xmldoc, name, 0);          xmlNode *node=(xmlNode*)xmlNewDocProp(&xmldoc, name, 0);
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
Line 321  static void _createAttributeNS(Request& Line 316  static void _createAttributeNS(Request&
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         xmlChar* qualifiedName=as_xmlchar(r, params, 1, "name must be string");          xmlChar* qualifiedName=as_xmlchar(r, params, 1, NAME_MUST_BE_STRING);
   
         xmlChar* prefix=0;          xmlChar* prefix=0;
         xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);          xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);
Line 342  static void _createEntityReference(Reque Line 337  static void _createEntityReference(Reque
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         xmlChar* name=as_xmlchar(r, params, 0, "name must be string");          xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         xmlNode *node=xmlNewReference(&xmldoc, name);          xmlNode *node=xmlNewReference(&xmldoc, name);
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
Line 391  static void _create(Request& r, MethodPa Line 386  static void _create(Request& r, MethodPa
                 Temp_lang temp_lang(r, String::L_XML);                  Temp_lang temp_lang(r, String::L_XML);
                 const String& xml=r.process_to_string(param);                  const String& xml=r.process_to_string(param);
   
                 const char* cstr=xml.cstr(String::L_UNSPECIFIED, 0, &r.charsets);                  String::Body sbody=xml.cstr_to_string_body_untaint(r.flang, 0, &r.charsets);
                 xmldoc=xmlParseMemory(cstr, strlen(cstr));                  xmldoc=xmlParseMemory(sbody.cstr(), sbody.length());
   
                 //printf("document=0x%p\n", document);                  //printf("document=0x%p\n", document);
                 if(!xmldoc || xmlHaveGenericErrors())                  if(!xmldoc || xmlHaveGenericErrors())
                         throw XmlException(0);                          throw XmlException(0);
   
                 // must be last action in if, see after if}                  // must be last action in if, see after if}
         } else { // [localName]          } else { // [localName]
                 xmlChar* localName=r.transcode(param.as_string());                  if(const String* value = param.get_string()){
                           xmlChar* localName=r.transcode(*value);
 #if 0  #if 0
                 GdomeDocumentType *documentType=gdome_di_createDocumentType (                          GdomeDocumentType *documentType=gdome_di_createDocumentType (
                         docimpl,                                   docimpl, 
                         r.transcode(qualifiedName),                                   r.transcode(qualifiedName), 
                         0/*publicId*/,                                   0/*publicId*/, 
                         0/*systemId*/,                                   0/*systemId*/, 
                         &exc);                                  &exc);
                 if(!documentType || exc || xmlHaveGenericErrors())                          if(!documentType || exc || xmlHaveGenericErrors())
                         throw Exception(                                  throw Exception(
                                 method_name,                                           method_name, 
                                 exc);                                          exc);
                 /// +xalan createXMLDecl ?                          /// +xalan createXMLDecl ?
 #endif  #endif
                 xmldoc=xmlNewDoc(0);                          xmldoc=xmlNewDoc(0);
                 if(!xmldoc || xmlHaveGenericErrors())                          if(!xmldoc || xmlHaveGenericErrors())
                         throw XmlException(0);                                  throw XmlException(0);
                 xmlNode* node=xmlNewChild((xmlNode*)xmldoc, NULL, localName, NULL);                          xmlNode* node=xmlNewChild((xmlNode*)xmldoc, NULL, localName, NULL);
                 if(!node || xmlHaveGenericErrors())                          if(!node || xmlHaveGenericErrors())
                         throw XmlException(0);                                  throw XmlException(0);
   
                 set_encoding=true;                          set_encoding=true;
                 // must be last action in if, see after if}                          // must be last action in if, see after if}
                   } else {
                           VFile* vfile=param.as_vfile(String::L_AS_IS);
                           xmldoc=xmlParseMemory(vfile->value_ptr(), vfile->value_size());
                           if(!xmldoc || xmlHaveGenericErrors())
                                   throw XmlException(0);
                   }
         }          }
         // must be first action after if}          // must be first action after if}
         // replace any previous parsed source          // replace any previous parsed source
Line 448  static void _load(Request& r, MethodPara Line 450  static void _load(Request& r, MethodPara
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
   
         // filespec          // filespec
         const String* uri=&params.as_string(0, "uri must be string");          const String* uri=&params.as_string(0, "URI must be string");
         const char* uri_cstr;          const char* uri_cstr;
         if(uri->pos("://")==STRING_NOT_FOUND) // disk path          if(uri->pos("://")==STRING_NOT_FOUND) // disk path
                 uri_cstr=r.absolute(*uri).cstr(String::L_FILE_SPEC);                  uri_cstr=r.absolute(*uri).taint_cstr(String::L_FILE_SPEC);
         else // xxx://           else // xxx:// 
                 uri_cstr=uri->cstr(String::L_AS_IS); // leave as-is for xmlParseFile to handle                  uri_cstr=uri->taint_cstr(String::L_AS_IS); // leave as-is for xmlParseFile to handle
   
         /// todo!! add SAFE MODE!!          /// @todo!! add SAFE MODE!!
         xmlDoc* xmldoc=xmlParseFile(uri_cstr);          xmlDoc* xmldoc=xmlParseFile(uri_cstr);
         if(!xmldoc || xmlHaveGenericErrors())          if(!xmldoc || xmlHaveGenericErrors())
                 throw XmlException(uri);                  throw XmlException(uri);
Line 465  static void _load(Request& r, MethodPara Line 467  static void _load(Request& r, MethodPara
         vdoc.set_xmldoc(r.charsets, *xmldoc);           vdoc.set_xmldoc(r.charsets, *xmldoc); 
 }  }
   
 static void param_option_over_output_option(  String::C xdoc2buf(Request& r, VXdoc& vdoc, 
                                             HashStringValue& param_options, const char* option_name,                                          XDocOutputOptions& oo,
                                             const String*& output_option) {                                          const String* file_spec,
         if(Value* value=param_options.get(String::Body(option_name)))                                          bool use_source_charset_to_render_and_client_charset_to_write_to_header=false) {
                 output_option=&value->as_string();  
 }  
 static void param_option_over_output_option(  
                                             HashStringValue& param_options, const char* option_name,  
                                             int& output_option) {  
         if(Value* value=param_options.get(String::Body(option_name))) {  
                 const String& s=value->as_string();  
                 if(s=="yes")  
                         output_option=1;  
                 else if(s=="no")  
                         output_option=0;  
                 else  
                         throw Exception("parser.runtime",  
                                 &s,  
                                 "%s must be either 'yes' or 'no'", option_name);  
         }  
 }  
   
 /// @test valid_options check  
 static void prepare_output_options(Request& r,  
                                    MethodParams& params, size_t index,  
                                    VXdoc::Output_options& oo) {  
 /*  
 <xsl:output  
   !method = "xml" | "html" | "text" | qname-but-not-ncname   
   !version = nmtoken   
   !encoding = string   
   !omit-xml-declaration = "yes" | "no"  
   !standalone = "yes" | "no"  
   !doctype-public = string   
   !doctype-system = string   
   cdata-section-elements = qnames   
   !indent = "yes" | "no"  
   !media-type = string />   
 */  
   
         // configuring with options from parameter...  
         if(params.count()>index) {  
                 Value& voptions=params.as_no_junction(index, "options must be string");  
                 if(voptions.is_defined()) {  
                         if(HashStringValue *options=voptions.get_hash()) {  
                                 // $.method[xml|html|text]  
                                 if(Value* vmethod=options->get(String::Body(XDOC_OUTPUT_METHOD_OPTION_NAME)))  
                                         oo.method=&vmethod->as_string();  
   
                                 // $.version[1.0]  
                                 param_option_over_output_option(*options, "version", oo.version);  
                                 // $.encoding[windows-1251|...]  
                                 param_option_over_output_option(*options, "encoding", oo.encoding);  
                                 // $.omit-xml-declaration[yes|no]  
                                 param_option_over_output_option(*options, "omit-xml-declaration", oo.omitXmlDeclaration);  
                                 // $.standalone[yes|no]  
                                 param_option_over_output_option(*options, "standalone", oo.standalone);  
                                 // $.indent[yes|no]  
                                 param_option_over_output_option(*options, "indent", oo.indent);  
                                 // $.media-type[text/{html|xml|plain}]  
                                 param_option_over_output_option(*options, "media-type", oo.mediaType);                             
                         }  
                 }  
         }  
   
         // default encoding from pool  
         if(!oo.encoding)  
                 oo.encoding=new String(r.charsets.source().NAME(), String::L_TAINTED);  
         // default method=xml  
         if(!oo.method)  
                 oo.method=new String(XDOC_OUTPUT_METHOD_OPTION_VALUE_XML);  
         // default mediaType = depending on method  
         if(!oo.mediaType) {  
                 if(*oo.method==XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)  
                         oo.mediaType=new String("text/xml");  
                 else if(*oo.method==XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)  
                         oo.mediaType=new String("text/html");  
                 else // XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT & all others  
                         oo.mediaType=new String("text/plain");  
         }  
 }  
   
 struct Xdoc2buf_result {  
         char* str;  
         size_t length;  
 };  
 static Xdoc2buf_result xdoc2buf(Request& r, VXdoc& vdoc,   
                                          MethodParams& params, int index,  
                                          VXdoc::Output_options& oo,  
                                          const String* file_spec,  
                                          bool use_source_charset_to_render_and_client_charset_to_write_to_header=false) {  
         Xdoc2buf_result result;  
         prepare_output_options(r, params, index,  
                 oo);  
   
         const char* render_encoding;          const char* render_encoding;
         const char* header_encoding;          const char* header_encoding;
         if(use_source_charset_to_render_and_client_charset_to_write_to_header) {          if(use_source_charset_to_render_and_client_charset_to_write_to_header) {
Line 571  static Xdoc2buf_result xdoc2buf(Request& Line 482  static Xdoc2buf_result xdoc2buf(Request&
   
         xmlCharEncodingHandler *renderer=xmlFindCharEncodingHandler(render_encoding);          xmlCharEncodingHandler *renderer=xmlFindCharEncodingHandler(render_encoding);
         if(!renderer)          if(!renderer)
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         0,                          0,
                         "encoding '%s' not supported", render_encoding);                          "encoding '%s' not supported", render_encoding);
         // UTF-8 renderer contains empty input/output converters,           // UTF-8 renderer contains empty input/output converters, 
Line 612  static Xdoc2buf_result xdoc2buf(Request& Line 523  static Xdoc2buf_result xdoc2buf(Request&
                 throw XmlException(0);                  throw XmlException(0);
   
         // write out result          // write out result
         char *gnome_str;  size_t gnome_length;          char *gnome_str;
           size_t gnome_length;
         if(outputBuffer->conv) {          if(outputBuffer->conv) {
                 gnome_length=outputBuffer->conv->use;                  gnome_length=outputBuffer->conv->use;
                 gnome_str=(char *)outputBuffer->conv->content;                  gnome_str=(char *)outputBuffer->conv->content;
Line 621  static Xdoc2buf_result xdoc2buf(Request& Line 533  static Xdoc2buf_result xdoc2buf(Request&
                 gnome_str=(char *)outputBuffer->buffer->content;                  gnome_str=(char *)outputBuffer->buffer->content;
         }          }
   
         if((result.length=gnome_length)) {          if(file_spec){
                 result.str=pa_strdup(gnome_str, gnome_length);                  file_write(r.charsets,
         } else                          *file_spec,
                 result.str=0;                          gnome_str,
                           gnome_length, 
         if(file_spec)  
                 file_write(*file_spec,  
                         gnome_str, gnome_length,   
                         true/*as_text*/);                          true/*as_text*/);
                   return String::C(); // actually, we don't need this output at all
           } else
                   return String::C(gnome_length ? pa_strdup(gnome_str, gnome_length) : 0, gnome_length);
   }
   
         return result;  inline HashStringValue* get_options(MethodParams& params, size_t index){
           return (params.count()>index) ? params.as_hash(index) : 0;
 }  }
   
 static void _file(Request& r, MethodParams& params) {  static void _file(Request& r, MethodParams& params) {
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         VXdoc::Output_options oo(vdoc.output_options);  
         Xdoc2buf_result buf=xdoc2buf(r, vdoc, params, 0,   
                 oo,  
                 0/*not to file, to memory*/);  
         // write out result  
         r.write_no_lang(String(buf.str, buf.length));  
   
         // write out result          XDocOutputOptions oo(r, get_options(params, 0));
           String::C buf=xdoc2buf(r, vdoc, oo, 0/*file_name. not to file, to memory*/);
   
         VFile& vfile=*new VFile;          VFile& vfile=*new VFile;
         VHash& vhcontent_type=*new VHash;          VHash& vhcontent_type=*new VHash;
         vhcontent_type.hash().put(          vhcontent_type.hash().put(
Line 655  static void _file(Request& r, MethodPara Line 565  static void _file(Request& r, MethodPara
   
         vfile.set(false/*tainted*/, buf.str?buf.str:""/*to distinguish from stat-ed file*/, buf.length,           vfile.set(false/*tainted*/, buf.str?buf.str:""/*to distinguish from stat-ed file*/, buf.length, 
                 0/*file_name*/, &vhcontent_type);                  0/*file_name*/, &vhcontent_type);
   
           // write out result
         r.write_no_lang(vfile);          r.write_no_lang(vfile);
 }  }
   
 static void _save(Request& r, MethodParams& params) {  static void _save(Request& r, MethodParams& params) {
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
   
         const String& file_spec=r.absolute(params.as_string(0, "file name must be string"));          const String& file_spec=r.absolute(params.as_string(0, FILE_NAME_MUST_BE_STRING));
                   
         VXdoc::Output_options oo(vdoc.output_options);          XDocOutputOptions oo(r, get_options(params, 1));
         xdoc2buf(r, vdoc, params, 1,           xdoc2buf(r, vdoc, oo, &file_spec);
                 oo,  
                 &file_spec);  
 }  }
   
 static void _string(Request& r, MethodParams& params) {  static void _string(Request& r, MethodParams& params) {
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
         VXdoc::Output_options oo(vdoc.output_options);  
         Xdoc2buf_result buf=xdoc2buf(r, vdoc, params, 0,           XDocOutputOptions oo(r, get_options(params, 0));
                 oo,          String::C buf=xdoc2buf(r, vdoc, oo,
                 0/*not to file, to memory*/,                  0/*file_name. not to file, to memory*/,
                 true/*use source charset to render, client charset to put to header*/);                  true/*use source charset to render, client charset to put to header*/);
   
         // write out result          // write out result
         r.write_no_lang(String(String::Body(buf.str), String::L_AS_IS));          r.write_no_lang(String(buf, String::L_AS_IS));
 }  }
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
Line 720  static VXdoc& _transform(Request& r, con Line 631  static VXdoc& _transform(Request& r, con
   
         //gdome_xml_doc_mkref dislikes XML_HTML_DOCUMENT_NODE  type, fixing          //gdome_xml_doc_mkref dislikes XML_HTML_DOCUMENT_NODE  type, fixing
         transformed->type=XML_DOCUMENT_NODE;          transformed->type=XML_DOCUMENT_NODE;
         // constructing result  
         VXdoc& result=*new VXdoc(r.charsets, *transformed);  
         /* grabbing options  
   
                 <xsl:output          // constructing result
                 !method = "xml" | "html" | "text"          return *new VXdoc(r.charsets, *transformed);
                         X| qname-but-not-ncname   
                 !version = nmtoken   
                 !encoding = string   
                 !omit-xml-declaration = "yes" | "no"  
                 !standalone = "yes" | "no"  
                 !doctype-public = string   
                 !doctype-system = string   
                 Xcdata-section-elements = qnames   
                 !indent = "yes" | "no"  
                 !media-type = string />   
         */  
         VXdoc::Output_options& oo=result.output_options;  
   
         oo.method=stylesheet->method?&r.transcode(stylesheet->method):0;  
         oo.encoding=stylesheet->encoding?&r.transcode(stylesheet->encoding):0;  
         oo.mediaType=stylesheet->mediaType?&r.transcode(stylesheet->mediaType):0;  
         oo.indent=stylesheet->indent;  
         oo.version=stylesheet->version?&r.transcode(stylesheet->version):0;  
         oo.standalone=stylesheet->standalone;  
         oo.omitXmlDeclaration=stylesheet->omitXmlDeclaration;  
   
         // return  
         return result;  
 }  }
 static void _transform(Request& r, MethodParams& params) {  static void _transform(Request& r, MethodParams& params) {
         VXdoc& vdoc=GET_SELF(r, VXdoc);          VXdoc& vdoc=GET_SELF(r, VXdoc);
Line 756  static void _transform(Request& r, Metho Line 641  static void _transform(Request& r, Metho
         // params          // params
         Array<const xmlChar*> transform_strings;          Array<const xmlChar*> transform_strings;
         const xmlChar** transform_params=0;          const xmlChar** transform_params=0;
         if(params.count()>1) {          if(params.count()>1)
                 Value& vparams=params.as_no_junction(1, "transform parameters must be hash");                  if(HashStringValue* hash=params.as_hash(1)) {
                 if(!vparams.is_string())                          transform_params=new(UseGC) const xmlChar*[hash->count()*2+1];
                         if(HashStringValue* hash=vparams.get_hash()) {                          Add_xslt_param_info info={
                                 transform_params=new(UseGC) const xmlChar*[hash->count()*2+1];                                  &r, 
                                 Add_xslt_param_info info={                                  &transform_strings,
                                         &r,                                   transform_params
                                         &transform_strings,                          };
                                         transform_params                          hash->for_each<Add_xslt_param_info*>(add_xslt_param, &info);
                                 };                          transform_params[hash->count()*2]=0;
                                 hash->for_each(add_xslt_param, &info);                  }
                                 transform_params[hash->count()*2]=0;                              
                         } else  
                                 throw Exception("parser.runtime",  
                                         0,  
                                         "transform parameters parameter must be hash");  
         }  
   
         VXdoc* result;          VXdoc* result;
         if(Value *vxdoc=params[0].as(VXDOC_TYPE, false)) { // stylesheet (xdoc)          if(Value *vxdoc=params[0].as(VXDOC_TYPE)) { // stylesheet (xdoc)
                 xmlDoc& stylesheetdoc=static_cast<VXdoc *>(vxdoc)->get_xmldoc();                  xmlDoc& stylesheetdoc=static_cast<VXdoc *>(vxdoc)->get_xmldoc();
                 // compile xdoc stylesheet                  // compile xdoc stylesheet
                 xsltStylesheet_auto_ptr stylesheet_ptr(xsltParseStylesheetDoc(&stylesheetdoc));                   xsltStylesheet_auto_ptr stylesheet_ptr(xsltParseStylesheetDoc(&stylesheetdoc)); 

Removed from v.1.149  
changed lines
  Added in v.1.167


E-mail: