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: