blob: 2653f327c078fa6484f3635ae98543be0e922bfa [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.com3a31ac12011-06-24 13:11:05 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.com3a31ac12011-06-24 13:11:05 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.com3a31ac12011-06-24 13:11:05 +000011#include "SkData.h"
12
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000013SK_DEFINE_INST_COUNT(SkData)
14
reed@google.com3a31ac12011-06-24 13:11:05 +000015SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
16 fPtr = ptr;
17 fSize = size;
18 fReleaseProc = proc;
19 fReleaseProcContext = context;
20}
21
22SkData::~SkData() {
23 if (fReleaseProc) {
24 fReleaseProc(fPtr, fSize, fReleaseProcContext);
25 }
26}
27
reed@google.comdbc936d2012-06-28 15:40:09 +000028bool SkData::equals(const SkData* other) const {
29 if (NULL == other) {
30 return false;
31 }
32
33 return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize);
34}
35
reed@google.com3a31ac12011-06-24 13:11:05 +000036size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {
37 size_t available = fSize;
38 if (offset >= available || 0 == length) {
39 return 0;
40 }
41 available -= offset;
42 if (length > available) {
43 length = available;
44 }
45 SkASSERT(length > 0);
46
47 memcpy(buffer, this->bytes() + offset, length);
48 return length;
49}
50
51///////////////////////////////////////////////////////////////////////////////
52
53SkData* SkData::NewEmpty() {
54 static SkData* gEmptyRef;
55 if (NULL == gEmptyRef) {
56 gEmptyRef = new SkData(NULL, 0, NULL, NULL);
57 }
58 gEmptyRef->ref();
59 return gEmptyRef;
60}
61
62// assumes fPtr was allocated via sk_malloc
reed@google.com8a85d0c2011-06-24 19:12:12 +000063static void sk_free_releaseproc(const void* ptr, size_t, void*) {
reed@google.com3a31ac12011-06-24 13:11:05 +000064 sk_free((void*)ptr);
65}
66
reed@google.com8a85d0c2011-06-24 19:12:12 +000067SkData* SkData::NewFromMalloc(const void* data, size_t length) {
68 return new SkData(data, length, sk_free_releaseproc, NULL);
69}
70
reed@google.com3a31ac12011-06-24 13:11:05 +000071SkData* SkData::NewWithCopy(const void* data, size_t length) {
72 if (0 == length) {
73 return SkData::NewEmpty();
74 }
75
reed@google.com8a85d0c2011-06-24 19:12:12 +000076 void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
reed@google.com3a31ac12011-06-24 13:11:05 +000077 memcpy(copy, data, length);
reed@google.com8a85d0c2011-06-24 19:12:12 +000078 return new SkData(copy, length, sk_free_releaseproc, NULL);
reed@google.com3a31ac12011-06-24 13:11:05 +000079}
80
81SkData* SkData::NewWithProc(const void* data, size_t length,
reed@google.com8a85d0c2011-06-24 19:12:12 +000082 ReleaseProc proc, void* context) {
reed@google.com3a31ac12011-06-24 13:11:05 +000083 return new SkData(data, length, proc, context);
84}
85
86// assumes context is a SkData
87static void sk_dataref_releaseproc(const void*, size_t, void* context) {
88 SkData* src = reinterpret_cast<SkData*>(context);
89 src->unref();
90}
91
92SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) {
93 /*
94 We could, if we wanted/need to, just make a deep copy of src's data,
95 rather than referencing it. This would duplicate the storage (of the
96 subset amount) but would possibly allow src to go out of scope sooner.
97 */
98
99 size_t available = src->size();
100 if (offset >= available || 0 == length) {
101 return SkData::NewEmpty();
102 }
103 available -= offset;
104 if (length > available) {
105 length = available;
106 }
107 SkASSERT(length > 0);
108
109 src->ref(); // this will be balanced in sk_dataref_releaseproc
110 return new SkData(src->bytes() + offset, length, sk_dataref_releaseproc,
111 const_cast<SkData*>(src));
112}
113
reed@google.comdbc936d2012-06-28 15:40:09 +0000114SkData* SkData::NewWithCString(const char cstr[]) {
115 if (NULL == cstr || 0 == cstr[0]) {
116 return NewEmpty();
117 } else {
118 return NewWithCopy(cstr, strlen(cstr));
119 }
120}
121