Annotation of parser3/src/classes/table.C, revision 1.12
1.1 paf 1: /*
2: Parser
3: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
4: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
5:
1.11 paf 6: $Id: table.C,v 1.10 2001/03/12 21:54:18 paf Exp $
1.1 paf 7: */
8:
9: #include "pa_request.h"
10: #include "_table.h"
11: #include "pa_vtable.h"
1.2 paf 12: #include "pa_common.h"
1.6 paf 13: #include "pa_vint.h"
1.1 paf 14:
15: // global var
16:
17: VClass *table_class;
18:
19: // methods
20:
21:
22: // TODO: проверить ^set в ^menu & co
23:
1.2 paf 24: static void set_or_load(
25: Request& r,
26: const String& method_name, Array *params,
27: bool is_load) {
1.1 paf 28: Pool& pool=r.pool();
29: // data is last parameter
30: Value *vdata=static_cast<Value *>(params->get(params->size()-1));
1.4 paf 31: // forcing
32: // [this param type]
33: // [this param type]
1.3 paf 34: r.fail_if_junction_(true, *vdata,
35: method_name, "body must not be a junction");
1.1 paf 36:
1.2 paf 37: // data or file_name
38: char *data_or_filename=vdata->as_string().cstr();
39: // data
40: char *data=is_load?file_read(pool, r.absolute(data_or_filename)):data_or_filename;
1.1 paf 41:
42: // parse columns
43: Array *columns;
44: #ifndef NO_STRING_ORIGIN
45: const Origin& origin=method_name.origin();
1.2 paf 46: const char *file=origin.file;
1.1 paf 47: uint line=origin.line;
48: #endif
49: if(params->size()==2) {
50: columns=0;
51: } else {
52: columns=new(pool) Array(pool);
53:
54: if(char *row_chars=getrow(&data))
55: do {
56: String *name=new(pool) String(pool);
57: name->APPEND(lsplit(&row_chars, '\t'), 0, file, line++);
58: *columns+=name;
59: } while(row_chars);
60: }
61:
62: // parse cells
63: Table& table=*new(pool) Table(pool, method_name, columns);
64: char *row_chars;
65: while(row_chars=getrow(&data)) {
66: Array *row=new(pool) Array(pool);
67: while(char *cell_chars=lsplit(&row_chars, '\t')) {
68: String *cell=new(pool) String(pool);
69: cell->APPEND(cell_chars, 0, file, line);
70: *row+=cell;
71: }
72: line++;
73: table+=row;
74: };
75:
76: // replace any previous table value
77: r.self->as_vtable().set_table(table);
78: }
79:
1.2 paf 80:
81: static void _set(Request& r, const String& method_name, Array *params) {
82: set_or_load(r, method_name, params, false);
83: }
84:
85: static void _load(Request& r, const String& method_name, Array *params) {
86: set_or_load(r, method_name, params, true);
87: }
88:
1.6 paf 89: static void _count(Request& r, const String&, Array *) {
90: Pool& pool=r.pool();
91: Value& value=*new(pool) VInt(pool, r.self->as_vtable().table().size());
92: r.wcontext->write(value, String::Untaint_lang::NO /*always object, not string*/);
93: }
94:
95: static void _line(Request& r, const String&, Array *) {
96: Pool& pool=r.pool();
97: Value& value=*new(pool) VInt(pool, 1+r.self->as_vtable().table().get_current());
98: r.wcontext->write(value, String::Untaint_lang::NO /*always object, not string*/);
99: }
100:
101: static void _offset(Request& r, const String&, Array *params) {
102: Pool& pool=r.pool();
103: Table& table=r.self->as_vtable().table();
104: if(params->size()) {
105: if(int size=table.size()) {
1.9 paf 106: int offset=
107: (int)r.process(*static_cast<Value *>(params->get(0))).get_double();
1.6 paf 108: table.set_current((table.get_current()+offset+size)%size);
109: }
110: } else {
111: Value& value=*new(pool) VInt(pool, table.get_current());
112: r.wcontext->write(value, String::Untaint_lang::NO /*always object, not string*/);
113: }
114: }
115:
1.7 paf 116: static void _menu(Request& r, const String& method_name, Array *params) {
117: Value& body_code=*static_cast<Value *>(params->get(0));
118: // forcing ^menu{this param type}
119: r.fail_if_junction_(false, body_code,
120: method_name, "body must be junction");
121:
122: Value *delim_code=params->size()==2?static_cast<Value *>(params->get(1)):0;
123:
124: Table& table=r.self->as_vtable().table();
125: bool need_delim=false;
126: for(int i=0; i<table.size(); i++) {
127: table.set_current(i);
128:
1.12 ! paf 129: Value& processed_body=r.process(body_code);
1.7 paf 130: if(delim_code) { // delimiter set?
131: const String *string=processed_body.get_string();
132: if(need_delim && string && string->size()) // need delim & iteration produced string?
133: r.write_pass_lang(r.process(*delim_code));
134: need_delim=true;
135: }
136: r.write_pass_lang(processed_body);
137: }
138: }
139:
1.8 paf 140: static void _empty(Request& r, const String&, Array *params) {
141: Table& table=r.self->as_vtable().table();
142: if(table.size()==0) {
143: Value& value=r.process(*static_cast<Value *>(params->get(0)));
144: r.write_pass_lang(value);
145: } else if(params->size()==2) {
146: Value& value=r.process(*static_cast<Value *>(params->get(1)));
147: r.write_pass_lang(value);
148: }
149: }
150:
1.1 paf 151: void initialize_table_class(Pool& pool, VClass& vclass) {
1.10 paf 152: // ^table.set[data]
153: // ^table.set[nameless;data]
1.1 paf 154: vclass.add_native_method("set", _set, 1, 2);
1.2 paf 155:
1.10 paf 156: // ^table.load[file]
157: // ^table.load[nameless;file]
1.2 paf 158: vclass.add_native_method("load", _load, 1, 2);
1.6 paf 159:
160: // ^table.count[]
161: vclass.add_native_method("count", _count, 0, 0);
162:
163: // ^table.line[]
164: vclass.add_native_method("line", _line, 0, 0);
165:
1.10 paf 166: // ^table.offset[]
167: // ^table.offset[offset]
1.6 paf 168: vclass.add_native_method("offset", _offset, 0, 1);
1.7 paf 169:
1.10 paf 170: // ^table.menu{code}
171: // ^table.menu{code}[delim]
1.7 paf 172: vclass.add_native_method("menu", _menu, 1, 2);
1.8 paf 173:
1.10 paf 174: // ^table.empty{code-when-empty}
175: // ^table.empty{code-when-empty}{code-when-not}
1.8 paf 176: vclass.add_native_method("empty", _empty, 1, 2);
177:
1.1 paf 178: }
E-mail: