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

1.1       parser      1: /** @dom
                      2:        Parser: @b dom parser type.
                      3: 
1.51    ! moko        4:        Copyright (c) 2001-2017 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.51    ! moko       15: volatile const char * IDENT_PA_VXDOC_C="$Id: pa_vxdoc.C,v 1.50 2015/10/26 01:22:03 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.48      misha      50: /// VXdoc: $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) {
1.49      moko       87:        if(Value* value=param_options.get(option_name)){
1.39      misha      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.47      moko      111: void XDocOutputOptions::append(Request& r, HashStringValue* options, bool with_filename){
1.39      misha     112: /*
                    113: <xsl:output
                    114:   !method = "xml" | "html" | "text" | qname-but-not-ncname 
                    115:   !version = nmtoken 
                    116:   !encoding = string 
                    117:   !omit-xml-declaration = "yes" | "no"
                    118:   !standalone = "yes" | "no"
                    119:   !doctype-public = string 
                    120:   !doctype-system = string 
                    121:   cdata-section-elements = qnames 
                    122:   !indent = "yes" | "no"
                    123:   !media-type = string /> 
                    124: */
                    125: 
                    126:        if(options) {
1.40      misha     127:                int valid_options=0;
1.43      misha     128:                // $.charset[windows-1251|...]
                    129:                valid_options+=param_option_over_output_option(*options, "charset", this->encoding);
                    130:                // $.encoding[windows-1251|...]
                    131:                valid_options+=param_option_over_output_option(*options, "encoding", this->encoding);
                    132:                if(valid_options==2)
                    133:                        throw Exception(PARSER_RUNTIME, 0, "you can not specify $.charset and $.encoding together");
1.39      misha     134:                // $.method[xml|html|text]
1.40      misha     135:                valid_options+=param_option_over_output_option(*options, XDOC_OUTPUT_METHOD_OPTION_NAME, this->method);
1.39      misha     136:                // $.version[1.0]
                    137:                valid_options+=param_option_over_output_option(*options, "version", this->version);
                    138:                // $.omit-xml-declaration[yes|no]
                    139:                valid_options+=param_option_over_output_option(*options, "omit-xml-declaration", this->omitXmlDeclaration);
                    140:                // $.standalone[yes|no]
                    141:                valid_options+=param_option_over_output_option(*options, "standalone", this->standalone);
                    142:                // $.indent[yes|no]
                    143:                valid_options+=param_option_over_output_option(*options, "indent", this->indent);
                    144:                // $.media-type[text/{html|xml|plain}]
1.41      misha     145:                valid_options+=param_option_over_output_option(*options, "media-type", this->mediaType);
                    146:                if(with_filename)
                    147:                        // $.name[file name]
                    148:                        valid_options+=param_option_over_output_option(*options, XDOC_OUTPUT_FILENAME_OPTION_NAME, this->filename);
1.39      misha     149: 
                    150:                if(valid_options!=options->count())
                    151:                        throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
                    152:        }
                    153: 
                    154:        // default encoding from pool
                    155:        if(!this->encoding)
                    156:                this->encoding=new String(r.charsets.source().NAME(), String::L_TAINTED);
                    157:        // default method=xml
                    158:        if(!this->method)
                    159:                this->method=new String(XDOC_OUTPUT_METHOD_OPTION_VALUE_XML);
                    160:        // default mediaType = depending on method
                    161:        if(!this->mediaType) {
                    162:                if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)
                    163:                        this->mediaType=new String("text/xml");
                    164:                else if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)
                    165:                        this->mediaType=new String("text/html");
                    166:                else // XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT & all others
                    167:                        this->mediaType=new String("text/plain");
                    168:        }
                    169: }
                    170: 
                    171: // defined at classes/xdoc.C
                    172: String::C xdoc2buf(Request& r, VXdoc& vdoc, 
                    173:                                        XDocOutputOptions& oo,
                    174:                                        const String* file_spec,
                    175:                                        bool use_source_charset_to_render_and_client_charset_to_write_to_header);
                    176: 
1.46      moko      177: const String* VXdoc::get_json_string(Json_options& options){
1.39      misha     178:        XDocOutputOptions xdoc_options_default;
1.46      moko      179:        String::C buf=xdoc2buf(*options.r, *this, options.xdoc_options ? *options.xdoc_options : xdoc_options_default,
1.39      misha     180:                0/*file_name. not to file, to memory*/,
                    181:                true/*use source charset to render, client charset to put to header*/);
                    182: 
                    183:        String& result=*new String("\"", String::L_AS_IS);
                    184:        result << String(buf, String::L_JSON);
                    185:        result << "\"";
                    186:        return &result;
                    187: }
                    188: 
1.1       parser    189: #endif

E-mail: