Annotation of parser3/src/types/pa_vxdoc.C, revision 1.39
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.39 ! misha 10: static const char * const IDENT_VXDOC="$Date: 2009-11-27 02:29:01 $";
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"
! 26:
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:
! 112: XDocOutputOptions::XDocOutputOptions(Request& r, HashStringValue* options){
! 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) {
! 131: // $.method[xml|html|text]
! 132: if(Value* vmethod=options->get(String::Body(XDOC_OUTPUT_METHOD_OPTION_NAME)))
! 133: this->method=&vmethod->as_string();
! 134: int valid_options=0;
! 135:
! 136: // $.version[1.0]
! 137: valid_options+=param_option_over_output_option(*options, "version", this->version);
! 138: // $.encoding[windows-1251|...]
! 139: valid_options+=param_option_over_output_option(*options, "encoding", this->encoding);
! 140: // $.omit-xml-declaration[yes|no]
! 141: valid_options+=param_option_over_output_option(*options, "omit-xml-declaration", this->omitXmlDeclaration);
! 142: // $.standalone[yes|no]
! 143: valid_options+=param_option_over_output_option(*options, "standalone", this->standalone);
! 144: // $.indent[yes|no]
! 145: valid_options+=param_option_over_output_option(*options, "indent", this->indent);
! 146: // $.media-type[text/{html|xml|plain}]
! 147: valid_options+=param_option_over_output_option(*options, "media-type", this->mediaType);
! 148:
! 149: if(valid_options!=options->count())
! 150: throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
! 151: }
! 152:
! 153: // default encoding from pool
! 154: if(!this->encoding)
! 155: this->encoding=new String(r.charsets.source().NAME(), String::L_TAINTED);
! 156: // default method=xml
! 157: if(!this->method)
! 158: this->method=new String(XDOC_OUTPUT_METHOD_OPTION_VALUE_XML);
! 159: // default mediaType = depending on method
! 160: if(!this->mediaType) {
! 161: if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)
! 162: this->mediaType=new String("text/xml");
! 163: else if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)
! 164: this->mediaType=new String("text/html");
! 165: else // XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT & all others
! 166: this->mediaType=new String("text/plain");
! 167: }
! 168: }
! 169:
! 170: // defined at classes/xdoc.C
! 171: String::C xdoc2buf(Request& r, VXdoc& vdoc,
! 172: XDocOutputOptions& oo,
! 173: const String* file_spec,
! 174: bool use_source_charset_to_render_and_client_charset_to_write_to_header);
! 175:
! 176: const String* VXdoc::get_json_string(Json_options* options){
! 177: XDocOutputOptions xdoc_options_default;
! 178: String::C buf=xdoc2buf(*options->r, *this, options->xdoc_options ? *options->xdoc_options : xdoc_options_default,
! 179: 0/*file_name. not to file, to memory*/,
! 180: true/*use source charset to render, client charset to put to header*/);
! 181:
! 182: String& result=*new String("\"", String::L_AS_IS);
! 183: result << String(buf, String::L_JSON);
! 184: result << "\"";
! 185: return &result;
! 186: }
! 187:
1.1 parser 188: #endif
E-mail: