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