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

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

Issue 137433003: Convert SkWriter32 to use an SkTDArray for its internal storage. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: of course 0's fine too... Created 6 years, 11 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/SkScalerContext.cpp ('k') | src/pipe/SkGPipeWrite.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 "SkWriter32.h"
9
10 SkWriter32::SkWriter32(size_t minSize, void* storage, size_t storageSize) {
11 fMinSize = minSize;
12 fSize = 0;
13 fWrittenBeforeLastBlock = 0;
14 fHead = fTail = NULL;
15
16 if (storageSize) {
17 this->reset(storage, storageSize);
18 }
19 }
20
21 SkWriter32::~SkWriter32() {
22 this->reset();
23 }
24
25 void SkWriter32::reset() {
26 Block* block = fHead;
27
28 if (this->isHeadExternallyAllocated()) {
29 SkASSERT(block);
30 // don't 'free' the first block, since it is owned by the caller
31 block = block->fNext;
32 }
33 while (block) {
34 Block* next = block->fNext;
35 sk_free(block);
36 block = next;
37 }
38
39 fSize = 0;
40 fWrittenBeforeLastBlock = 0;
41 fHead = fTail = NULL;
42 }
43
44 void SkWriter32::reset(void* storage, size_t storageSize) {
45 this->reset();
46
47 storageSize &= ~3; // trunc down to multiple of 4
48 if (storageSize > 0 && SkIsAlign4((intptr_t)storage)) {
49 fHead = fTail = fExternalBlock.initFromStorage(storage, storageSize);
50 }
51 }
52
53 SkWriter32::Block* SkWriter32::doReserve(size_t size) {
54 SkASSERT(SkAlign4(size) == size);
55
56 Block* block = fTail;
57 SkASSERT(NULL == block || block->available() < size);
58
59 if (NULL == block) {
60 SkASSERT(NULL == fHead);
61 fHead = fTail = block = Block::Create(SkMax32(size, fMinSize));
62 SkASSERT(0 == fWrittenBeforeLastBlock);
63 } else {
64 fWrittenBeforeLastBlock = fSize;
65
66 fTail = Block::Create(SkMax32(size, fMinSize));
67 block->fNext = fTail;
68 block = fTail;
69 }
70 return block;
71 }
72
73 uint32_t* SkWriter32::peek32(size_t offset) {
74 SkDEBUGCODE(this->validate();)
75
76 SkASSERT(SkAlign4(offset) == offset);
77 SkASSERT(offset <= fSize);
78
79 // try the fast case, where offset is within fTail
80 if (offset >= fWrittenBeforeLastBlock) {
81 return fTail->peek32(offset - fWrittenBeforeLastBlock);
82 }
83
84 Block* block = fHead;
85 SkASSERT(NULL != block);
86
87 while (offset >= block->fAllocatedSoFar) {
88 offset -= block->fAllocatedSoFar;
89 block = block->fNext;
90 SkASSERT(NULL != block);
91 }
92 return block->peek32(offset);
93 }
94
95 void SkWriter32::rewindToOffset(size_t offset) {
96 if (offset >= fSize) {
97 return;
98 }
99 if (0 == offset) {
100 this->reset();
101 return;
102 }
103
104 SkDEBUGCODE(this->validate();)
105
106 SkASSERT(SkAlign4(offset) == offset);
107 SkASSERT(offset <= fSize);
108 fSize = offset;
109
110 // Try the fast case, where offset is within fTail
111 if (offset >= fWrittenBeforeLastBlock) {
112 fTail->fAllocatedSoFar = offset - fWrittenBeforeLastBlock;
113 } else {
114 // Similar to peek32, except that we free up any following blocks.
115 // We have to re-compute fWrittenBeforeLastBlock as well.
116
117 size_t globalOffset = offset;
118 Block* block = fHead;
119 SkASSERT(NULL != block);
120 while (offset >= block->fAllocatedSoFar) {
121 offset -= block->fAllocatedSoFar;
122 block = block->fNext;
123 SkASSERT(NULL != block);
124 }
125
126 // this has to be recomputed, since we may free up fTail
127 fWrittenBeforeLastBlock = globalOffset - offset;
128
129 // update the size on the "last" block
130 block->fAllocatedSoFar = offset;
131 // end our list
132 fTail = block;
133 Block* next = block->fNext;
134 block->fNext = NULL;
135 // free up any trailing blocks
136 block = next;
137 while (block) {
138 Block* next = block->fNext;
139 sk_free(block);
140 block = next;
141 }
142 }
143 SkDEBUGCODE(this->validate();)
144 }
145
146 void SkWriter32::flatten(void* dst) const {
147 const Block* block = fHead;
148 SkDEBUGCODE(size_t total = 0;)
149
150 while (block) {
151 size_t allocated = block->fAllocatedSoFar;
152 memcpy(dst, block->base(), allocated);
153 dst = (char*)dst + allocated;
154 block = block->fNext;
155
156 SkDEBUGCODE(total += allocated;)
157 SkASSERT(total <= fSize);
158 }
159 SkASSERT(total == fSize);
160 }
161
162 uint32_t* SkWriter32::reservePad(size_t size) {
163 if (size > 0) {
164 size_t alignedSize = SkAlign4(size);
165 char* dst = (char*)this->reserve(alignedSize);
166 // Pad the last four bytes with zeroes in one step.
167 uint32_t* padding = (uint32_t*)(dst + (alignedSize - 4));
168 *padding = 0;
169 return (uint32_t*) dst;
170 }
171 return this->reserve(0);
172 }
173
174 void SkWriter32::writePad(const void* src, size_t size) {
175 if (size > 0) {
176 char* dst = (char*)this->reservePad(size);
177 // Copy the actual data.
178 memcpy(dst, src, size);
179 }
180 }
181
182 #include "SkStream.h"
183
184 size_t SkWriter32::readFromStream(SkStream* stream, size_t length) {
185 char scratch[1024];
186 const size_t MAX = sizeof(scratch);
187 size_t remaining = length;
188
189 while (remaining != 0) {
190 size_t n = remaining;
191 if (n > MAX) {
192 n = MAX;
193 }
194 size_t bytes = stream->read(scratch, n);
195 this->writePad(scratch, bytes);
196 remaining -= bytes;
197 if (bytes != n) {
198 break;
199 }
200 }
201 return length - remaining;
202 }
203
204 bool SkWriter32::writeToStream(SkWStream* stream) {
205 const Block* block = fHead;
206 while (block) {
207 if (!stream->write(block->base(), block->fAllocatedSoFar)) {
208 return false;
209 }
210 block = block->fNext;
211 }
212 return true;
213 }
214
215 #ifdef SK_DEBUG
216 void SkWriter32::validate() const {
217 SkASSERT(SkIsAlign4(fSize));
218
219 size_t accum = 0;
220 const Block* block = fHead;
221 while (block) {
222 SkASSERT(SkIsAlign4(block->fSizeOfBlock));
223 SkASSERT(SkIsAlign4(block->fAllocatedSoFar));
224 SkASSERT(block->fAllocatedSoFar <= block->fSizeOfBlock);
225 if (NULL == block->fNext) {
226 SkASSERT(fTail == block);
227 SkASSERT(fWrittenBeforeLastBlock == accum);
228 }
229 accum += block->fAllocatedSoFar;
230 SkASSERT(accum <= fSize);
231 block = block->fNext;
232 }
233 SkASSERT(accum == fSize);
234 }
235 #endif
236
237 ///////////////////////////////////////////////////////////////////////////////
238
239 #include "SkReader32.h" 8 #include "SkReader32.h"
240 #include "SkString.h" 9 #include "SkString.h"
10 #include "SkWriter32.h"
241 11
242 /* 12 /*
243 * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4 13 * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4
244 */ 14 */
245 15
246 const char* SkReader32::readString(size_t* outLen) { 16 const char* SkReader32::readString(size_t* outLen) {
247 size_t len = this->readInt(); 17 size_t len = this->readInt();
248 const void* ptr = this->peek(); 18 const void* ptr = this->peek();
249 19
250 // skip over teh string + '\0' and then pad to a multiple of 4 20 // skip over the string + '\0' and then pad to a multiple of 4
251 size_t alignedSize = SkAlign4(len + 1); 21 size_t alignedSize = SkAlign4(len + 1);
252 this->skip(alignedSize); 22 this->skip(alignedSize);
253 23
254 if (outLen) { 24 if (outLen) {
255 *outLen = len; 25 *outLen = len;
256 } 26 }
257 return (const char*)ptr; 27 return (const char*)ptr;
258 } 28 }
259 29
260 size_t SkReader32::readIntoString(SkString* copy) { 30 size_t SkReader32::readIntoString(SkString* copy) {
(...skipping 28 matching lines...) Expand all
289 59
290 size_t SkWriter32::WriteStringSize(const char* str, size_t len) { 60 size_t SkWriter32::WriteStringSize(const char* str, size_t len) {
291 if ((long)len < 0) { 61 if ((long)len < 0) {
292 SkASSERT(str); 62 SkASSERT(str);
293 len = strlen(str); 63 len = strlen(str);
294 } 64 }
295 const size_t lenBytes = 4; // we use 4 bytes to record the length 65 const size_t lenBytes = 4; // we use 4 bytes to record the length
296 // add 1 since we also write a terminating 0 66 // add 1 since we also write a terminating 0
297 return SkAlign4(lenBytes + len + 1); 67 return SkAlign4(lenBytes + len + 1);
298 } 68 }
OLDNEW
« no previous file with comments | « src/core/SkScalerContext.cpp ('k') | src/pipe/SkGPipeWrite.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698