Diff for /parser3/src/classes/string.C between versions 1.255 and 1.263

version 1.255, 2024/09/28 14:37:53 version 1.263, 2025/10/05 19:41:27
Line 1 Line 1
 /** @file  /** @file
         Parser: @b string parser class.          Parser: @b string parser class.
   
         Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com)
         Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>          Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
 */  */
   
Line 15 Line 15
 #include "pa_vtable.h"  #include "pa_vtable.h"
 #include "pa_vbool.h"  #include "pa_vbool.h"
 #include "pa_string.h"  #include "pa_string.h"
   #include "pa_varray.h"
 #include "pa_sql_connection.h"  #include "pa_sql_connection.h"
 #include "pa_dictionary.h"  #include "pa_dictionary.h"
 #include "pa_vmethod_frame.h"  #include "pa_vmethod_frame.h"
Line 147  static void _bool(Request& r, MethodPara Line 148  static void _bool(Request& r, MethodPara
         // for some time due to stupid {} in original design          // for some time due to stupid {} in original design
         const String& fmt=r.process_to_string(fmt_maybe_code);          const String& fmt=r.process_to_string(fmt_maybe_code);
   
         const char* buf=format(r.get_self().as_double(), fmt.trim().cstrm());          const char* buf=format_double(r.get_self().as_double(), fmt.trim().cstrm());
   
         r.write(String(buf));          r.write(String(buf));
 }  }
Line 208  static void _pos(Request& r, MethodParam Line 209  static void _pos(Request& r, MethodParam
 struct Split_action_info {  struct Split_action_info {
         const String& src;          const String& src;
         ArrayString &result;          ArrayString &result;
           Split_action_info(const String& s, ArrayString& r) : src(s), result(r) {}
 };  };
   
 static void split_action(Table& , ArrayString* row, int prestart, int prefinish, int poststart, int postfinish, void *info) {  static void split_action(Table& , ArrayString* row, int prestart, int prefinish, int poststart, int postfinish, void *info) {
Line 225  static void split_list(Value& delim_valu Line 227  static void split_list(Value& delim_valu
                 vregex->study();                  vregex->study();
   
                 int matches_count=0;                  int matches_count=0;
                 Split_action_info ai = { string, result };                  Split_action_info ai(string, result);
   
                 string.match(vregex, split_action, &ai, matches_count);                  string.match(vregex, split_action, &ai, matches_count);
         } else          } else
Line 236  static void split_list(Value& delim_valu Line 238  static void split_list(Value& delim_valu
 #define SPLIT_RIGHT 0x0010  #define SPLIT_RIGHT 0x0010
 #define SPLIT_HORIZONTAL 0x0100  #define SPLIT_HORIZONTAL 0x0100
 #define SPLIT_VERTICAL 0x1000  #define SPLIT_VERTICAL 0x1000
   #define SPLIT_ARRAY 0x10000
   
 static int split_options(const String* options) {  static int split_options(const String* options) {
     struct Split_option {      struct Split_option {
Line 244  static int split_options(const String* o Line 247  static int split_options(const String* o
                 int setBit;                  int setBit;
                 int checkBit;                  int checkBit;
     } split_option[]={      } split_option[]={
                 {"l", "L", SPLIT_LEFT, SPLIT_RIGHT}, // 0xVHRL                  {"l", "L", SPLIT_LEFT, SPLIT_RIGHT}, // 0xAVHRL
                 {"r", "R", SPLIT_RIGHT, SPLIT_LEFT},                  {"r", "R", SPLIT_RIGHT, SPLIT_LEFT},
                 {"h", "H", SPLIT_HORIZONTAL, SPLIT_VERTICAL},                  {"h", "H", SPLIT_HORIZONTAL, SPLIT_VERTICAL | SPLIT_ARRAY},
                 {"v", "V", SPLIT_VERTICAL, SPLIT_HORIZONTAL},                  {"v", "V", SPLIT_VERTICAL, SPLIT_HORIZONTAL | SPLIT_ARRAY},
                   {"a", "A", SPLIT_ARRAY, SPLIT_VERTICAL | SPLIT_HORIZONTAL},
                 {0, 0, 0, 0}                  {0, 0, 0, 0}
     };      };
   
Line 302  static Table& split_horizontal(ArrayStri Line 306  static Table& split_horizontal(ArrayStri
         return table;          return table;
 }  }
   
   static VArray& split_array(ArrayString& pieces, bool right) {
           VArray& result=*new VArray(pieces.count());
           ArrayValue &array=result.array();
           if(right) { // right
                   for(int i=pieces.count(); --i>=0; )
                           array+=new VString(*pieces[i]);
           } else { // left
                   for(ArrayString::Iterator i(pieces); i; )
                           array+=new VString(*i.next());
           }
           return result;
   }
   
 static void split_with_options(Request& r, MethodParams& params, int bits) {  static void split_with_options(Request& r, MethodParams& params, int bits) {
         const String& string=GET_SELF(r, VString).string();          const String& string=GET_SELF(r, VString).string();
         size_t params_count=params.count();          size_t params_count=params.count();
Line 318  static void split_with_options(Request& Line 335  static void split_with_options(Request&
   
         bool right=(bits & SPLIT_RIGHT) != 0;          bool right=(bits & SPLIT_RIGHT) != 0;
         bool horizontal=(bits & SPLIT_HORIZONTAL) !=0;          bool horizontal=(bits & SPLIT_HORIZONTAL) !=0;
           bool array=(bits & SPLIT_ARRAY) !=0;
   
         const String* column_name=0;          const String* column_name=0;
         if(params_count>2){          if(params_count>2){
                 column_name=&params.as_string(2, COLUMN_NAME_MUST_BE_STRING);                  column_name=&params.as_string(2, COLUMN_NAME_MUST_BE_STRING);
                 if (horizontal && !column_name->is_empty())                   if (horizontal && !column_name->is_empty())
                         throw Exception(PARSER_RUNTIME, column_name, "column name can't be specified with horisontal split");                          throw Exception(PARSER_RUNTIME, column_name, "column name cannot be specified when splitting into a table horizontal row");
         }                   if (array && !column_name->is_empty())
         if(!column_name || column_name->is_empty())                          throw Exception(PARSER_RUNTIME, column_name, "column name cannot be specified when splitting into an array");
                 column_name=new String("piece");          }
   
         Table& table=horizontal?split_horizontal(pieces, right):split_vertical(pieces, right, column_name);  
   
         r.write(*new VTable(&table));          if(array){
                   r.write(split_array(pieces, right));
           } else {
                   if(!column_name || column_name->is_empty())
                           column_name=new String("piece");
                   Table& table=horizontal ? split_horizontal(pieces, right) : split_vertical(pieces, right, column_name);
                   r.write(*new VTable(&table));
           }
 }  }
 static void _split(Request& r, MethodParams& params) {  static void _split(Request& r, MethodParams& params) {
         split_with_options(r, params, 0 /* maybe-determine from param #2 */);          split_with_options(r, params, 0 /* maybe-determine from param #2 */);
Line 618  static void _save(Request& r, MethodPara Line 641  static void _save(Request& r, MethodPara
                 }                  }
         }          }
   
         const String& file_name=params.as_string(file_name_index, FILE_NAME_MUST_BE_STRING);          const String& file_name=params.as_file_name(file_name_index);
         const String& src=GET_SELF(r, VString).string();          const String& src=GET_SELF(r, VString).string();
   
         String::Body sbody=src.cstr_to_string_body_untaint(String::L_AS_IS, r.connection(false), &r.charsets);          String::Body sbody=src.cstr_to_string_body_untaint(String::L_AS_IS, r.connection(false), &r.charsets);
Line 667  static void _trim(Request& r, MethodPara Line 690  static void _trim(Request& r, MethodPara
 Base64Options base64_encode_options(Request& r, HashStringValue* options) {  Base64Options base64_encode_options(Request& r, HashStringValue* options) {
         Base64Options result;          Base64Options result;
         if(options) {          if(options) {
                 int valid_options=0;  
                 for(HashStringValue::Iterator i(*options); i; i.next()) {                  for(HashStringValue::Iterator i(*options); i; i.next()) {
                         String::Body key=i.key();                          String::Body key=i.key();
                         Value* value=i.value();                          Value* value=i.value();
                         if(key == "pad") {                          if(key == "pad") {
                                 result.pad=r.process(*value).as_bool();                                  result.pad=r.process(*value).as_bool();
                                 valid_options++;  
                         } else if(key == "wrap") {                          } else if(key == "wrap") {
                                 result.wrap=r.process(*value).as_bool();                                  result.wrap=r.process(*value).as_bool();
                                 valid_options++;  
                         } else if(key == "url-safe") {                          } else if(key == "url-safe") {
                                 if(r.process(*value).as_bool())                                  if(r.process(*value).as_bool())
                                         result.set_url_safe_abc();                                          result.set_url_safe_abc();
                                 valid_options++;                          } else
                         }                                  throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
                 }                  }
   
                 if(valid_options != options->count())  
                         throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);  
         }          }
         return result;          return result;
 }  }
Line 693  Base64Options base64_encode_options(Requ Line 710  Base64Options base64_encode_options(Requ
 Base64Options base64_decode_options(Request& r, HashStringValue* options) {  Base64Options base64_decode_options(Request& r, HashStringValue* options) {
         Base64Options result;          Base64Options result;
         if(options) {          if(options) {
                 int valid_options=0;  
                 for(HashStringValue::Iterator i(*options); i; i.next() ) {                  for(HashStringValue::Iterator i(*options); i; i.next() ) {
                         String::Body key=i.key();                          String::Body key=i.key();
                         Value* value=i.value();                          Value* value=i.value();
                         if(key == "pad") {                          if(key == "pad") {
                                 result.pad=r.process(*value).as_bool();                                  result.pad=r.process(*value).as_bool();
                                 valid_options++;  
                         } else if(key == "strict") {                          } else if(key == "strict") {
                                 result.strict=r.process(*value).as_bool();                                  result.strict=r.process(*value).as_bool();
                                 valid_options++;  
                         } else if(key == "url-safe") {                          } else if(key == "url-safe") {
                                 if(r.process(*value).as_bool())                                  if(r.process(*value).as_bool())
                                         result.set_url_safe_abc();                                          result.set_url_safe_abc();
                                 valid_options++;                          } else
                         }                                  throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
                 }                  }
   
                 if(valid_options != options->count())  
                         throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);  
         }          }
         return result;          return result;
 }  }
Line 769  static void _js_unescape(Request& r, Met Line 780  static void _js_unescape(Request& r, Met
 }  }
   
 static void _unescape(Request& r, MethodParams& params){  static void _unescape(Request& r, MethodParams& params){
         const String& mode=params.as_string(0, MODE_MUST_NOT_BE_CODE);          const String& mode=params.as_string(0, MODE_MUST_BE_STRING);
         const String& src=params.as_string(1, PARAMETER_MUST_BE_STRING);          const String& src=params.as_string(1, PARAMETER_MUST_BE_STRING);
   
         Charset* from_charset=&r.charsets.client();          Charset* from_charset=&r.charsets.client();
Line 791  static void _unescape(Request& r, Method Line 802  static void _unescape(Request& r, Method
         } else if(mode==UNESCAPE_MODE_URI){          } else if(mode==UNESCAPE_MODE_URI){
                 mode_js=false;                  mode_js=false;
         } else {          } else {
                 throw Exception(PARSER_RUNTIME, &mode, "is invalid mode, must be either '" UNESCAPE_MODE_JS "' or '" UNESCAPE_MODE_URI "'");                  throw Exception(PARSER_RUNTIME, &mode, "is an invalid mode, must be either '" UNESCAPE_MODE_JS "' or '" UNESCAPE_MODE_URI "'");
         }          }
   
         const char* unescaped=unescape_chars(src.cstr(), src.length(), from_charset, mode_js);          const char* unescaped=unescape_chars(src.cstr(), src.length(), from_charset, mode_js);

Removed from v.1.255  
changed lines
  Added in v.1.263


E-mail: