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: