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 :
13 0 : SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
14 0 : fPtr = ptr;
15 0 : fSize = size;
16 0 : fReleaseProc = proc;
17 0 : fReleaseProcContext = context;
18 0 : }
19 :
20 0 : SkData::~SkData() {
21 0 : if (fReleaseProc) {
22 0 : fReleaseProc(fPtr, fSize, fReleaseProcContext);
23 : }
24 0 : }
25 :
26 0 : size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {
27 0 : size_t available = fSize;
28 0 : if (offset >= available || 0 == length) {
29 0 : return 0;
30 : }
31 0 : available -= offset;
32 0 : if (length > available) {
33 0 : length = available;
34 : }
35 0 : SkASSERT(length > 0);
36 :
37 0 : memcpy(buffer, this->bytes() + offset, length);
38 0 : return length;
39 : }
40 :
41 : ///////////////////////////////////////////////////////////////////////////////
42 :
43 0 : SkData* SkData::NewEmpty() {
44 : static SkData* gEmptyRef;
45 0 : if (NULL == gEmptyRef) {
46 0 : gEmptyRef = new SkData(NULL, 0, NULL, NULL);
47 : }
48 0 : gEmptyRef->ref();
49 0 : return gEmptyRef;
50 : }
51 :
52 : // assumes fPtr was allocated via sk_malloc
53 0 : static void sk_free_releaseproc(const void* ptr, size_t, void*) {
54 0 : sk_free((void*)ptr);
55 0 : }
56 :
57 0 : SkData* SkData::NewFromMalloc(const void* data, size_t length) {
58 0 : return new SkData(data, length, sk_free_releaseproc, NULL);
59 : }
60 :
61 0 : SkData* SkData::NewWithCopy(const void* data, size_t length) {
62 0 : if (0 == length) {
63 0 : return SkData::NewEmpty();
64 : }
65 :
66 0 : void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
67 0 : memcpy(copy, data, length);
68 0 : return new SkData(copy, length, sk_free_releaseproc, NULL);
69 : }
70 :
71 0 : SkData* SkData::NewWithProc(const void* data, size_t length,
72 : ReleaseProc proc, void* context) {
73 0 : return new SkData(data, length, proc, context);
74 : }
75 :
76 : // assumes context is a SkData
77 0 : static void sk_dataref_releaseproc(const void*, size_t, void* context) {
78 0 : SkData* src = reinterpret_cast<SkData*>(context);
79 0 : src->unref();
80 0 : }
81 :
82 0 : 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 0 : size_t available = src->size();
90 0 : if (offset >= available || 0 == length) {
91 0 : return SkData::NewEmpty();
92 : }
93 0 : available -= offset;
94 0 : if (length > available) {
95 0 : length = available;
96 : }
97 0 : SkASSERT(length > 0);
98 :
99 0 : src->ref(); // this will be balanced in sk_dataref_releaseproc
100 0 : return new SkData(src->bytes() + offset, length, sk_dataref_releaseproc,
101 0 : const_cast<SkData*>(src));
102 : }
103 :
|