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: