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

1.1       paf         1: /** @file
                      2:        Parser: Value class.
                      3: 
1.9       paf         4:        Copyright (c) 2001, 2003 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.9.2.4 ! paf         8: static const char* IDENT_VALUE_C="$Date: 2003/01/29 12:57:37 $";
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.9.2.3   paf        13: 
                     14: // globals
                     15: 
                     16: StringPtr value_name(new String(VALUE_NAME));
1.9.2.4 ! paf        17: StringPtr content_type_name(new String(CONTENT_TYPE_NAME));
1.9.2.3   paf        18: 
                     19: // methods
1.9.2.2   paf        20: 
                     21: VFilePtr Value::as_vfile(String::Untaint_lang /*lang*/=String::UL_UNSPECIFIED,
                     22:        bool /*origins_mode*/=false) { 
                     23:        bark("(%s) does not have file value"); 
                     24:        return VFilePtr(0);  //never
                     25: }
1.1       paf        26: 
                     27: /// call this before invoking to ensure proper actual numbered params count
                     28: void Method::check_actual_numbered_params(
1.8       paf        29:        Value& self, const String& actual_name, Array *actual_numbered_params) const {
1.1       paf        30: 
                     31:        int actual_count=actual_numbered_params?actual_numbered_params->size():0;
                     32:        if(actual_count<min_numbered_params_count) // not proper count? bark
                     33:                throw Exception("parser.runtime",
                     34:                        &actual_name,
                     35:                        "native method of %s (%s) accepts minimum %d parameter(s) (%d present)", 
1.8       paf        36:                                self.get_class()->name_cstr(),
                     37:                                self.type(),
1.1       paf        38:                                min_numbered_params_count,
                     39:                                actual_count);
                     40: 
                     41: }
1.4       paf        42: 
                     43: Junction::Junction(Pool& apool,
1.8       paf        44:        Value& aself,
1.7       paf        45:        const Method *amethod,
1.4       paf        46:        VMethodFrame *amethod_frame,
                     47:        Value *arcontext,
                     48:        WContext *awcontext,
                     49:        const Array *acode) : Pooled(apool),
                     50:        
                     51:        self(aself),
1.7       paf        52:        method(amethod),
1.4       paf        53:        method_frame(amethod_frame),
                     54:        rcontext(arcontext),
                     55:        wcontext(awcontext),
                     56:        code(acode) {
1.5       paf        57:        if(wcontext)
                     58:                wcontext->attach_junction(*this);
1.4       paf        59: }
                     60: 
1.5       paf        61: void Junction::reattach(WContext *new_wcontext) {
                     62:        if(new_wcontext)
                     63:                wcontext=new_wcontext;
                     64:        else {
                     65:                method_frame=0;
                     66:                rcontext=0;
                     67:                wcontext=0;
                     68:        }
1.4       paf        69: }
                     70: 
                     71: /*
                     72: void Junction::change_context(Junction *source) {
                     73:        if(source) {
                     74:                method_frame=source->method_frame;
                     75:                rcontext=source->rcontext;
                     76:                wcontext=source->wcontext;
                     77:        } else {
                     78:                method_frame=rcontext=0;
                     79:                wcontext=0;
                     80:        }
                     81: }
                     82: */
                     83: 
1.9.2.1   paf        84: // attributed meaning
                     85: 
                     86: static size_t date_attribute(const VDate& vdate, char *buf, size_t buf_size) {
                     87:     const char month_names[12][4]={
                     88:                "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
                     89:     const char days[7][4]={
                     90:                "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
                     91: 
                     92:        time_t when=vdate.get_time();
                     93:        struct tm *tms=gmtime(&when);
                     94:        if(!tms)
                     95:                throw Exception(0,
                     96:                        0,
                     97:                        "bad time in attribute value (seconds from epoch=%ld)", when);
                     98:        return snprintf(buf, MAX_STRING, "%s, %.2d-%s-%.4d %.2d:%.2d:%.2d GMT", 
                     99:                days[tms->tm_wday],
                    100:                tms->tm_mday,month_names[tms->tm_mon],tms->tm_year+1900,
                    101:                tms->tm_hour,tms->tm_min,tms->tm_sec);
                    102: }
                    103: static void append_attribute_meaning(String& result,
                    104:                                                                         Value& value, String::Untaint_lang lang, bool forced) {
                    105:        if(const String *string=value.get_string())
                    106:                result.append(string->join_chains(result.pool(), 0), lang, forced);
                    107:        else
                    108:                if(Value *vdate=value.as(VDATE_TYPE, false)) {
                    109:                        char *buf=(char *)result.malloc(MAX_STRING);
                    110:                        size_t size=date_attribute(*static_cast<VDate *>(vdate), 
                    111:                                buf, MAX_STRING);
                    112: 
                    113:                        result.APPEND_CLEAN(buf, size, "converted from date", 0);
                    114:                } else
                    115:                        throw Exception("parser.runtime",
                    116:                                &result,
                    117:                                "trying to append here neither string nor date (%s)",
                    118:                                        value.type());
                    119: }
                    120: #ifndef DOXYGEN
                    121: struct Attributed_meaning_info {
                    122:        String *header; // header line being constructed
                    123:        String::Untaint_lang lang; // language in which to append to that line
                    124:        bool forced; // do they force that lang?
                    125: };
                    126: #endif
                    127: static void append_attribute_subattribute(const Hash::Key& akey, Hash::Val *avalue, 
                    128:                                                                                  void *info) {
                    129:        if(akey==VALUE_NAME)
                    130:                return;
                    131: 
                    132:        Attributed_meaning_info& ami=*static_cast<Attributed_meaning_info *>(info);
                    133: 
                    134:        // ...; charset=windows1251
                    135:        *ami.header << "; ";
                    136:        ami.header->append(akey, ami.lang, ami.forced);
                    137:        *ami.header << "=";
                    138:        append_attribute_meaning(*ami.header, *static_cast<Value *>(avalue), ami.lang, ami.forced);
                    139: }
                    140: const String& attributed_meaning_to_string(Value& meaning, 
                    141:                                                                                   String::Untaint_lang lang, bool forced) {
                    142:        String &result=*new(meaning.pool()) String(meaning.pool());
                    143:        if(Hash *hash=meaning.get_hash(0)) {
                    144:                // $value(value) $subattribute(subattribute value)
                    145:                if(Value *value=static_cast<Value *>(hash->get(*value_name)))
                    146:                        append_attribute_meaning(result, *value, lang, forced);
                    147: 
                    148:                Attributed_meaning_info attributed_meaning_info={&result, lang};
                    149:                hash->for_each(append_attribute_subattribute, &attributed_meaning_info);
                    150:        } else // result value
                    151:                append_attribute_meaning(result, meaning, lang, forced);
                    152: 
                    153:        return result;
                    154: }

E-mail: