Annotation of parser3/src/types/pa_value.C, revision 1.17

1.1       paf         1: /** @file
                      2:        Parser: Value class.
                      3: 
1.16      paf         4:        Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com)
1.1       paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.2       paf         6: */
1.1       paf         7: 
1.17    ! paf         8: static const char * const IDENT_VALUE_C="$Date: 2004/02/11 15:33:17 $";
1.1       paf         9: 
                     10: #include "pa_value.h"
                     11: #include "pa_vstateless_class.h"
1.4       paf        12: #include "pa_vmethod_frame.h"
1.10      paf        13: #include "pa_vdate.h"
                     14: #include "pa_vobject.h"
                     15: 
                     16: // defines for globals
                     17: 
                     18: #define NAME_NAME "name"
                     19: 
                     20: // globals
                     21: 
                     22: const String name_name(NAME_NAME);
                     23: 
                     24: const String value_name(VALUE_NAME);
1.12      paf        25: const String expires_name(EXPIRES_NAME);
1.10      paf        26: const String content_type_name(CONTENT_TYPE_NAME);
                     27: 
                     28: // methods
                     29: 
                     30: VObject* Value::set_derived(VObject* /*aderived*/) { return 0; }
                     31: 
                     32: Junction* Value::get_junction() { return 0; }
                     33: 
1.11      paf        34: Value* Value::base_object() { return bark("is '%s', it has no base object"); }
1.10      paf        35: 
                     36: Value* Value::get_element(const String& /*aname*/, Value& /*aself*/, bool /*looking_up*/) {
1.11      paf        37:        return bark("is '%s', it has no elements");
1.10      paf        38: }
                     39: 
                     40: 
                     41: VFile* Value::as_vfile(String::Language /*lang*/, const Request_charsets* /*charsets*/) { 
1.11      paf        42:        bark("is '%s', it does not have file value"); return 0;
1.10      paf        43: }
1.1       paf        44: 
                     45: /// call this before invoking to ensure proper actual numbered params count
1.10      paf        46: void Method::check_actual_numbered_params(Value& self, 
                     47:                                          MethodParams* actual_numbered_params) const {
1.1       paf        48: 
1.10      paf        49:        int actual_count=actual_numbered_params?actual_numbered_params->count():0;
1.1       paf        50:        if(actual_count<min_numbered_params_count) // not proper count? bark
                     51:                throw Exception("parser.runtime",
1.10      paf        52:                        0,
1.1       paf        53:                        "native method of %s (%s) accepts minimum %d parameter(s) (%d present)", 
1.8       paf        54:                                self.get_class()->name_cstr(),
                     55:                                self.type(),
1.1       paf        56:                                min_numbered_params_count,
                     57:                                actual_count);
                     58: 
                     59: }
1.4       paf        60: 
1.10      paf        61: Junction::Junction(Value& aself,
                     62:        const Method* amethod,
                     63:        VMethodFrame* amethod_frame,
                     64:        Value* arcontext,
                     65:        WContext* awcontext,
                     66:        ArrayOperation* acode): self(aself),
1.7       paf        67:        method(amethod),
1.4       paf        68:        method_frame(amethod_frame),
                     69:        rcontext(arcontext),
                     70:        wcontext(awcontext),
                     71:        code(acode) {
1.5       paf        72:        if(wcontext)
1.10      paf        73:                wcontext->attach_junction(this);
1.4       paf        74: }
                     75: 
1.5       paf        76: void Junction::reattach(WContext *new_wcontext) {
1.17    ! paf        77:        if(new_wcontext) {
        !            78:                assert(wcontext!=new_wcontext);
1.5       paf        79:                wcontext=new_wcontext;
1.17    ! paf        80:                wcontext->attach_junction(this);
        !            81:        } else {
1.5       paf        82:                method_frame=0;
                     83:                rcontext=0;
                     84:                wcontext=0;
                     85:        }
1.4       paf        86: }
                     87: 
1.10      paf        88: // attributed meaning
                     89: 
                     90: static String::C date_attribute(const VDate& vdate) {
                     91:        /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
                     92:        const char month_names[12][4]={
                     93:                "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
                     94:        const char days[7][4]={
                     95:                "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
                     96:                        
                     97:        time_t when=vdate.get_time();
                     98:        struct tm *tms=gmtime(&when);
                     99:        if(!tms)
                    100:                throw Exception(0,
                    101:                        0,
1.15      paf       102:                        "bad time in attribute value (seconds from epoch=%u)", when);
1.10      paf       103: 
                    104:        char *buf=new(PointerFreeGC) char[MAX_STRING];
                    105:        return String::C(buf, 
                    106:                snprintf(buf, MAX_STRING, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT", 
                    107:                days[tms->tm_wday],
                    108:                tms->tm_mday,month_names[tms->tm_mon],tms->tm_year+1900,
                    109:                tms->tm_hour,tms->tm_min,tms->tm_sec));
                    110: }
                    111: static void append_attribute_meaning(String& result,
                    112:                                     Value& value, String::Language lang, bool forced) {
                    113:        if(const String* string=value.get_string())
                    114:                result.append(*string, lang, forced);
                    115:        else
                    116:                if(Value* vdate=value.as(VDATE_TYPE, false)) {
                    117:                        String::C attribute=date_attribute(static_cast<VDate&>(*vdate));
                    118: 
                    119:                        result.append_help_length(attribute.str, attribute.length, String::L_CLEAN);
                    120:                } else
                    121:                        throw Exception("parser.runtime",
                    122:                                &result,
                    123:                                "trying to append here neither string nor date (%s)",
                    124:                                        value.type());
                    125: }
                    126: #ifndef DOXYGEN
                    127: struct Attributed_meaning_info {
                    128:        String* header; // header line being constructed
                    129:        String::Language lang; // language in which to append to that line
                    130:        bool forced; // do they force that lang?
                    131: };
                    132: #endif
                    133: static void append_attribute_subattribute(HashStringValue::key_type akey, 
                    134:                                          HashStringValue::value_type avalue, 
                    135:                                          Attributed_meaning_info *info) {
                    136:        if(akey==VALUE_NAME)
                    137:                return;
                    138: 
                    139:        // ...; charset=windows1251
                    140:        *info->header << "; ";
                    141:        info->header->append(String(akey, String::L_TAINTED), info->lang, info->forced);
                    142:        *info->header << "=";
                    143:        append_attribute_meaning(*info->header, *avalue, info->lang, info->forced);
                    144: }
                    145: const String& attributed_meaning_to_string(Value& meaning, 
                    146:                                           String::Language lang, bool forced) {
                    147:        String& result=*new String;
                    148:        if(HashStringValue *hash=meaning.get_hash()) {
                    149:                // $value(value) $subattribute(subattribute value)
                    150:                if(Value* value=hash->get(value_name))
                    151:                        append_attribute_meaning(result, *value, lang, forced);
                    152: 
1.14      paf       153:                Attributed_meaning_info attributed_meaning_info={&result, lang, false};
1.10      paf       154:                hash->for_each(append_attribute_subattribute, &attributed_meaning_info);
                    155:        } else // result value
                    156:                append_attribute_meaning(result, meaning, lang, forced);
                    157: 
                    158:        return result;
                    159: }

E-mail: