gfx/skia/trunk/src/core/SkData.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:1cbd0202e5ef
1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkData.h"
9 #include "SkReadBuffer.h"
10 #include "SkWriteBuffer.h"
11 #include "SkOSFile.h"
12 #include "SkOnce.h"
13
14 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
15 fPtr = ptr;
16 fSize = size;
17 fReleaseProc = proc;
18 fReleaseProcContext = context;
19 }
20
21 SkData::~SkData() {
22 if (fReleaseProc) {
23 fReleaseProc(fPtr, fSize, fReleaseProcContext);
24 }
25 }
26
27 bool SkData::equals(const SkData* other) const {
28 if (NULL == other) {
29 return false;
30 }
31
32 return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize);
33 }
34
35 size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {
36 size_t available = fSize;
37 if (offset >= available || 0 == length) {
38 return 0;
39 }
40 available -= offset;
41 if (length > available) {
42 length = available;
43 }
44 SkASSERT(length > 0);
45
46 memcpy(buffer, this->bytes() + offset, length);
47 return length;
48 }
49
50 ///////////////////////////////////////////////////////////////////////////////
51
52 static SkData* gEmptyDataRef = NULL;
53 static void cleanup_gEmptyDataRef() { gEmptyDataRef->unref(); }
54
55 void SkData::NewEmptyImpl(int) {
56 gEmptyDataRef = new SkData(NULL, 0, NULL, NULL);
57 }
58
59 SkData* SkData::NewEmpty() {
60 SK_DECLARE_STATIC_ONCE(once);
61 SkOnce(&once, SkData::NewEmptyImpl, 0, cleanup_gEmptyDataRef);
62 gEmptyDataRef->ref();
63 return gEmptyDataRef;
64 }
65
66 // assumes fPtr was allocated via sk_malloc
67 static void sk_free_releaseproc(const void* ptr, size_t, void*) {
68 sk_free((void*)ptr);
69 }
70
71 SkData* SkData::NewFromMalloc(const void* data, size_t length) {
72 return new SkData(data, length, sk_free_releaseproc, NULL);
73 }
74
75 SkData* SkData::NewWithCopy(const void* data, size_t length) {
76 if (0 == length) {
77 return SkData::NewEmpty();
78 }
79
80 void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
81 memcpy(copy, data, length);
82 return new SkData(copy, length, sk_free_releaseproc, NULL);
83 }
84
85 SkData* SkData::NewWithProc(const void* data, size_t length,
86 ReleaseProc proc, void* context) {
87 return new SkData(data, length, proc, context);
88 }
89
90 // assumes fPtr was allocated with sk_fmmap
91 static void sk_mmap_releaseproc(const void* addr, size_t length, void*) {
92 sk_fmunmap(addr, length);
93 }
94
95 SkData* SkData::NewFromFILE(SkFILE* f) {
96 size_t size;
97 void* addr = sk_fmmap(f, &size);
98 if (NULL == addr) {
99 return NULL;
100 }
101
102 return SkData::NewWithProc(addr, size, sk_mmap_releaseproc, NULL);
103 }
104
105 SkData* SkData::NewFromFileName(const char path[]) {
106 SkFILE* f = path ? sk_fopen(path, kRead_SkFILE_Flag) : NULL;
107 if (NULL == f) {
108 return NULL;
109 }
110 SkData* data = NewFromFILE(f);
111 sk_fclose(f);
112 return data;
113 }
114
115 SkData* SkData::NewFromFD(int fd) {
116 size_t size;
117 void* addr = sk_fdmmap(fd, &size);
118 if (NULL == addr) {
119 return NULL;
120 }
121
122 return SkData::NewWithProc(addr, size, sk_mmap_releaseproc, NULL);
123 }
124
125 // assumes context is a SkData
126 static void sk_dataref_releaseproc(const void*, size_t, void* context) {
127 SkData* src = reinterpret_cast<SkData*>(context);
128 src->unref();
129 }
130
131 SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) {
132 /*
133 We could, if we wanted/need to, just make a deep copy of src's data,
134 rather than referencing it. This would duplicate the storage (of the
135 subset amount) but would possibly allow src to go out of scope sooner.
136 */
137
138 size_t available = src->size();
139 if (offset >= available || 0 == length) {
140 return SkData::NewEmpty();
141 }
142 available -= offset;
143 if (length > available) {
144 length = available;
145 }
146 SkASSERT(length > 0);
147
148 src->ref(); // this will be balanced in sk_dataref_releaseproc
149 return new SkData(src->bytes() + offset, length, sk_dataref_releaseproc,
150 const_cast<SkData*>(src));
151 }
152
153 SkData* SkData::NewWithCString(const char cstr[]) {
154 size_t size;
155 if (NULL == cstr) {
156 cstr = "";
157 size = 1;
158 } else {
159 size = strlen(cstr) + 1;
160 }
161 return NewWithCopy(cstr, size);
162 }

mercurial