Add a Uint16List typed data wrapper
Change-Id: I85fbd1dae7a8234eed25c9138d81159a28bb5451
diff --git a/typed_data/BUILD.gn b/typed_data/BUILD.gn
index 8cc067e..496bdbf 100644
--- a/typed_data/BUILD.gn
+++ b/typed_data/BUILD.gn
@@ -18,6 +18,8 @@
"int32_list.h",
"uint8_list.cc",
"uint8_list.h",
+ "uint16_list.cc",
+ "uint16_list.h",
]
deps = [
diff --git a/typed_data/uint16_list.cc b/typed_data/uint16_list.cc
new file mode 100644
index 0000000..955a3bf
--- /dev/null
+++ b/typed_data/uint16_list.cc
@@ -0,0 +1,82 @@
+// Copyright 2015 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tonic/typed_data/uint16_list.h"
+
+#include <string.h>
+
+#include "tonic/logging/dart_error.h"
+
+namespace tonic {
+
+Uint16List::Uint16List()
+ : data_(nullptr), num_elements_(0), dart_handle_(nullptr) {}
+
+Uint16List::Uint16List(Dart_Handle list)
+ : data_(nullptr), num_elements_(0), dart_handle_(list) {
+ if (Dart_IsNull(list))
+ return;
+
+ Dart_TypedData_Type type;
+ Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
+ &num_elements_);
+ TONIC_DCHECK(!LogIfError(list));
+ if (type != Dart_TypedData_kUint16)
+ Dart_ThrowException(ToDart("Non-genuine Uint16List passed to engine."));
+}
+
+Uint16List::Uint16List(Uint16List&& other)
+ : data_(other.data_),
+ num_elements_(other.num_elements_),
+ dart_handle_(other.dart_handle_) {
+ other.data_ = nullptr;
+ other.dart_handle_ = nullptr;
+}
+
+Uint16List::~Uint16List() {
+ Release();
+}
+
+void Uint16List::Release() {
+ if (data_) {
+ Dart_TypedDataReleaseData(dart_handle_);
+ data_ = nullptr;
+ num_elements_ = 0;
+ dart_handle_ = nullptr;
+ }
+}
+
+Uint16List DartConverter<Uint16List>::FromArguments(Dart_NativeArguments args,
+ int index,
+ Dart_Handle& exception) {
+ Dart_Handle list = Dart_GetNativeArgument(args, index);
+ TONIC_DCHECK(!LogIfError(list));
+ return Uint16List(list);
+}
+
+void DartConverter<Uint16List>::SetReturnValue(Dart_NativeArguments args,
+ Uint16List val) {
+ Dart_SetReturnValue(args, val.dart_handle());
+}
+
+Dart_Handle DartConverter<Uint16List>::ToDart(const uint16_t* buffer,
+ unsigned int length) {
+ const intptr_t buffer_length = static_cast<intptr_t>(length);
+ Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint16, buffer_length);
+ TONIC_DCHECK(!LogIfError(array));
+ {
+ Dart_TypedData_Type type;
+ void* data = nullptr;
+ intptr_t data_length = 0;
+ Dart_TypedDataAcquireData(array, &type, &data, &data_length);
+ TONIC_CHECK(type == Dart_TypedData_kUint16);
+ TONIC_CHECK(data);
+ TONIC_CHECK(data_length == buffer_length);
+ memmove(data, buffer, data_length);
+ Dart_TypedDataReleaseData(array);
+ }
+ return array;
+}
+
+} // namespace tonic
diff --git a/typed_data/uint16_list.h b/typed_data/uint16_list.h
new file mode 100644
index 0000000..f606893
--- /dev/null
+++ b/typed_data/uint16_list.h
@@ -0,0 +1,62 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIB_TONIC_TYPED_DATA_UINT16_LIST_H_
+#define LIB_TONIC_TYPED_DATA_UINT16_LIST_H_
+
+#include "third_party/dart/runtime/include/dart_api.h"
+#include "tonic/converter/dart_converter.h"
+
+namespace tonic {
+
+// A simple wrapper around a Dart Uint16List. It uses Dart_TypedDataAcquireData
+// to obtain a raw pointer to the data, which is released when this object is
+// destroyed.
+//
+// This is designed to be used with DartConverter only.
+class Uint16List {
+ public:
+ explicit Uint16List(Dart_Handle list);
+ Uint16List(Uint16List&& other);
+ Uint16List();
+ ~Uint16List();
+
+ uint16_t& at(intptr_t i) {
+ TONIC_CHECK(i < num_elements_);
+ return data_[i];
+ }
+ const uint16_t& at(intptr_t i) const {
+ TONIC_CHECK(i < num_elements_);
+ return data_[i];
+ }
+
+ uint16_t& operator[](intptr_t i) { return at(i); }
+ const uint16_t& operator[](intptr_t i) const { return at(i); }
+
+ const uint16_t* data() const { return data_; }
+ intptr_t num_elements() const { return num_elements_; }
+ Dart_Handle dart_handle() const { return dart_handle_; }
+
+ void Release();
+
+ private:
+ uint16_t* data_;
+ intptr_t num_elements_;
+ Dart_Handle dart_handle_;
+
+ Uint16List(const Uint16List& other) = delete;
+};
+
+template <>
+struct DartConverter<Uint16List> {
+ static void SetReturnValue(Dart_NativeArguments args, Uint16List val);
+ static Uint16List FromArguments(Dart_NativeArguments args,
+ int index,
+ Dart_Handle& exception);
+ static Dart_Handle ToDart(const uint16_t* buffer, unsigned int length);
+};
+
+} // namespace tonic
+
+#endif // LIB_TONIC_TYPED_DATA_UINT16_LIST_H_