blob: 26ef43f624739d591576dd4f0bdd83ae2e7794ca [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkStream_DEFINED
18#define SkStream_DEFINED
19
20#include "SkRefCnt.h"
21#include "SkScalar.h"
22
23class SkStream : public SkRefCnt {
24public:
25 virtual ~SkStream();
26 /** Called to rewind to the beginning of the stream. If this cannot be
27 done, return false.
28 */
29 virtual bool rewind() = 0;
30 /** If this stream represents a file, this method returns the file's name.
31 If it does not, it returns NULL (the default behavior).
32 */
33 virtual const char* getFileName();
34 /** Called to read or skip size number of bytes.
35 If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
36 If buffer is NULL and size == 0, return the total length of the stream.
37 If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
38 @param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
39 @param size The number of bytes to skip or copy
40 @return bytes read on success
41 */
42 virtual size_t read(void* buffer, size_t size) = 0;
43
44 /** Return the total length of the stream.
45 */
46 size_t getLength() { return this->read(NULL, 0); }
47
48 /** Skip the specified number of bytes, returning the actual number
49 of bytes that could be skipped.
50 */
51 size_t skip(size_t bytes);
52
53 /** If the stream is backed by RAM, this method returns the starting
54 address for the data. If not (i.e. it is backed by a file or other
55 structure), this method returns NULL.
56 The default implementation returns NULL.
57 */
58 virtual const void* getMemoryBase();
59
60 int8_t readS8();
61 int16_t readS16();
62 int32_t readS32();
63
64 uint8_t readU8() { return (uint8_t)this->readS8(); }
65 uint16_t readU16() { return (uint16_t)this->readS16(); }
66 uint32_t readU32() { return (uint32_t)this->readS32(); }
67
68 bool readBool() { return this->readU8() != 0; }
69 SkScalar readScalar();
70 size_t readPackedUInt();
71
72 static void UnitTest();
73};
74
75class SkWStream : SkNoncopyable {
76public:
77 virtual ~SkWStream();
78
79 /** Called to write bytes to a SkWStream. Returns true on success
80 @param buffer the address of at least size bytes to be written to the stream
81 @param size The number of bytes in buffer to write to the stream
82 @return true on success
83 */
84 virtual bool write(const void* buffer, size_t size) = 0;
85 virtual void newline();
86 virtual void flush();
87
88 // helpers
89
90 bool write8(U8CPU);
91 bool write16(U16CPU);
92 bool write32(uint32_t);
93
94 bool writeText(const char text[]);
95 bool writeDecAsText(int32_t);
96 bool writeHexAsText(uint32_t, int minDigits = 0);
97 bool writeScalarAsText(SkScalar);
98
99 bool writeBool(bool v) { return this->write8(v); }
100 bool writeScalar(SkScalar);
101 bool writePackedUInt(size_t);
102
103 bool writeStream(SkStream* input, size_t length);
104
105 static void UnitTest();
106};
107
108////////////////////////////////////////////////////////////////////////////////////////
109
110#include "SkString.h"
111
112struct SkFILE;
113
114/** A stream that reads from a FILE*, which is opened in the constructor and
115 closed in the destructor
116 */
117class SkFILEStream : public SkStream {
118public:
119 /** Initialize the stream by calling fopen on the specified path. Will be
120 closed in the destructor.
121 */
122 explicit SkFILEStream(const char path[] = NULL);
123 virtual ~SkFILEStream();
124
125 /** Returns true if the current path could be opened.
126 */
127 bool isValid() const { return fFILE != NULL; }
128 /** Close the current file, and open a new file with the specified
129 path. If path is NULL, just close the current file.
130 */
131 void setPath(const char path[]);
132
133 virtual bool rewind();
134 virtual size_t read(void* buffer, size_t size);
135 virtual const char* getFileName();
136
137private:
138 SkFILE* fFILE;
139 SkString fName;
140};
141
142/** A stream that reads from a file descriptor
143 */
144class SkFDStream : public SkStream {
145public:
146 /** Initialize the stream with a dup() of the specified file descriptor.
147 If closeWhenDone is true, then the descriptor will be closed in the
148 destructor.
149 */
150 SkFDStream(int fileDesc, bool closeWhenDone);
151 virtual ~SkFDStream();
152
153 /** Returns true if the current path could be opened.
154 */
155 bool isValid() const { return fFD >= 0; }
156
157 virtual bool rewind();
158 virtual size_t read(void* buffer, size_t size);
159 virtual const char* getFileName() { return NULL; }
160
161private:
162 int fFD;
163 bool fCloseWhenDone;
164};
165
166class SkMemoryStream : public SkStream {
167public:
168 SkMemoryStream();
169 /** We allocate (and free) the memory. Write to it via getMemoryBase()
170 */
171 SkMemoryStream(size_t length);
172 /** if copyData is true, the stream makes a private copy of the data
173 */
174 SkMemoryStream(const void* data, size_t length, bool copyData = false);
175 virtual ~SkMemoryStream();
176
177 /** Resets the stream to the specified data and length,
178 just like the constructor.
179 if copyData is true, the stream makes a private copy of the data
180 */
181 virtual void setMemory(const void* data, size_t length,
182 bool copyData = false);
183 void skipToAlign4();
184 virtual bool rewind();
185 virtual size_t read(void* buffer, size_t size);
186 virtual const void* getMemoryBase();
187 const void* getAtPos();
188 size_t seek(size_t offset);
189 size_t peek() const { return fOffset; }
190
191private:
192 const void* fSrc;
193 size_t fSize, fOffset;
194 SkBool8 fWeOwnTheData;
195};
196
197/** \class SkBufferStream
198 This is a wrapper class that adds buffering to another stream.
199 The caller can provide the buffer, or ask SkBufferStream to allocated/free
200 it automatically.
201*/
202class SkBufferStream : public SkStream {
203public:
204 /** Provide the stream to be buffered (proxy), and the size of the buffer that
205 should be used. This will be allocated and freed automatically. If bufferSize is 0,
206 a default buffer size will be used.
207 The proxy stream is referenced, and will be unreferenced in when the
208 bufferstream is destroyed.
209 */
210 SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
211 /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
212 This buffer is owned by the caller, and must be at least bufferSize bytes big.
213 Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
214 If buffer is not NULL, it is an error for bufferSize to be 0.
215 The proxy stream is referenced, and will be unreferenced in when the
216 bufferstream is destroyed.
217 */
218 SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
219 virtual ~SkBufferStream();
220
221 virtual bool rewind();
222 virtual const char* getFileName();
223 virtual size_t read(void* buffer, size_t size);
224 virtual const void* getMemoryBase();
225
226private:
227 enum {
228 kDefaultBufferSize = 128
229 };
230 // illegal
231 SkBufferStream(const SkBufferStream&);
232 SkBufferStream& operator=(const SkBufferStream&);
233
234 SkStream* fProxy;
235 char* fBuffer;
236 size_t fOrigBufferSize, fBufferSize, fBufferOffset;
237 bool fWeOwnTheBuffer;
238
239 void init(void*, size_t);
240};
241
242/////////////////////////////////////////////////////////////////////////////////////////////
243
244class SkFILEWStream : public SkWStream {
245public:
246 SkFILEWStream(const char path[]);
247 virtual ~SkFILEWStream();
248
249 /** Returns true if the current path could be opened.
250 */
251 bool isValid() const { return fFILE != NULL; }
252
253 virtual bool write(const void* buffer, size_t size);
254 virtual void flush();
255private:
256 SkFILE* fFILE;
257};
258
259class SkMemoryWStream : public SkWStream {
260public:
261 SkMemoryWStream(void* buffer, size_t size);
262 virtual bool write(const void* buffer, size_t size);
263
264private:
265 char* fBuffer;
266 size_t fMaxLength;
267 size_t fBytesWritten;
268};
269
270class SkDynamicMemoryWStream : public SkWStream {
271public:
272 SkDynamicMemoryWStream();
273 virtual ~SkDynamicMemoryWStream();
274 virtual bool write(const void* buffer, size_t size);
275 // random access write
276 // modifies stream and returns true if offset + size is less than or equal to getOffset()
277 bool write(const void* buffer, size_t offset, size_t size);
278 bool read(void* buffer, size_t offset, size_t size);
279 size_t getOffset() { return fBytesWritten; }
280
281 // copy what has been written to the stream into dst
282 void copyTo(void* dst) const;
283 /* return a cache of the flattened data returned by copyTo().
284 This copy is only valid until the next call to write().
285 The memory is managed by the stream class.
286 */
287 const char* getStream() const;
288
289 // same as getStream, but additionally detach the flattened datat
290 const char* detach();
291
292 // reset the stream to its original state
293 void reset();
294 void padToAlign4();
295private:
296 struct Block;
297 Block* fHead;
298 Block* fTail;
299 size_t fBytesWritten;
300 mutable char* fCopyToCache;
301};
302
303
304class SkDebugWStream : public SkWStream {
305public:
306 // overrides
307 virtual bool write(const void* buffer, size_t size);
308 virtual void newline();
309};
310
311// for now
312typedef SkFILEStream SkURLStream;
313
314#endif
315