blob: 9b26787f31b202227f79f81ee35df95fe086e652 [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
reed@google.com8d0b5772011-06-24 13:07:31 +000023class SkData;
reed@google.com70442a62011-06-23 21:48:04 +000024
reed@google.comf3166342011-04-26 20:06:08 +000025class SK_API SkStream : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000026public:
27 virtual ~SkStream();
28 /** Called to rewind to the beginning of the stream. If this cannot be
29 done, return false.
30 */
31 virtual bool rewind() = 0;
32 /** If this stream represents a file, this method returns the file's name.
33 If it does not, it returns NULL (the default behavior).
34 */
35 virtual const char* getFileName();
36 /** Called to read or skip size number of bytes.
37 If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
38 If buffer is NULL and size == 0, return the total length of the stream.
39 If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
40 @param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
41 @param size The number of bytes to skip or copy
42 @return bytes read on success
43 */
44 virtual size_t read(void* buffer, size_t size) = 0;
45
46 /** Return the total length of the stream.
47 */
48 size_t getLength() { return this->read(NULL, 0); }
49
50 /** Skip the specified number of bytes, returning the actual number
51 of bytes that could be skipped.
52 */
53 size_t skip(size_t bytes);
54
55 /** If the stream is backed by RAM, this method returns the starting
56 address for the data. If not (i.e. it is backed by a file or other
57 structure), this method returns NULL.
58 The default implementation returns NULL.
59 */
60 virtual const void* getMemoryBase();
61
62 int8_t readS8();
63 int16_t readS16();
64 int32_t readS32();
65
66 uint8_t readU8() { return (uint8_t)this->readS8(); }
67 uint16_t readU16() { return (uint16_t)this->readS16(); }
68 uint32_t readU32() { return (uint32_t)this->readS32(); }
69
70 bool readBool() { return this->readU8() != 0; }
71 SkScalar readScalar();
72 size_t readPackedUInt();
reed@android.com8a1c16f2008-12-17 15:59:43 +000073};
74
ctguil@chromium.orgdfc5ffe2011-03-30 20:14:49 +000075class SK_API SkWStream : SkNoncopyable {
reed@android.com8a1c16f2008-12-17 15:59:43 +000076public:
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);
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000096 bool writeBigDecAsText(int64_t, int minDigits = 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +000097 bool writeHexAsText(uint32_t, int minDigits = 0);
98 bool writeScalarAsText(SkScalar);
99
100 bool writeBool(bool v) { return this->write8(v); }
101 bool writeScalar(SkScalar);
102 bool writePackedUInt(size_t);
103
104 bool writeStream(SkStream* input, size_t length);
reed@google.com8a85d0c2011-06-24 19:12:12 +0000105
106 bool writeData(const SkData*);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000107};
108
109////////////////////////////////////////////////////////////////////////////////////////
110
111#include "SkString.h"
112
113struct SkFILE;
114
115/** A stream that reads from a FILE*, which is opened in the constructor and
116 closed in the destructor
117 */
118class SkFILEStream : public SkStream {
119public:
120 /** Initialize the stream by calling fopen on the specified path. Will be
121 closed in the destructor.
122 */
123 explicit SkFILEStream(const char path[] = NULL);
124 virtual ~SkFILEStream();
125
126 /** Returns true if the current path could be opened.
127 */
128 bool isValid() const { return fFILE != NULL; }
129 /** Close the current file, and open a new file with the specified
130 path. If path is NULL, just close the current file.
131 */
132 void setPath(const char path[]);
133
134 virtual bool rewind();
135 virtual size_t read(void* buffer, size_t size);
136 virtual const char* getFileName();
137
138private:
139 SkFILE* fFILE;
140 SkString fName;
141};
142
143/** A stream that reads from a file descriptor
144 */
145class SkFDStream : public SkStream {
146public:
147 /** Initialize the stream with a dup() of the specified file descriptor.
148 If closeWhenDone is true, then the descriptor will be closed in the
149 destructor.
150 */
151 SkFDStream(int fileDesc, bool closeWhenDone);
152 virtual ~SkFDStream();
153
154 /** Returns true if the current path could be opened.
155 */
156 bool isValid() const { return fFD >= 0; }
157
158 virtual bool rewind();
159 virtual size_t read(void* buffer, size_t size);
160 virtual const char* getFileName() { return NULL; }
161
162private:
163 int fFD;
164 bool fCloseWhenDone;
165};
166
167class SkMemoryStream : public SkStream {
168public:
169 SkMemoryStream();
170 /** We allocate (and free) the memory. Write to it via getMemoryBase()
171 */
172 SkMemoryStream(size_t length);
173 /** if copyData is true, the stream makes a private copy of the data
174 */
175 SkMemoryStream(const void* data, size_t length, bool copyData = false);
176 virtual ~SkMemoryStream();
177
178 /** Resets the stream to the specified data and length,
179 just like the constructor.
180 if copyData is true, the stream makes a private copy of the data
181 */
182 virtual void setMemory(const void* data, size_t length,
183 bool copyData = false);
djsollen@google.com57f49692011-02-23 20:46:31 +0000184 /** Replace any memory buffer with the specified buffer. The caller
185 must have allocated data with sk_malloc or sk_realloc, since it
186 will be freed with sk_free.
187 */
188 void setMemoryOwned(const void* data, size_t length);
reed@google.com8a85d0c2011-06-24 19:12:12 +0000189
190 /**
191 * Return the stream's data in a SkData. The caller must call unref() when
192 * it is finished using the data.
193 */
194 SkData* copyToData() const;
195
196 /**
197 * Use the specified data as the memory for this stream. The stream will
198 * call ref() on the data (assuming it is not null). The function returns
199 * the data parameter as a convenience.
200 */
201 SkData* setData(SkData*);
202
reed@android.com8a1c16f2008-12-17 15:59:43 +0000203 void skipToAlign4();
204 virtual bool rewind();
205 virtual size_t read(void* buffer, size_t size);
206 virtual const void* getMemoryBase();
207 const void* getAtPos();
208 size_t seek(size_t offset);
209 size_t peek() const { return fOffset; }
210
211private:
reed@google.com8a85d0c2011-06-24 19:12:12 +0000212 SkData* fData;
213 size_t fOffset;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000214};
215
216/** \class SkBufferStream
217 This is a wrapper class that adds buffering to another stream.
218 The caller can provide the buffer, or ask SkBufferStream to allocated/free
219 it automatically.
220*/
221class SkBufferStream : public SkStream {
222public:
223 /** Provide the stream to be buffered (proxy), and the size of the buffer that
224 should be used. This will be allocated and freed automatically. If bufferSize is 0,
225 a default buffer size will be used.
226 The proxy stream is referenced, and will be unreferenced in when the
227 bufferstream is destroyed.
228 */
229 SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
230 /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
231 This buffer is owned by the caller, and must be at least bufferSize bytes big.
232 Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
233 If buffer is not NULL, it is an error for bufferSize to be 0.
234 The proxy stream is referenced, and will be unreferenced in when the
235 bufferstream is destroyed.
236 */
237 SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
238 virtual ~SkBufferStream();
239
240 virtual bool rewind();
241 virtual const char* getFileName();
242 virtual size_t read(void* buffer, size_t size);
243 virtual const void* getMemoryBase();
244
245private:
246 enum {
247 kDefaultBufferSize = 128
248 };
249 // illegal
250 SkBufferStream(const SkBufferStream&);
251 SkBufferStream& operator=(const SkBufferStream&);
252
253 SkStream* fProxy;
254 char* fBuffer;
255 size_t fOrigBufferSize, fBufferSize, fBufferOffset;
256 bool fWeOwnTheBuffer;
257
258 void init(void*, size_t);
259};
260
261/////////////////////////////////////////////////////////////////////////////////////////////
262
263class SkFILEWStream : public SkWStream {
264public:
265 SkFILEWStream(const char path[]);
266 virtual ~SkFILEWStream();
267
268 /** Returns true if the current path could be opened.
269 */
270 bool isValid() const { return fFILE != NULL; }
271
272 virtual bool write(const void* buffer, size_t size);
273 virtual void flush();
274private:
275 SkFILE* fFILE;
276};
277
278class SkMemoryWStream : public SkWStream {
279public:
280 SkMemoryWStream(void* buffer, size_t size);
281 virtual bool write(const void* buffer, size_t size);
282
283private:
284 char* fBuffer;
285 size_t fMaxLength;
286 size_t fBytesWritten;
287};
288
ctguil@chromium.orgdfc5ffe2011-03-30 20:14:49 +0000289class SK_API SkDynamicMemoryWStream : public SkWStream {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000290public:
291 SkDynamicMemoryWStream();
292 virtual ~SkDynamicMemoryWStream();
reed@google.com8a85d0c2011-06-24 19:12:12 +0000293
reed@android.com8a1c16f2008-12-17 15:59:43 +0000294 virtual bool write(const void* buffer, size_t size);
295 // random access write
296 // modifies stream and returns true if offset + size is less than or equal to getOffset()
297 bool write(const void* buffer, size_t offset, size_t size);
298 bool read(void* buffer, size_t offset, size_t size);
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000299 size_t getOffset() const { return fBytesWritten; }
reed@google.com8a85d0c2011-06-24 19:12:12 +0000300 size_t bytesWritten() const { return fBytesWritten; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000301
302 // copy what has been written to the stream into dst
reed@google.com8a85d0c2011-06-24 19:12:12 +0000303 void copyTo(void* dst) const;
reed@google.com70442a62011-06-23 21:48:04 +0000304
305 /**
reed@google.com8a85d0c2011-06-24 19:12:12 +0000306 * Return a copy of the data written so far. This call is responsible for
307 * calling unref() when they are finished with the data.
reed@google.com70442a62011-06-23 21:48:04 +0000308 */
reed@google.com8d0b5772011-06-24 13:07:31 +0000309 SkData* copyToData() const;
reed@google.com70442a62011-06-23 21:48:04 +0000310
reed@android.com8a1c16f2008-12-17 15:59:43 +0000311 // reset the stream to its original state
312 void reset();
313 void padToAlign4();
314private:
315 struct Block;
316 Block* fHead;
317 Block* fTail;
318 size_t fBytesWritten;
reed@google.com8a85d0c2011-06-24 19:12:12 +0000319 mutable SkData* fCopy; // is invalidated if we write after it is created
320
321 void invalidateCopy();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000322};
323
324
325class SkDebugWStream : public SkWStream {
326public:
327 // overrides
328 virtual bool write(const void* buffer, size_t size);
329 virtual void newline();
330};
331
332// for now
333typedef SkFILEStream SkURLStream;
334
335#endif