Annotation of parser3/src/classes/string.C, revision 1.25
1.24 paf 1: /** @file
2: Parser: @b string parser class.
3:
1.4 paf 4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.24 paf 5:
1.5 paf 6: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
1.4 paf 7:
1.25 ! paf 8: $Id: string.C,v 1.24 2001/04/03 08:23:06 paf Exp $
1.1 paf 9: */
10:
11: #include "pa_request.h"
12: #include "_string.h"
13: #include "pa_vdouble.h"
14: #include "pa_vint.h"
1.17 paf 15: #include "pa_vtable.h"
1.25 ! paf 16: #include "pa_vbool.h"
1.1 paf 17:
18: // global var
19:
1.10 paf 20: VStateless_class *string_class;
1.1 paf 21:
22: // methods
23:
1.7 paf 24: static void _length(Request& r, const String&, Array *) {
1.1 paf 25: Pool& pool=r.pool();
1.15 paf 26: Value& value=*new(pool) VDouble(pool, r.self->get_string()->size());
1.11 paf 27: r.write_no_lang(value);
1.1 paf 28: }
29:
1.7 paf 30: static void _int(Request& r, const String&, Array *) {
1.1 paf 31: Pool& pool=r.pool();
1.13 paf 32: Value& value=*new(pool) VInt(pool, (int)r.self->as_double());
1.11 paf 33: r.write_no_lang(value);
1.1 paf 34: }
35:
1.7 paf 36: static void _double(Request& r, const String&, Array *) {
1.1 paf 37: Pool& pool=r.pool();
1.13 paf 38: Value& value=*new(pool) VDouble(pool, r.self->as_double());
1.11 paf 39: r.write_no_lang(value);
1.1 paf 40: }
41:
1.24 paf 42: /// ^string.format{format}
1.18 paf 43: /*not static*/void _string_format(Request& r, const String& method_name, Array *params) {
1.9 paf 44: Pool& pool=r.pool();
45:
46: Value& fmt=*static_cast<Value *>(params->get(0));
1.24 paf 47: // forcing {this param type}
48: r.fail_if_junction_(false, fmt, method_name, "fmt must be junction");
1.9 paf 49:
1.24 paf 50: Temp_lang temp_lang(r, String::UL_PASS_APPENDED);
51: char *buf=format(pool, r.self->as_double(), r.process(fmt).as_string().cstr());
1.9 paf 52:
1.12 paf 53: r.write_no_lang(String(pool, buf));
1.9 paf 54: }
1.11 paf 55:
1.18 paf 56: static void _left(Request& r, const String&, Array *params) {
1.15 paf 57: Pool& pool=r.pool();
58:
59: size_t n=(size_t)r.process(*static_cast<Value *>(params->get(0))).as_double();
60:
61: const String& string=*static_cast<VString *>(r.self)->get_string();
62: r.write_assign_lang(*new(pool) VString(string.piece(0, n)));
63: }
64:
1.18 paf 65: static void _right(Request& r, const String&, Array *params) {
1.15 paf 66: Pool& pool=r.pool();
67:
68: size_t n=(size_t)r.process(*static_cast<Value *>(params->get(0))).as_double();
69:
70: const String& string=*static_cast<VString *>(r.self)->get_string();
71: r.write_assign_lang(*new(pool) VString(string.piece(string.size()-n, string.size())));
72: }
73:
1.18 paf 74: static void _mid(Request& r, const String&, Array *params) {
1.15 paf 75: Pool& pool=r.pool();
76:
77: size_t p=(size_t)r.process(*static_cast<Value *>(params->get(0))).as_double();
78: size_t n=(size_t)r.process(*static_cast<Value *>(params->get(1))).as_double();
79:
80: const String& string=*static_cast<VString *>(r.self)->get_string();
81: r.write_assign_lang(*new(pool) VString(string.piece(p, p+n)));
82: }
83:
1.18 paf 84: static void _pos(Request& r, const String& method_name, Array *params) {
1.16 paf 85: Pool& pool=r.pool();
86:
87: Value& substr=*static_cast<Value *>(params->get(0));
1.17 paf 88: // forcing [this param type]
1.16 paf 89: r.fail_if_junction_(true, substr, method_name, "substr must not be junction");
90:
91: const String& string=*static_cast<VString *>(r.self)->get_string();
92: r.write_assign_lang(*new(pool) VInt(pool, string.pos(substr.as_string())));
93: }
94:
1.19 paf 95: static void split_list(Request& r, const String& method_name, Array *params,
1.23 paf 96: const String& string,
97: Array& result) {
1.17 paf 98: Pool& pool=r.pool();
99:
100: Value& delim_value=*static_cast<Value *>(params->get(0));
101: // forcing [this param type]
102: r.fail_if_junction_(true, delim_value, method_name, "delimiter must not be junction");
1.23 paf 103:
104: string.split(result, 0, delim_value.as_string(), String::UL_CLEAN, -1);
1.19 paf 105: }
106:
107: static void _lsplit(Request& r, const String& method_name, Array *params) {
108: Pool& pool=r.pool();
109: const String& string=*static_cast<VString *>(r.self)->get_string();
110:
1.21 paf 111: Array& row=*new(pool) Array(pool);
112: split_list(r, method_name, params, string, row);
1.19 paf 113:
1.21 paf 114: Table& table=*new(pool) Table(pool, &string,
115: 0/*nameless*/, 1/*row preallocate(and only)*/);
116: table+=&row;
1.19 paf 117:
118: r.write_no_lang(*new(pool) VTable(pool, &table));
119: }
120:
121: static void _rsplit(Request& r, const String& method_name, Array *params) {
122: Pool& pool=r.pool();
123: const String& string=*static_cast<VString *>(r.self)->get_string();
124:
125: Array list(pool);
126: split_list(r, method_name, params, string, list);
127:
1.21 paf 128: Array& row=*new(pool) Array(pool);
129: for(int i=list.size(); --i>=0; )
130: row+=list.get(i);
131:
132: Table& table=*new(pool) Table(pool, &string,
133: 0/*nameless*/, 1/*row preallocate(and only)*/);
134: table+=&row;
1.17 paf 135:
1.19 paf 136: r.write_no_lang(*new(pool) VTable(pool, &table));
1.17 paf 137: }
138:
1.24 paf 139: /// ^string.match{regexp}[options]
140: static void _match(Request& r, const String& method_name, Array *params) {
141: Pool& pool=r.pool();
142: const String& string=*static_cast<VString *>(r.self)->get_string();
143:
144: Value& regexp=*static_cast<Value *>(params->get(0));
145: // forcing {this param type}
146: r.fail_if_junction_(false, regexp, method_name, "regexp must be junction");
147:
148: Value& options=*static_cast<Value *>(params->get(1));
149: // forcing {this param type}
150: r.fail_if_junction_(true, options, method_name, "options must not be junction");
151:
152: Temp_lang temp_lang(r, String::UL_PASS_APPENDED);
1.25 ! paf 153: Table *table;
! 154: Value *result;
! 155: if(string.match(&method_name,
! 156: r.process(regexp).as_string(), options.as_string(),
! 157: &table)) {
! 158: // matched
! 159: if(table->columns()->size()==1) // just matched, no substrings
! 160: result=new(pool) VBool(pool, true);
! 161: else // table of match column+substring columns
! 162: result=new(pool) VTable(pool, table);
! 163: } else // not matched
! 164: result=new(pool) VBool(pool, false);
1.24 paf 165:
1.25 ! paf 166: r.write_no_lang(*result);
1.24 paf 167: }
168:
1.11 paf 169: // initialize
1.9 paf 170:
1.10 paf 171: void initialize_string_class(Pool& pool, VStateless_class& vclass) {
1.1 paf 172: // ^string.length[]
1.22 paf 173: vclass.add_native_method("length", Method::CT_DYNAMIC, _length, 0, 0);
1.6 paf 174:
1.1 paf 175: // ^string.int[]
1.22 paf 176: vclass.add_native_method("int", Method::CT_DYNAMIC, _int, 0, 0);
1.6 paf 177:
1.1 paf 178: // ^string.double[]
1.22 paf 179: vclass.add_native_method("double", Method::CT_DYNAMIC, _double, 0, 0);
1.9 paf 180:
1.24 paf 181: // ^string.format{format}
1.22 paf 182: vclass.add_native_method("format", Method::CT_DYNAMIC, _string_format, 1, 1);
1.14 paf 183:
1.15 paf 184: // ^string.left(n)
1.22 paf 185: vclass.add_native_method("left", Method::CT_DYNAMIC, _left, 1, 1);
1.15 paf 186: // ^string.right(n)
1.22 paf 187: vclass.add_native_method("right", Method::CT_DYNAMIC, _right, 1, 1);
1.15 paf 188: // ^string.mid(p;n)
1.22 paf 189: vclass.add_native_method("mid", Method::CT_DYNAMIC, _mid, 2, 2);
1.16 paf 190:
191: // ^string.pos[substr]
1.22 paf 192: vclass.add_native_method("pos", Method::CT_DYNAMIC, _pos, 1, 1);
1.17 paf 193:
194: // ^string.lsplit[delim]
1.22 paf 195: vclass.add_native_method("lsplit", Method::CT_DYNAMIC, _lsplit, 1, 1);
1.19 paf 196: // ^string.rsplit[delim]
1.22 paf 197: vclass.add_native_method("rsplit", Method::CT_DYNAMIC, _rsplit, 1, 1);
1.24 paf 198:
199: // ^string.match{regexp}[options]
200: vclass.add_native_method("match", Method::CT_DYNAMIC, _match, 2, 2);
1.2 paf 201: }
1.1 paf 202:
E-mail: