| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/accessibility/features/text_encoder.h" |
| |
| #include <cstring> |
| #include <memory> |
| |
| #include "base/logging.h" |
| #include "gin/arguments.h" |
| #include "gin/array_buffer.h" |
| #include "gin/converter.h" |
| #include "gin/data_object_builder.h" |
| #include "gin/handle.h" |
| #include "gin/public/wrapper_info.h" |
| #include "services/accessibility/features/registered_wrappable.h" |
| #include "v8/include/v8-array-buffer.h" |
| #include "v8/include/v8-isolate.h" |
| #include "v8/include/v8-local-handle.h" |
| #include "v8/include/v8-primitive.h" |
| #include "v8/include/v8-typed-array.h" |
| |
| namespace ax { |
| |
| // static |
| gin::WrapperInfo TextEncoder::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| |
| // static |
| gin::Handle<TextEncoder> TextEncoder::Create(v8::Local<v8::Context> context) { |
| return gin::CreateHandle(context->GetIsolate(), new TextEncoder(context)); |
| } |
| |
| gin::ObjectTemplateBuilder TextEncoder::GetObjectTemplateBuilder( |
| v8::Isolate* isolate) { |
| // Note: We do not support TextEncoder::encodeInto. |
| return gin::Wrappable<TextEncoder>::GetObjectTemplateBuilder(isolate) |
| .SetMethod("encode", &TextEncoder::Encode); |
| } |
| |
| void TextEncoder::Encode(gin::Arguments* arguments) { |
| v8::Isolate* isolate = arguments->isolate(); |
| CHECK(isolate); |
| v8::HandleScope handle_scope(isolate); |
| |
| v8::LocalVector<v8::Value> args = arguments->GetAll(); |
| CHECK_GT(args.size(), 0u); |
| CHECK(args[0]->IsString()); |
| v8::Local<v8::String> v8_input = args[0].As<v8::String>(); |
| std::string input; |
| gin::ConvertFromV8(isolate, v8_input, &input); |
| |
| int num_bytes = input.size(); |
| void* buffer = |
| gin::ArrayBufferAllocator::SharedInstance()->Allocate(num_bytes); |
| auto deleter = [](void* buffer, size_t length, void* data) { |
| gin::ArrayBufferAllocator::SharedInstance()->Free(buffer, length); |
| }; |
| std::unique_ptr<v8::BackingStore> backing_store = |
| v8::ArrayBuffer::NewBackingStore(buffer, num_bytes, deleter, nullptr); |
| |
| v8::Local<v8::ArrayBuffer> array_buffer = |
| v8::ArrayBuffer::New(isolate, std::move(backing_store)); |
| if (num_bytes) { |
| CHECK(array_buffer->Data()); |
| memcpy(array_buffer->Data(), input.c_str(), num_bytes); |
| } |
| v8::Local<v8::Uint8Array> result = |
| v8::Uint8Array::New(array_buffer, 0, num_bytes); |
| arguments->GetFunctionCallbackInfo()->GetReturnValue().Set(result); |
| } |
| |
| TextEncoder::TextEncoder(v8::Local<v8::Context> context) |
| : RegisteredWrappable(context) {} |
| |
| } // namespace ax |