Annotation of parser3/src/classes/dom.C, revision 1.7

1.2       parser      1: /** @file
                      2:        Parser: @b dom parser class.
                      3: 
                      4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
                      5: 
                      6:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
                      7: */
1.7     ! parser      8: static const char *RCSId="$Id: dom.C,v 1.6 2001/09/10 09:34:51 parser Exp $"; 
1.2       parser      9: 
                     10: #if _MSC_VER
                     11: #      pragma warning(disable:4291)   // disable warning 
                     12: //     "no matching operator delete found; memory will not be freed if initialization throws an exception
                     13: #endif
                     14: 
                     15: #include "classes.h"
                     16: #include "pa_request.h"
                     17: #include "pa_vdom.h"
                     18: 
                     19: #include <Include/PlatformDefinitions.hpp>
                     20: #include <util/PlatformUtils.hpp>
1.5       parser     21: #include <util/XMLString.hpp>
1.2       parser     22: #include <XalanTransformer/XalanTransformer.hpp>
1.4       parser     23: #include <XalanTransformer/XalanParsedSource.hpp>
                     24: #include <PlatformSupport/XalanFileOutputStream.hpp>
                     25: #include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>
1.6       parser     26: #include <PlatformSupport/DOMStringPrintWriter.hpp>
1.4       parser     27: #include <XMLSupport/FormatterToXML.hpp>
                     28: #include <XMLSupport/FormatterTreeWalker.hpp>
1.2       parser     29: 
1.6       parser     30: 
1.2       parser     31: // defines
                     32: 
1.4       parser     33: #define DOM_CLASS_NAME "dom"
1.2       parser     34: 
                     35: // class
                     36: 
                     37: class MDom : public Methoded {
                     38: public: // VStateless_class
                     39:        Value *create_new_value(Pool& pool) { return new(pool) VDOM(pool, 0); }
                     40: 
                     41: public:
                     42:        MDom(Pool& pool);
                     43: 
                     44: public: // Methoded
                     45:        bool used_directly() { return true; }
                     46: };
                     47: 
                     48: // methods
                     49: 
                     50: static void _load(Request& r, const String& method_name, MethodParams *params) {
                     51:        Pool& pool=r.pool();
                     52:        VDOM& vDOM=*static_cast<VDOM *>(r.self);
                     53: 
                     54:        // filename
                     55:        const String& filename=params->as_string(0, "file name must not be code");
                     56: 
                     57:        // filespec
                     58:        const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME);
                     59:        
                     60: //     XSLTInputSource::XSLTInputSource (  std::istream * stream )  
                     61: //     XalanNode *node=inputSource.getNode();
                     62:        XSLTInputSource inputSource(filespec);
                     63:        XalanParsedSource* parsedSource;
                     64:        int error=vDOM.getXalanTransformer().parseSource(inputSource, parsedSource);
                     65: 
                     66:        if(error)
                     67:                PTHROW(0, 0,
                     68:                        &filename,
                     69:                        vDOM.getXalanTransformer().getLastError());
                     70: 
                     71:        // replace any previous node value
                     72:        vDOM.setParsedSource(parsedSource);
                     73: }
                     74: 
1.5       parser     75: const char *strX(const XalanDOMString& s) {
                     76:        return XMLString::transcode(s.c_str());
                     77: }
                     78: 
                     79: static void _throw(Pool& pool, const String *source, const XSLException& e) {
                     80:        if(e.getURI().empty())
                     81:                PTHROW(0, 0,
                     82:                        source,
                     83:                        "%s (%s)",
                     84:                                strX(e.getMessage()),  // message for exception
                     85:                                strX(e.getType()) // type of exception
                     86:                );
                     87:        else
                     88:                PTHROW(0, 0,
                     89:                        source,
                     90:                        "%s (%s) %s(%d:%d)'", 
                     91:                                strX(e.getMessage()),  // message for exception
                     92:                                strX(e.getType()), // type of exception
                     93:                                
                     94:                                strX(e.getURI()),  // URI for the associated document, if any
                     95:                                e.getLineNumber(),  // line number, or -1 if unknown
                     96:                                e.getColumnNumber() // column number, or -1 if unknown
                     97:                );
                     98: }
                     99: 
1.6       parser    100: class ParserStringOutputStream: public XalanOutputStream {
                    101: public:
                    102:        
1.7     ! parser    103:        explicit ParserStringOutputStream(String& astring) : fstring(astring) {}
        !           104: 
        !           105: protected: // XalanOutputStream
        !           106: 
        !           107:        virtual void writeData(const char *theBuffer, unsigned long theBufferLength) {
1.6       parser    108:                char *copy=(char *)fstring.malloc((size_t)theBufferLength);
                    109:                memcpy(copy, theBuffer, (size_t)theBufferLength);
                    110:                fstring.APPEND_CLEAN(copy, (size_t)theBufferLength, "dom", -1);
                    111:        }
                    112: 
1.7     ! parser    113:        virtual void doFlush() {}
1.6       parser    114: 
                    115: private:
                    116: 
                    117:        String& fstring;
                    118:        
                    119: };
                    120: 
                    121: 
