2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* ustring.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 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 */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2020-08-05 08:25:28 +02:00
# ifndef USTRING_GODOT_H
# define USTRING_GODOT_H
2014-02-10 02:10:30 +01:00
2022-09-26 13:03:44 +02:00
// Note: _GODOT suffix added to header guard to avoid conflict with ICU header.
2022-02-04 09:32:20 +01:00
# include "core/string/char_utils.h"
2020-11-07 23:33:38 +01:00
# include "core/templates/cowdata.h"
# include "core/templates/vector.h"
2018-09-11 18:13:45 +02:00
# include "core/typedefs.h"
2020-11-07 23:33:38 +01:00
# include "core/variant/array.h"
2014-02-10 02:10:30 +01:00
2020-07-27 12:43:20 +02:00
/*************************************************************************/
/* CharProxy */
/*************************************************************************/
2024-03-08 03:29:49 +01:00
template < typename T >
2018-12-16 01:44:18 +01:00
class CharProxy {
2020-07-27 12:43:20 +02:00
friend class Char16String ;
2018-12-16 01:44:18 +01:00
friend class CharString ;
friend class String ;
const int _index ;
CowData < T > & _cowdata ;
2019-01-04 17:01:54 +01:00
static const T _null = 0 ;
2018-12-16 01:44:18 +01:00
2021-09-30 23:02:41 +02:00
_FORCE_INLINE_ CharProxy ( const int & p_index , CowData < T > & p_cowdata ) :
2018-12-16 01:44:18 +01:00
_index ( p_index ) ,
2021-09-30 23:02:41 +02:00
_cowdata ( p_cowdata ) { }
2018-12-16 01:44:18 +01:00
public :
2021-09-30 23:02:41 +02:00
_FORCE_INLINE_ CharProxy ( const CharProxy < T > & p_other ) :
_index ( p_other . _index ) ,
_cowdata ( p_other . _cowdata ) { }
2018-12-16 01:44:18 +01:00
_FORCE_INLINE_ operator T ( ) const {
2020-05-14 16:41:43 +02:00
if ( unlikely ( _index = = _cowdata . size ( ) ) ) {
2019-01-04 17:01:54 +01:00
return _null ;
2020-05-14 16:41:43 +02:00
}
2019-01-04 17:01:54 +01:00
2018-12-16 01:44:18 +01:00
return _cowdata . get ( _index ) ;
}
_FORCE_INLINE_ const T * operator & ( ) const {
return _cowdata . ptr ( ) + _index ;
}
2021-09-30 23:02:41 +02:00
_FORCE_INLINE_ void operator = ( const T & p_other ) const {
_cowdata . set ( _index , p_other ) ;
2018-12-16 01:44:18 +01:00
}
2021-09-30 23:02:41 +02:00
_FORCE_INLINE_ void operator = ( const CharProxy < T > & p_other ) const {
_cowdata . set ( _index , p_other . operator T ( ) ) ;
2018-12-16 01:44:18 +01:00
}
} ;
2020-07-27 12:43:20 +02:00
/*************************************************************************/
/* Char16String */
/*************************************************************************/
class Char16String {
CowData < char16_t > _cowdata ;
static const char16_t _null ;
public :
_FORCE_INLINE_ char16_t * ptrw ( ) { return _cowdata . ptrw ( ) ; }
_FORCE_INLINE_ const char16_t * ptr ( ) const { return _cowdata . ptr ( ) ; }
_FORCE_INLINE_ int size ( ) const { return _cowdata . size ( ) ; }
Error resize ( int p_size ) { return _cowdata . resize ( p_size ) ; }
_FORCE_INLINE_ char16_t get ( int p_index ) const { return _cowdata . get ( p_index ) ; }
_FORCE_INLINE_ void set ( int p_index , const char16_t & p_elem ) { _cowdata . set ( p_index , p_elem ) ; }
_FORCE_INLINE_ const char16_t & operator [ ] ( int p_index ) const {
if ( unlikely ( p_index = = _cowdata . size ( ) ) ) {
return _null ;
}
return _cowdata . get ( p_index ) ;
}
_FORCE_INLINE_ CharProxy < char16_t > operator [ ] ( int p_index ) { return CharProxy < char16_t > ( p_index , _cowdata ) ; }
_FORCE_INLINE_ Char16String ( ) { }
_FORCE_INLINE_ Char16String ( const Char16String & p_str ) { _cowdata . _ref ( p_str . _cowdata ) ; }
2021-11-30 15:19:26 +01:00
_FORCE_INLINE_ void operator = ( const Char16String & p_str ) { _cowdata . _ref ( p_str . _cowdata ) ; }
2020-07-27 12:43:20 +02:00
_FORCE_INLINE_ Char16String ( const char16_t * p_cstr ) { copy_from ( p_cstr ) ; }
2021-11-30 15:19:26 +01:00
void operator = ( const char16_t * p_cstr ) ;
2020-07-27 12:43:20 +02:00
bool operator < ( const Char16String & p_right ) const ;
Char16String & operator + = ( char16_t p_char ) ;
int length ( ) const { return size ( ) ? size ( ) - 1 : 0 ; }
const char16_t * get_data ( ) const ;
operator const char16_t * ( ) const { return get_data ( ) ; } ;
protected :
void copy_from ( const char16_t * p_cstr ) ;
} ;
/*************************************************************************/
/* CharString */
/*************************************************************************/
2018-07-25 03:11:03 +02:00
class CharString {
CowData < char > _cowdata ;
2019-01-04 17:01:54 +01:00
static const char _null ;
2018-07-25 03:11:03 +02:00
2016-03-09 00:00:52 +01:00
public :
2018-07-25 03:11:03 +02:00
_FORCE_INLINE_ char * ptrw ( ) { return _cowdata . ptrw ( ) ; }
_FORCE_INLINE_ const char * ptr ( ) const { return _cowdata . ptr ( ) ; }
_FORCE_INLINE_ int size ( ) const { return _cowdata . size ( ) ; }
Error resize ( int p_size ) { return _cowdata . resize ( p_size ) ; }
2019-02-21 20:24:29 +01:00
_FORCE_INLINE_ char get ( int p_index ) const { return _cowdata . get ( p_index ) ; }
2018-07-25 03:11:03 +02:00
_FORCE_INLINE_ void set ( int p_index , const char & p_elem ) { _cowdata . set ( p_index , p_elem ) ; }
2019-01-04 17:01:54 +01:00
_FORCE_INLINE_ const char & operator [ ] ( int p_index ) const {
2020-05-14 16:41:43 +02:00
if ( unlikely ( p_index = = _cowdata . size ( ) ) ) {
2019-01-04 17:01:54 +01:00
return _null ;
2020-05-14 16:41:43 +02:00
}
2019-01-04 17:01:54 +01:00
return _cowdata . get ( p_index ) ;
}
2018-12-16 01:44:18 +01:00
_FORCE_INLINE_ CharProxy < char > operator [ ] ( int p_index ) { return CharProxy < char > ( p_index , _cowdata ) ; }
2018-07-25 03:11:03 +02:00
_FORCE_INLINE_ CharString ( ) { }
_FORCE_INLINE_ CharString ( const CharString & p_str ) { _cowdata . _ref ( p_str . _cowdata ) ; }
2021-11-30 15:19:26 +01:00
_FORCE_INLINE_ void operator = ( const CharString & p_str ) { _cowdata . _ref ( p_str . _cowdata ) ; }
2019-03-12 13:57:22 +01:00
_FORCE_INLINE_ CharString ( const char * p_cstr ) { copy_from ( p_cstr ) ; }
2018-07-25 03:11:03 +02:00
2021-11-30 15:19:26 +01:00
void operator = ( const char * p_cstr ) ;
2017-03-05 16:44:50 +01:00
bool operator < ( const CharString & p_right ) const ;
2022-11-18 14:17:37 +01:00
bool operator = = ( const CharString & p_right ) const ;
2018-07-25 03:11:03 +02:00
CharString & operator + = ( char p_char ) ;
2017-03-05 16:44:50 +01:00
int length ( ) const { return size ( ) ? size ( ) - 1 : 0 ; }
2014-02-10 02:10:30 +01:00
const char * get_data ( ) const ;
2018-12-03 21:25:23 +01:00
operator const char * ( ) const { return get_data ( ) ; } ;
2019-03-12 13:57:22 +01:00
protected :
void copy_from ( const char * p_cstr ) ;
2014-02-10 02:10:30 +01:00
} ;
2020-07-27 12:43:20 +02:00
/*************************************************************************/
/* String */
/*************************************************************************/
2016-06-19 00:05:23 +02:00
2014-02-10 02:10:30 +01:00
struct StrRange {
2020-07-27 12:43:20 +02:00
const char32_t * c_str ;
2014-02-10 02:10:30 +01:00
int len ;
2020-07-27 12:43:20 +02:00
StrRange ( const char32_t * p_c_str = nullptr , int p_len = 0 ) {
2017-03-05 16:44:50 +01:00
c_str = p_c_str ;
len = p_len ;
}
2014-02-10 02:10:30 +01:00
} ;
2018-07-25 03:11:03 +02:00
class String {
2020-07-27 12:43:20 +02:00
CowData < char32_t > _cowdata ;
static const char32_t _null ;
2023-03-11 10:31:41 +01:00
static const char32_t _replacement_char ;
2014-02-10 02:10:30 +01:00
void copy_from ( const char * p_cstr ) ;
2020-07-27 12:43:20 +02:00
void copy_from ( const char * p_cstr , const int p_clip_to ) ;
void copy_from ( const wchar_t * p_cstr ) ;
void copy_from ( const wchar_t * p_cstr , const int p_clip_to ) ;
void copy_from ( const char32_t * p_cstr ) ;
void copy_from ( const char32_t * p_cstr , const int p_clip_to ) ;
void copy_from ( const char32_t & p_char ) ;
void copy_from_unchecked ( const char32_t * p_char , const int p_length ) ;
2017-03-05 16:44:50 +01:00
bool _base_is_subsequence_of ( const String & p_string , bool case_insensitive ) const ;
2019-01-18 09:29:28 +01:00
int _count ( const String & p_string , int p_from , int p_to , bool p_case_insensitive ) const ;
2022-08-30 11:36:24 +02:00
String _camelcase_to_underscore ( ) const ;
2014-02-10 02:10:30 +01:00
public :
enum {
2017-03-05 16:44:50 +01:00
npos = - 1 ///<for "some" compatibility with std::string (npos is a huge value in std::string)
2014-02-10 02:10:30 +01:00
} ;
2020-07-27 12:43:20 +02:00
_FORCE_INLINE_ char32_t * ptrw ( ) { return _cowdata . ptrw ( ) ; }
_FORCE_INLINE_ const char32_t * ptr ( ) const { return _cowdata . ptr ( ) ; }
2018-07-25 03:11:03 +02:00
2021-07-04 00:17:03 +02:00
void remove_at ( int p_index ) { _cowdata . remove_at ( p_index ) ; }
2018-07-25 03:11:03 +02:00
_FORCE_INLINE_ void clear ( ) { resize ( 0 ) ; }
2020-07-27 12:43:20 +02:00
_FORCE_INLINE_ char32_t get ( int p_index ) const { return _cowdata . get ( p_index ) ; }
_FORCE_INLINE_ void set ( int p_index , const char32_t & p_elem ) { _cowdata . set ( p_index , p_elem ) ; }
2018-07-25 03:11:03 +02:00
_FORCE_INLINE_ int size ( ) const { return _cowdata . size ( ) ; }
Error resize ( int p_size ) { return _cowdata . resize ( p_size ) ; }
2018-12-16 01:44:18 +01:00
2020-07-27 12:43:20 +02:00
_FORCE_INLINE_ const char32_t & operator [ ] ( int p_index ) const {
2020-05-14 16:41:43 +02:00
if ( unlikely ( p_index = = _cowdata . size ( ) ) ) {
2019-01-04 17:01:54 +01:00
return _null ;
2020-05-14 16:41:43 +02:00
}
2019-01-04 17:01:54 +01:00
return _cowdata . get ( p_index ) ;
}
2020-07-27 12:43:20 +02:00
_FORCE_INLINE_ CharProxy < char32_t > operator [ ] ( int p_index ) { return CharProxy < char32_t > ( p_index , _cowdata ) ; }
2018-07-25 03:11:03 +02:00
2017-03-05 16:44:50 +01:00
bool operator = = ( const String & p_str ) const ;
bool operator ! = ( const String & p_str ) const ;
String operator + ( const String & p_str ) const ;
2022-02-13 13:41:29 +01:00
String operator + ( char32_t p_char ) const ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String & operator + = ( const String & ) ;
2020-07-27 12:43:20 +02:00
String & operator + = ( char32_t p_char ) ;
2017-03-05 16:44:50 +01:00
String & operator + = ( const char * p_str ) ;
2020-07-27 12:43:20 +02:00
String & operator + = ( const wchar_t * p_str ) ;
String & operator + = ( const char32_t * p_str ) ;
2014-02-10 02:10:30 +01:00
/* Compatibility Operators */
void operator = ( const char * p_str ) ;
2020-07-27 12:43:20 +02:00
void operator = ( const wchar_t * p_str ) ;
void operator = ( const char32_t * p_str ) ;
2014-02-10 02:10:30 +01:00
bool operator = = ( const char * p_str ) const ;
2020-07-27 12:43:20 +02:00
bool operator = = ( const wchar_t * p_str ) const ;
bool operator = = ( const char32_t * p_str ) const ;
2014-02-10 02:10:30 +01:00
bool operator = = ( const StrRange & p_str_range ) const ;
2020-07-27 12:43:20 +02:00
2014-02-10 02:10:30 +01:00
bool operator ! = ( const char * p_str ) const ;
2020-07-27 12:43:20 +02:00
bool operator ! = ( const wchar_t * p_str ) const ;
bool operator ! = ( const char32_t * p_str ) const ;
bool operator < ( const char32_t * p_str ) const ;
2014-02-10 02:10:30 +01:00
bool operator < ( const char * p_str ) const ;
2020-07-27 12:43:20 +02:00
bool operator < ( const wchar_t * p_str ) const ;
2017-12-11 23:38:07 +01:00
bool operator < ( const String & p_str ) const ;
bool operator < = ( const String & p_str ) const ;
2020-11-05 03:01:55 +01:00
bool operator > ( const String & p_str ) const ;
bool operator > = ( const String & p_str ) const ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
signed char casecmp_to ( const String & p_str ) const ;
signed char nocasecmp_to ( const String & p_str ) const ;
2023-05-04 20:32:45 +02:00
signed char naturalcasecmp_to ( const String & p_str ) const ;
2017-05-11 21:07:59 +02:00
signed char naturalnocasecmp_to ( const String & p_str ) const ;
2024-02-02 16:50:23 +01:00
// Special sorting for file names. Names starting with `_` are put before all others except those starting with `.`, otherwise natural comparison is used.
signed char filecasecmp_to ( const String & p_str ) const ;
signed char filenocasecmp_to ( const String & p_str ) const ;
2014-02-10 02:10:30 +01:00
2020-07-27 12:43:20 +02:00
const char32_t * get_data ( ) const ;
2014-02-10 02:10:30 +01:00
/* standard size stuff */
2017-12-11 23:38:07 +01:00
_FORCE_INLINE_ int length ( ) const {
int s = size ( ) ;
return s ? ( s - 1 ) : 0 ; // length does not include zero
}
2014-02-10 02:10:30 +01:00
2020-07-27 12:43:20 +02:00
bool is_valid_string ( ) const ;
2022-07-05 14:18:29 +02:00
/* debug, error messages */
void print_unicode_error ( const String & p_message , bool p_critical = false ) const ;
2014-02-10 02:10:30 +01:00
/* complex helpers */
2019-05-03 14:21:04 +02:00
String substr ( int p_from , int p_chars = - 1 ) const ;
2017-12-11 23:38:07 +01:00
int find ( const String & p_str , int p_from = 0 ) const ; ///< return <0 if failed
2019-01-07 18:02:55 +01:00
int find ( const char * p_str , int p_from = 0 ) const ; ///< return <0 if failed
2020-07-27 12:43:20 +02:00
int find_char ( const char32_t & p_char , int p_from = 0 ) const ; ///< return <0 if failed
2017-12-11 23:38:07 +01:00
int findn ( const String & p_str , int p_from = 0 ) const ; ///< return <0 if failed, case insensitive
int rfind ( const String & p_str , int p_from = - 1 ) const ; ///< return <0 if failed
int rfindn ( const String & p_str , int p_from = - 1 ) const ; ///< return <0 if failed, case insensitive
2020-04-02 01:20:12 +02:00
int findmk ( const Vector < String > & p_keys , int p_from = 0 , int * r_key = nullptr ) const ; ///< return <0 if failed
2017-03-05 16:44:50 +01:00
bool match ( const String & p_wildcard ) const ;
bool matchn ( const String & p_wildcard ) const ;
bool begins_with ( const String & p_string ) const ;
bool begins_with ( const char * p_string ) const ;
bool ends_with ( const String & p_string ) const ;
2017-10-28 23:46:20 +02:00
bool is_enclosed_in ( const String & p_string ) const ;
2017-03-05 16:44:50 +01:00
bool is_subsequence_of ( const String & p_string ) const ;
2022-01-27 00:03:56 +01:00
bool is_subsequence_ofn ( const String & p_string ) const ;
2017-10-28 23:46:20 +02:00
bool is_quoted ( ) const ;
2016-06-13 19:06:03 +02:00
Vector < String > bigrams ( ) const ;
2017-03-05 16:44:50 +01:00
float similarity ( const String & p_string ) const ;
2023-11-02 18:36:57 +01:00
String format ( const Variant & values , const String & placeholder = " {_} " ) const ;
2017-12-11 23:38:07 +01:00
String replace_first ( const String & p_key , const String & p_with ) const ;
String replace ( const String & p_key , const String & p_with ) const ;
String replace ( const char * p_key , const char * p_with ) const ;
String replacen ( const String & p_key , const String & p_with ) const ;
2019-09-02 05:49:55 +02:00
String repeat ( int p_count ) const ;
2023-06-21 19:40:48 +02:00
String reverse ( ) const ;
2017-12-11 23:38:07 +01:00
String insert ( int p_at_pos , const String & p_string ) const ;
2023-03-30 15:45:45 +02:00
String erase ( int p_pos , int p_chars = 1 ) const ;
2014-02-10 02:10:30 +01:00
String pad_decimals ( int p_digits ) const ;
String pad_zeros ( int p_digits ) const ;
2018-04-13 16:40:27 +02:00
String trim_prefix ( const String & p_prefix ) const ;
String trim_suffix ( const String & p_suffix ) const ;
2017-03-05 16:44:50 +01:00
String lpad ( int min_length , const String & character = " " ) const ;
String rpad ( int min_length , const String & character = " " ) const ;
String sprintf ( const Array & values , bool * error ) const ;
2023-11-02 18:36:57 +01:00
String quote ( const String & quotechar = " \" " ) const ;
2017-10-28 23:46:20 +02:00
String unquote ( ) const ;
2017-03-05 16:44:50 +01:00
static String num ( double p_num , int p_decimals = - 1 ) ;
2014-02-10 02:10:30 +01:00
static String num_scientific ( double p_num ) ;
2021-02-25 15:54:50 +01:00
static String num_real ( double p_num , bool p_trailing = true ) ;
2017-03-05 16:44:50 +01:00
static String num_int64 ( int64_t p_num , int base = 10 , bool capitalize_hex = false ) ;
2018-02-22 13:13:51 +01:00
static String num_uint64 ( uint64_t p_num , int base = 10 , bool capitalize_hex = false ) ;
2020-07-27 12:43:20 +02:00
static String chr ( char32_t p_char ) ;
2014-02-10 02:10:30 +01:00
static String md5 ( const uint8_t * p_md5 ) ;
2016-06-17 09:55:16 +02:00
static String hex_encode_buffer ( const uint8_t * p_buffer , int p_len ) ;
2023-03-06 04:17:33 +01:00
Vector < uint8_t > hex_decode ( ) const ;
2014-02-10 02:10:30 +01:00
bool is_numeric ( ) const ;
2020-07-27 12:43:20 +02:00
double to_float ( ) const ;
2021-01-28 13:39:05 +01:00
int64_t hex_to_int ( ) const ;
int64_t bin_to_int ( ) const ;
2020-05-13 11:31:51 +02:00
int64_t to_int ( ) const ;
2020-07-27 12:43:20 +02:00
2020-06-03 06:04:04 +02:00
static int64_t to_int ( const char * p_str , int p_len = - 1 ) ;
2020-07-27 12:43:20 +02:00
static int64_t to_int ( const wchar_t * p_str , int p_len = - 1 ) ;
static int64_t to_int ( const char32_t * p_str , int p_len = - 1 , bool p_clamp = false ) ;
2020-07-24 20:07:57 +02:00
static double to_float ( const char * p_str ) ;
2020-07-27 12:43:20 +02:00
static double to_float ( const wchar_t * p_str , const wchar_t * * r_end = nullptr ) ;
static double to_float ( const char32_t * p_str , const char32_t * * r_end = nullptr ) ;
2023-04-06 17:54:56 +02:00
static uint32_t num_characters ( int64_t p_int ) ;
2020-07-27 12:43:20 +02:00
2014-02-10 02:10:30 +01:00
String capitalize ( ) const ;
2022-08-30 11:36:24 +02:00
String to_camel_case ( ) const ;
String to_pascal_case ( ) const ;
String to_snake_case ( ) const ;
2014-02-10 02:10:30 +01:00
2019-06-16 04:45:24 +02:00
String get_with_code_lines ( ) const ;
2023-11-02 18:36:57 +01:00
int get_slice_count ( const String & p_splitter ) const ;
String get_slice ( const String & p_splitter , int p_slice ) const ;
2020-07-27 12:43:20 +02:00
String get_slicec ( char32_t p_splitter , int p_slice ) const ;
2014-02-10 02:10:30 +01:00
2022-08-12 16:21:15 +02:00
Vector < String > split ( const String & p_splitter = " " , bool p_allow_empty = true , int p_maxsplit = 0 ) const ;
Vector < String > rsplit ( const String & p_splitter = " " , bool p_allow_empty = true , int p_maxsplit = 0 ) const ;
2014-10-10 00:44:27 +02:00
Vector < String > split_spaces ( ) const ;
2022-11-20 12:29:50 +01:00
Vector < double > split_floats ( const String & p_splitter , bool p_allow_empty = true ) const ;
2017-03-05 16:44:50 +01:00
Vector < float > split_floats_mk ( const Vector < String > & p_splitters , bool p_allow_empty = true ) const ;
Vector < int > split_ints ( const String & p_splitter , bool p_allow_empty = true ) const ;
Vector < int > split_ints_mk ( const Vector < String > & p_splitters , bool p_allow_empty = true ) const ;
2014-02-10 02:10:30 +01:00
2024-01-09 02:36:19 +01:00
String join ( const Vector < String > & parts ) const ;
2017-10-02 17:01:43 +02:00
2020-07-27 12:43:20 +02:00
static char32_t char_uppercase ( char32_t p_char ) ;
static char32_t char_lowercase ( char32_t p_char ) ;
2014-02-10 02:10:30 +01:00
String to_upper ( ) const ;
String to_lower ( ) const ;
2019-01-18 09:29:28 +01:00
int count ( const String & p_string , int p_from = 0 , int p_to = 0 ) const ;
int countn ( const String & p_string , int p_from = 0 , int p_to = 0 ) const ;
2022-06-12 04:45:58 +02:00
String left ( int p_len ) const ;
String right ( int p_len ) const ;
2021-12-15 16:01:06 +01:00
String indent ( const String & p_prefix ) const ;
2017-10-11 10:27:54 +02:00
String dedent ( ) const ;
2016-05-11 09:22:59 +02:00
String strip_edges ( bool left = true , bool right = true ) const ;
2014-02-10 02:10:30 +01:00
String strip_escapes ( ) const ;
2018-07-25 03:11:03 +02:00
String lstrip ( const String & p_chars ) const ;
String rstrip ( const String & p_chars ) const ;
2017-01-14 04:51:09 +01:00
String get_extension ( ) const ;
String get_basename ( ) const ;
2022-08-30 02:34:01 +02:00
String path_join ( const String & p_file ) const ;
2020-11-23 12:47:11 +01:00
char32_t unicode_at ( int p_idx ) const ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
CharString ascii ( bool p_allow_extended = false ) const ;
2014-02-10 02:10:30 +01:00
CharString utf8 ( ) const ;
2022-07-31 18:46:53 +02:00
Error parse_utf8 ( const char * p_utf8 , int p_len = - 1 , bool p_skip_cr = false ) ;
2017-03-05 16:44:50 +01:00
static String utf8 ( const char * p_utf8 , int p_len = - 1 ) ;
2016-03-09 00:00:52 +01:00
2020-07-27 12:43:20 +02:00
Char16String utf16 ( ) const ;
2024-03-23 18:18:50 +01:00
Error parse_utf16 ( const char16_t * p_utf16 , int p_len = - 1 , bool p_default_little_endian = true ) ;
2020-07-27 12:43:20 +02:00
static String utf16 ( const char16_t * p_utf16 , int p_len = - 1 ) ;
static uint32_t hash ( const char32_t * p_cstr , int p_len ) ; /* hash the string */
static uint32_t hash ( const char32_t * p_cstr ) ; /* hash the string */
static uint32_t hash ( const wchar_t * p_cstr , int p_len ) ; /* hash the string */
static uint32_t hash ( const wchar_t * p_cstr ) ; /* hash the string */
2017-03-05 16:44:50 +01:00
static uint32_t hash ( const char * p_cstr , int p_len ) ; /* hash the string */
static uint32_t hash ( const char * p_cstr ) ; /* hash the string */
2014-02-10 02:10:30 +01:00
uint32_t hash ( ) const ; /* hash the string */
2016-03-09 00:00:52 +01:00
uint64_t hash64 ( ) const ; /* hash the string */
2014-03-14 02:57:24 +01:00
String md5_text ( ) const ;
2019-07-02 16:07:02 +02:00
String sha1_text ( ) const ;
2016-06-17 09:55:16 +02:00
String sha256_text ( ) const ;
2014-08-02 03:10:38 +02:00
Vector < uint8_t > md5_buffer ( ) const ;
2019-07-02 16:07:02 +02:00
Vector < uint8_t > sha1_buffer ( ) const ;
2016-06-23 18:57:45 +02:00
Vector < uint8_t > sha256_buffer ( ) const ;
2014-08-02 03:10:38 +02:00
2020-12-15 13:04:21 +01:00
_FORCE_INLINE_ bool is_empty ( ) const { return length ( ) = = 0 ; }
2022-02-03 17:03:38 +01:00
_FORCE_INLINE_ bool contains ( const char * p_str ) const { return find ( p_str ) ! = - 1 ; }
_FORCE_INLINE_ bool contains ( const String & p_str ) const { return find ( p_str ) ! = - 1 ; }
2014-02-10 02:10:30 +01:00
// path functions
2021-06-03 15:41:22 +02:00
bool is_absolute_path ( ) const ;
2021-08-30 01:43:47 +02:00
bool is_relative_path ( ) const ;
2014-02-10 02:10:30 +01:00
bool is_resource_file ( ) const ;
2017-03-05 16:44:50 +01:00
String path_to ( const String & p_path ) const ;
String path_to_file ( const String & p_path ) const ;
2014-02-10 02:10:30 +01:00
String get_base_dir ( ) const ;
String get_file ( ) const ;
2019-10-04 13:35:01 +02:00
static String humanize_size ( uint64_t p_size ) ;
2014-02-10 02:10:30 +01:00
String simplify_path ( ) const ;
2022-01-24 12:12:46 +01:00
bool is_network_share_path ( ) const ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String xml_escape ( bool p_escape_quotes = false ) const ;
2014-02-10 02:10:30 +01:00
String xml_unescape ( ) const ;
2020-11-30 04:43:38 +01:00
String uri_encode ( ) const ;
String uri_decode ( ) const ;
2014-02-10 02:10:30 +01:00
String c_escape ( ) const ;
2017-01-16 18:03:38 +01:00
String c_escape_multiline ( ) const ;
2014-02-10 02:10:30 +01:00
String c_unescape ( ) const ;
2016-01-10 19:01:06 +01:00
String json_escape ( ) const ;
2021-04-26 09:33:28 +02:00
Error parse_url ( String & r_scheme , String & r_host , int & r_port , String & r_path ) const ;
2016-03-09 00:00:52 +01:00
2019-12-20 03:03:15 +01:00
String property_name_encode ( ) const ;
2021-01-28 21:48:12 +01:00
// node functions
2023-11-09 15:37:08 +01:00
static String get_invalid_node_name_characters ( bool p_allow_internal = false ) ;
2021-01-28 21:48:12 +01:00
String validate_node_name ( ) const ;
2022-05-02 15:04:17 +02:00
String validate_identifier ( ) const ;
2022-07-19 02:58:27 +02:00
String validate_filename ( ) const ;
2021-01-28 21:48:12 +01:00
2014-02-10 02:10:30 +01:00
bool is_valid_identifier ( ) const ;
2021-06-16 18:24:34 +02:00
bool is_valid_int ( ) const ;
2014-02-10 02:10:30 +01:00
bool is_valid_float ( ) const ;
2016-10-20 14:58:00 +02:00
bool is_valid_hex_number ( bool p_with_prefix ) const ;
2014-02-10 02:10:30 +01:00
bool is_valid_html_color ( ) const ;
bool is_valid_ip_address ( ) const ;
2019-04-09 00:18:03 +02:00
bool is_valid_filename ( ) const ;
2014-02-10 02:10:30 +01:00
/**
* The constructors must not depend on other overloads
*/
2018-07-25 03:11:03 +02:00
_FORCE_INLINE_ String ( ) { }
_FORCE_INLINE_ String ( const String & p_str ) { _cowdata . _ref ( p_str . _cowdata ) ; }
2021-11-30 15:19:26 +01:00
_FORCE_INLINE_ void operator = ( const String & p_str ) { _cowdata . _ref ( p_str . _cowdata ) ; }
2018-07-25 03:11:03 +02:00
2020-10-13 20:59:37 +02:00
Vector < uint8_t > to_ascii_buffer ( ) const ;
Vector < uint8_t > to_utf8_buffer ( ) const ;
Vector < uint8_t > to_utf16_buffer ( ) const ;
Vector < uint8_t > to_utf32_buffer ( ) const ;
2023-02-13 15:18:12 +01:00
Vector < uint8_t > to_wchar_buffer ( ) const ;
2020-10-13 20:59:37 +02:00
2014-02-10 02:10:30 +01:00
String ( const char * p_str ) ;
2020-07-27 12:43:20 +02:00
String ( const wchar_t * p_str ) ;
String ( const char32_t * p_str ) ;
String ( const char * p_str , int p_clip_to_len ) ;
String ( const wchar_t * p_str , int p_clip_to_len ) ;
String ( const char32_t * p_str , int p_clip_to_len ) ;
2017-03-05 16:44:50 +01:00
String ( const StrRange & p_range ) ;
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
bool operator = = ( const char * p_chr , const String & p_str ) ;
2020-07-27 12:43:20 +02:00
bool operator = = ( const wchar_t * p_chr , const String & p_str ) ;
2020-11-05 03:01:55 +01:00
bool operator ! = ( const char * p_chr , const String & p_str ) ;
bool operator ! = ( const wchar_t * p_chr , const String & p_str ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String operator + ( const char * p_chr , const String & p_str ) ;
2020-07-27 12:43:20 +02:00
String operator + ( const wchar_t * p_chr , const String & p_str ) ;
String operator + ( char32_t p_chr , const String & p_str ) ;
2014-02-10 02:10:30 +01:00
String itos ( int64_t p_val ) ;
2019-11-01 16:16:31 +01:00
String uitos ( uint64_t p_val ) ;
2014-02-10 02:10:30 +01:00
String rtos ( double p_val ) ;
String rtoss ( double p_val ) ; //scientific version
struct NoCaseComparator {
2017-03-05 16:44:50 +01:00
bool operator ( ) ( const String & p_a , const String & p_b ) const {
return p_a . nocasecmp_to ( p_b ) < 0 ;
2014-02-10 02:10:30 +01:00
}
} ;
2017-05-11 21:07:59 +02:00
struct NaturalNoCaseComparator {
bool operator ( ) ( const String & p_a , const String & p_b ) const {
return p_a . naturalnocasecmp_to ( p_b ) < 0 ;
}
} ;
2024-02-02 16:50:23 +01:00
struct FileNoCaseComparator {
bool operator ( ) ( const String & p_a , const String & p_b ) const {
return p_a . filenocasecmp_to ( p_b ) < 0 ;
}
} ;
2017-12-16 15:31:30 +01:00
template < typename L , typename R >
_FORCE_INLINE_ bool is_str_less ( const L * l_ptr , const R * r_ptr ) {
while ( true ) {
2020-07-27 12:43:20 +02:00
const char32_t l = * l_ptr ;
const char32_t r = * r_ptr ;
if ( l = = 0 & & r = = 0 ) {
2017-12-16 15:31:30 +01:00
return false ;
2020-07-27 12:43:20 +02:00
} else if ( l = = 0 ) {
2017-12-16 15:31:30 +01:00
return true ;
2020-07-27 12:43:20 +02:00
} else if ( r = = 0 ) {
2017-12-16 15:31:30 +01:00
return false ;
2020-07-27 12:43:20 +02:00
} else if ( l < r ) {
2017-12-16 15:31:30 +01:00
return true ;
2020-07-27 12:43:20 +02:00
} else if ( l > r ) {
2017-12-16 15:31:30 +01:00
return false ;
2020-05-14 16:41:43 +02:00
}
2017-12-16 15:31:30 +01:00
l_ptr + + ;
r_ptr + + ;
}
}
2017-03-05 16:44:50 +01:00
/* end of namespace */
2014-02-10 02:10:30 +01:00
2020-03-18 18:34:36 +01:00
// Tool translate (TTR and variants) for the editor UI,
// and doc translate for the class reference (DTR).
2016-05-17 23:27:15 +02:00
# ifdef TOOLS_ENABLED
2020-03-18 18:34:36 +01:00
// Gets parsed.
2020-07-16 10:52:06 +02:00
String TTR ( const String & p_text , const String & p_context = " " ) ;
String TTRN ( const String & p_text , const String & p_text_plural , int p_n , const String & p_context = " " ) ;
String DTR ( const String & p_text , const String & p_context = " " ) ;
String DTRN ( const String & p_text , const String & p_text_plural , int p_n , const String & p_context = " " ) ;
2020-03-18 18:34:36 +01:00
// Use for C strings.
2019-06-16 21:57:34 +02:00
# define TTRC(m_value) (m_value)
2020-03-18 18:34:36 +01:00
// Use to avoid parsing (for use later with C strings).
2019-04-09 00:18:03 +02:00
# define TTRGET(m_value) TTR(m_value)
2014-02-10 02:10:30 +01:00
2016-05-17 23:27:15 +02:00
# else
2019-04-09 00:18:03 +02:00
# define TTRC(m_value) (m_value)
2019-06-16 21:57:34 +02:00
# define TTRGET(m_value) (m_value)
2016-05-17 23:27:15 +02:00
# endif
2022-05-19 08:08:47 +02:00
// Use this to mark property names for editor translation.
// Often for dynamic properties defined in _get_property_list().
// Property names defined directly inside EDITOR_DEF, GLOBAL_DEF, and ADD_PROPERTY macros don't need this.
# define PNAME(m_value) (m_value)
// Similar to PNAME, but to mark groups, i.e. properties with PROPERTY_USAGE_GROUP.
// Groups defined directly inside ADD_GROUP macros don't need this.
// The arguments are the same as ADD_GROUP. m_prefix is only used for extraction.
# define GNAME(m_value, m_prefix) (m_value)
2020-03-18 18:34:36 +01:00
// Runtime translate for the public node API.
2020-07-16 10:52:06 +02:00
String RTR ( const String & p_text , const String & p_context = " " ) ;
String RTRN ( const String & p_text , const String & p_text_plural , int p_n , const String & p_context = " " ) ;
2016-05-17 23:27:15 +02:00
2023-12-16 00:56:06 +01:00
/**
* " Extractable TRanslate " . Used for strings that can appear inside an exported
* project ( such as the ones in nodes like ` FileDialog ` ) , which are made possible
* to add in the POT generator . A translation context can optionally be specified
* to disambiguate between identical source strings in translations .
* When placeholders are desired , use vformat ( ETR ( " Example: %s " ) , some_string ) ` .
* If a string mentions a quantity ( and may therefore need a dynamic plural form ) ,
* use ` ETRN ( ) ` instead of ` ETR ( ) ` .
*
* NOTE : This function is for string extraction only , and will just return the
* string it was given . The translation itself should be done internally by nodes
* with ` atr ( ) ` instead .
*/
_FORCE_INLINE_ String ETR ( const String & p_text , const String & p_context = " " ) {
return p_text ;
}
/**
* " Extractable TRanslate for N items " . Used for strings that can appear inside an
* exported project ( such as the ones in nodes like ` FileDialog ` ) , which are made
* possible to add in the POT generator . A translation context can optionally be
* specified to disambiguate between identical source strings in translations .
* Use ` ETR ( ) ` if the string doesn ' t need dynamic plural form . When placeholders
* are desired , use ` vformat ( ETRN ( " %d item " , " %d items " , some_integer ) , some_integer ) ` .
* The placeholder must be present in both strings to avoid run - time warnings in ` vformat ( ) ` .
*
* NOTE : This function is for string extraction only , and will just return the
* string it was given . The translation itself should be done internally by nodes
* with ` atr ( ) ` instead .
*/
_FORCE_INLINE_ String ETRN ( const String & p_text , const String & p_text_plural , int p_n , const String & p_context = " " ) {
if ( p_n = = 1 ) {
return p_text ;
}
return p_text_plural ;
}
2017-12-23 09:59:54 +01:00
bool select_word ( const String & p_s , int p_col , int & r_beg , int & r_end ) ;
2020-11-10 22:31:33 +01:00
_FORCE_INLINE_ void sarray_add_str ( Vector < String > & arr ) {
}
_FORCE_INLINE_ void sarray_add_str ( Vector < String > & arr , const String & p_str ) {
arr . push_back ( p_str ) ;
}
2024-03-08 03:29:49 +01:00
template < typename . . . P >
2020-11-10 22:31:33 +01:00
_FORCE_INLINE_ void sarray_add_str ( Vector < String > & arr , const String & p_str , P . . . p_args ) {
arr . push_back ( p_str ) ;
sarray_add_str ( arr , p_args . . . ) ;
}
2024-03-08 03:29:49 +01:00
template < typename . . . P >
2020-11-10 22:31:33 +01:00
_FORCE_INLINE_ Vector < String > sarray ( P . . . p_args ) {
Vector < String > arr ;
sarray_add_str ( arr , p_args . . . ) ;
return arr ;
}
2020-08-05 08:25:28 +02:00
# endif // USTRING_GODOT_H