Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Unified Diff: ppapi/cpp/dev/array_dev.h

Issue 60173003: Draft: apps APIs in Pepper (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove PP_ArrayOutput from array structs. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/cpp/dev/alarms_dev.cc ('k') | ppapi/cpp/dev/foobar_dev.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/cpp/dev/array_dev.h
diff --git a/ppapi/cpp/dev/array_dev.h b/ppapi/cpp/dev/array_dev.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e56702565e92c360acce7c35c5083cc2c1b4810
--- /dev/null
+++ b/ppapi/cpp/dev/array_dev.h
@@ -0,0 +1,246 @@
+// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_DEV_ARRAY_DEV_H_
+#define PPAPI_CPP_DEV_ARRAY_DEV_H_
+
+#include <cstdlib>
+
+#include "ppapi/c/dev/pp_array_structs_dev.h"
+#include "ppapi/cpp/dev/may_own_ptr_dev.h"
+#include "ppapi/cpp/logging.h"
+
+namespace pp {
+
+namespace internal {
+
+class ArrayAllocator {
+ public:
+ static PP_ArrayOutput Get() {
+ PP_ArrayOutput array_output = { &ArrayAllocator::GetDataBuffer, NULL };
+ return array_output;
+ }
+
+ static void Free(void* mem) {
+ free(mem);
+ }
+
+ private:
+ static void* GetDataBuffer(void* /* user_data */,
+ uint32_t element_count,
+ uint32_t element_size) {
+ if (element_count == 0 || element_size == 0)
+ return NULL;
+
+ return calloc(element_count, element_size);
+ }
+};
+
+} // namespace internal
+
+template <class T>
+class Array {
+ public:
+ typedef typename T::CArrayType CArrayType;
+ typedef typename T::CType CType;
+ typedef CArrayType* COutputType;
+
+ Array() {
+ }
+
+ Array(CArrayType* storage, NotOwned) : storage_(storage, NOT_OWNED) {
+ PP_DCHECK(storage_->size == 0);
+ PP_DCHECK(storage_->elements == NULL);
+ }
+
+ explicit Array(uint32_t size) {
+ Reset(size);
+ }
+
+ Array(const Array<T>& other) {
+ DeepCopy(*other.storage_);
+ }
+
+ ~Array() {
+ Reset(0);
+ }
+
+ Array<T>& operator=(const Array<T>& other) {
+ return operator=(*other.storage_);
+ }
+
+ Array<T>& operator=(const CArrayType& other) {
+ if (storage_.get() == &other)
+ return *this;
+
+ Reset(0);
+ DeepCopy(other);
+
+ return *this;
+ }
+
+ uint32_t size() const {
+ return storage_->size;
+ }
+
+ T& operator[](uint32_t index) {
+ PP_DCHECK(storage_->size == wrappers_.size());
+ PP_DCHECK(index < storage_->size);
+ PP_DCHECK(wrappers_[index]->ToStruct() == storage_->elements + index);
+ return *wrappers_[index];
+ }
+
+ const T& operator[](uint32_t index) const {
+ PP_DCHECK(storage_->size == wrappers_.size());
+ PP_DCHECK(index < storage_->size);
+ PP_DCHECK(wrappers_[index]->ToStruct() == storage_->elements + index);
+ return *wrappers_[index];
+ }
+
+ void Reset(uint32_t size) {
+ internal::ArrayAllocator::Free(storage_->elements);
+ storage_->elements = NULL;
+
+ storage_->size = size;
+ if (size > 0) {
+ storage_->elements = new CType[size];
+ memset(storage_->elements, 0, sizeof(CType) * size);
+ }
+
+ UpdateWrappers();
Sam McNally 2013/12/11 08:10:43 This is unsafe for wrappers with a destructor that
yzshen1 2013/12/11 18:01:32 Good catch! Thanks! :) On 2013/12/11 08:10:43, Sa
+ }
+
+ CArrayType* StartRawUpdate() {
+ Reset(0);
+ return storage_.get();
+ }
+
+ void EndRawUpdate() {
+ PP_DCHECK(wrappers_.empty());
+ UpdateWrappers();
+ }
+
+ private:
+ void DeepCopy(const CArrayType& other) {
+ storage_->size = other.size;
+
+ if (storage_->size > 0) {
+ storage_->elements = new CType[storage_->size];
+ memset(storage_->elements, 0, sizeof(CType) * storage_->size);
+ }
+
+ UpdateWrappers();
+
+ for (size_t i = 0; i < storage_->size; ++i)
+ wrappers_[i] = other.elements[i];
+ }
+
+ void UpdateWrappers() {
+ for (typename std::vector<T*>::iterator iter = wrappers_.begin();
+ iter != wrappers_.end();
+ ++iter) {
+ delete *iter;
+ }
+ wrappers_.clear();
+
+ uint32_t size = storage_->size;
+ if (size == 0)
+ return;
+
+ wrappers_.reserve(size);
+ for (size_t i = 0; i < size; ++i)
+ wrappers_.push_back(new T(&storage_->elements[i], NOT_OWNED));
+ }
+
+ internal::MayOwnPtr<CArrayType> storage_;
+ std::vector<T*> wrappers_;
+};
+
+template <>
+class Array<double> {
+ public:
+ typedef PP_Double_Array* COutputType;
+
+ Array(PP_Double_Array* storage, NotOwned) : storage_(storage, NOT_OWNED) {
+ PP_DCHECK(storage_->size == 0);
+ PP_DCHECK(storage_->elements == NULL);
+ }
+
+ explicit Array(uint32_t size) {
+ Reset(size);
+ }
+
+ Array(const Array<double>& other) {
+ DeepCopy(*other.storage_);
+ }
+
+ ~Array() {
+ Reset(0);
+ }
+
+ Array<double>& operator=(const Array<double>& other) {
+ return operator=(*other.storage_);
+ }
+
+ Array<double>& operator=(const PP_Double_Array& other) {
+ if (storage_.get() == &other)
+ return *this;
+
+ Reset(0);
+ DeepCopy(other);
+
+ return *this;
+ }
+
+ uint32_t size() const {
+ return storage_->size;
+ }
+
+ double& operator[](uint32_t index) {
+ PP_DCHECK(index < storage_->size);
+ return storage_->elements[index];
+ }
+
+ double operator[](uint32_t index) const {
+ PP_DCHECK(index < storage_->size);
+ return storage_->elements[index];
+ }
+
+ void Reset(uint32_t size) {
+ internal::ArrayAllocator::Free(storage_->elements);
+ storage_->elements = NULL;
+
+ storage_->size = size;
+ if (size == 0)
+ return;
+
+ storage_->elements = new double[size];
+ memset(storage_->elements, 0, sizeof(double) * size);
+ }
+
+ PP_Double_Array* StartRawUpdate() {
+ Reset(0);
+ return storage_.get();
+ }
+
+ void EndRawUpdate() {}
+
+ private:
+ void DeepCopy(const PP_Double_Array& other) {
+ storage_->size = other.size;
+
+ if (storage_->size == 0)
+ return;
+
+ storage_->elements = new double[storage_->size];
+ // TODO(yzshen): for different things, this needs different handling.
+ memcpy(storage_->elements, other.elements, sizeof(double) * storage_->size);
+ }
+
+ internal::MayOwnPtr<PP_Double_Array> storage_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_ARRAY_DEV_H_
« no previous file with comments | « ppapi/cpp/dev/alarms_dev.cc ('k') | ppapi/cpp/dev/foobar_dev.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698