Annotation of parser3/src/classes/table.C, revision 1.7
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.7 ! paf 6: $Id: table.C,v 1.6 2001/03/12 20:36:52 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()) {
106: int offset=static_cast<int>(
107: r.process(*static_cast<Value *>(params->get(0))).get_double());
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:
! 129: Value& processed_body=r.process(body_code);
! 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.1 paf 140: void initialize_table_class(Pool& pool, VClass& vclass) {
1.2 paf 141: // ^table.set[data] ^table.set[nameless;data]
1.1 paf 142: vclass.add_native_method("set", _set, 1, 2);
1.2 paf 143:
1.5 paf 144: // ^table.load[file] ^table.load[nameless;file]
1.2 paf 145: vclass.add_native_method("load", _load, 1, 2);
1.6 paf 146:
147: // ^table.count[]
148: vclass.add_native_method("count", _count, 0, 0);
149:
150: // ^table.line[]
151: vclass.add_native_method("line", _line, 0, 0);
152:
153: // ^table.offset[] ^table.offset[offset]
154: vclass.add_native_method("offset", _offset, 0, 1);
1.7 ! paf 155:
! 156: // ^table.menu{code} ^table.menu{code}[delim]
! 157: vclass.add_native_method("menu", _menu, 1, 2);
1.1 paf 158: }
E-mail: