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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/cpp/dev/alarms_dev.cc ('k') | ppapi/cpp/dev/foobar_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 "ppapi/c/dev/pp_array_structs_dev.h"
11 #include "ppapi/cpp/dev/may_own_ptr_dev.h"
12 #include "ppapi/cpp/logging.h"
13
14 namespace pp {
15
16 namespace internal {
17
18 class ArrayAllocator {
19 public:
20 static PP_ArrayOutput Get() {
21 PP_ArrayOutput array_output = { &ArrayAllocator::GetDataBuffer, NULL };
22 return array_output;
23 }
24
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) {
34 free(mem);
35 }
36
37 private:
38 static void* GetDataBuffer(void* /* user_data */,
39 uint32_t element_count,
40 uint32_t element_size) {
41 return Alloc(element_count, element_size);
42 }
43 };
44
45 } // namespace internal
46
47 template <class T>
48 class Array {
49 public:
50 typedef typename T::CArrayType CArrayType;
51 typedef typename T::CType CType;
52 typedef CArrayType* COutputType;
53
54 Array() {
55 }
56
57 Array(CArrayType* storage, NotOwned) : storage_(storage, NOT_OWNED) {
58 PP_DCHECK(storage_->size == 0);
59 PP_DCHECK(storage_->elements == NULL);
60 }
61
62 explicit Array(uint32_t size) {
63 Reset(size);
64 }
65
66 Array(const Array<T>& other) {
67 DeepCopy(*other.storage_);
68 }
69
70 ~Array() {
71 Reset(0);
72 }
73
74 Array<T>& operator=(const Array<T>& other) {
75 return operator=(*other.storage_);
76 }
77
78 Array<T>& operator=(const CArrayType& other) {
79 if (storage_.get() == &other)
80 return *this;
81
82 Reset(0);
83 DeepCopy(other);
84
85 return *this;
86 }
87
88 uint32_t size() const {
89 return storage_->size;
90 }
91
92 T& operator[](uint32_t index) {
93 PP_DCHECK(storage_->size == wrappers_.size());
94 PP_DCHECK(index < storage_->size);
95 PP_DCHECK(wrappers_[index]->ToStruct() == storage_->elements + index);
96 return *wrappers_[index];
97 }
98
99 const T& operator[](uint32_t index) const {
100 PP_DCHECK(storage_->size == wrappers_.size());
101 PP_DCHECK(index < storage_->size);
102 PP_DCHECK(wrappers_[index]->ToStruct() == storage_->elements + index);
103 return *wrappers_[index];
104 }
105
106 void Reset(uint32_t size) {
107 // Wrappers must be destroyed before we free |storage_->elements|, because
108 // they may try to access the memory in their destructors.
109 DeleteWrappers();
110
111 internal::ArrayAllocator::Free(storage_->elements);
112 storage_->elements = NULL;
113
114 storage_->size = size;
115 if (size > 0) {
116 storage_->elements = static_cast<CType*>(
117 internal::ArrayAllocator::Alloc(size, sizeof(CType)));
118 }
119
120 CreateWrappers();
121 }
122
123 CArrayType* StartRawUpdate() {
124 Reset(0);
125 return storage_.get();
126 }
127
128 void EndRawUpdate() {
129 CreateWrappers();
130 }
131
132 private:
133 void DeepCopy(const CArrayType& other) {
134 storage_->size = other.size;
135
136 if (storage_->size > 0) {
137 storage_->elements = static_cast<CType*>(
138 internal::ArrayAllocator::Alloc(storage_->size, sizeof(CType)));
139 }
140
141 CreateWrappers();
142
143 for (size_t i = 0; i < storage_->size; ++i)
144 wrappers_[i] = other.elements[i];
145 }
146
147 void DeleteWrappers() {
148 for (typename std::vector<T*>::iterator iter = wrappers_.begin();
149 iter != wrappers_.end();
150 ++iter) {
151 delete *iter;
152 }
153 wrappers_.clear();
154 }
155
156 void CreateWrappers() {
157 PP_DCHECK(wrappers_.empty());
158
159 uint32_t size = storage_->size;
160 if (size == 0)
161 return;
162
163 wrappers_.reserve(size);
164 for (size_t i = 0; i < size; ++i)
165 wrappers_.push_back(new T(&storage_->elements[i], NOT_OWNED));
166 }
167
168 internal::MayOwnPtr<CArrayType> storage_;
169 std::vector<T*> wrappers_;
170 };
171
172 template <>
173 class Array<double> {
174 public:
175 typedef PP_Double_Array* COutputType;
176
177 Array(PP_Double_Array* storage, NotOwned) : storage_(storage, NOT_OWNED) {
178 PP_DCHECK(storage_->size == 0);
179 PP_DCHECK(storage_->elements == NULL);
180 }
181
182 explicit Array(uint32_t size) {
183 Reset(size);
184 }
185
186 Array(const Array<double>& other) {
187 DeepCopy(*other.storage_);
188 }
189
190 ~Array() {
191 Reset(0);
192 }
193
194 Array<double>& operator=(const Array<double>& other) {
195 return operator=(*other.storage_);
196 }
197
198 Array<double>& operator=(const PP_Double_Array& other) {
199 if (storage_.get() == &other)
200 return *this;
201
202 Reset(0);
203 DeepCopy(other);
204
205 return *this;
206 }
207
208 uint32_t size() const {
209 return storage_->size;
210 }
211
212 double& operator[](uint32_t index) {
213 PP_DCHECK(index < storage_->size);
214 return storage_->elements[index];
215 }
216
217 double operator[](uint32_t index) const {
218 PP_DCHECK(index < storage_->size);
219 return storage_->elements[index];
220 }
221
222 void Reset(uint32_t size) {
223 internal::ArrayAllocator::Free(storage_->elements);
224 storage_->elements = NULL;
225
226 storage_->size = size;
227 if (size == 0)
228 return;
229
230 storage_->elements = static_cast<double*>(
231 internal::ArrayAllocator::Alloc(size, sizeof(double)));
232 }
233
234 PP_Double_Array* StartRawUpdate() {
235 Reset(0);
236 return storage_.get();
237 }
238
239 void EndRawUpdate() {}
240
241 private:
242 void DeepCopy(const PP_Double_Array& other) {
243 storage_->size = other.size;
244
245 if (storage_->size == 0)
246 return;
247
248 storage_->elements = static_cast<double*>(
249 internal::ArrayAllocator::Alloc(storage_->size, sizeof(double)));
250 // TODO(yzshen): for different things, this needs different handling.
251 memcpy(storage_->elements, other.elements, sizeof(double) * storage_->size);
252 }
253
254 internal::MayOwnPtr<PP_Double_Array> storage_;
255 };
256
257 } // namespace pp
258
259 #endif // PPAPI_CPP_DEV_ARRAY_DEV_H_
OLDNEW
« 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