OLD | NEW |
| (Empty) |
1 #include "SkWriter32.h" | |
2 | |
3 struct SkWriter32::Block { | |
4 Block* fNext; | |
5 size_t fSize; | |
6 size_t fAllocated; | |
7 | |
8 size_t available() const { return fSize - fAllocated; } | |
9 char* base() { return (char*)(this + 1); } | |
10 const char* base() const { return (const char*)(this + 1); } | |
11 | |
12 uint32_t* alloc(size_t size) | |
13 { | |
14 SkASSERT(SkAlign4(size) == size); | |
15 SkASSERT(this->available() >= size); | |
16 void* ptr = this->base() + fAllocated; | |
17 fAllocated += size; | |
18 SkASSERT(fAllocated <= fSize); | |
19 return (uint32_t*)ptr; | |
20 } | |
21 | |
22 uint32_t* peek32(size_t offset) | |
23 { | |
24 SkASSERT(offset <= fAllocated + 4); | |
25 void* ptr = this->base() + offset; | |
26 return (uint32_t*)ptr; | |
27 } | |
28 | |
29 static Block* Create(size_t size) | |
30 { | |
31 SkASSERT(SkAlign4(size) == size); | |
32 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); | |
33 block->fNext = NULL; | |
34 block->fSize = size; | |
35 block->fAllocated = 0; | |
36 return block; | |
37 } | |
38 }; | |
39 | |
40 static size_t compute_block_size(size_t currSize, size_t minSize) | |
41 { | |
42 if (currSize < minSize) | |
43 currSize = minSize; | |
44 | |
45 currSize += (currSize >> 1); | |
46 return SkAlign4(currSize); | |
47 } | |
48 | |
49 /////////////////////////////////////////////////////////////////////////////// | |
50 | |
51 SkWriter32::~SkWriter32() | |
52 { | |
53 this->reset(); | |
54 } | |
55 | |
56 void SkWriter32::reset() | |
57 { | |
58 Block* block = fHead; | |
59 while (block) | |
60 { | |
61 Block* next = block->fNext; | |
62 sk_free(block); | |
63 block = next; | |
64 } | |
65 fHead = fTail = NULL; | |
66 fSize = 0; | |
67 } | |
68 | |
69 uint32_t* SkWriter32::reserve(size_t size) | |
70 { | |
71 SkASSERT(SkAlign4(size) == size); | |
72 | |
73 Block* block = fTail; | |
74 | |
75 if (NULL == block) | |
76 { | |
77 SkASSERT(NULL == fHead); | |
78 fHead = fTail = block = Block::Create(SkMax32(size, fMinSize)); | |
79 } | |
80 else if (block->available() < size) | |
81 { | |
82 fTail = Block::Create(SkMax32(size, fMinSize)); | |
83 block->fNext = fTail; | |
84 block = fTail; | |
85 } | |
86 | |
87 fSize += size; | |
88 | |
89 return block->alloc(size); | |
90 } | |
91 | |
92 uint32_t* SkWriter32::peek32(size_t offset) | |
93 { | |
94 SkASSERT(SkAlign4(offset) == offset); | |
95 SkASSERT(offset <= fSize); | |
96 | |
97 Block* block = fHead; | |
98 SkASSERT(NULL != block); | |
99 | |
100 while (offset >= block->fAllocated) | |
101 { | |
102 offset -= block->fAllocated; | |
103 block = block->fNext; | |
104 SkASSERT(NULL != block); | |
105 } | |
106 return block->peek32(offset); | |
107 } | |
108 | |
109 void SkWriter32::flatten(void* dst) const | |
110 { | |
111 const Block* block = fHead; | |
112 SkDEBUGCODE(size_t total = 0;) | |
113 | |
114 while (block) | |
115 { | |
116 size_t allocated = block->fAllocated; | |
117 memcpy(dst, block->base(), allocated); | |
118 dst = (char*)dst + allocated; | |
119 block = block->fNext; | |
120 | |
121 SkDEBUGCODE(total += allocated;) | |
122 SkASSERT(total <= fSize); | |
123 } | |
124 SkASSERT(total == fSize); | |
125 } | |
126 | |
127 void SkWriter32::writePad(const void* src, size_t size) { | |
128 size_t alignedSize = SkAlign4(size); | |
129 char* dst = (char*)this->reserve(alignedSize); | |
130 memcpy(dst, src, size); | |
131 dst += size; | |
132 int n = alignedSize - size; | |
133 while (--n >= 0) { | |
134 *dst++ = 0; | |
135 } | |
136 } | |
137 | |
138 #include "SkStream.h" | |
139 | |
140 size_t SkWriter32::readFromStream(SkStream* stream, size_t length) { | |
141 char scratch[1024]; | |
142 const size_t MAX = sizeof(scratch); | |
143 size_t remaining = length; | |
144 | |
145 while (remaining != 0) { | |
146 size_t n = remaining; | |
147 if (n > MAX) { | |
148 n = MAX; | |
149 } | |
150 size_t bytes = stream->read(scratch, n); | |
151 this->writePad(scratch, bytes); | |
152 remaining -= bytes; | |
153 if (bytes != n) { | |
154 break; | |
155 } | |
156 } | |
157 return length - remaining; | |
158 } | |
159 | |
160 bool SkWriter32::writeToStream(SkWStream* stream) { | |
161 const Block* block = fHead; | |
162 while (block) { | |
163 if (!stream->write(block->base(), block->fAllocated)) { | |
164 return false; | |
165 } | |
166 block = block->fNext; | |
167 } | |
168 return true; | |
169 } | |
170 | |
OLD | NEW |