Annotation of parser3/src/types/pa_vxdoc.C, revision 1.45

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

E-mail: