MCPcopy Create free account
hub / github.com/GNOME/gjs / gjs_lossy_decode_from_uint8array_slow

Function gjs_lossy_decode_from_uint8array_slow

gjs/text-encoding.cpp:77–195  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

75#endif
76
77GJS_JSAPI_RETURN_CONVENTION
78static JSString* gjs_lossy_decode_from_uint8array_slow(
79 JSContext* cx, const uint8_t* bytes, size_t bytes_len,
80 const char* from_codeset) {
81 Gjs::AutoError error;
82 Gjs::AutoUnref<GCharsetConverter> converter{
83 g_charset_converter_new(UTF16_CODESET, from_codeset, &error)};
84
85 // This should only throw if an encoding is not available.
86 if (error)
87 return gjs_throw_type_error_from_gerror(cx, error);
88
89 // This function converts *to* UTF-16, using a std::u16string
90 // as its buffer.
91 //
92 // UTF-16 represents each character with 2 bytes or
93 // 4 bytes, the best case scenario when converting to
94 // UTF-16 is that every input byte encodes to two bytes,
95 // this is typical for ASCII and non-supplementary characters.
96 // Because we are converting from an unknown encoding
97 // technically a single byte could be supplementary in
98 // Unicode (4 bytes) or even represent multiple Unicode characters.
99 //
100 // std::u16string does not care about these implementation
101 // details, its only concern is that is consists of byte pairs.
102 // Given this, a single UTF-16 character could be represented
103 // by one or two std::u16string characters.
104
105 // Allocate bytes_len * 2 + 12 as our initial buffer.
106 // bytes_len * 2 is the "best case" for LATIN1 strings
107 // and strings which are in the basic multilingual plane.
108 // Add 12 as a slight cushion and set the minimum allocation
109 // at 256 to prefer running a single iteration for
110 // small strings with supplemental plane characters.
111 //
112 // When converting Chinese characters, for example,
113 // some dialectal characters are in the supplemental plane
114 // Adding a padding of 12 prevents a few dialectal characters
115 // from requiring a reallocation.
116 size_t buffer_size =
117 std::max(bytes_len * 2 + 12, static_cast<size_t>(256u));
118
119 // Cast data to correct input types
120 const char* input = reinterpret_cast<const char*>(bytes);
121 size_t input_len = bytes_len;
122
123 // The base string that we'll append to.
124 std::u16string output_str;
125
126 do {
127 Gjs::AutoError local_error;
128
129 // Create a buffer to convert into.
130 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(buffer_size);
131 size_t bytes_written = 0, bytes_read = 0;
132
133 g_converter_convert(G_CONVERTER(converter.get()), input, input_len,
134 buffer.get(), buffer_size, G_CONVERTER_INPUT_AT_END,

Callers 1

Calls 3

getMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected