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: