blob: a44ac737c9b7f24bce1d748a97995f811b2012d2 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkStream_DEFINED
11#define SkStream_DEFINED
12
13#include "SkRefCnt.h"
14#include "SkScalar.h"
15
reed@google.com8d0b5772011-06-24 13:07:31 +000016class SkData;
reed@google.com70442a62011-06-23 21:48:04 +000017
reed@google.comf3166342011-04-26 20:06:08 +000018class SK_API SkStream : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000019public:
20 virtual ~SkStream();
21 /** Called to rewind to the beginning of the stream. If this cannot be
22 done, return false.
23 */
24 virtual bool rewind() = 0;
25 /** If this stream represents a file, this method returns the file's name.
26 If it does not, it returns NULL (the default behavior).
27 */
28 virtual const char* getFileName();
29 /** Called to read or skip size number of bytes.
30 If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
31 If buffer is NULL and size == 0, return the total length of the stream.
32 If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
33 @param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
34 @param size The number of bytes to skip or copy
35 @return bytes read on success
36 */
37 virtual size_t read(void* buffer, size_t size) = 0;
38
39 /** Return the total length of the stream.
40 */
41 size_t getLength() { return this->read(NULL, 0); }
42
43 /** Skip the specified number of bytes, returning the actual number
44 of bytes that could be skipped.
45 */
46 size_t skip(size_t bytes);
47
48 /** If the stream is backed by RAM, this method returns the starting
49 address for the data. If not (i.e. it is backed by a file or other
50 structure), this method returns NULL.
51 The default implementation returns NULL.
52 */
53 virtual const void* getMemoryBase();
54
55 int8_t readS8();
56 int16_t readS16();
57 int32_t readS32();
58
59 uint8_t readU8() { return (uint8_t)this->readS8(); }
60 uint16_t readU16() { return (uint16_t)this->readS16(); }
61 uint32_t readU32() { return (uint32_t)this->readS32(); }
62
63 bool readBool() { return this->readU8() != 0; }
64 SkScalar readScalar();
65 size_t readPackedUInt();
reed@android.com8a1c16f2008-12-17 15:59:43 +000066};
67
ctguil@chromium.orgdfc5ffe2011-03-30 20:14:49 +000068class SK_API SkWStream : SkNoncopyable {
reed@android.com8a1c16f2008-12-17 15:59:43 +000069public:
70 virtual ~SkWStream();
71
72 /** Called to write bytes to a SkWStream. Returns true on success
73 @param buffer the address of at least size bytes to be written to the stream
74 @param size The number of bytes in buffer to write to the stream
75 @return true on success
76 */
77 virtual bool write(const void* buffer, size_t size) = 0;
78 virtual void newline();
79 virtual void flush();
80
81 // helpers
82
83 bool write8(U8CPU);
84 bool write16(U16CPU);
85 bool write32(uint32_t);
86
87 bool writeText(const char text[]);
88 bool writeDecAsText(int32_t);
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000089 bool writeBigDecAsText(int64_t, int minDigits = 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +000090 bool writeHexAsText(uint32_t, int minDigits = 0);
91 bool writeScalarAsText(SkScalar);
92
93 bool writeBool(bool v) { return this->write8(v); }
94 bool writeScalar(SkScalar);
95 bool writePackedUInt(size_t);
96
97 bool writeStream(SkStream* input, size_t length);
reed@google.com8a85d0c2011-06-24 19:12:12 +000098
99 bool writeData(const SkData*);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100};
101
102////////////////////////////////////////////////////////////////////////////////////////
103
104#include "SkString.h"
105
106struct SkFILE;
107
108/** A stream that reads from a FILE*, which is opened in the constructor and
109 closed in the destructor
110 */
111class SkFILEStream : public SkStream {
112public:
113 /** Initialize the stream by calling fopen on the specified path. Will be
114 closed in the destructor.
115 */
116 explicit SkFILEStream(const char path[] = NULL);
117 virtual ~SkFILEStream();
118
119 /** Returns true if the current path could be opened.
120 */
121 bool isValid() const { return fFILE != NULL; }
122 /** Close the current file, and open a new file with the specified
123 path. If path is NULL, just close the current file.
124 */
125 void setPath(const char path[]);
126
127 virtual bool rewind();
128 virtual size_t read(void* buffer, size_t size);
129 virtual const char* getFileName();
130
131private:
132 SkFILE* fFILE;
133 SkString fName;
134};
135
136/** A stream that reads from a file descriptor
137 */
138class SkFDStream : public SkStream {
139public:
140 /** Initialize the stream with a dup() of the specified file descriptor.
141 If closeWhenDone is true, then the descriptor will be closed in the
142 destructor.
143 */
144 SkFDStream(int fileDesc, bool closeWhenDone);
145 virtual ~SkFDStream();
146
147 /** Returns true if the current path could be opened.
148 */
149 bool isValid() const { return fFD >= 0; }
150
151 virtual bool rewind();
152 virtual size_t read(void* buffer, size_t size);
153 virtual const char* getFileName() { return NULL; }
154
155private:
156 int fFD;
157 bool fCloseWhenDone;
158};
159
160class SkMemoryStream : public SkStream {
161public:
162 SkMemoryStream();
163 /** We allocate (and free) the memory. Write to it via getMemoryBase()
164 */
165 SkMemoryStream(size_t length);
166 /** if copyData is true, the stream makes a private copy of the data
167 */
168 SkMemoryStream(const void* data, size_t length, bool copyData = false);
169 virtual ~SkMemoryStream();
170
171 /** Resets the stream to the specified data and length,
172 just like the constructor.
173 if copyData is true, the stream makes a private copy of the data
174 */
175 virtual void setMemory(const void* data, size_t length,
176 bool copyData = false);
djsollen@google.com57f49692011-02-23 20:46:31 +0000177 /** Replace any memory buffer with the specified buffer. The caller
178 must have allocated data with sk_malloc or sk_realloc, since it
179 will be freed with sk_free.
180 */
181 void setMemoryOwned(const void* data, size_t length);
reed@google.com8a85d0c2011-06-24 19:12:12 +0000182
183 /**
184 * Return the stream's data in a SkData. The caller must call unref() when
185 * it is finished using the data.
186 */
187 SkData* copyToData() const;
188
189 /**
190 * Use the specified data as the memory for this stream. The stream will
191 * call ref() on the data (assuming it is not null). The function returns
192 * the data parameter as a convenience.
193 */
194 SkData* setData(SkData*);
195
reed@android.com8a1c16f2008-12-17 15:59:43 +0000196 void skipToAlign4();
197 virtual bool rewind();
198 virtual size_t read(void* buffer, size_t size);
199 virtual const void* getMemoryBase();
200 const void* getAtPos();
201 size_t seek(size_t offset);
202 size_t peek() const { return fOffset; }
203
204private:
reed@google.com8a85d0c2011-06-24 19:12:12 +0000205 SkData* fData;
206 size_t fOffset;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000207};
208
209/** \class SkBufferStream
210 This is a wrapper class that adds buffering to another stream.
211 The caller can provide the buffer, or ask SkBufferStream to allocated/free
212 it automatically.
213*/
214class SkBufferStream : public SkStream {
215public:
216 /** Provide the stream to be buffered (proxy), and the size of the buffer that
217 should be used. This will be allocated and freed automatically. If bufferSize is 0,
218 a default buffer size will be used.
219 The proxy stream is referenced, and will be unreferenced in when the
220 bufferstream is destroyed.
221 */
222 SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
223 /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
224 This buffer is owned by the caller, and must be at least bufferSize bytes big.
225 Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
226 If buffer is not NULL, it is an error for bufferSize to be 0.
227 The proxy stream is referenced, and will be unreferenced in when the
228 bufferstream is destroyed.
229 */
230 SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
231 virtual ~SkBufferStream();
232
233 virtual bool rewind();
234 virtual const char* getFileName();
235 virtual size_t read(void* buffer, size_t size);
236 virtual const void* getMemoryBase();
237
238private:
239 enum {
240 kDefaultBufferSize = 128
241 };
242 // illegal
243 SkBufferStream(const SkBufferStream&);
244 SkBufferStream& operator=(const SkBufferStream&);
245
246 SkStream* fProxy;
247 char* fBuffer;
248 size_t fOrigBufferSize, fBufferSize, fBufferOffset;
249 bool fWeOwnTheBuffer;
250
251 void init(void*, size_t);
252};
253
254/////////////////////////////////////////////////////////////////////////////////////////////
255
256class SkFILEWStream : public SkWStream {
257public:
258 SkFILEWStream(const char path[]);
259 virtual ~SkFILEWStream();
260
261 /** Returns true if the current path could be opened.
262 */
263 bool isValid() const { return fFILE != NULL; }
264
265 virtual bool write(const void* buffer, size_t size);
266 virtual void flush();
267private:
268 SkFILE* fFILE;
269};
270
271class SkMemoryWStream : public SkWStream {
272public:
273 SkMemoryWStream(void* buffer, size_t size);
274 virtual bool write(const void* buffer, size_t size);
275
276private:
277 char* fBuffer;
278 size_t fMaxLength;
279 size_t fBytesWritten;
280};
281
ctguil@chromium.orgdfc5ffe2011-03-30 20:14:49 +0000282class SK_API SkDynamicMemoryWStream : public SkWStream {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000283public:
284 SkDynamicMemoryWStream();
285 virtual ~SkDynamicMemoryWStream();
reed@google.com8a85d0c2011-06-24 19:12:12 +0000286
reed@android.com8a1c16f2008-12-17 15:59:43 +0000287 virtual bool write(const void* buffer, size_t size);
288 // random access write
289 // modifies stream and returns true if offset + size is less than or equal to getOffset()
290 bool write(const void* buffer, size_t offset, size_t size);
291 bool read(void* buffer, size_t offset, size_t size);
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000292 size_t getOffset() const { return fBytesWritten; }
reed@google.com8a85d0c2011-06-24 19:12:12 +0000293 size_t bytesWritten() const { return fBytesWritten; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000294
295 // copy what has been written to the stream into dst
reed@google.com8a85d0c2011-06-24 19:12:12 +0000296 void copyTo(void* dst) const;
reed@google.com70442a62011-06-23 21:48:04 +0000297
298 /**
reed@google.com8a85d0c2011-06-24 19:12:12 +0000299 * Return a copy of the data written so far. This call is responsible for
300 * calling unref() when they are finished with the data.
reed@google.com70442a62011-06-23 21:48:04 +0000301 */
reed@google.com8d0b5772011-06-24 13:07:31 +0000302 SkData* copyToData() const;
reed@google.com70442a62011-06-23 21:48:04 +0000303
reed@android.com8a1c16f2008-12-17 15:59:43 +0000304 // reset the stream to its original state
305 void reset();
306 void padToAlign4();
307private:
308 struct Block;
309 Block* fHead;
310 Block* fTail;
311 size_t fBytesWritten;
reed@google.com8a85d0c2011-06-24 19:12:12 +0000312 mutable SkData* fCopy; // is invalidated if we write after it is created
313
314 void invalidateCopy();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000315};
316
317
318class SkDebugWStream : public SkWStream {
319public:
320 // overrides
321 virtual bool write(const void* buffer, size_t size);
322 virtual void newline();
323};
324
325// for now
326typedef SkFILEStream SkURLStream;
327
328#endif