--- parser3/src/classes/string.C 2002/09/18 08:52:49 1.120 +++ parser3/src/classes/string.C 2003/02/04 14:04:46 1.125.2.3 @@ -1,11 +1,11 @@ /** @file Parser: @b string parser class. - Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_STRING_C="$Date: 2002/09/18 08:52:49 $"; +static const char* IDENT_STRING_C="$Date: 2003/02/04 14:04:46 $"; #include "classes.h" #include "pa_request.h" @@ -29,38 +29,46 @@ public: // Methoded // methods -static void _length(Request& r, const String& method_name, MethodParams *) { +static void _length(Request& r, StringPtr method_name, MethodParams& ) { Pool& pool=r.pool(); double result=r.get_self()->get_string()->size(); r.write_no_lang(*new(pool) VDouble(pool, result)); } -static void _int(Request& r, const String& method_name, MethodParams *params) { +static void _int(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); + const String *self_string=r.get_self()->get_string(); int converted; - Value *default_code=params->size()>0? - default_code=¶ms->as_junction(0, "default must be int"):0; // (default) + Value *default_code=params.count()>0?¶ms.as_junction(0, "default must be int"):0; // (default) try { - converted=r.get_self()->as_int(); + if(!self_string || self_string->is_empty()) + throw Exception("parser.runtime", + &method_name, + "parameter is empty string, error converting"); + converted=self_string->as_int(); } catch(...) { // convert problem if(!default_code) // we have a problem when no default - /*re*/throw; + rethrow; else converted=r.process_to_value(*default_code).as_int(); } r.write_no_lang(*new(pool) VInt(pool, converted)); } -static void _double(Request& r, const String& method_name, MethodParams *params) { +static void _double(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); + const String *self_string=r.get_self()->get_string(); double converted; - Value *default_code=params->size()>0? - default_code=¶ms->as_junction(0, "default must be double"):0; // (default) + Value *default_code=params.count()>0?¶ms.as_junction(0, "default must be double"):0; // (default) try { - converted=r.get_self()->as_double(); + if(!self_string || self_string->is_empty()) + throw Exception("parser.runtime", + &method_name, + "parameter is empty string, error converting"); + converted=self_string->as_double(); } catch(...) { // convert problem if(!default_code) // we have a problem when no default - /*re*/throw; + rethrow; else converted=r.process_to_value(*default_code).as_double(); } @@ -68,10 +76,10 @@ static void _double(Request& r, const St r.write_no_lang(*new(pool) VDouble(pool, converted)); } -/*not static*/void _string_format(Request& r, const String& method_name, MethodParams *params) { +/*not static*/void _string_format(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); - Value& fmt_maybe_code=params->get(0); + Value& fmt_maybe_code=params.get(0); // for some time due to stupid {} in original design const String& fmt=r.process_to_string(fmt_maybe_code); @@ -84,39 +92,39 @@ static void _double(Request& r, const St r.write_no_lang(result); } -static void _left(Request& r, const String&, MethodParams *params) { +static void _left(Request& r, StringPtr /*method_name*/, MethodParams& params) { Pool& pool=r.pool(); - size_t n=(size_t)params->as_int(0, "n must be int", r); + size_t n=(size_t)params.as_int(0, "n must be int", r); const String& string=static_cast(r.get_self())->string(); r.write_assign_lang(string.mid(0, n)); } -static void _right(Request& r, const String&, MethodParams *params) { +static void _right(Request& r, StringPtr /*method_name*/, MethodParams& params) { Pool& pool=r.pool(); - size_t n=(size_t)params->as_int(0, "n must be int", r); + size_t n=(size_t)params.as_int(0, "n must be int", r); const String& string=static_cast(r.get_self())->string(); r.write_assign_lang(string.mid(string.size()-n, string.size())); } -static void _mid(Request& r, const String&, MethodParams *params) { +static void _mid(Request& r, StringPtr /*method_name*/, MethodParams& params) { Pool& pool=r.pool(); const String& string=*r.get_self()->get_string(); - size_t p=(size_t)max(0, params->as_int(0, "p must be int", r)); - size_t n=params->size()>1? - (size_t)max(0, params->as_int(1, "n must be int", r)):string.size(); + size_t p=(size_t)max(0, params.as_int(0, "p must be int", r)); + size_t n=params.count()>1? + (size_t)max(0, params.as_int(1, "n must be int", r)):string.size(); r.write_assign_lang(string.mid(p, p+n)); } -static void _pos(Request& r, const String& method_name, MethodParams *params) { +static void _pos(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); - Value& substr=params->as_no_junction(0, "substr must not be code"); + Value& substr=params.as_no_junction(0, "substr must not be code"); const String& string=static_cast(r.get_self())->string(); r.write_assign_lang(*new(pool) VInt(pool, string.pos(substr.as_string()))); @@ -126,7 +134,7 @@ static void split_list(Request& r, const MethodParams *params, int paramIndex, const String& string, Array& result) { - Value& delim_value=params->as_no_junction(paramIndex, "delimiter must not be code"); + Value& delim_value=params.as_no_junction(paramIndex, "delimiter must not be code"); string.split(result, 0, delim_value.as_string()); } @@ -138,8 +146,8 @@ static void split_list(Request& r, const static int split_options(const String *options) { struct Split_option { - const char *keyL; - const char *keyU; + const char* keyL; + const char* keyU; int setBit; int checkBit; } split_option[]={ @@ -212,7 +220,7 @@ static Table *split_horizontal(Request& return &table; } -static void split_with_options(Request& r, const String& method_name, MethodParams *params, +static void split_with_options(Request& r, StringPtr method_name, MethodParams& params, int bits) { Pool& pool=r.pool(); const String& string=*r.get_self()->get_string(); @@ -223,8 +231,8 @@ static void split_with_options(Request& if(!bits) { const String *options=0; - if(params->size()>1) { - options=¶ms->as_string(1, "options must not be code"); + if(params.count()>1) { + options=¶ms.as_string(1, "options must not be code"); } bits=split_options(options); } @@ -239,13 +247,13 @@ static void split_with_options(Request& r.write_no_lang(*new(pool) VTable(pool, table)); } -static void _split(Request& r, const String& method_name, MethodParams *params) { +static void _split(Request& r, StringPtr method_name, MethodParams& params) { split_with_options(r, method_name, params, 0 /* maybe-determine from param #2 */); } -static void _lsplit(Request& r, const String& method_name, MethodParams *params) { +static void _lsplit(Request& r, StringPtr method_name, MethodParams& params) { split_with_options(r, method_name, params, SPLIT_LEFT); } -static void _rsplit(Request& r, const String& method_name, MethodParams *params) { +static void _rsplit(Request& r, StringPtr method_name, MethodParams& params) { split_with_options(r, method_name, params, SPLIT_RIGHT); } @@ -287,17 +295,17 @@ static void replace_action(Table& table, } /// @todo use pcre:study somehow -static void _match(Request& r, const String& method_name, MethodParams *params) { +static void _match(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); - Value& regexp=params->as_no_junction(0, "regexp must not be code"); + Value& regexp=params.as_no_junction(0, "regexp must not be code"); const String *options= - params->size()>1? - ¶ms->as_no_junction(1, "options must not be code").as_string():0; + params.count()>1? + ¶ms.as_no_junction(1, "options must not be code").as_string():0; Temp_lang temp_lang(r, String::UL_PASS_APPENDED); Table *table; - if(params->size()<3) { // search + if(params.count()<3) { // search const String& src=static_cast(r.get_self())->string(); bool was_global; @@ -318,7 +326,7 @@ static void _match(Request& r, const Str } else { // replace const String& src=*r.get_self()->get_string(); - Value& replacement_code=params->as_junction(2, "replacement param must be code"); + Value& replacement_code=params.as_junction(2, "replacement param must be code"); String& result=*new(pool) String(pool); VTable vtable(pool); @@ -340,17 +348,17 @@ static void _match(Request& r, const Str } } -static void change_case(Request& r, const String& method_name, MethodParams *params, +static void change_case(Request& r, StringPtr method_name, MethodParams& params, String::Change_case_kind kind) { Pool& pool=r.pool(); const String& src=static_cast(r.get_self())->string(); r.write_assign_lang(src.change_case(pool, kind)); } -static void _upper(Request& r, const String& method_name, MethodParams *params) { +static void _upper(Request& r, StringPtr method_name, MethodParams& params) { change_case(r, method_name, params, String::CC_UPPER); } -static void _lower(Request& r, const String& method_name, MethodParams *params) { +static void _lower(Request& r, StringPtr method_name, MethodParams& params) { change_case(r, method_name, params, String::CC_LOWER); } @@ -358,7 +366,7 @@ static void _lower(Request& r, const Str class String_sql_event_handlers : public SQL_Driver_query_event_handlers { public: String_sql_event_handlers(Pool& apool, - const String& astatement_string, const char *astatement_cstr) : + const String& astatement_string, const char* astatement_cstr): pool(apool), statement_string(astatement_string), statement_cstr(astatement_cstr), @@ -366,45 +374,56 @@ public: result=new(pool) String(pool); } - void add_column(void *ptr, size_t size) { - if(got_column) - throw Exception("parser.runtime", + bool add_column(SQL_Error& error, void *ptr, size_t size) { + if(got_column) { + error=SQL_Error("parser.runtime", &statement_string, "result must contain exactly one column"); + return true; + } got_column=true; + return false; } - void before_rows() { /* ignore */ } - void add_row() { /* ignore */ } - void add_row_cell(void *ptr, size_t size) { - if(got_cell) - throw Exception("parser.runtime", + bool before_rows(SQL_Error& /*error*/ ) { /* ignore */ return false; } + bool add_row(SQL_Error& /*error*/) { /* ignore */ return false; } + bool add_row_cell(SQL_Error& error, void *ptr, size_t size) { + if(got_cell) { + error=SQL_Error("parser.runtime", &statement_string, "result must not contain more then one row"); - got_cell=true; + return true; + } - result->APPEND_TAINTED((const char *)ptr, size, statement_cstr, 0); + try { + got_cell=true; + result->APPEND_TAINTED((const char* )ptr, size, statement_cstr, 0); + return false; + } catch(...) { + error=SQL_Error("exception occured in String_sql_event_handlers::add_row_cell"); + return true; + } } private: Pool& pool; - const String& statement_string; const char *statement_cstr; + const String& statement_string; const char* statement_cstr; bool got_column; public: bool got_cell; String *result; }; #endif -const String* sql_result_string(Request& r, const String& method_name, MethodParams *params, +const String* sql_result_string(Request& r, StringPtr method_name, MethodParams& params, Hash *& options, Value *& default_code) { Pool& pool=r.pool(); - Value& statement=params->as_junction(0, "statement must be code"); + Value& statement=params.as_junction(0, "statement must be code"); ulong limit=0; ulong offset=0; default_code=0; - if(params->size()>1) { - Value& voptions=params->as_no_junction(1, "options must be hash, not code"); + if(params.count()>1) { + Value& voptions=params.as_no_junction(1, "options must be hash, not code"); if(!voptions.is_string()) if(options=voptions.get_hash(&method_name)) { if(Value *vlimit=(Value *)options->get(*sql_limit_name)) @@ -428,7 +447,7 @@ const String* sql_result_string(Request& Temp_lang temp_lang(r, String::UL_SQL); const String& statement_string=r.process_to_string(statement); - const char *statement_cstr= + const char* statement_cstr= statement_string.cstr(String::UL_UNSPECIFIED, r.connection(&method_name)); String_sql_event_handlers handlers(pool, statement_string, statement_cstr); r.connection(&method_name)->query( @@ -442,7 +461,7 @@ const String* sql_result_string(Request& return handlers.result; } -static void _sql(Request& r, const String& method_name, MethodParams *params) { +static void _sql(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); Hash *options; @@ -462,11 +481,11 @@ static void _sql(Request& r, const Strin r.write_assign_lang(*string); } -static void _replace(Request& r, const String& method_name, MethodParams *params) { +static void _replace(Request& r, StringPtr method_name, MethodParams& params) { Pool& pool=r.pool(); const String& src=*r.get_self()->get_string(); - Table *table=params->as_no_junction(0, "parameter must not be code").get_table(); + Table *table=params.as_no_junction(0, "parameter must not be code").get_table(); if(!table) throw Exception("parser.runtime", &method_name, @@ -476,15 +495,15 @@ static void _replace(Request& r, const S r.write_assign_lang(src.replace(pool, dict)); } -static void _save(Request& r, const String& method_name, MethodParams *params) { - const String& file_name=params->as_string(params->size()-1, +static void _save(Request& r, StringPtr method_name, MethodParams& params) { + const String& file_name=params.as_string(params.count()-1, "file name must be string"); const String& src=static_cast(r.get_self())->string(); bool do_append=false; - if(params->size()>1) { - const String& mode=params->as_string(0, "mode must be string"); + if(params.count()>1) { + const String& mode=params.as_string(0, "mode must be string"); if(mode=="append") do_append=true; else @@ -494,12 +513,12 @@ static void _save(Request& r, const Stri } // write - const char *buf=src.cstr(String::UL_UNSPECIFIED); + const char* buf=src.cstr(String::UL_UNSPECIFIED, r.connection(0/*no error if none*/)); file_write(r.absolute(file_name), buf, strlen(buf), true, do_append); } -static void _normalize(Request& r, const String& method_name, MethodParams * /*params*/) { +static void _normalize(Request& r, StringPtr method_name, MethodParams& /*params*/) { r.write_assign_lang(r.get_self()->get_string()->join_chains(r.pool(), 0/*cstr*/)); }