1.3       parser    122: static void _save(Request& r, const String& method_name, MethodParams *params) {
                    123:        Pool& pool=r.pool();
                    124:        VDOM& vDOM=*static_cast<VDOM *>(r.self);
                    125: 
1.7     ! parser    126:        // encoding
        !           127:        const char *encoding=params->as_string(0, "encoding must not be code").cstr();
1.3       parser    128: 
                    129:        // filespec
1.7     ! parser    130:        const String& filename=params->as_string(1, "file name must not be code");
1.3       parser    131:        const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME);
                    132:        
1.4       parser    133:        XalanParsedSource* parsedSource=vDOM.getParsedSource();
                    134:        if(!parsedSource)
                    135:                PTHROW(0, 0,
                    136:                        &method_name,
                    137:                        "on empty document");
1.3       parser    138: 
1.5       parser    139:        try {
                    140:                XalanDocument *document=parsedSource->getDocument();
1.6       parser    141:                XalanFileOutputStream stream(XalanDOMString(filespec, strlen(filespec)));
                    142:                XalanOutputStreamPrintWriter writer(stream);
1.7     ! parser    143:                FormatterToXML formatterListener(writer,
        !           144:                        XalanDOMString(),  // version
        !           145:                        true , // doIndent
        !           146:                        4, // indent 
        !           147:                        XalanDOMString(encoding, strlen(encoding))  // encoding
        !           148:                );
1.6       parser    149:                FormatterTreeWalker treeWalker(formatterListener);
                    150:                treeWalker.traverse(document); // Walk the document and produce the XML...
                    151:        } catch(const XSLException& e) {
                    152:                _throw(pool, &method_name, e);
                    153:        }
                    154: }
                    155: 
                    156: static void _string(Request& r, const String& method_name, MethodParams *params) {
                    157:        Pool& pool=r.pool();
                    158:        VDOM& vDOM=*static_cast<VDOM *>(r.self);
                    159: 
1.7     ! parser    160:        // encoding
        !           161:        const char *encoding=params->as_string(0, "encoding must not be code").cstr();
        !           162: 
1.6       parser    163:        XalanParsedSource* parsedSource=vDOM.getParsedSource();
                    164:        if(!parsedSource)
                    165:                PTHROW(0, 0,
                    166:                        &method_name,
                    167:                        "on empty document");
                    168: 
                    169:        try {
                    170:                XalanDocument *document=parsedSource->getDocument();
                    171:                String *parserString=new(pool) String(pool);
                    172:                ParserStringOutputStream stream(*parserString);
                    173:                XalanOutputStreamPrintWriter writer(stream);
1.7     ! parser    174:                FormatterToXML formatterListener(writer,
        !           175:                        XalanDOMString(),  // version
        !           176:                        true , // doIndent
        !           177:                        4, // indent 
        !           178:                        XalanDOMString(encoding, strlen(encoding)),  // encoding
        !           179:                        XalanDOMString(),  // mediaType
        !           180:                        XalanDOMString(),  // doctypeSystem
        !           181:                        XalanDOMString(),  // doctypePublic
        !           182:                        false // xmlDecl 
        !           183:                );
1.6       parser    184:                FormatterTreeWalker treeWalker(formatterListener);
                    185:                treeWalker.traverse(document); // Walk the document and produce the XML...
                    186: 
                    187:                // write out result
                    188:                r.write_no_lang(*parserString);
1.5       parser    189:        } catch(const XSLException& e) {
                    190:                _throw(pool, &method_name, e);
                    191:        }
1.3       parser    192: }
                    193: 
1.2       parser    194: // constructor
                    195: 
                    196: MDom::MDom(Pool& apool) : Methoded(apool) {
1.4       parser    197:        set_name(*NEW String(pool(), DOM_CLASS_NAME));
1.2       parser    198: 
1.3       parser    199:        // ^dom::load[some.xml]
1.2       parser    200:        add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
1.3       parser    201: 
                    202:        // ^dom.save[some.xml]
                    203:        add_native_method("save", Method::CT_DYNAMIC, _save, 1, 1);
1.2       parser    204: 
1.7     ! parser    205:        // ^dom.string[windows-1251] <doc/>
        !           206:        add_native_method("string", Method::CT_DYNAMIC, _string, 1, 1);
1.6       parser    207: 
1.2       parser    208: }
                    209: // global variable
                    210: 
                    211: Methoded *Dom_class;
                    212: 
                    213: // creator
                    214: 
                    215: Methoded *MDom_create(Pool& pool) {
                    216:        // Use the static initializers to initialize the Xalan-C++ and Xerces-C++ platforms. 
                    217:        // You must initialize Xerces-C++ once per process
                    218:        XMLPlatformUtils::Initialize();
                    219:        XalanTransformer::initialize();
                    220: 
                    221:        return Dom_class=new(pool) MDom(pool);
                    222: }

E-mail: