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: