diff options
Diffstat (limited to 'core/ustring.cpp')
| -rw-r--r-- | core/ustring.cpp | 283 |
1 files changed, 231 insertions, 52 deletions
diff --git a/core/ustring.cpp b/core/ustring.cpp index 0d887210c..66608379b 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -560,7 +560,7 @@ String String::get_slice(String p_splitter, int p_slice) const { int pos=0; int prev_pos=0; -// int slices=1; + //int slices=1; if (p_slice<0) return ""; if (find(p_splitter)==-1) @@ -574,7 +574,7 @@ String String::get_slice(String p_splitter, int p_slice) const { pos=length(); //reached end int from=prev_pos; - // int to=pos; + //int to=pos; if (p_slice==i) { @@ -612,6 +612,8 @@ String String::get_slicec(CharType p_splitter, int p_slice) const { if (p_slice==count) { return substr(prev,i-prev); + } else if (c[i]==0) { + return String(); } else { count++; prev=i+1; @@ -1418,7 +1420,7 @@ bool String::parse_utf8(const char* p_utf8,int p_len) { } } -// printf("char %i, len %i\n",unichar,len); + //printf("char %i, len %i\n",unichar,len); if (sizeof(wchar_t)==2 && unichar>0xFFFF) { unichar=' '; //too long for windows @@ -1543,49 +1545,98 @@ String::String(const StrRange& p_range) { copy_from(p_range.c_str,p_range.len); } -int String::hex_to_int() const { +int String::hex_to_int(bool p_with_prefix) const { - int l = length(); - if (l<3) - return 0; + int l = length(); + if (p_with_prefix && l<3) + return 0; - const CharType *s=ptr(); + const CharType *s=ptr(); - int sign = s[0]=='-' ? -1 : 1; + int sign = s[0]=='-' ? -1 : 1; - if (sign<0) { - s++; - l--; - if (l<2) - return 0; - } + if (sign<0) { + s++; + l--; + if (p_with_prefix && l<2) + return 0; + } - if (s[0]!='0' || s[1]!='x') - return 0; + if (p_with_prefix) { + if (s[0]!='0' || s[1]!='x') + return 0; + s+=2; + l-=2; + }; - s+=2; - l-=2; + int hex=0; - int hex=0; + while(*s) { - while(*s) { + CharType c = LOWERCASE(*s); + int n; + if (c>='0' && c<='9') { + n=c-'0'; + } else if (c>='a' && c<='f') { + n=(c-'a')+10; + } else { + return 0; + } - CharType c = LOWERCASE(*s); - int n; - if (c>='0' && c<='9') { - n=c-'0'; - } else if (c>='a' && c<='f') { - n=(c-'a')+10; - } else { - return 0; - } + hex*=16; + hex+=n; + s++; + } - hex*=16; - hex+=n; - s++; - } + return hex*sign; + +} + + +int64_t String::hex_to_int64(bool p_with_prefix) const { + + int l = length(); + if (p_with_prefix && l<3) + return 0; + + const CharType *s=ptr(); + + int64_t sign = s[0]=='-' ? -1 : 1; + + if (sign<0) { + s++; + l--; + if (p_with_prefix && l<2) + return 0; + } + + if (p_with_prefix) { + if (s[0]!='0' || s[1]!='x') + return 0; + s+=2; + l-=2; + }; + + int64_t hex=0; - return hex*sign; + while(*s) { + + CharType c = LOWERCASE(*s); + int64_t n; + if (c>='0' && c<='9') { + n=c-'0'; + } else if (c>='a' && c<='f') { + n=(c-'a')+10; + } else { + return 0; + } + + hex*=16; + hex+=n; + s++; + } + + return hex*sign; } @@ -2900,6 +2951,78 @@ bool String::matchn(const String& p_wildcard) const { } +String String::format(const Variant& values,String placeholder) const { + + String new_string = String( this->ptr() ); + + if( values.get_type() == Variant::ARRAY ) { + Array values_arr = values; + + for(int i=0;i<values_arr.size();i++) { + String i_as_str = String::num_int64( i ); + + if( values_arr[i].get_type() == Variant::ARRAY ) {//Array in Array structure [["name","RobotGuy"],[0,"godot"],["strength",9000.91]] + Array value_arr = values_arr[i]; + + if( value_arr.size()==2 ) { + Variant v_key = value_arr[0]; + String key; + + key = v_key.get_construct_string(); + if( key.left(1)=="\"" && key.right(key.length()-1)=="\"" ) { + key = key.substr(1,key.length()-2); + } + + Variant v_val = value_arr[1]; + String val; + val = v_val.get_construct_string(); + + if( val.left(1)=="\"" && val.right(val.length()-1)=="\"" ) { + val = val.substr(1,val.length()-2); + } + + new_string = new_string.replacen( placeholder.replace("_", key ), val ); + }else { + ERR_PRINT(String("STRING.format Inner Array size != 2 ").ascii().get_data()); + } + } else {//Array structure ["RobotGuy","Logis","rookie"] + Variant v_val = values_arr[i]; + String val; + val = v_val.get_construct_string(); + + if( val.left(1)=="\"" && val.right(val.length()-1)=="\"" ) { + val = val.substr(1,val.length()-2); + } + + new_string = new_string.replacen( placeholder.replace("_", i_as_str ), val ); + } + } + }else if( values.get_type() == Variant::DICTIONARY ) { + Dictionary d = values; + List<Variant> keys; + d.get_key_list(&keys); + + for (List<Variant>::Element *E=keys.front();E;E=E->next()) { + String key = E->get().get_construct_string(); + String val = d[E->get()].get_construct_string(); + + if( key.left(1)=="\"" && key.right(key.length()-1)=="\"" ) { + key = key.substr(1,key.length()-2); + } + + if( val.left(1)=="\"" && val.right(val.length()-1)=="\"" ) { + val = val.substr(1,val.length()-2); + } + + new_string = new_string.replacen( placeholder.replace("_", key ), val ); + } + }else{ + ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data()); + } + + return new_string; +} + String String::replace(String p_key,String p_with) const { String new_string; @@ -3073,6 +3196,11 @@ String String::simplify_path() const { } s =s.replace("\\","/"); + while(true){ // in case of using 2 or more slash + String compare = s.replace("//","/"); + if (s==compare) break; + else s=compare; + } Vector<String> dirs = s.split("/",false); for(int i=0;i<dirs.size();i++) { @@ -3173,7 +3301,7 @@ bool String::is_valid_identifier() const { //kind of poor should be rewritten properly -String String::world_wrap(int p_chars_per_line) const { +String String::word_wrap(int p_chars_per_line) const { int from=0; int last_space=0; @@ -3505,6 +3633,36 @@ bool String::is_valid_integer() const { } +bool String::is_valid_hex_number(bool p_with_prefix) const { + + int from = 0; + int len = length(); + + if (len!=1 && (operator[](0)=='+' || operator[](0)=='-')) + from++; + + if (p_with_prefix) { + + if (len < 2) + return false; + if (operator[](from) != '0' || operator[](from+1) != 'x') { + return false; + }; + from += 2; + }; + + for (int i=from; i<len; i++) { + + CharType c = operator[](i); + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) + continue; + return false; + }; + + return true; +}; + + bool String::is_valid_float() const { int len = length(); @@ -3641,20 +3799,41 @@ bool String::is_valid_html_color() const { } + bool String::is_valid_ip_address() const { - Vector<String> ip = split("."); - if (ip.size()!=4) - return false; - for(int i=0;i<ip.size();i++) { + if (find(":") >= 0) { - String n = ip[i]; - if (!n.is_valid_integer()) - return false; - int val = n.to_int(); - if (val<0 || val>255) + Vector<String> ip = split(":"); + for (int i=0; i<ip.size(); i++) { + + String n = ip[i]; + if (n.empty()) + continue; + if (n.is_valid_hex_number(false)) { + int nint = n.hex_to_int(false); + if (nint < 0 || nint > 0xffff) + return false; + continue; + }; + if (!n.is_valid_ip_address()) + return false; + }; + + } else { + Vector<String> ip = split("."); + if (ip.size()!=4) return false; - } + for(int i=0;i<ip.size();i++) { + + String n = ip[i]; + if (!n.is_valid_integer()) + return false; + int val = n.to_int(); + if (val<0 || val>255) + return false; + } + }; return true; } @@ -3705,7 +3884,7 @@ String String::get_file() const { return substr(sep+1,length()); } -String String::extension() const { +String String::get_extension() const { int pos = find_last("."); if (pos<0) @@ -3715,8 +3894,9 @@ String String::extension() const { } String String::plus_file(const String& p_file) const { - - if (length()>0 && operator [](length()-1)=='/') + if (empty()) + return p_file; + if (operator [](length()-1)=='/' || p_file.operator [](0)=='/') return *this+p_file; else return *this+"/"+p_file; @@ -3784,7 +3964,7 @@ String String::percent_decode() const { return String::utf8(pe.ptr()); } -String String::basename() const { +String String::get_basename() const { int pos = find_last("."); if (pos<0) @@ -4104,4 +4284,3 @@ String RTR(const String& p_text) { return p_text; } - |
