GDExtension: construct StringName directly from char*
So far, an indirection via String was necessary, causing at least 2 allocations and copies (String; String inside StringName). Since StringNames often refer to string literals, this allows them to be directly constructed from C strings. There are two formats: Latin-1 and UTF-8. The Latin-1 constructor also provides the `p_is_static` flag: when the source has static storage duration, no copy/allocation will be needed. However, the extension developer needs to uphold this lifetime guarantee.
This commit is contained in:
parent
59139df16e
commit
ed3015e979
|
@ -877,6 +877,24 @@ static GDExtensionInt gdextension_string_resize(GDExtensionStringPtr p_self, GDE
|
|||
return (*self).resize(p_length);
|
||||
}
|
||||
|
||||
static void gdextension_string_name_new_with_latin1_chars(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionBool p_is_static) {
|
||||
memnew_placement(r_dest, StringName(p_contents, static_cast<bool>(p_is_static)));
|
||||
}
|
||||
|
||||
static void gdextension_string_name_new_with_utf8_chars(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents) {
|
||||
String tmp;
|
||||
tmp.parse_utf8(p_contents);
|
||||
|
||||
memnew_placement(r_dest, StringName(tmp));
|
||||
}
|
||||
|
||||
static void gdextension_string_name_new_with_utf8_chars_and_len(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
String tmp;
|
||||
tmp.parse_utf8(p_contents, p_size);
|
||||
|
||||
memnew_placement(r_dest, StringName(tmp));
|
||||
}
|
||||
|
||||
static GDExtensionInt gdextension_xml_parser_open_buffer(GDExtensionObjectPtr p_instance, const uint8_t *p_buffer, size_t p_size) {
|
||||
XMLParser *xml = (XMLParser *)p_instance;
|
||||
return (GDExtensionInt)xml->_open_buffer(p_buffer, p_size);
|
||||
|
@ -1426,6 +1444,9 @@ void gdextension_setup_interface() {
|
|||
REGISTER_INTERFACE_FUNC(string_operator_plus_eq_wcstr);
|
||||
REGISTER_INTERFACE_FUNC(string_operator_plus_eq_c32str);
|
||||
REGISTER_INTERFACE_FUNC(string_resize);
|
||||
REGISTER_INTERFACE_FUNC(string_name_new_with_latin1_chars);
|
||||
REGISTER_INTERFACE_FUNC(string_name_new_with_utf8_chars);
|
||||
REGISTER_INTERFACE_FUNC(string_name_new_with_utf8_chars_and_len);
|
||||
REGISTER_INTERFACE_FUNC(xml_parser_open_buffer);
|
||||
REGISTER_INTERFACE_FUNC(file_access_store_buffer);
|
||||
REGISTER_INTERFACE_FUNC(file_access_get_buffer);
|
||||
|
|
|
@ -1664,6 +1664,50 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionString
|
|||
*/
|
||||
typedef GDExtensionInt (*GDExtensionInterfaceStringResize)(GDExtensionStringPtr p_self, GDExtensionInt p_resize);
|
||||
|
||||
/* INTERFACE: StringName Utilities */
|
||||
|
||||
/**
|
||||
* @name string_name_new_with_latin1_chars
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a StringName from a Latin-1 encoded C string.
|
||||
*
|
||||
* If `p_is_static` is true, then:
|
||||
* - The StringName will reuse the `p_contents` buffer instead of copying it.
|
||||
* You must guarantee that the buffer remains valid for the duration of the application (e.g. string literal).
|
||||
* - You must not call a destructor for this StringName. Incrementing the initial reference once should achieve this.
|
||||
*
|
||||
* `p_is_static` is purely an optimization and can easily introduce undefined behavior if used wrong. In case of doubt, set it to false.
|
||||
*
|
||||
* @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed.
|
||||
* @param p_contents A pointer to a C string (null terminated and Latin-1 or ASCII encoded).
|
||||
* @param p_is_static Whether the StringName reuses the buffer directly (see above).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNameNewWithLatin1Chars)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionBool p_is_static);
|
||||
|
||||
/**
|
||||
* @name string_name_new_with_utf8_chars
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a StringName from a UTF-8 encoded C string.
|
||||
*
|
||||
* @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed.
|
||||
* @param p_contents A pointer to a C string (null terminated and UTF-8 encoded).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNameNewWithUtf8Chars)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents);
|
||||
|
||||
/**
|
||||
* @name string_name_new_with_utf8_chars_and_len
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a StringName from a UTF-8 encoded string with a given number of characters.
|
||||
*
|
||||
* @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed.
|
||||
* @param p_contents A pointer to a C string (null terminated and UTF-8 encoded).
|
||||
* @param p_size The number of bytes (not UTF-8 code points).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNameNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
/* INTERFACE: XMLParser Utilities */
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue