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: