Add methods to decode/encode Windows system encodings.

This commit is contained in:
bruvzg 2024-09-13 09:19:26 +03:00
parent 83d54ab2ad
commit 41432e30e9
10 changed files with 103 additions and 1 deletions

View File

@ -200,6 +200,30 @@ void OS::set_stderr_enabled(bool p_enabled) {
_stderr_enabled = p_enabled;
}
String OS::multibyte_to_string(int p_encoding, const PackedByteArray &p_array) const {
String s;
if (p_array.size() > 0) {
const uint8_t *r = p_array.ptr();
s.parse_utf8((const char *)r, p_array.size());
}
return s;
}
PackedByteArray OS::string_to_multibyte(int p_encoding, const String &p_string) const {
if (p_string.is_empty()) {
return PackedByteArray();
}
CharString charstr = p_string.utf8();
PackedByteArray ret;
size_t len = charstr.length();
ret.resize(len);
uint8_t *w = ret.ptrw();
memcpy(w, charstr.ptr(), len);
return ret;
}
int OS::get_exit_code() const {
return _exit_code;
}

View File

@ -254,6 +254,9 @@ public:
void set_stdout_enabled(bool p_enabled);
void set_stderr_enabled(bool p_enabled);
virtual String multibyte_to_string(int p_encoding, const PackedByteArray &p_array) const;
virtual PackedByteArray string_to_multibyte(int p_encoding, const String &p_string) const;
virtual void disable_crash_handler() {}
virtual bool is_disable_crash_handler() const { return false; }
virtual void initialize_debugging() {}

View File

@ -34,6 +34,7 @@
#include "core/math/color.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/os/os.h"
#include "core/string/print_string.h"
#include "core/string/string_name.h"
#include "core/string/translation_server.h"
@ -5964,6 +5965,10 @@ Vector<uint8_t> String::to_wchar_buffer() const {
#endif
}
Vector<uint8_t> String::to_multibyte_char_buffer(int p_encoding) const {
return OS::get_singleton()->string_to_multibyte(p_encoding, *this);
}
#ifdef TOOLS_ENABLED
/**
* "Tools TRanslate". Performs string replacement for internationalization

View File

@ -487,6 +487,7 @@ public:
Vector<uint8_t> to_utf16_buffer() const;
Vector<uint8_t> to_utf32_buffer() const;
Vector<uint8_t> to_wchar_buffer() const;
Vector<uint8_t> to_multibyte_char_buffer(int p_encoding = 0) const;
String(const char *p_str);
String(const wchar_t *p_str);

View File

@ -712,6 +712,14 @@ struct _VariantCall {
return s;
}
static String func_PackedByteArray_get_string_from_multibyte_char(PackedByteArray *p_instance, int p_encoding) {
String s;
if (p_instance->size() > 0) {
s = OS::get_singleton()->multibyte_to_string(p_encoding, *p_instance);
}
return s;
}
static PackedByteArray func_PackedByteArray_compress(PackedByteArray *p_instance, int p_mode) {
PackedByteArray compressed;
@ -1750,8 +1758,9 @@ static void _register_variant_builtin_methods_string() {
bind_string_method(to_utf8_buffer, sarray(), varray());
bind_string_method(to_utf16_buffer, sarray(), varray());
bind_string_method(to_utf32_buffer, sarray(), varray());
bind_string_method(hex_decode, sarray(), varray());
bind_string_method(to_wchar_buffer, sarray(), varray());
bind_string_method(to_multibyte_char_buffer, sarray("encoding"), varray(0));
bind_string_method(hex_decode, sarray(), varray());
bind_static_method(String, num_scientific, sarray("number"), varray());
bind_static_method(String, num, sarray("number", "decimals"), varray(-1));
@ -2361,6 +2370,7 @@ static void _register_variant_builtin_methods_array() {
bind_function(PackedByteArray, get_string_from_utf16, _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray());
bind_function(PackedByteArray, get_string_from_utf32, _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray());
bind_function(PackedByteArray, get_string_from_wchar, _VariantCall::func_PackedByteArray_get_string_from_wchar, sarray(), varray());
bind_function(PackedByteArray, get_string_from_multibyte_char, _VariantCall::func_PackedByteArray_get_string_from_multibyte_char, sarray("encoding"), varray(0));
bind_function(PackedByteArray, hex_encode, _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray());
bind_function(PackedByteArray, compress, _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray(0));
bind_function(PackedByteArray, decompress, _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0));

View File

@ -313,6 +313,15 @@
Converts ASCII/Latin-1 encoded array to [String]. Fast alternative to [method get_string_from_utf8] if the content is ASCII/Latin-1 only. Unlike the UTF-8 function this function maps every byte to a character in the array. Multibyte sequences will not be interpreted correctly. For parsing user input always use [method get_string_from_utf8]. This is the inverse of [method String.to_ascii_buffer].
</description>
</method>
<method name="get_string_from_multibyte_char" qualifiers="const">
<return type="String" />
<param index="0" name="encoding" type="int" default="0" />
<description>
Converts system multibyte code page encoded array to [String]. This is the inverse of [method String.to_multibyte_char_buffer].
[param encoding] is one of the [url=https://learn.microsoft.com/en-us/windows/win32/Intl/code-page-identifiers]Code Page Identifiers[/url], or [code]0[/code] for system default Windows ANSI code page.
[b]Note:[/b] This method is implemented only on Windows, on other platforms [param encoding] is ignored, and this method is equivalent to [method get_string_from_utf8].
</description>
</method>
<method name="get_string_from_utf8" qualifiers="const">
<return type="String" />
<description>

View File

@ -1009,6 +1009,15 @@
Returns the string converted to [code]lowercase[/code].
</description>
</method>
<method name="to_multibyte_char_buffer" qualifiers="const">
<return type="PackedByteArray" />
<param index="0" name="encoding" type="int" default="0" />
<description>
Converts the string to system multibyte code page encoded [PackedByteArray].
[param encoding] is one of the [url=https://learn.microsoft.com/en-us/windows/win32/Intl/code-page-identifiers]Code Page Identifiers[/url], or [code]0[/code] for system default Windows ANSI code page.
[b]Note:[/b] This method is implemented only on Windows, on other platforms [param encoding] is ignored, and this method is equivalent to [method to_utf8_buffer].
</description>
</method>
<method name="to_pascal_case" qualifiers="const">
<return type="String" />
<description>

View File

@ -911,6 +911,15 @@
Returns the string converted to [code]lowercase[/code].
</description>
</method>
<method name="to_multibyte_char_buffer" qualifiers="const">
<return type="PackedByteArray" />
<param index="0" name="encoding" type="int" default="0" />
<description>
Converts the string to system multibyte code page encoded [PackedByteArray].
[param encoding] is one of the [url=https://learn.microsoft.com/en-us/windows/win32/Intl/code-page-identifiers]Code Page Identifiers[/url], or [code]0[/code] for system default Windows ANSI code page.
[b]Note:[/b] This method is implemented only on Windows, on other platforms [param encoding] is ignored, and this method is equivalent to [method to_utf8_buffer].
</description>
</method>
<method name="to_pascal_case" qualifiers="const">
<return type="String" />
<description>

View File

@ -841,6 +841,35 @@ static void _append_to_pipe(char *p_bytes, int p_size, String *r_pipe, Mutex *p_
}
}
String OS_Windows::multibyte_to_string(int p_encoding, const PackedByteArray &p_array) const {
LocalVector<wchar_t> wchars;
int total_wchars = MultiByteToWideChar(p_encoding, 0, (const char *)p_array.ptr(), p_array.size(), nullptr, 0);
if (total_wchars > 0) {
wchars.resize(total_wchars);
if (MultiByteToWideChar(p_encoding, 0, (const char *)p_array.ptr(), p_array.size(), wchars.ptr(), total_wchars) == 0) {
wchars.clear();
}
}
return String::utf16((const char16_t *)wchars.ptr(), wchars.size());
}
PackedByteArray OS_Windows::string_to_multibyte(int p_encoding, const String &p_string) const {
if (p_string.is_empty()) {
return PackedByteArray();
}
Char16String charstr = p_string.utf16();
PackedByteArray ret;
int total_mbchars = WideCharToMultiByte(p_encoding, 0, (const wchar_t *)charstr.ptr(), charstr.size(), nullptr, 0, nullptr, nullptr);
if (total_mbchars) {
ret.resize(total_mbchars);
if (WideCharToMultiByte(p_encoding, 0, (const wchar_t *)charstr.ptr(), charstr.size(), (char *)ret.ptrw(), ret.size(), nullptr, nullptr) == 0) {
ret.clear();
}
}
return ret;
}
Dictionary OS_Windows::get_memory_info() const {
Dictionary meminfo;

View File

@ -229,6 +229,9 @@ public:
virtual bool _check_internal_feature_support(const String &p_feature) override;
virtual String multibyte_to_string(int p_encoding, const PackedByteArray &p_array) const override;
virtual PackedByteArray string_to_multibyte(int p_encoding, const String &p_string) const override;
virtual void disable_crash_handler() override;
virtual bool is_disable_crash_handler() const override;
virtual void initialize_debugging() override;