1
2 /*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10
11 #include "SkData.h"
12
SkData(const void * ptr,size_t size,ReleaseProc proc,void * context)13 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
14 fPtr = ptr;
15 fSize = size;
16 fReleaseProc = proc;
17 fReleaseProcContext = context;
18 }
19
~SkData()20 SkData::~SkData() {
21 if (fReleaseProc) {
22 fReleaseProc(fPtr, fSize, fReleaseProcContext);
23 }
24 }
25
copyRange(size_t offset,size_t length,void * buffer) const26 size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {
27 size_t available = fSize;
28 if (offset >= available || 0 == length) {
29 return 0;
30 }
31 available -= offset;
32 if (length > available) {
33 length = available;
34 }
35 SkASSERT(length > 0);
36
37 memcpy(buffer, this->bytes() + offset, length);
38 return length;
39 }
40
41 ///////////////////////////////////////////////////////////////////////////////
42
NewEmpty()43 SkData* SkData::NewEmpty() {
44 static SkData* gEmptyRef;
45 if (NULL == gEmptyRef) {
46 gEmptyRef = new SkData(NULL, 0, NULL, NULL);
47 }
48 gEmptyRef->ref();
49 return gEmptyRef;
50 }
51
52 // assumes fPtr was allocated via sk_malloc
sk_free_releaseproc(const void * ptr,size_t,void *)53 static void sk_free_releaseproc(const void* ptr, size_t, void*) {
54 sk_free((void*)ptr);
55 }
56
NewFromMalloc(const void * data,size_t length)57 SkData* SkData::NewFromMalloc(const void* data, size_t length) {
58 return new SkData(data, length, sk_free_releaseproc, NULL);
59 }
60
NewWithCopy(const void * data,size_t length)61 SkData* SkData::NewWithCopy(const void* data, size_t length) {
62 if (0 == length) {
63 return SkData::NewEmpty();
64 }
65
66 void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
67 memcpy(copy, data, length);
68 return new SkData(copy, length, sk_free_releaseproc, NULL);
69 }
70
NewWithProc(const void * data,size_t length,ReleaseProc proc,void * context)71 SkData* SkData::NewWithProc(const void* data, size_t length,
72 ReleaseProc proc, void* context) {
73 return new SkData(data, length, proc, context);
74 }
75
76 // assumes context is a SkData
sk_dataref_releaseproc(const void *,size_t,void * context)77 static void sk_dataref_releaseproc(const void*, size_t, void* context) {
78 SkData* src = reinterpret_cast<SkData*>(context);
79 src->unref();
80 }
81
NewSubset(const SkData * src,size_t offset,size_t length)82 SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) {
83 /*
84 We could, if we wanted/need to, just make a deep copy of src's data,
85 rather than referencing it. This would duplicate the storage (of the
86 subset amount) but would possibly allow src to go out of scope sooner.
87 */
88
89 size_t available = src->size();
90 if (offset >= available || 0 == length) {
91 return SkData::NewEmpty();
92 }
93 available -= offset;
94 if (length > available) {
95 length = available;
96 }
97 SkASSERT(length > 0);
98
99 src->ref(); // this will be balanced in sk_dataref_releaseproc
100 return new SkData(src->bytes() + offset, length, sk_dataref_releaseproc,
101 const_cast<SkData*>(src));
102 }
103
104