Diff for /parser3/src/classes/xdoc.C between versions 1.185 and 1.197

version 1.185, 2016/04/06 16:08:19 version 1.197, 2020/11/10 22:42:25
Line 1 Line 1
 /** @file  /** @file
         Parser: @b xdoc parser class.          Parser: @b xdoc parser class.
   
         Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2017 Art. Lebedev Studio (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 47  public: Line 47  public:
   
 // global variable  // global variable
   
   DECLARE_CLASS_VAR(xnode, new MXnode); // must be here as Xdoc is inherited from Xnode and should be inited before
 DECLARE_CLASS_VAR(xdoc, new MXdoc);  DECLARE_CLASS_VAR(xdoc, new MXdoc);
   
 // helper classes  // helper classes
Line 159  static void writeNode(Request& r, VXdoc& Line 160  static void writeNode(Request& r, VXdoc&
                         "error creating node"); // OOM, bad name, things like that                          "error creating node"); // OOM, bad name, things like that
   
         // write out result          // write out result
         r.write_no_lang(xdoc.wrap(*node));          r.write(xdoc.wrap(*node));
 }  }
   
 struct IdsIteratorInfo {  struct IdsIteratorInfo {
Line 167  struct IdsIteratorInfo { Line 168  struct IdsIteratorInfo {
         xmlNode *element;          xmlNode *element;
 };  };
   
 /* Hash Scanner function for pa_getElementById */  /* switching to calling convetion of libxml */
 extern "C" void // switching to calling convetion of libxml  extern "C" void idsHashScanner (void *payload, void *data, const xmlChar *name) {
 idsHashScanner (void *payload, void *data, xmlChar *name) {  
         IdsIteratorInfo *priv = (IdsIteratorInfo *)data;          IdsIteratorInfo *priv = (IdsIteratorInfo *)data;
   
         if (priv->element == NULL && xmlStrEqual (name, priv->elementId))          if (priv->element == NULL && xmlStrEqual (name, priv->elementId))
Line 180  idsHashScanner (void *payload, void *dat Line 180  idsHashScanner (void *payload, void *dat
         }          }
 }  }
   
 static xmlNode*  static xmlNode* pa_getElementById(xmlDoc& xmldoc, xmlChar* elementId) {
 pa_getElementById(xmlDoc& xmldoc, xmlChar* elementId) {  
         xmlHashTable *ids = (xmlHashTable *)xmldoc.ids;          xmlHashTable *ids = (xmlHashTable *)xmldoc.ids;
         IdsIteratorInfo iter={elementId, NULL};          IdsIteratorInfo iter={elementId, NULL};
         xmlHashScan(ids, idsHashScanner, &iter);          xmlHashScan(ids, (xmlHashScanner)idsHashScanner, &iter);
         return iter.element;          return iter.element;
 }  }
   
Line 365  static void _importNode(Request& r, Meth Line 364  static void _importNode(Request& r, Meth
         writeNode(r, vdoc, node);          writeNode(r, vdoc, node);
 }  }
   
 /*  #define XML_PARSE_OPTIONS (XML_PARSE_DTDLOAD | XML_PARSE_NOENT | XML_PARSE_HUGE)
 GdomeElement *gdome_doc_createElementNS (GdomeDocument *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeException *exc);  
 GdomeAttr *gdome_doc_createAttributeNS (GdomeDocument *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeException *exc);  
 */  
   
 static void _create(Request& r, MethodParams& params) {  static void _create(Request& r, MethodParams& params) {
         Charset& source_charset=r.charsets.source();          Charset& source_charset=r.charsets.source();
Line 378  static void _create(Request& r, MethodPa Line 374  static void _create(Request& r, MethodPa
         xmlDoc* xmldoc;          xmlDoc* xmldoc;
         bool set_encoding=false;          bool set_encoding=false;
         if(param.get_junction()) { // {<?xml?>...}          if(param.get_junction()) { // {<?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);
                   String::Body sbody=xml.cstr_to_string_body_untaint(String::L_XML, r.connection(false), &r.charsets);
   
                 String::Body sbody=xml.cstr_to_string_body_untaint(r.flang, r.connection(false), &r.charsets);                  xmldoc=xmlReadMemory(sbody.cstr(), sbody.length(), NULL, NULL, XML_PARSE_OPTIONS);
                 xmldoc=xmlParseMemory(sbody.cstr(), sbody.length());  
   
                 //printf("document=0x%p\n", document);  
                 if(!xmldoc || xmlHaveGenericErrors())                  if(!xmldoc || xmlHaveGenericErrors())
                         throw XmlException(0, r);                          throw XmlException(0, r);
   
Line 395  static void _create(Request& r, MethodPa Line 390  static void _create(Request& r, MethodPa
                         if(xmlValidateNCName(localName, 0) != 0)                          if(xmlValidateNCName(localName, 0) != 0)
                                 throw XmlException(0, XML_INVALID_LOCAL_NAME, localName);                                  throw XmlException(0, XML_INVALID_LOCAL_NAME, localName);
   
 #if 0  
                         GdomeDocumentType *documentType=gdome_di_createDocumentType (  
                                 docimpl,   
                                 r.transcode(qualifiedName),   
                                 0/*publicId*/,   
                                 0/*systemId*/,   
                                 &exc);  
                         if(!documentType || exc || xmlHaveGenericErrors())  
                                 throw Exception(  
                                         method_name,   
                                         exc);  
                         /// +xalan createXMLDecl ?  
 #endif  
                         xmldoc=xmlNewDoc(0);                          xmldoc=xmlNewDoc(0);
                         if(!xmldoc || xmlHaveGenericErrors())                          if(!xmldoc || xmlHaveGenericErrors())
                                 throw XmlException(0, r);                                  throw XmlException(0, r);
Line 420  static void _create(Request& r, MethodPa Line 402  static void _create(Request& r, MethodPa
                         // must be last action in if, see after if}                          // must be last action in if, see after if}
                 } else {                  } else {
                         VFile* vfile=param.as_vfile(String::L_AS_IS);                          VFile* vfile=param.as_vfile(String::L_AS_IS);
                         xmldoc=xmlParseMemory(vfile->value_ptr(), vfile->value_size());                          xmldoc=xmlReadMemory(vfile->value_ptr(), vfile->value_size(), NULL, NULL, XML_PARSE_OPTIONS);
                         if(!xmldoc || xmlHaveGenericErrors())                          if(!xmldoc || xmlHaveGenericErrors())
                                 throw XmlException(0, r);                                  throw XmlException(0, r);
                 }                  }
Line 433  static void _create(Request& r, MethodPa Line 415  static void _create(Request& r, MethodPa
         const char* URI_cstr;          const char* URI_cstr;
         if(params.count()>1) { // absolute(param)          if(params.count()>1) { // absolute(param)
                 const String& URI=params.as_string(0, "URI must be string");                  const String& URI=params.as_string(0, "URI must be string");
                 URI_cstr=r.absolute(URI).cstr();                  URI_cstr=r.full_disk_path(URI).cstr();
         } else // default = disk path to requested document          } else // default = disk path to requested document
                 URI_cstr=r.request_info.path_translated;                  URI_cstr=r.request_info.path_translated;
         if(URI_cstr)          if(URI_cstr)
Line 452  static void _load(Request& r, MethodPara Line 434  static void _load(Request& r, MethodPara
         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).taint_cstr(String::L_FILE_SPEC);                  uri_cstr=r.full_disk_path(*uri).taint_cstr(String::L_FILE_SPEC);
         else // xxx://           else // xxx:// 
                 uri_cstr=uri->taint_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=xmlReadFile(uri_cstr, NULL, XML_PARSE_OPTIONS);
         if(!xmldoc || xmlHaveGenericErrors())          if(!xmldoc || xmlHaveGenericErrors())
                 throw XmlException(uri, r);                  throw XmlException(uri, r);
                   
Line 476  String::C xdoc2buf(Request& r, VXdoc& vd Line 458  String::C xdoc2buf(Request& r, VXdoc& vd
                 render=&r.charsets.source();                  render=&r.charsets.source();
                 header=&r.charsets.client();                  header=&r.charsets.client();
         } else {          } else {
                 header=render=&charsets.get(oo.encoding->change_case(r.charsets.source(), String::CC_UPPER));                  header=render=&pa_charsets.get(*oo.encoding);
         }          }
         const char* render_encoding=render->NAME_CSTR();          const char* render_encoding=render->NAME_CSTR();
         const char* header_encoding=header->NAME_CSTR();          const char* header_encoding=header->NAME_CSTR();
Line 570  static void _file(Request& r, MethodPara Line 552  static void _file(Request& r, MethodPara
         vfile.set_binary(false/*not tainted*/, buf.str?buf.str:""/*to distinguish from stat-ed file*/, buf.length, oo.filename, &vhcontent_type);          vfile.set_binary(false/*not tainted*/, buf.str?buf.str:""/*to distinguish from stat-ed file*/, buf.length, oo.filename, &vhcontent_type);
   
         // write out result          // write out result
         r.write_no_lang(vfile);          r.write(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.full_disk_path(params.as_string(0, FILE_NAME_MUST_BE_STRING));
                   
         XDocOutputOptions oo(vdoc.output_options);          XDocOutputOptions oo(vdoc.output_options);
         oo.append(r, get_options(params, 1));          oo.append(r, get_options(params, 1));
Line 593  static void _string(Request& r, MethodPa Line 575  static void _string(Request& r, MethodPa
                 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(buf, String::L_AS_IS));          r.write(String(buf, String::L_AS_IS));
 }  }
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
Line 674  static void _transform(Request& r, Metho Line 656  static void _transform(Request& r, Metho
         const xmlChar** transform_params=0;          const xmlChar** transform_params=0;
         if(params.count()>1)          if(params.count()>1)
                 if(HashStringValue* hash=params.as_hash(1, "transform options")) {                  if(HashStringValue* hash=params.as_hash(1, "transform options")) {
                         transform_params=new const xmlChar*[hash->count()*2+1];                          transform_params=new(PointerGC) const xmlChar*[hash->count()*2+1];
                         Add_xslt_param_info info={                          Add_xslt_param_info info={
                                 &r,                                   &r, 
                                 &transform_strings,                                  &transform_strings,
Line 686  static void _transform(Request& r, Metho Line 668  static void _transform(Request& r, Metho
   
         VXdoc* result;          VXdoc* result;
         if(Value *vxdoc=params[0].as(VXDOC_TYPE)) { // stylesheet (xdoc)          if(Value *vxdoc=params[0].as(VXDOC_TYPE)) { // stylesheet (xdoc)
                 xmlDoc& stylesheetdoc=static_cast<VXdoc *>(vxdoc)->get_xmldoc();                  VXdoc& vstylesheet=static_cast<VXdoc &>(*vxdoc);
                 // compile xdoc stylesheet  
                 xsltStylesheet_auto_ptr stylesheet_ptr(xsltParseStylesheetDoc(&stylesheetdoc));                   if(!vstylesheet.stylesheet){
                 if(xmlHaveGenericErrors())                          xmlDoc& stylesheetdoc=vstylesheet.get_xmldoc();
                         throw XmlException(0, r);  
                 if(!stylesheet_ptr.get())                          // compile xdoc stylesheet
                         throw Exception("xml",                          vstylesheet.stylesheet=xsltParseStylesheetDoc(&stylesheetdoc);
                                 0,                          if(xmlHaveGenericErrors())
                                 "stylesheet failed to compile");                                  throw XmlException(0, r);
                 // strange thing - xsltParseStylesheetDoc records document and destroys it in stylesheet destructor                          if(!vstylesheet.stylesheet)
                 // we don't need that                                  throw Exception("xml", 0, "stylesheet failed to compile");
                 stylesheet_ptr->doc=0;                  }
   
                 // transform!                  // transform!
                 result=&_transform(r, 0,                  result=&_transform(r, 0, vdoc, vstylesheet.stylesheet, transform_params);
                         vdoc, stylesheet_ptr.get(),  
                         transform_params);  
         } else { // stylesheet (file name)          } else { // stylesheet (file name)
                 // extablish stylesheet connection                  // extablish stylesheet connection
                 const String& stylesheet_filespec=                  const String& stylesheet_filespec=r.full_disk_path(params.as_string(0, "stylesheet must be file name (string) or DOM document (xdoc)"));
                         r.absolute(params.as_string(0, "stylesheet must be file name (string) or DOM document (xdoc)"));  
                 Stylesheet_connection_ptr connection=stylesheet_manager->get_connection(stylesheet_filespec);                  Stylesheet_connection_ptr connection=stylesheet_manager->get_connection(stylesheet_filespec);
   
                 // load and compile file to stylesheet [or get cached if any]                  // load and compile file to stylesheet [or get cached if any]
                 // transform!                  // transform!
                 result=&_transform(r, &stylesheet_filespec, vdoc, connection->stylesheet(),                  result=&_transform(r, &stylesheet_filespec, vdoc, connection->stylesheet(), transform_params);
                         transform_params);  
         }          }
   
         // write out result          // write out result
         r.write_no_lang(*result);          r.write(*result);
 }  }
   
 // constructor  // constructor
Line 794  MXdoc::MXdoc(): MXnode(XDOC_CLASS_NAME) Line 772  MXdoc::MXdoc(): MXnode(XDOC_CLASS_NAME)
   
 // global variable  // global variable
   
   DECLARE_CLASS_VAR(xnode, 0); // fictive
 DECLARE_CLASS_VAR(xdoc, 0); // fictive  DECLARE_CLASS_VAR(xdoc, 0); // fictive
   
 #endif  #endif

Removed from v.1.185  
changed lines
  Added in v.1.197


E-mail: