| 1084 | } |
| 1085 | |
| 1086 | bool gjs_array_to_explicit_array(JSContext* cx, JS::HandleValue value, |
| 1087 | const GI::TypeInfo& type_info, |
| 1088 | const char* arg_name, GjsArgumentType arg_type, |
| 1089 | GITransfer transfer, GjsArgumentFlags flags, |
| 1090 | void** contents, size_t* length_p) { |
| 1091 | GI::AutoTypeInfo element_type{type_info.element_type()}; |
| 1092 | GITypeTag element_tag = element_type.tag(); |
| 1093 | |
| 1094 | if (GI_TYPE_TAG_IS_BASIC(element_tag)) { |
| 1095 | return gjs_array_to_basic_explicit_array(cx, value, element_tag, |
| 1096 | arg_name, arg_type, flags, |
| 1097 | contents, length_p); |
| 1098 | } |
| 1099 | |
| 1100 | gjs_debug_marshal( |
| 1101 | GJS_DEBUG_GFUNCTION, |
| 1102 | "Converting argument '%s' JS value %s to C array, transfer %d", |
| 1103 | arg_name, gjs_debug_value(value).c_str(), transfer); |
| 1104 | |
| 1105 | if ((value.isNull() && !(flags & GjsArgumentFlags::MAY_BE_NULL)) || |
| 1106 | (!value.isString() && !value.isObjectOrNull())) { |
| 1107 | throw_invalid_argument(cx, value, element_type, arg_name, arg_type); |
| 1108 | return false; |
| 1109 | } |
| 1110 | |
| 1111 | if (value.isNull()) { |
| 1112 | *contents = nullptr; |
| 1113 | *length_p = 0; |
| 1114 | return true; |
| 1115 | } |
| 1116 | |
| 1117 | if (value.isString()) { |
| 1118 | // Allow strings as int8/uint8/int16/uint16 arrays |
| 1119 | JS::RootedString str{cx, value.toString()}; |
| 1120 | return gjs_string_to_intarray(cx, str, element_tag, contents, length_p); |
| 1121 | } |
| 1122 | |
| 1123 | JS::RootedObject array_obj{cx, &value.toObject()}; |
| 1124 | if (JS_IsUint8Array(array_obj) && |
| 1125 | (element_tag == GI_TYPE_TAG_INT8 || element_tag == GI_TYPE_TAG_UINT8)) { |
| 1126 | GBytes* bytes = gjs_byte_array_get_bytes(array_obj); |
| 1127 | *contents = g_bytes_unref_to_data(bytes, length_p); |
| 1128 | return true; |
| 1129 | } |
| 1130 | |
| 1131 | const GjsAtoms& atoms = GjsContextPrivate::atoms(cx); |
| 1132 | bool found_length; |
| 1133 | if (!JS_HasPropertyById(cx, array_obj, atoms.length(), &found_length)) |
| 1134 | return false; |
| 1135 | if (found_length) { |
| 1136 | uint32_t length; |
| 1137 | if (!gjs_object_require_converted_property(cx, array_obj, nullptr, |
| 1138 | atoms.length(), &length) || |
| 1139 | !gjs_array_to_array(cx, value, length, transfer, element_type, |
| 1140 | contents)) |
| 1141 | return false; |
| 1142 | |
| 1143 | *length_p = length; |
no test coverage detected