Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: src/core/SkData.cpp

Issue 560653004: SkData can allocate room for its contents in the same block (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update dox, change fPtr to non const Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkBitmap.cpp ('k') | src/core/SkFlattenableSerialization.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkLazyPtr.h" 9 #include "SkLazyPtr.h"
10 #include "SkOSFile.h" 10 #include "SkOSFile.h"
11 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h" 12 #include "SkWriteBuffer.h"
13 13
14 static void sk_inplace_sentinel_releaseproc(const void*, size_t, void*) {
15 // we should never get called, as we are just a sentinel
16 sk_throw();
17 }
18
14 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) { 19 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
15 fPtr = ptr; 20 fPtr = const_cast<void*>(ptr);
16 fSize = size; 21 fSize = size;
17 fReleaseProc = proc; 22 fReleaseProc = proc;
18 fReleaseProcContext = context; 23 fReleaseProcContext = context;
19 } 24 }
20 25
26 // This constructor means we are inline with our fPtr's contents. Thus we set fP tr
27 // to point right after this. We also set our releaseproc to sk_inplace_sentinel _releaseproc,
28 // since we need to handle "delete" ourselves. See internal_displose().
29 //
30 SkData::SkData(size_t size) {
31 fPtr = (char*)(this + 1); // contents are immediately after this
32 fSize = size;
33 fReleaseProc = sk_inplace_sentinel_releaseproc;
34 fReleaseProcContext = NULL;
35 }
36
21 SkData::~SkData() { 37 SkData::~SkData() {
22 if (fReleaseProc) { 38 if (fReleaseProc) {
23 fReleaseProc(fPtr, fSize, fReleaseProcContext); 39 fReleaseProc(fPtr, fSize, fReleaseProcContext);
24 } 40 }
25 } 41 }
26 42
43 void SkData::internal_dispose() const {
44 if (sk_inplace_sentinel_releaseproc == fReleaseProc) {
45 const_cast<SkData*>(this)->fReleaseProc = NULL; // so we don't call i t in our destructor
46
47 this->internal_dispose_restore_refcnt_to_1();
48 this->~SkData(); // explicitly call this for refcnt bookkeeping
49
50 sk_free(const_cast<SkData*>(this));
51 } else {
52 this->internal_dispose_restore_refcnt_to_1();
53 SkDELETE(this);
54 }
55 }
56
27 bool SkData::equals(const SkData* other) const { 57 bool SkData::equals(const SkData* other) const {
28 if (NULL == other) { 58 if (NULL == other) {
29 return false; 59 return false;
30 } 60 }
31 61
32 return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize); 62 return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize);
33 } 63 }
34 64
35 size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const { 65 size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {
36 size_t available = fSize; 66 size_t available = fSize;
37 if (offset >= available || 0 == length) { 67 if (offset >= available || 0 == length) {
38 return 0; 68 return 0;
39 } 69 }
40 available -= offset; 70 available -= offset;
41 if (length > available) { 71 if (length > available) {
42 length = available; 72 length = available;
43 } 73 }
44 SkASSERT(length > 0); 74 SkASSERT(length > 0);
45 75
46 memcpy(buffer, this->bytes() + offset, length); 76 memcpy(buffer, this->bytes() + offset, length);
47 return length; 77 return length;
48 } 78 }
49 79
80 SkData* SkData::PrivateNewWithCopy(const void* srcOrNull, size_t length) {
81 if (0 == length) {
82 return SkData::NewEmpty();
83 }
84 char* storage = (char*)sk_malloc_throw(sizeof(SkData) + length);
85 SkData* data = new (storage) SkData(length);
86 if (srcOrNull) {
87 memcpy(data->writable_data(), srcOrNull, length);
88 }
89 return data;
90 }
91
50 /////////////////////////////////////////////////////////////////////////////// 92 ///////////////////////////////////////////////////////////////////////////////
51 93
52 SkData* SkData::NewEmptyImpl() { 94 SkData* SkData::NewEmptyImpl() {
53 return new SkData(NULL, 0, NULL, NULL); 95 return new SkData(NULL, 0, NULL, NULL);
54 } 96 }
97
55 void SkData::DeleteEmpty(SkData* ptr) { SkDELETE(ptr); } 98 void SkData::DeleteEmpty(SkData* ptr) { SkDELETE(ptr); }
56 99
57 SkData* SkData::NewEmpty() { 100 SkData* SkData::NewEmpty() {
58 SK_DECLARE_STATIC_LAZY_PTR(SkData, empty, NewEmptyImpl, DeleteEmpty); 101 SK_DECLARE_STATIC_LAZY_PTR(SkData, empty, NewEmptyImpl, DeleteEmpty);
59 return SkRef(empty.get()); 102 return SkRef(empty.get());
60 } 103 }
61 104
62 // assumes fPtr was allocated via sk_malloc 105 // assumes fPtr was allocated via sk_malloc
63 static void sk_free_releaseproc(const void* ptr, size_t, void*) { 106 static void sk_free_releaseproc(const void* ptr, size_t, void*) {
64 sk_free((void*)ptr); 107 sk_free((void*)ptr);
65 } 108 }
66 109
67 SkData* SkData::NewFromMalloc(const void* data, size_t length) { 110 SkData* SkData::NewFromMalloc(const void* data, size_t length) {
68 return new SkData(data, length, sk_free_releaseproc, NULL); 111 return new SkData(data, length, sk_free_releaseproc, NULL);
69 } 112 }
70 113
71 SkData* SkData::NewWithCopy(const void* data, size_t length) { 114 SkData* SkData::NewWithCopy(const void* src, size_t length) {
72 if (0 == length) { 115 SkASSERT(src);
73 return SkData::NewEmpty(); 116 return PrivateNewWithCopy(src, length);
74 } 117 }
75 118
76 void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc 119 SkData* SkData::NewUninitialized(size_t length) {
77 memcpy(copy, data, length); 120 return PrivateNewWithCopy(NULL, length);
78 return new SkData(copy, length, sk_free_releaseproc, NULL);
79 } 121 }
80 122
81 SkData* SkData::NewWithProc(const void* data, size_t length, 123 SkData* SkData::NewWithProc(const void* data, size_t length,
82 ReleaseProc proc, void* context) { 124 ReleaseProc proc, void* context) {
83 return new SkData(data, length, proc, context); 125 return new SkData(data, length, proc, context);
84 } 126 }
85 127
86 // assumes fPtr was allocated with sk_fmmap 128 // assumes fPtr was allocated with sk_fmmap
87 static void sk_mmap_releaseproc(const void* addr, size_t length, void*) { 129 static void sk_mmap_releaseproc(const void* addr, size_t length, void*) {
88 sk_fmunmap(addr, length); 130 sk_fmunmap(addr, length);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 SkData* SkData::NewWithCString(const char cstr[]) { 191 SkData* SkData::NewWithCString(const char cstr[]) {
150 size_t size; 192 size_t size;
151 if (NULL == cstr) { 193 if (NULL == cstr) {
152 cstr = ""; 194 cstr = "";
153 size = 1; 195 size = 1;
154 } else { 196 } else {
155 size = strlen(cstr) + 1; 197 size = strlen(cstr) + 1;
156 } 198 }
157 return NewWithCopy(cstr, size); 199 return NewWithCopy(cstr, size);
158 } 200 }
OLDNEW
« no previous file with comments | « src/core/SkBitmap.cpp ('k') | src/core/SkFlattenableSerialization.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698