• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkWriter32.h"
2 
3 struct SkWriter32::Block {
4     Block*  fNext;
5     size_t  fSize;
6     size_t  fAllocated;
7 
availableSkWriter32::Block8     size_t  available() const { return fSize - fAllocated; }
baseSkWriter32::Block9     char*   base() { return (char*)(this + 1); }
baseSkWriter32::Block10     const char* base() const { return (const char*)(this + 1); }
11 
allocSkWriter32::Block12     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 
peek32SkWriter32::Block22     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 
CreateSkWriter32::Block29     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 ///////////////////////////////////////////////////////////////////////////////
41 
~SkWriter32()42 SkWriter32::~SkWriter32()
43 {
44     this->reset();
45 }
46 
reset()47 void SkWriter32::reset()
48 {
49     Block* block = fHead;
50     while (block)
51     {
52         Block* next = block->fNext;
53         sk_free(block);
54         block = next;
55     }
56     fHead = fTail = NULL;
57     fSize = 0;
58 }
59 
reserve(size_t size)60 uint32_t* SkWriter32::reserve(size_t size)
61 {
62     SkASSERT(SkAlign4(size) == size);
63 
64     Block* block = fTail;
65 
66     if (NULL == block)
67     {
68         SkASSERT(NULL == fHead);
69         fHead = fTail = block = Block::Create(SkMax32(size, fMinSize));
70     }
71     else if (block->available() < size)
72     {
73         fTail = Block::Create(SkMax32(size, fMinSize));
74         block->fNext = fTail;
75         block = fTail;
76     }
77 
78     fSize += size;
79 
80     return block->alloc(size);
81 }
82 
peek32(size_t offset)83 uint32_t* SkWriter32::peek32(size_t offset)
84 {
85     SkASSERT(SkAlign4(offset) == offset);
86     SkASSERT(offset <= fSize);
87 
88     Block* block = fHead;
89     SkASSERT(NULL != block);
90 
91     while (offset >= block->fAllocated)
92     {
93         offset -= block->fAllocated;
94         block = block->fNext;
95         SkASSERT(NULL != block);
96     }
97     return block->peek32(offset);
98 }
99 
flatten(void * dst) const100 void SkWriter32::flatten(void* dst) const
101 {
102     const Block* block = fHead;
103     SkDEBUGCODE(size_t total = 0;)
104 
105     while (block)
106     {
107         size_t allocated = block->fAllocated;
108         memcpy(dst, block->base(), allocated);
109         dst = (char*)dst + allocated;
110         block = block->fNext;
111 
112         SkDEBUGCODE(total += allocated;)
113         SkASSERT(total <= fSize);
114     }
115     SkASSERT(total == fSize);
116 }
117 
writePad(const void * src,size_t size)118 void SkWriter32::writePad(const void* src, size_t size) {
119     size_t alignedSize = SkAlign4(size);
120     char* dst = (char*)this->reserve(alignedSize);
121     memcpy(dst, src, size);
122     dst += size;
123     int n = alignedSize - size;
124     while (--n >= 0) {
125         *dst++ = 0;
126     }
127 }
128 
129 #include "SkStream.h"
130 
readFromStream(SkStream * stream,size_t length)131 size_t SkWriter32::readFromStream(SkStream* stream, size_t length) {
132     char scratch[1024];
133     const size_t MAX = sizeof(scratch);
134     size_t remaining = length;
135 
136     while (remaining != 0) {
137         size_t n = remaining;
138         if (n > MAX) {
139             n = MAX;
140         }
141         size_t bytes = stream->read(scratch, n);
142         this->writePad(scratch, bytes);
143         remaining -= bytes;
144         if (bytes != n) {
145             break;
146         }
147     }
148     return length - remaining;
149 }
150 
writeToStream(SkWStream * stream)151 bool SkWriter32::writeToStream(SkWStream* stream) {
152     const Block* block = fHead;
153     while (block) {
154         if (!stream->write(block->base(), block->fAllocated)) {
155             return false;
156         }
157         block = block->fNext;
158     }
159     return true;
160 }
161 
162