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

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

E-mail: