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: