--- parser3/src/classes/Attic/dom.C 2001/09/15 14:22:47 1.22 +++ parser3/src/classes/Attic/dom.C 2001/09/26 10:32:25 1.35 @@ -2,36 +2,32 @@ Parser: @b dom parser class. Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) -*/ -static const char *RCSId="$Id: dom.C,v 1.22 2001/09/15 14:22:47 parser Exp $"; - -#if _MSC_VER -# pragma warning(disable:4291) // disable warning -// "no matching operator delete found; memory will not be freed if initialization throws an exception -#endif + $Id: dom.C,v 1.35 2001/09/26 10:32:25 parser Exp $ +*/ #include "classes.h" +#ifdef XML + #include "pa_request.h" #include "pa_vdom.h" -#include "pa_vfile.h" #include "pa_xslt_stylesheet_manager.h" #include "pa_stylesheet_connection.h" +#include "pa_vfile.h" +#include "dnode.h" #include #include #include -#include #include #include -#include -#include -#include #include #include #include #include +#include +#include +#include // defines @@ -48,7 +44,7 @@ static const char *RCSId="$Id: dom.C,v 1 // class -class MDom : public Methoded { +class MDom : public MDnode { public: // VStateless_class Value *create_new_value(Pool& pool) { return new(pool) VDom(pool); } @@ -61,72 +57,6 @@ public: // Methoded // methods -static void _set(Request& r, const String& method_name, MethodParams *params) { - Pool& pool=r.pool(); - VDom& vDom=*static_cast(r.self); - - Value& vxml=params->as_junction(0, "xml must be code"); - Temp_lang temp_lang(r, String::UL_XML); - const String& xml=r.process(vxml).as_string(); - - std::istrstream stream(xml.cstr()); - XalanParsedSource* parsedSource; - int error=vDom.transformer().parseSource(&stream, parsedSource); - - if(error) - PTHROW(0, 0, - &method_name, - vDom.transformer().getLastError()); - - // replace any previous parsed source - vDom.set_parsed_source(*parsedSource); -} - -static void _load(Request& r, const String& method_name, MethodParams *params) { - Pool& pool=r.pool(); - VDom& vDom=*static_cast(r.self); - - // filespec - const String& file_name=params->as_string(0, "file name must not be code"); - const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC); - - XalanParsedSource* parsedSource; - int error=vDom.transformer().parseSource(filespec, parsedSource); - - if(error) - PTHROW(0, 0, - &file_name, - vDom.transformer().getLastError()); - - // replace any previous parsed source - vDom.set_parsed_source(*parsedSource); -} - -static const char *strX(const XalanDOMString& s) { - return XMLString::transcode(s.c_str()); -} - -static void _throw(Pool& pool, const String *source, const XSLException& e) { - if(e.getURI().empty()) - PTHROW(0, 0, - source, - "%s (%s)", - strX(e.getMessage()), // message for exception - strX(e.getType()) // type of exception - ); - else - PTHROW(0, 0, - source, - "%s (%s) %s(%d:%d)'", - strX(e.getMessage()), // message for exception - strX(e.getType()), // type of exception - - strX(e.getURI()), // URI for the associated document, if any - e.getLineNumber(), // line number, or -1 if unknown - e.getColumnNumber() // column number, or -1 if unknown - ); -} - class ParserStringXalanOutputStream: public XalanOutputStream { public: @@ -137,7 +67,7 @@ protected: // XalanOutputStream virtual void writeData(const char *theBuffer, unsigned long theBufferLength) { char *copy=(char *)fstring.malloc((size_t)theBufferLength); memcpy(copy, theBuffer, (size_t)theBufferLength); - fstring.APPEND_CLEAN(copy, (size_t)theBufferLength, "dom", -1); + fstring.APPEND_CLEAN(copy, (size_t)theBufferLength, "dom", 0); } virtual void doFlush() {} @@ -148,35 +78,37 @@ private: }; - static void create_optioned_listener( const char *& content_type, const char *& charset, FormatterListener *& listener, Pool& pool, const String& method_name, MethodParams *params, int index, Writer& writer) { - charset=0; + // default encoding from pool + const String *scharset=&pool.get_charset(); const String *method=0; XalanDOMString xalan_encoding; - Value& voptions=params->as_no_junction(index, "options must not be code"); - if(voptions.is_defined()) { - if(Hash *options=voptions.get_hash()) { - // $.method[xml|html|text] - if(Value *vmethod=static_cast(options->get(*new(pool) - String(pool, DOM_OUTPUT_METHOD_OPTION_NAME)))) - method=&vmethod->as_string(); - - // $.encoding[windows-1251|...] - if(Value *vencoding=static_cast(options->get(*new(pool) - String(pool, DOM_OUTPUT_ENCODING_OPTION_NAME)))) { - charset=vencoding->as_string().cstr(); - xalan_encoding.append(charset, strlen(charset)); - } - } else - PTHROW(0, 0, - &method_name, - "options must be hash"); + if(params->size()>index) { + Value& voptions=params->as_no_junction(index, "options must not be code"); + if(voptions.is_defined()) { + if(Hash *options=voptions.get_hash()) { + // $.method[xml|html|text] + if(Value *vmethod=static_cast(options->get(*new(pool) + String(pool, DOM_OUTPUT_METHOD_OPTION_NAME)))) + method=&vmethod->as_string(); + + // $.encoding[windows-1251|...] + if(Value *vencoding=static_cast(options->get(*new(pool) + String(pool, DOM_OUTPUT_ENCODING_OPTION_NAME)))) { + scharset=&vencoding->as_string(); + } + } else + PTHROW(0, 0, + &method_name, + "options must be hash"); + } } + xalan_encoding.append(charset=scharset->cstr()); if(!method/*default='xml'*/ || *method == DOM_OUTPUT_METHOD_OPTION_VALUE_XML) { content_type="text/xml"; listener=new FormatterToXML(writer, @@ -213,14 +145,14 @@ static void create_optioned_listener( static void _save(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - VDom& vDom=*static_cast(r.self); + VDnode& vnode=*static_cast(r.self); // filespec - const String& file_name=params->as_string(1, "file name must not be code"); + const String& file_name=params->as_string(0, "file name must not be code"); const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC); - // document - XalanDocument& document=vDom.get_document(pool, &method_name); + // node + XalanNode& node=vnode.get_node(pool, &method_name); try { XalanFileOutputStream stream(XalanDOMString(filespec, strlen(filespec))); @@ -228,20 +160,20 @@ static void _save(Request& r, const Stri const char *content_type, *charset; FormatterListener *formatterListener; create_optioned_listener(content_type, charset, formatterListener, - pool, method_name, params, 0, writer); + pool, method_name, params, 1, writer); FormatterTreeWalker treeWalker(*formatterListener); - treeWalker.traverse(&document); // Walk the document and produce the XML... + treeWalker.traverse(&node); // Walk that node and produce the XML... } catch(const XSLException& e) { - _throw(pool, &method_name, e); + r._throw(&method_name, e); } } static void _string(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - VDom& vDom=*static_cast(r.self); + VDnode& vnode=*static_cast(r.self); - // document - XalanDocument& document=vDom.get_document(pool, &method_name); + // node + XalanNode& node=vnode.get_node(pool, &method_name); try { String parserString=*new(pool) String(pool); @@ -252,22 +184,22 @@ static void _string(Request& r, const St create_optioned_listener(content_type, charset, formatterListener, pool, method_name, params, 0, writer); FormatterTreeWalker treeWalker(*formatterListener); - treeWalker.traverse(&document); // Walk the document and produce the XML... + treeWalker.traverse(&node); // Walk that node and produce the XML... // write out result r.write_no_lang(parserString); } catch(const XSLException& e) { - _throw(pool, &method_name, e); + r._throw(&method_name, e); } } static void _file(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - VDom& vDom=*static_cast(r.self); + VDnode& vnode=*static_cast(r.self); - // document - XalanDocument& document=vDom.get_document(pool, &method_name); + // node + XalanNode& node=vnode.get_node(pool, &method_name); try { String& parserString=*new(pool) String(pool); @@ -278,7 +210,7 @@ static void _file(Request& r, const Stri create_optioned_listener(content_type, charset, formatterListener, pool, method_name, params, 0, writer); FormatterTreeWalker treeWalker(*formatterListener); - treeWalker.traverse(&document); // Walk the document and produce the XML... + treeWalker.traverse(&node); // Walk that node and produce the XML... // write out result VFile& vfile=*new(pool) VFile(pool); @@ -296,10 +228,50 @@ static void _file(Request& r, const Stri vfile.set(false/*tainted*/, cstr, strlen(cstr), 0/*file_name*/, vcontent_type); r.write_no_lang(vfile); } catch(const XSLException& e) { - _throw(pool, &method_name, e); + r._throw(&method_name, e); } } +static void _set(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); + VDom& vdom=*static_cast(r.self); + + Value& vxml=params->as_junction(0, "xml must be code"); + Temp_lang temp_lang(r, String::UL_XML); + const String& xml=r.process(vxml).as_string(); + + std::istrstream stream(xml.cstr()); + const XalanParsedSource* parsedSource; + int error=vdom.transformer().parseSource(&stream, parsedSource); + + if(error) + PTHROW(0, 0, + &method_name, + vdom.transformer().getLastError()); + + // replace any previous parsed source + vdom.set_parsed_source(*parsedSource); +} + +static void _load(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); + VDom& vdom=*static_cast(r.self); + + // filespec + const String& file_name=params->as_string(0, "file name must not be code"); + const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC); + + const XalanParsedSource* parsedSource; + int error=vdom.transformer().parseSource(filespec, parsedSource); + + if(error) + PTHROW(0, 0, + &file_name, + vdom.transformer().getLastError()); + + // replace any previous parsed source + vdom.set_parsed_source(*parsedSource); +} static void add_xslt_param(const Hash::Key& aattribute, Hash::Val *ameaning, void *info) { @@ -308,19 +280,19 @@ static void add_xslt_param(const Hash::K const char *meaning_cstr=static_cast(ameaning)->as_string().cstr(); transformer.setStylesheetParam( - XalanDOMString(attribute_cstr, strlen(attribute_cstr)), - XalanDOMString(meaning_cstr, strlen(meaning_cstr))); + XalanDOMString(attribute_cstr), + XalanDOMString(meaning_cstr)); } static void _xslt(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - VDom& vDom=*static_cast(r.self); + VDom& vdom=*static_cast(r.self); // params if(params->size()>1) { Value& vparams=params->as_no_junction(1, "transform parameters parameter must not be code"); if(vparams.is_defined()) if(Hash *params=vparams.get_hash()) - params->for_each(add_xslt_param, &vDom.transformer()); + params->for_each(add_xslt_param, &vdom.transformer()); else PTHROW(0, 0, &method_name, @@ -328,7 +300,7 @@ static void _xslt(Request& r, const Stri } // source - XalanParsedSource &parsed_source=vDom.get_parsed_source(pool, &method_name); + const XalanParsedSource &parsed_source=vdom.get_parsed_source(pool, &method_name); // stylesheet const String& stylesheet_file_name=params->as_string(0, "file name must not be code"); @@ -337,11 +309,11 @@ static void _xslt(Request& r, const Stri Stylesheet_connection& connection=XSLT_stylesheet_manager->get_connection(stylesheet_filespec); // target - XalanDocument* target=vDom.parser_liaison().createDocument(); + XalanDocument* target=vdom.parser_liaison().createDocument(); XSLTResultTarget domResultTarget(target); // transform - int error=vDom.transformer().transform( + int error=vdom.transformer().transform( parsed_source, &connection.stylesheet(), domResultTarget); @@ -349,7 +321,7 @@ static void _xslt(Request& r, const Stri if(error) PTHROW(0, 0, &stylesheet_file_name, - vDom.transformer().getLastError()); + vdom.transformer().getLastError()); // write out result VDom& result=*new(pool) VDom(pool); @@ -359,24 +331,27 @@ static void _xslt(Request& r, const Stri // constructor -MDom::MDom(Pool& apool) : Methoded(apool) { +MDom::MDom(Pool& apool) : MDnode(apool) { set_name(*NEW String(pool(), DOM_CLASS_NAME)); + // ^dom.save[some.xml] + // ^dom.save[some.xml;options hash] + add_native_method("save", Method::CT_DYNAMIC, _save, 1, 2); + + // ^dom.string[] + // ^dom.string[options hash] + add_native_method("string", Method::CT_DYNAMIC, _string, 0, 1); + + // ^dom.file[] file with "" + // ^dom.file[options hash] file with "" + add_native_method("file", Method::CT_DYNAMIC, _file, 0, 1); + // ^dom::set[xml] add_native_method("set", Method::CT_DYNAMIC, _set, 1, 1); // ^dom::load[some.xml] add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1); - // ^dom.save[options hash;some.xml] - add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2); - - // ^dom.string[options hash] - add_native_method("string", Method::CT_DYNAMIC, _string, 1, 1); - - // ^dom.file[options hash] file with "" - add_native_method("file", Method::CT_DYNAMIC, _file, 1, 1); - // ^dom.xslt[stylesheet file_name] // ^dom.xslt[stylesheet file_name;params hash] add_native_method("xslt", Method::CT_DYNAMIC, _xslt, 1, 2); @@ -388,11 +363,14 @@ Methoded *Dom_class; // creator -Methoded *MDom_create(Pool& pool) { - // Use the static initializers to initialize the Xalan-C++ and Xerces-C++ platforms. - // You must initialize Xerces-C++ once per process - XMLPlatformUtils::Initialize(); - XalanTransformer::initialize(); +#endif - return Dom_class=new(pool) MDom(pool); +Methoded *MDom_create(Pool& pool) { + return +#ifdef XML + Dom_class=new(pool) MDom(pool); +#else + 0 +#endif + ; }