Annotation of parser3/src/types/pa_vresponse.C, revision 1.15
1.1 paf 1: /** @file
2: Parser: @b response class.
3:
1.5 paf 4: Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.4 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.6 paf 6: */
1.1 paf 7:
1.15 ! paf 8: static const char* IDENT_VRESPONSE_C="$Date: 2002/10/31 12:22:15 $";
1.1 paf 9:
10: #include "pa_vresponse.h"
11: #include "pa_charsets.h"
12: #include "pa_charset.h"
13: #include "pa_vstring.h"
1.11 paf 14: #include "pa_vdate.h"
1.1 paf 15:
1.15 ! paf 16: Value *VResponse::get_element(const String& aname, Value& aself, bool looking_up) {
1.1 paf 17: // $charset
1.8 paf 18: if(aname==CHARSET_NAME)
1.1 paf 19: return NEW VString(pool().get_client_charset().name());
1.8 paf 20:
21: // $method
1.10 paf 22: if(Value *result=VStateless_object::get_element(aname, aself, looking_up))
1.8 paf 23: return result;
24:
25: // $field
1.14 paf 26: return static_cast<Value *>(ffields.get(aname.change_case(pool(), String::CC_LOWER)));
1.1 paf 27: }
28:
1.8 paf 29: bool VResponse::put_element(const String& aname, Value *avalue, bool /*replace*/) {
1.1 paf 30: // guard charset change
1.8 paf 31: if(aname==CHARSET_NAME)
32: pool().set_client_charset(charsets->get_charset(avalue->as_string()));
1.2 paf 33: else
1.14 paf 34: ffields.put(aname.change_case(pool(), String::CC_LOWER), avalue);
1.8 paf 35:
36: return true;
1.1 paf 37: }
38:
1.11 paf 39: // helper funcs
40:
41: static size_t date_attribute(const VDate& vdate, char *buf, size_t buf_size) {
42: const char month_names[12][4]={
43: "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
44: const char days[7][4]={
45: "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
46:
47: time_t when=vdate.get_time();
48: struct tm *tms=gmtime(&when);
49: if(!tms)
50: throw Exception(0,
51: 0,
52: "bad time in attribute value (seconds from epoch=%ld)", when);
53: return snprintf(buf, MAX_STRING, "%s, %.2d-%s-%.4d %.2d:%.2d:%.2d GMT",
54: days[tms->tm_wday],
55: tms->tm_mday,month_names[tms->tm_mon],tms->tm_year+1900,
56: tms->tm_hour,tms->tm_min,tms->tm_sec);
57: }
58: static void append_attribute_meaning(String& result,
59: Value& value, String::Untaint_lang lang,
60: bool forced=false) {
61: if(const String *string=value.get_string())
1.13 paf 62: result.append(string->join_chains(result.pool(), 0), lang, forced);
1.11 paf 63: else
64: if(Value *vdate=value.as(VDATE_TYPE, false)) {
65: char *buf=(char *)result.malloc(MAX_STRING);
66: size_t size=date_attribute(*static_cast<VDate *>(vdate),
67: buf, MAX_STRING);
68:
1.12 paf 69: result.APPEND_CLEAN(buf, size, "converted from date", 0);
1.11 paf 70: } else
71: throw Exception("parser.runtime",
72: &result,
73: "trying to append here neither string nor date (%s)",
74: value.type());
75: }
76: #ifndef DOXYGEN
77: struct Attributed_meaning_info {
78: String *header; // header line being constructed
79: String::Untaint_lang lang; // language in which to append to that line
80: };
81: #endif
82: static void append_attribute_subattribute(const Hash::Key& akey, Hash::Val *avalue,
83: void *info) {
84: if(akey==VALUE_NAME)
85: return;
86:
87: Attributed_meaning_info& ami=*static_cast<Attributed_meaning_info *>(info);
88:
89: // ...; charset=windows1251
90: *ami.header << "; ";
91: ami.header->append(akey, ami.lang);
92: *ami.header << "=";
93: append_attribute_meaning(*ami.header, *static_cast<Value *>(avalue), ami.lang);
94: }
95: const String& attributed_meaning_to_string(Value& meaning,
96: String::Untaint_lang lang) {
97: String &result=*new(meaning.pool()) String(meaning.pool());
98: if(Hash *hash=meaning.get_hash(0)) {
99: // $value(value) $subattribute(subattribute value)
100: if(Value *value=static_cast<Value *>(hash->get(*value_name)))
101: append_attribute_meaning(result, *value, lang, true);
102:
103: Attributed_meaning_info attributed_meaning_info={&result, lang};
104: hash->for_each(append_attribute_subattribute, &attributed_meaning_info);
105: } else // result value
106: append_attribute_meaning(result, meaning, lang, true);
107:
108: return result;
109: }
E-mail: