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

Function gjs_decode_from_uint8array

gjs/text-encoding.cpp:269–361  ·  view source on GitHub ↗

decode() function implementation

Source from the content-addressed store, hash-verified

267
268// decode() function implementation
269JSString* gjs_decode_from_uint8array(JSContext* cx, JS::HandleObject byte_array,
270 const char* encoding,
271 GjsStringTermination string_termination,
272 bool fatal) {
273 g_assert(encoding && "encoding must be non-null");
274
275 if (!JS_IsUint8Array(byte_array)) {
276 gjs_throw(cx, "Argument to decode() must be a Uint8Array");
277 return nullptr;
278 }
279
280 uint8_t* data;
281 size_t len;
282 bool is_shared_memory;
283 js::GetUint8ArrayLengthAndData(byte_array, &len, &is_shared_memory, &data);
284
285 // If the desired behavior is zero-terminated, calculate the
286 // zero-terminated length of the given data.
287 if (len && string_termination == GjsStringTermination::ZERO_TERMINATED)
288 len = zero_terminated_length(data, len);
289
290 // If the calculated length is 0 we can just return an empty string.
291 if (len == 0)
292 return JS_GetEmptyString(cx);
293
294 // Optimization, only use glib's iconv-based converters if we're dealing
295 // with a non-UTF8 encoding. SpiderMonkey has highly optimized UTF-8 decoder
296 // and encoders.
297 bool encoding_is_utf8 = is_utf8_label(encoding);
298 if (!encoding_is_utf8)
299 return gjs_decode_from_uint8array_slow(cx, data, len, encoding, fatal);
300
301 JS::RootedString decoded(cx);
302 if (!fatal) {
303 decoded.set(gjs_lossy_string_from_utf8_n(
304 cx, reinterpret_cast<char*>(data), len));
305 } else {
306 JS::UTF8Chars chars(reinterpret_cast<char*>(data), len);
307 JS::RootedString str(cx, JS_NewStringCopyUTF8N(cx, chars));
308
309 // If an exception occurred, we need to check if the
310 // exception was an InternalError. Unfortunately,
311 // SpiderMonkey's decoder can throw InternalError for some
312 // invalid UTF-8 sources, we have to convert this into a
313 // TypeError to match the Encoding specification.
314 if (str) {
315 decoded.set(str);
316 } else {
317 JS::RootedValue exc(cx);
318 if (!JS_GetPendingException(cx, &exc) || !exc.isObject())
319 return nullptr;
320
321 JS::RootedObject exc_obj(cx, &exc.toObject());
322 const JSClass* internal_error =
323 js::ProtoKeyToClass(JSProto_InternalError);
324 if (JS_InstanceOf(cx, exc_obj, internal_error, nullptr)) {
325 // Clear the existing exception.
326 JS_ClearPendingException(cx);

Callers 3

to_string_funcFunction · 0.85
instance_to_string_funcFunction · 0.85
gjs_decodeFunction · 0.85

Calls 7

gjs_throwFunction · 0.85
zero_terminated_lengthFunction · 0.85
is_utf8_labelFunction · 0.85
gjs_throw_customFunction · 0.85
setMethod · 0.80

Tested by

no test coverage detected