| 156 | } |
| 157 | |
| 158 | JSObject* gjs_byte_array_from_data_copy(JSContext* cx, size_t nbytes, |
| 159 | void* data) { |
| 160 | JS::RootedObject array_buffer(cx); |
| 161 | // a null data pointer takes precedence over whatever `nbytes` says |
| 162 | if (data) { |
| 163 | array_buffer = JS::NewArrayBuffer(cx, nbytes); |
| 164 | |
| 165 | JS::AutoCheckCannotGC nogc{}; |
| 166 | bool unused; |
| 167 | uint8_t* storage = JS::GetArrayBufferData(array_buffer, &unused, nogc); |
| 168 | std::copy_n(static_cast<uint8_t*>(data), nbytes, storage); |
| 169 | } else { |
| 170 | array_buffer = JS::NewArrayBuffer(cx, 0); |
| 171 | } |
| 172 | if (!array_buffer) |
| 173 | return nullptr; |
| 174 | |
| 175 | JS::RootedObject array(cx, |
| 176 | JS_NewUint8ArrayWithBuffer(cx, array_buffer, 0, -1)); |
| 177 | |
| 178 | const GjsAtoms& atoms = GjsContextPrivate::atoms(cx); |
| 179 | if (!JS_DefineFunctionById(cx, array, atoms.to_string(), |
| 180 | instance_to_string_func, 1, 0)) |
| 181 | return nullptr; |
| 182 | return array; |
| 183 | } |
| 184 | |
| 185 | JSObject* gjs_byte_array_from_byte_array(JSContext* cx, GByteArray* array) { |
| 186 | return gjs_byte_array_from_data_copy(cx, array->len, array->data); |
no test coverage detected