Annotation of parser3/src/types/pa_value.C, revision 1.25
1.1 paf 1: /** @file
2: Parser: Value class.
3:
1.19 paf 4: Copyright (c) 2001-2005 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.25 ! misha 8: static const char * const IDENT_VALUE_C="$Date: 2008-02-21 14:17:12 $";
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: // globals
17:
18: const String name_name(NAME_NAME);
19:
20: const String value_name(VALUE_NAME);
1.12 paf 21: const String expires_name(EXPIRES_NAME);
1.10 paf 22: const String content_type_name(CONTENT_TYPE_NAME);
23:
24: // methods
25:
26: VObject* Value::set_derived(VObject* /*aderived*/) { return 0; }
27:
28: Junction* Value::get_junction() { return 0; }
29:
1.11 paf 30: Value* Value::base_object() { return bark("is '%s', it has no base object"); }
1.10 paf 31:
32: Value* Value::get_element(const String& /*aname*/, Value& /*aself*/, bool /*looking_up*/) {
1.11 paf 33: return bark("is '%s', it has no elements");
1.10 paf 34: }
35:
36:
37: VFile* Value::as_vfile(String::Language /*lang*/, const Request_charsets* /*charsets*/) {
1.11 paf 38: bark("is '%s', it does not have file value"); return 0;
1.10 paf 39: }
1.1 paf 40:
41: /// call this before invoking to ensure proper actual numbered params count
1.10 paf 42: void Method::check_actual_numbered_params(Value& self,
43: MethodParams* actual_numbered_params) const {
1.1 paf 44:
1.10 paf 45: int actual_count=actual_numbered_params?actual_numbered_params->count():0;
1.1 paf 46: if(actual_count<min_numbered_params_count) // not proper count? bark
1.22 misha 47: throw Exception(PARSER_RUNTIME,
1.10 paf 48: 0,
1.1 paf 49: "native method of %s (%s) accepts minimum %d parameter(s) (%d present)",
1.8 paf 50: self.get_class()->name_cstr(),
51: self.type(),
1.1 paf 52: min_numbered_params_count,
53: actual_count);
54:
55: }
1.4 paf 56:
1.10 paf 57: Junction::Junction(Value& aself,
58: const Method* amethod,
59: VMethodFrame* amethod_frame,
60: Value* arcontext,
61: WContext* awcontext,
62: ArrayOperation* acode): self(aself),
1.7 paf 63: method(amethod),
1.4 paf 64: method_frame(amethod_frame),
65: rcontext(arcontext),
66: wcontext(awcontext),
67: code(acode) {
1.5 paf 68: if(wcontext)
1.10 paf 69: wcontext->attach_junction(this);
1.4 paf 70: }
71:
1.5 paf 72: void Junction::reattach(WContext *new_wcontext) {
1.17 paf 73: if(new_wcontext) {
74: assert(wcontext!=new_wcontext);
1.5 paf 75: wcontext=new_wcontext;
1.17 paf 76: wcontext->attach_junction(this);
77: } else {
1.5 paf 78: method_frame=0;
79: rcontext=0;
80: wcontext=0;
81: }
1.4 paf 82: }
83:
1.10 paf 84: // attributed meaning
85:
86: static String::C date_attribute(const VDate& vdate) {
87: time_t when=vdate.get_time();
88: struct tm *tms=gmtime(&when);
89: if(!tms)
1.25 ! misha 90: throw Exception(DATE_RANGE_EXCEPTION_TYPE,
1.10 paf 91: 0,
1.15 paf 92: "bad time in attribute value (seconds from epoch=%u)", when);
1.24 misha 93: return date_gmt_string(tms);
94: }
1.10 paf 95:
96: static void append_attribute_meaning(String& result,
97: Value& value, String::Language lang, bool forced) {
98: if(const String* string=value.get_string())
99: result.append(*string, lang, forced);
100: else
101: if(Value* vdate=value.as(VDATE_TYPE, false)) {
102: String::C attribute=date_attribute(static_cast<VDate&>(*vdate));
103:
104: result.append_help_length(attribute.str, attribute.length, String::L_CLEAN);
105: } else
1.22 misha 106: throw Exception(PARSER_RUNTIME,
1.10 paf 107: &result,
108: "trying to append here neither string nor date (%s)",
109: value.type());
110: }
111: #ifndef DOXYGEN
112: struct Attributed_meaning_info {
113: String* header; // header line being constructed
114: String::Language lang; // language in which to append to that line
115: bool forced; // do they force that lang?
1.23 misha 116: bool allow_bool; // allow bool types during print attributes
1.10 paf 117: };
118: #endif
119: static void append_attribute_subattribute(HashStringValue::key_type akey,
120: HashStringValue::value_type avalue,
121: Attributed_meaning_info *info) {
122: if(akey==VALUE_NAME)
123: return;
124:
125: // ...; charset=windows1251
126: *info->header << "; ";
127: info->header->append(String(akey, String::L_TAINTED), info->lang, info->forced);
1.21 misha 128: if(!info->allow_bool || !avalue->is_bool()){
129: *info->header << "=";
130: append_attribute_meaning(*info->header, *avalue, info->lang, info->forced);
131: }
1.10 paf 132: }
133: const String& attributed_meaning_to_string(Value& meaning,
1.21 misha 134: String::Language lang, bool forced, bool allow_bool) {
1.10 paf 135: String& result=*new String;
136: if(HashStringValue *hash=meaning.get_hash()) {
137: // $value(value) $subattribute(subattribute value)
138: if(Value* value=hash->get(value_name))
139: append_attribute_meaning(result, *value, lang, forced);
140:
1.21 misha 141: Attributed_meaning_info attributed_meaning_info={&result, lang, false, allow_bool};
1.20 paf 142: hash->for_each<Attributed_meaning_info*>(append_attribute_subattribute, &attributed_meaning_info);
1.10 paf 143: } else // result value
144: append_attribute_meaning(result, meaning, lang, forced);
145:
146: return result;
147: }
E-mail: