Annotation of parser3/src/types/pa_vxdoc.C, revision 1.43
1.1 parser 1: /** @dom
2: Parser: @b dom parser type.
3:
1.35 misha 4: Copyright(c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com)
1.11 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 parser 6: */
7: #include "pa_config_includes.h"
8: #ifdef XML
1.14 paf 9:
1.43 ! misha 10: static const char * const IDENT_VXDOC="$Date: 2011-11-11 03:57:12 $";
1.1 parser 11:
12: #include "pa_vxdoc.h"
1.34 misha 13: #include "pa_vbool.h"
1.1 parser 14:
1.39 misha 15: #include "pa_request.h"
16: #include "pa_charset.h"
17:
1.28 paf 18: // defines
19:
20: #define SEARCH_NAMESPACES_NAME "search-namespaces"
21:
1.39 misha 22: #define XDOC_OUTPUT_METHOD_OPTION_NAME "method"
23: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "xml"
24: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "html"
25: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "text"
1.41 misha 26: #define XDOC_OUTPUT_FILENAME_OPTION_NAME "name"
1.30 paf 27:
28: VXnode& VXdoc::wrap(xmlNode& anode) {
29: VXnode* result;
30: if((result=static_cast<VXnode*>(anode._private))) {
31: assert(anode.doc==fdocument);
32: return *result;
33: }
34:
35: result=new VXnode(anode);
36: anode._private=result;
37: anode.doc=fdocument;
38:
39: return *result;
40: }
41:
42:
1.36 misha 43: Value* VXdoc::as(const char* atype) {
1.32 misha 44: return atype && ( strcmp(VXdoc::type(), atype)==0 || strcmp(VXnode::type(), atype)==0 )?this:0;
1.18 paf 45: }
46:
1.34 misha 47: /// VXdoc: true
1.35 misha 48: Value& VXdoc::as_expr_result(bool /*return_string_as_is=false*/) { return VBool::get(as_bool()); }
1.34 misha 49:
1.33 misha 50:
1.2 parser 51: /// VXdoc: $CLASS,$method
1.36 misha 52: Value* VXdoc::get_element(const String& aname) {
1.28 paf 53: if(aname==SEARCH_NAMESPACES_NAME) {
54: return &search_namespaces;
55: }
56:
1.13 paf 57: // up
1.21 paf 58: try {
1.36 misha 59: return VXnode::get_element(aname);
1.24 paf 60: } catch(Exception) {
61: // ignore bad node elements, they can be valid here...
62:
63: // fields
1.31 paf 64: xmlDoc& xmldoc=get_xmldoc();
1.24 paf 65:
66: if(aname=="doctype") {
67: // readonly attribute DocumentType doctype;
1.31 paf 68: if(xmlNode* node=(xmlNode*)xmldoc.intSubset)
69: return &wrap(*node);
70: else
71: return 0;
1.24 paf 72: } else if(aname=="implementation") {
73: // readonly attribute DOMImplementation implementation;
74: return 0;
75: } else if(aname=="documentElement") {
76: // readonly attribute Element documentElement;
1.38 misha 77: xmlNode* rootElement=xmlDocGetRootElement(&xmldoc);
78: return rootElement ? &wrap(*rootElement) : 0;
79: }
1.31 paf 80:
1.25 paf 81: return bark("%s field not found", &aname);
1.24 paf 82: }
1.2 parser 83: }
84:
1.39 misha 85: static int param_option_over_output_option(
86: HashStringValue& param_options, const char* option_name,
87: const String*& output_option) {
88: if(Value* value=param_options.get(String::Body(option_name))){
89: output_option=&value->as_string();
90: return 1;
91: }
92: return 0;
93: }
94: static int param_option_over_output_option(
95: HashStringValue& param_options, const char* option_name,
96: int& output_option) {
97: if(Value* value=param_options.get(String::Body(option_name))) {
98: const String& s=value->as_string();
99: if(s=="yes")
100: output_option=1;
101: else if(s=="no")
102: output_option=0;
103: else
104: throw Exception(PARSER_RUNTIME,
105: &s,
106: "%s must be either 'yes' or 'no'", option_name);
107: return 1;
108: }
109: return 0;
110: }
111:
1.41 misha 112: XDocOutputOptions::XDocOutputOptions(Request& r, HashStringValue* options, bool with_filename){
1.39 misha 113: memset(this, 0, sizeof(*this));
114: indent=standalone=omitXmlDeclaration=-1;
115:
116: /*
117: <xsl:output
118: !method = "xml" | "html" | "text" | qname-but-not-ncname
119: !version = nmtoken
120: !encoding = string
121: !omit-xml-declaration = "yes" | "no"
122: !standalone = "yes" | "no"
123: !doctype-public = string
124: !doctype-system = string
125: cdata-section-elements = qnames
126: !indent = "yes" | "no"
127: !media-type = string />
128: */
129:
130: if(options) {
1.40 misha 131: int valid_options=0;
1.43 ! misha 132: // $.charset[windows-1251|...]
! 133: valid_options+=param_option_over_output_option(*options, "charset", this->encoding);
! 134: // $.encoding[windows-1251|...]
! 135: valid_options+=param_option_over_output_option(*options, "encoding", this->encoding);
! 136: if(valid_options==2)
! 137: throw Exception(PARSER_RUNTIME, 0, "you can not specify $.charset and $.encoding together");
1.39 misha 138: // $.method[xml|html|text]
1.40 misha 139: valid_options+=param_option_over_output_option(*options, XDOC_OUTPUT_METHOD_OPTION_NAME, this->method);
1.39 misha 140: // $.version[1.0]
141: valid_options+=param_option_over_output_option(*options, "version", this->version);
142: // $.omit-xml-declaration[yes|no]
143: valid_options+=param_option_over_output_option(*options, "omit-xml-declaration", this->omitXmlDeclaration);
144: // $.standalone[yes|no]
145: valid_options+=param_option_over_output_option(*options, "standalone", this->standalone);
146: // $.indent[yes|no]
147: valid_options+=param_option_over_output_option(*options, "indent", this->indent);
148: // $.media-type[text/{html|xml|plain}]
1.41 misha 149: valid_options+=param_option_over_output_option(*options, "media-type", this->mediaType);
150: if(with_filename)
151: // $.name[file name]
152: valid_options+=param_option_over_output_option(*options, XDOC_OUTPUT_FILENAME_OPTION_NAME, this->filename);
1.39 misha 153:
154: if(valid_options!=options->count())
155: throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
156: }
157:
158: // default encoding from pool
159: if(!this->encoding)
160: this->encoding=new String(r.charsets.source().NAME(), String::L_TAINTED);
161: // default method=xml
162: if(!this->method)
163: this->method=new String(XDOC_OUTPUT_METHOD_OPTION_VALUE_XML);
164: // default mediaType = depending on method
165: if(!this->mediaType) {
166: if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)
167: this->mediaType=new String("text/xml");
168: else if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)
169: this->mediaType=new String("text/html");
170: else // XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT & all others
171: this->mediaType=new String("text/plain");
172: }
173: }
174:
175: // defined at classes/xdoc.C
176: String::C xdoc2buf(Request& r, VXdoc& vdoc,
177: XDocOutputOptions& oo,
178: const String* file_spec,
179: bool use_source_charset_to_render_and_client_charset_to_write_to_header);
180:
181: const String* VXdoc::get_json_string(Json_options* options){
182: XDocOutputOptions xdoc_options_default;
183: String::C buf=xdoc2buf(*options->r, *this, options->xdoc_options ? *options->xdoc_options : xdoc_options_default,
184: 0/*file_name. not to file, to memory*/,
185: true/*use source charset to render, client charset to put to header*/);
186:
187: String& result=*new String("\"", String::L_AS_IS);
188: result << String(buf, String::L_JSON);
189: result << "\"";
190: return &result;
191: }
192:
1.1 parser 193: #endif
E-mail: