Annotation of parser3/src/types/pa_vtable.C, revision 1.38
1.1 parser 1: /** @file
2: Parser: @b table class.
3:
1.37 moko 4: Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
1.11 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.14 paf 6: */
1.1 parser 7:
8: #include "pa_vtable.h"
9: #include "pa_vstring.h"
1.5 parser 10: #include "pa_vhash.h"
1.22 paf 11: #include "pa_vvoid.h"
1.1 parser 12:
1.38 ! moko 13: volatile const char * IDENT_PA_VTABLE_C="$Id: pa_vtable.C,v 1.37 2012-03-16 09:24:19 moko Exp $" IDENT_PA_VTABLE_H;
1.37 moko 14:
1.3 parser 15: #ifndef DOXYGEN
1.1 parser 16: struct Record_info {
1.22 paf 17: Table* table;
18: HashStringValue* hash;
1.1 parser 19: };
1.3 parser 20: #endif
1.29 misha 21:
22: static void store_column_item_to_hash(const String* column_name, Record_info *info) {
23: const String* column_item=info->table->item(*column_name);
24: info->hash->put(*column_name,
25: (column_item && !column_item->is_empty())
26: ?new VString(*column_item)
27: :new VString()
28: );
1.1 parser 29: }
1.29 misha 30:
1.22 paf 31: Value* VTable::fields_element() {
1.29 misha 32: Value& result=*new VHash;
1.22 paf 33: Table& ltable=table();
1.29 misha 34: if(!ltable.count())
35: return &result;
36:
37: HashStringValue* hash=result.get_hash();
38:
39: if(Table::columns_type columns=ltable.columns()) { // named
40: Record_info record_info={<able, hash};
1.1 parser 41: columns->for_each(store_column_item_to_hash, &record_info);
1.29 misha 42: } else { // nameless
43: size_t row_size=ltable[ltable.current()]->count(); // number of columns in current row
44: for(size_t index=0; index<row_size; index++){
45: const String* column_item=ltable.item(index);
46: hash->put(String::Body::Format(index),
47: (column_item && !column_item->is_empty())
48: ?new VString(*column_item)
49: :new VString()
50: );
51: }
1.1 parser 52: }
1.29 misha 53:
54: return &result;
1.1 parser 55: }
56:
1.31 misha 57: Value* VTable::get_element(const String& aname) {
1.1 parser 58: // fields
1.16 paf 59: if(aname==TABLE_FIELDS_ELEMENT_NAME)
1.1 parser 60: return fields_element();
61:
1.2 parser 62: // methods
1.31 misha 63: if(Value* result=VStateless_object::get_element(aname))
1.2 parser 64: return result;
65:
1.1 parser 66: // columns
67: if(ftable) {
1.16 paf 68: int index=ftable->column_name2index(aname, false);
69: if(index>=0) // column aname|number valid
1.32 pretende 70: {
71: const String* string=ftable->item(index); // there is such column
72: return new VString(string ? *string : String::Empty);
73: }
1.1 parser 74: }
75:
1.27 misha 76: throw Exception(PARSER_RUNTIME,
1.16 paf 77: &aname,
1.1 parser 78: "column not found");
79: }
1.33 misha 80:
1.36 moko 81:
82: String& VTable::get_json_string_array(String& result, const char *indent) {
83: // [
84: // ["c1", "c2", "c3" ...] || null (for nameless),
85: // ["v11", "v12", "v13" ...],
86: // ["v21", "v22", "v23" ...],
87: // ...
88: // ]
1.33 misha 89: Table& ltable=table();
1.35 moko 90:
1.36 moko 91: // columns
92: if(ltable.columns()){
93: // named
94: indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
95:
96: bool need_delim=false;
97: for(Array_iterator<const String*> c(*ltable.columns()); c.has_next(); ) {
98: if(need_delim)
99: result << "\",\"";
100: result.append(*c.next(), String::L_JSON, true/*forced lang*/);
101: need_delim=true;
102: }
103: result << "\"]";
104: } else {
105: // nameless
106: indent ? result << "\n\t" << indent << "null" : result << "\nnull";
107: }
108:
109: // data
110: if(ltable.count()){
111: result << ",";
112: for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
113: indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
1.33 misha 114: bool need_delim=false;
1.36 moko 115: for(Array_iterator<const String*> c(*r.next()); c.has_next(); ) {
1.33 misha 116: if(need_delim)
117: result << "\",\"";
118: result.append(*c.next(), String::L_JSON, true/*forced lang*/);
119: need_delim=true;
120: }
1.36 moko 121: r.has_next() ? result << "\"]," : result << "\"]";
1.35 moko 122: }
1.36 moko 123: }
124:
125: result << "\n" << indent;
126: return result;
127: }
128:
129: String& VTable::get_json_string_object(String& result, const char *indent) {
130: // [
131: // {"c1":"v11", "c2":"v12", "c3":"v13"},
132: // {"c1":"v21", "c2":"v22", "c3":"v23"},
133: // ...
134: // ]
135: Table& ltable=table();
136: ArrayString* columns=ltable.columns();
137: size_t columns_count = (columns) ? columns->count() : 0;
138:
139: for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
140: indent ? result << "\n\t" << indent << "{\"" : result << "\n{\"";
1.33 misha 141:
1.36 moko 142: ArrayString* row=r.next();
143: for(size_t index=0; index<row->count(); index++){
144: if(index)
145: result << "\",\"";
146: result.append(index < columns_count ? *columns->get(index) : String(format(index, 0)), String::L_JSON, true/*forced lang*/);
147: result << "\":\"";
148: result.append(*row->get(index), String::L_JSON, true/*forced lang*/);
1.33 misha 149: }
1.36 moko 150: r.has_next() ? result << "\"}," : result << "\"}\n" << indent;
151: }
152: return result;
153: }
154:
155: String& VTable::get_json_string_compact(String& result, const char *indent) {
156: // [
157: // "v11",
158: // ["v21", "v22", "v23" ...],
159: // ...
160: // ]
161: Table& ltable=table();
162:
163: for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
164: ArrayString& line=*r.next();
165: if (line.count()==1){
166: indent ? result << "\n\t" << indent << "\"" : result << "\n\"";
1.33 misha 167:
1.36 moko 168: result.append(*line[0], String::L_JSON, true/*forced lang*/);
169: r.has_next() ? result << "\"," : result << "\"\n" << indent;
170: } else {
171: indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
1.33 misha 172:
1.36 moko 173: bool need_delim=false;
174: for(Array_iterator<const String*> c(line); c.has_next(); ) {
175: if(need_delim)
1.33 misha 176: result << "\",\"";
1.36 moko 177: result.append(*c.next(), String::L_JSON, true/*forced lang*/);
178: need_delim=true;
1.33 misha 179: }
1.36 moko 180: r.has_next() ? result << "\"]," : result << "\"]\n" << indent;
181: }
182: }
183: return result;
184: }
185:
1.38 ! moko 186: const String* VTable::get_json_string(Json_options& options) {
1.36 moko 187: String* result = new String("[", String::L_AS_IS);
1.33 misha 188:
1.38 ! moko 189: switch(options.table){
1.36 moko 190: case Json_options::T_ARRAY:
1.38 ! moko 191: result=&get_json_string_array(*result, options.indent);
1.36 moko 192: break;
193: case Json_options::T_OBJECT:
1.38 ! moko 194: result=&get_json_string_object(*result, options.indent);
1.36 moko 195: break;
196: case Json_options::T_COMPACT:
1.38 ! moko 197: result=&get_json_string_compact(*result, options.indent);
1.36 moko 198: break;
1.33 misha 199: }
200:
1.36 moko 201: *result << "]";
202: return result;
203: }
E-mail: