Diff for /parser3/src/classes/string.C between versions 1.219 and 1.225

version 1.219, 2015/09/03 20:47:21 version 1.225, 2016/05/18 17:47:22
Line 1 Line 1
 /** @file  /** @file
         Parser: @b string parser class.          Parser: @b string parser class.
   
         Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
Line 31  public: Line 31  public:
   
 // global variable  // global variable
   
 DECLARE_CLASS_VAR(string, new MString, 0);  DECLARE_CLASS_VAR(string, new MString);
   
 // void class, inherited from string and thus should be inited afterwards  // void class, inherited from string and thus should be inited afterwards
   
Line 42  public: Line 42  public:
   
 // void global variable should be after string global variable  // void global variable should be after string global variable
   
 DECLARE_CLASS_VAR(void, new MVoid, 0);  DECLARE_CLASS_VAR(void, new MVoid);
   
 // defines for statics  // defines for statics
   
Line 53  DECLARE_CLASS_VAR(void, new MVoid, 0); Line 53  DECLARE_CLASS_VAR(void, new MVoid, 0);
   
 #define MODE_APPEND "append"  #define MODE_APPEND "append"
   
   #define UNESCAPE_MODE_JS "js"
   #define UNESCAPE_MODE_URI "uri"
   
 // statics  // statics
   
 static const String match_var_name(MATCH_VAR_NAME);  static const String match_var_name(MATCH_VAR_NAME);
Line 89  static void _int(Request& r, MethodParam Line 92  static void _int(Request& r, MethodParam
   
 static void _double(Request& r, MethodParams& params) {  static void _double(Request& r, MethodParams& params) {
         const String& self_string=GET_SELF(r, VString).string();          const String& self_string=GET_SELF(r, VString).string();
         double converted;  
   
         if(self_string.is_empty()) {          if(self_string.is_empty()) {
                 if(params.count()>0)                  if(params.count()>0)
                         converted=params.as_double(0, "default must be double", r); // (default)                          r.write_no_lang(*new VDouble(params.as_double(0, "default must be double", r))); // (default)
                 else                  else
                         throw Exception(PARSER_RUNTIME, 0, "unable to convert empty string without default specified");                          throw Exception(PARSER_RUNTIME, 0, "unable to convert empty string without default specified");
         } else {          } else {
                 try {                  try {
                         converted=self_string.as_double();                          r.write_no_lang(*new VDouble(self_string.as_double()));
                 } catch(...) { // convert problem                  } catch(...) { // convert problem
                         if(params.count()>0)                          if(params.count()>0)
                                 converted=params.as_double(0, "default must be double", r); // (default)                                  r.write_no_lang(*new VDouble(params.as_double(0, "default must be double", r))); // (default)
                         else                          else
                                 rethrow; // we have a problem when no default                                  rethrow; // we have a problem when no default
                 }                  }
         }          }
   
         r.write_no_lang(*new VDouble(converted));  
 }  }
   
 static void _bool(Request& r, MethodParams& params) {  static void _bool(Request& r, MethodParams& params) {
Line 748  static void _idna(Request& r, MethodPara Line 748  static void _idna(Request& r, MethodPara
         }          }
 }  }
   
 static void _escape(Request& r, MethodParams&){  static void _js_escape(Request& r, MethodParams&){
         const String& src=GET_SELF(r, VString).string();          const String& src=GET_SELF(r, VString).string();
         r.write_assign_lang(src.escape(r.charsets.source()));          r.write_assign_lang(src.escape(r.charsets.source()));
 }  }
   
 static void _unescape(Request& r, MethodParams& params){  static void _js_unescape(Request& r, MethodParams& params){
         const String& src=params.as_string(0, PARAMETER_MUST_BE_STRING);          const String& src=params.as_string(0, PARAMETER_MUST_BE_STRING);
         if(const char* result=unescape_chars(src.cstr(), src.length(), &r.charsets.source(), true))          if(const char* result=unescape_chars(src.cstr(), src.length(), &r.charsets.source(), true))
                 r.write_assign_lang(*new String(result, String::L_TAINTED));                  r.write_assign_lang(*new String(result, String::L_TAINTED));
 }  }
   
   static void _unescape(Request& r, MethodParams& params){
           const String& mode=params.as_string(0, MODE_MUST_NOT_BE_CODE);
           const String& src=params.as_string(1, PARAMETER_MUST_BE_STRING);
   
           Charset* from_charset=&r.charsets.client();
   
           if(params.count() > 2)
                   if(HashStringValue* options=params.as_hash(2)) {
                           int valid_options=0;
                           if(Value* vcharset_name=options->get(PA_CHARSET_NAME)){
                                   from_charset=&::charsets.get(vcharset_name->as_string().change_case(r.charsets.source(), String::CC_UPPER));
                                   valid_options++;
                           }
                           if(valid_options!=options->count())
                                   throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
                   }
   
           bool mode_js;
           if(mode==UNESCAPE_MODE_JS){
                   mode_js=true;
           } else if(mode==UNESCAPE_MODE_URI){
                   mode_js=false;
           } else {
                   throw Exception(PARSER_RUNTIME, &mode, "is 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);
           if(*unescaped){
                   const String* result=new String(Charset::transcode(unescaped, *from_charset, r.charsets.source()), String::L_TAINTED);
                   r.write_assign_lang(*result);
           }
   }
   
   static void _contains(Request& r, MethodParams& params) {
           // empty or whitespace string is hash compatible
           GET_SELF(r, VString).get_element(params.as_string(0, "key must be string"));
           // ignoring result as it allways null
           r.write_no_lang(VBool::get(false));
   }
   
 // constructor  // constructor
   
 MString::MString(): Methoded("string") {  MString::MString(): Methoded("string") {
Line 837  MString::MString(): Methoded("string") { Line 877  MString::MString(): Methoded("string") {
         add_native_method("idna", Method::CT_ANY, _idna, 0, 1);          add_native_method("idna", Method::CT_ANY, _idna, 0, 1);
   
         // ^string.js-escape[]          // ^string.js-escape[]
         add_native_method("js-escape", Method::CT_DYNAMIC, _escape, 0, 0);          add_native_method("js-escape", Method::CT_DYNAMIC, _js_escape, 0, 0);
   
         // ^string:js-unescape[escaped%uXXXXstring]          // ^string:js-unescape[escaped%uXXXXstring]
         add_native_method("js-unescape", Method::CT_STATIC, _unescape, 1, 1);          add_native_method("js-unescape", Method::CT_STATIC, _js_unescape, 1, 1);
 }         
           // ^string:unescape[js|uri;escaped;$.charset[...]]
           add_native_method("unescape", Method::CT_STATIC, _unescape, 2, 3);
   
           // ^string.contains[key] for hash compatibility
           add_native_method("contains", Method::CT_DYNAMIC, _contains, 1, 1);
   }

Removed from v.1.219  
changed lines
  Added in v.1.225


E-mail: