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

Side by Side Diff: ppapi/cpp/dev/array_dev.h

Issue 116963003: App APIs in Pepper: C++ APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: changes according to Sam's suggestions. Created 6 years, 12 months 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 unified diff | Download patch
« no previous file with comments | « ppapi/cpp/dev/alarms_dev.cc ('k') | ppapi/cpp/dev/may_own_ptr_dev.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef PPAPI_CPP_DEV_ARRAY_DEV_H_
6 #define PPAPI_CPP_DEV_ARRAY_DEV_H_
7
8 #include <cstdlib>
9
10 #include <vector>
11
12 #include "ppapi/cpp/dev/may_own_ptr_dev.h"
13 #include "ppapi/cpp/logging.h"
14 #include "ppapi/cpp/output_traits.h"
15
16 namespace pp {
17
18 template <typename T>
19 class Array;
20
21 namespace internal {
22
23 class ArrayAllocator {
24 public:
25 // Allocates memory and zero-fills it.
26 static void* Alloc(uint32_t count, uint32_t size) {
27 if (count == 0 || size == 0)
28 return NULL;
29
30 return calloc(count, size);
31 }
32
33 static void Free(void* mem) { free(mem); }
34
35 static PP_ArrayOutput Get() {
36 PP_ArrayOutput array_output = { &ArrayAllocator::GetDataBuffer, NULL };
37 return array_output;
38 }
39
40 private:
41 static void* GetDataBuffer(void* /* user_data */,
42 uint32_t element_count,
43 uint32_t element_size) {
44 return Alloc(element_count, element_size);
45 }
46 };
47
48 // A specialization of CallbackOutputTraits for pp::Array parameters.
49 template <typename T>
50 struct CallbackOutputTraits<Array<T> > {
51 typedef typename Array<T>::CArrayType* APIArgType;
52 typedef Array<T> StorageType;
53
54 // Returns the underlying C struct of |t|, which can be passed to the browser
55 // as an output parameter.
56 static inline APIArgType StorageToAPIArg(StorageType& t) {
57 return t.StartRawUpdate();
58 }
59
60 // For each |t| passed into StorageToAPIArg(), this method must be called
61 // exactly once in order to match StartRawUpdate() and EndRawUpdate().
62 static inline Array<T>& StorageToPluginArg(StorageType& t) {
63 t.EndRawUpdate();
64 return t;
65 }
66
67 static inline void Initialize(StorageType* /* t */) {}
68 };
69
70 } // namespace internal
71
72 // Generic array for struct wrappers.
73 template <class T>
74 class Array {
75 public:
76 typedef typename T::CArrayType CArrayType;
77 typedef typename T::CType CType;
78
79 Array() {}
80
81 explicit Array(uint32_t size) { Reset(size); }
82
83 // Creates an accessor to |storage| but doesn't take ownership of the memory.
84 // |storage| must live longer than this object.
85 //
86 // Although this object doesn't own the memory of |storage|, it manages the
87 // memory pointed to by |storage->elements| and resets |storage| to empty when
88 // destructed.
89 Array(CArrayType* storage, NotOwned) : storage_(storage, NOT_OWNED) {
90 CreateWrappers();
91 }
92
93 Array(const Array<T>& other) { DeepCopy(*other.storage_); }
94
95 ~Array() { Reset(0); }
96
97 Array<T>& operator=(const Array<T>& other) {
98 return operator=(*other.storage_);
99 }
100
101 Array<T>& operator=(const CArrayType& other) {
102 if (storage_.get() == &other)
103 return *this;
104
105 Reset(0);
106 DeepCopy(other);
107
108 return *this;
109 }
110
111 uint32_t size() const { return storage_->size; }
112
113 T& operator[](uint32_t index) {
114 PP_DCHECK(storage_->size == wrappers_.size());
115 PP_DCHECK(index < storage_->size);
116 PP_DCHECK(wrappers_[index]->ToStruct() == storage_->elements + index);
117 return *wrappers_[index];
118 }
119
120 const T& operator[](uint32_t index) const {
121 PP_DCHECK(storage_->size == wrappers_.size());
122 PP_DCHECK(index < storage_->size);
123 PP_DCHECK(wrappers_[index]->ToStruct() == storage_->elements + index);
124 return *wrappers_[index];
125 }
126
127 // Clears the existing contents of the array, and resets it to |size| elements
128 // of default value.
129 void Reset(uint32_t size) {
130 // Wrappers must be destroyed before we free |storage_->elements|, because
131 // they may try to access the memory in their destructors.
132 DeleteWrappers();
133
134 internal::ArrayAllocator::Free(storage_->elements);
135 storage_->elements = NULL;
136
137 storage_->size = size;
138 if (size > 0) {
139 storage_->elements = static_cast<CType*>(
140 internal::ArrayAllocator::Alloc(size, sizeof(CType)));
141 }
142
143 CreateWrappers();
144 }
145
146 // Sets the underlying C array struct to empty before returning it.
147 CArrayType* StartRawUpdate() {
148 Reset(0);
149 return storage_.get();
150 }
151
152 void EndRawUpdate() { CreateWrappers(); }
153
154 private:
155 void DeepCopy(const CArrayType& other) {
156 storage_->size = other.size;
157
158 if (storage_->size > 0) {
159 storage_->elements = static_cast<CType*>(
160 internal::ArrayAllocator::Alloc(storage_->size, sizeof(CType)));
161 }
162
163 CreateWrappers();
164
165 for (size_t i = 0; i < storage_->size; ++i)
166 wrappers_[i] = other.elements[i];
167 }
168
169 void DeleteWrappers() {
170 for (typename std::vector<T*>::iterator iter = wrappers_.begin();
171 iter != wrappers_.end();
172 ++iter) {
173 delete *iter;
174 }
175 wrappers_.clear();
176 }
177
178 void CreateWrappers() {
179 PP_DCHECK(wrappers_.empty());
180
181 uint32_t size = storage_->size;
182 if (size == 0)
183 return;
184
185 wrappers_.reserve(size);
186 for (size_t i = 0; i < size; ++i)
187 wrappers_.push_back(new T(&storage_->elements[i], NOT_OWNED));
188 }
189
190 internal::MayOwnPtr<CArrayType> storage_;
191 std::vector<T*> wrappers_;
192 };
193
194 } // namespace pp
195
196 #endif // PPAPI_CPP_DEV_ARRAY_DEV_H_
OLDNEW
« no previous file with comments | « ppapi/cpp/dev/alarms_dev.cc ('k') | ppapi/cpp/dev/may_own_ptr_dev.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698