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

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: 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..ff2262cf1ce234eff2741e5a574ff9d27150efc4
--- /dev/null
+++ b/ppapi/cpp/dev/array_dev.h
@@ -0,0 +1,259 @@
+// 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;
+ }
+
+ // Allocates memory and zero-fills it.
+ static void* Alloc(uint32_t count, uint32_t size) {
+ if (count == 0 || size == 0)
+ return NULL;
+
+ return calloc(count, size);
+ }
+
+ static void Free(void* mem) {
+ free(mem);
+ }
+
+ private:
+ static void* GetDataBuffer(void* /* user_data */,
+ uint32_t element_count,
+ uint32_t element_size) {
+ return Alloc(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) {
+ // Wrappers must be destroyed before we free |storage_->elements|, because
+ // they may try to access the memory in their destructors.
+ DeleteWrappers();
+
+ internal::ArrayAllocator::Free(storage_->elements);
+ storage_->elements = NULL;
+
+ storage_->size = size;
+ if (size > 0) {
+ storage_->elements = static_cast<CType*>(
+ internal::ArrayAllocator::Alloc(size, sizeof(CType)));
+ }
+
+ CreateWrappers();
+ }
+
+ CArrayType* StartRawUpdate() {
+ Reset(0);
+ return storage_.get();
+ }
+
+ void EndRawUpdate() {
+ CreateWrappers();
+ }
+
+ private:
+ void DeepCopy(const CArrayType& other) {
+ storage_->size = other.size;
+
+ if (storage_->size > 0) {
+ storage_->elements = static_cast<CType*>(
+ internal::ArrayAllocator::Alloc(storage_->size, sizeof(CType)));
+ }
+
+ CreateWrappers();
+
+ for (size_t i = 0; i < storage_->size; ++i)
+ wrappers_[i] = other.elements[i];
+ }
+
+ void DeleteWrappers() {
+ for (typename std::vector<T*>::iterator iter = wrappers_.begin();
+ iter != wrappers_.end();
+ ++iter) {
+ delete *iter;
+ }
+ wrappers_.clear();
+ }
+
+ void CreateWrappers() {
+ PP_DCHECK(wrappers_.empty());
+
+ 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 = static_cast<double*>(
+ internal::ArrayAllocator::Alloc(size, sizeof(double)));
+ }
+
+ 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 = static_cast<double*>(
+ internal::ArrayAllocator::Alloc(storage_->size, sizeof(double)));
+ // 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