OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkData.h" | 8 #include "SkData.h" |
9 #include "SkFlattenableBuffers.h" | 9 #include "SkFlattenableBuffers.h" |
10 #include "SkOSFile.h" | 10 #include "SkOSFile.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 size_t size; | 149 size_t size; |
150 if (NULL == cstr) { | 150 if (NULL == cstr) { |
151 cstr = ""; | 151 cstr = ""; |
152 size = 1; | 152 size = 1; |
153 } else { | 153 } else { |
154 size = strlen(cstr) + 1; | 154 size = strlen(cstr) + 1; |
155 } | 155 } |
156 return NewWithCopy(cstr, size); | 156 return NewWithCopy(cstr, size); |
157 } | 157 } |
158 | 158 |
159 /////////////////////////////////////////////////////////////////////////////// | |
160 | |
161 #include "SkDataSet.h" | |
162 #include "SkFlattenable.h" | |
163 #include "SkStream.h" | |
164 | |
165 static SkData* dupdata(SkData* data) { | |
166 if (data) { | |
167 data->ref(); | |
168 } else { | |
169 data = SkData::NewEmpty(); | |
170 } | |
171 return data; | |
172 } | |
173 | |
174 static SkData* findValue(const char key[], const SkDataSet::Pair array[], int n)
{ | |
175 for (int i = 0; i < n; ++i) { | |
176 if (!strcmp(key, array[i].fKey)) { | |
177 return array[i].fValue; | |
178 } | |
179 } | |
180 return NULL; | |
181 } | |
182 | |
183 static SkDataSet::Pair* allocatePairStorage(int count, size_t storage) { | |
184 size_t size = count * sizeof(SkDataSet::Pair) + storage; | |
185 return (SkDataSet::Pair*)sk_malloc_throw(size); | |
186 } | |
187 | |
188 SkDataSet::SkDataSet(const char key[], SkData* value) { | |
189 size_t keyLen = strlen(key); | |
190 | |
191 fCount = 1; | |
192 fKeySize = keyLen + 1; | |
193 fPairs = allocatePairStorage(1, keyLen + 1); | |
194 | |
195 fPairs[0].fKey = (char*)(fPairs + 1); | |
196 memcpy(const_cast<char*>(fPairs[0].fKey), key, keyLen + 1); | |
197 | |
198 fPairs[0].fValue = dupdata(value); | |
199 } | |
200 | |
201 SkDataSet::SkDataSet(const Pair array[], int count) { | |
202 if (count < 1) { | |
203 fCount = 0; | |
204 fKeySize = 0; | |
205 fPairs = NULL; | |
206 return; | |
207 } | |
208 | |
209 int i; | |
210 size_t keySize = 0; | |
211 for (i = 0; i < count; ++i) { | |
212 keySize += strlen(array[i].fKey) + 1; | |
213 } | |
214 | |
215 Pair* pairs = fPairs = allocatePairStorage(count, keySize); | |
216 char* keyStorage = (char*)(pairs + count); | |
217 | |
218 keySize = 0; // reset this, so we can compute the size for unique keys | |
219 int uniqueCount = 0; | |
220 for (int i = 0; i < count; ++i) { | |
221 if (!findValue(array[i].fKey, pairs, uniqueCount)) { | |
222 size_t len = strlen(array[i].fKey); | |
223 memcpy(keyStorage, array[i].fKey, len + 1); | |
224 pairs[uniqueCount].fKey = keyStorage; | |
225 keyStorage += len + 1; | |
226 keySize += len + 1; | |
227 | |
228 pairs[uniqueCount].fValue = dupdata(array[i].fValue); | |
229 uniqueCount += 1; | |
230 } | |
231 } | |
232 fCount = uniqueCount; | |
233 fKeySize = keySize; | |
234 } | |
235 | |
236 SkDataSet::~SkDataSet() { | |
237 for (int i = 0; i < fCount; ++i) { | |
238 fPairs[i].fValue->unref(); | |
239 } | |
240 sk_free(fPairs); // this also frees the key storage | |
241 } | |
242 | |
243 SkData* SkDataSet::find(const char key[]) const { | |
244 return findValue(key, fPairs, fCount); | |
245 } | |
246 | |
247 void SkDataSet::writeToStream(SkWStream* stream) const { | |
248 stream->write32(fCount); | |
249 if (fCount > 0) { | |
250 stream->write32(fKeySize); | |
251 // our first key points to all the key storage | |
252 stream->write(fPairs[0].fKey, fKeySize); | |
253 for (int i = 0; i < fCount; ++i) { | |
254 stream->writeData(fPairs[i].fValue); | |
255 } | |
256 } | |
257 } | |
258 | |
259 void SkDataSet::flatten(SkFlattenableWriteBuffer& buffer) const { | |
260 buffer.writeInt(fCount); | |
261 if (fCount > 0) { | |
262 buffer.writeByteArray(fPairs[0].fKey, fKeySize); | |
263 for (int i = 0; i < fCount; ++i) { | |
264 buffer.writeDataAsByteArray(fPairs[i].fValue); | |
265 } | |
266 } | |
267 } | |
268 | |
269 SkDataSet::SkDataSet(SkStream* stream) { | |
270 fCount = stream->readU32(); | |
271 if (fCount > 0) { | |
272 fKeySize = stream->readU32(); | |
273 fPairs = allocatePairStorage(fCount, fKeySize); | |
274 char* keyStorage = (char*)(fPairs + fCount); | |
275 | |
276 stream->read(keyStorage, fKeySize); | |
277 | |
278 for (int i = 0; i < fCount; ++i) { | |
279 fPairs[i].fKey = keyStorage; | |
280 keyStorage += strlen(keyStorage) + 1; | |
281 fPairs[i].fValue = stream->readData(); | |
282 } | |
283 } else { | |
284 fKeySize = 0; | |
285 fPairs = NULL; | |
286 } | |
287 } | |
288 | |
289 SkDataSet::SkDataSet(SkFlattenableReadBuffer& buffer) { | |
290 fCount = buffer.readInt(); | |
291 if (fCount > 0) { | |
292 fKeySize = buffer.getArrayCount(); | |
293 fPairs = allocatePairStorage(fCount, fKeySize); | |
294 char* keyStorage = (char*)(fPairs + fCount); | |
295 | |
296 buffer.readByteArray(keyStorage); | |
297 | |
298 for (int i = 0; i < fCount; ++i) { | |
299 fPairs[i].fKey = keyStorage; | |
300 keyStorage += strlen(keyStorage) + 1; | |
301 fPairs[i].fValue = buffer.readByteArrayAsData(); | |
302 } | |
303 } else { | |
304 fKeySize = 0; | |
305 fPairs = NULL; | |
306 } | |
307 } | |
308 | |
309 SkDataSet* SkDataSet::NewEmpty() { | |
310 static SkDataSet* gEmptySet; | |
311 if (NULL == gEmptySet) { | |
312 gEmptySet = SkNEW_ARGS(SkDataSet, (NULL, 0)); | |
313 } | |
314 gEmptySet->ref(); | |
315 return gEmptySet; | |
316 } | |
OLD | NEW |