1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #ifndef SkStream_DEFINED
11 : #define SkStream_DEFINED
12 :
13 : #include "SkRefCnt.h"
14 : #include "SkScalar.h"
15 :
16 : class SkData;
17 :
18 0 : class SK_API SkStream : public SkRefCnt {
19 : public:
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 0 : 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 0 : uint8_t readU8() { return (uint8_t)this->readS8(); }
60 0 : uint16_t readU16() { return (uint16_t)this->readS16(); }
61 0 : uint32_t readU32() { return (uint32_t)this->readS32(); }
62 :
63 0 : bool readBool() { return this->readU8() != 0; }
64 : SkScalar readScalar();
65 : size_t readPackedUInt();
66 : };
67 :
68 0 : class SK_API SkWStream : SkNoncopyable {
69 : public:
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);
89 : bool writeBigDecAsText(int64_t, int minDigits = 0);
90 : bool writeHexAsText(uint32_t, int minDigits = 0);
91 : bool writeScalarAsText(SkScalar);
92 :
93 0 : 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);
98 :
99 : bool writeData(const SkData*);
100 : };
101 :
102 : ////////////////////////////////////////////////////////////////////////////////////////
103 :
104 : #include "SkString.h"
105 :
106 : struct SkFILE;
107 :
108 : /** A stream that reads from a FILE*, which is opened in the constructor and
109 : closed in the destructor
110 : */
111 : class SkFILEStream : public SkStream {
112 : public:
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 0 : 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() SK_OVERRIDE;
128 : virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
129 : virtual const char* getFileName() SK_OVERRIDE;
130 :
131 : private:
132 : SkFILE* fFILE;
133 : SkString fName;
134 : };
135 :
136 : /** A stream that reads from a file descriptor
137 : */
138 : class SkFDStream : public SkStream {
139 : public:
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() SK_OVERRIDE;
152 : virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
153 : virtual const char* getFileName() SK_OVERRIDE { return NULL; }
154 :
155 : private:
156 : int fFD;
157 : bool fCloseWhenDone;
158 : };
159 :
160 : class SkMemoryStream : public SkStream {
161 : public:
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);
177 : /** 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);
182 :
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 :
196 : void skipToAlign4();
197 : virtual bool rewind() SK_OVERRIDE;
198 : virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
199 : virtual const void* getMemoryBase() SK_OVERRIDE;
200 : const void* getAtPos();
201 : size_t seek(size_t offset);
202 : size_t peek() const { return fOffset; }
203 :
204 : private:
205 : SkData* fData;
206 : size_t fOffset;
207 : };
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 : */
214 : class SkBufferStream : public SkStream {
215 : public:
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() SK_OVERRIDE;
234 : virtual const char* getFileName() SK_OVERRIDE;
235 : virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
236 : virtual const void* getMemoryBase() SK_OVERRIDE;
237 :
238 : private:
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 :
256 : class SkFILEWStream : public SkWStream {
257 : public:
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) SK_OVERRIDE;
266 : virtual void flush() SK_OVERRIDE;
267 : private:
268 : SkFILE* fFILE;
269 : };
270 :
271 0 : class SkMemoryWStream : public SkWStream {
272 : public:
273 : SkMemoryWStream(void* buffer, size_t size);
274 : virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
275 :
276 : private:
277 : char* fBuffer;
278 : size_t fMaxLength;
279 : size_t fBytesWritten;
280 : };
281 :
282 : class SK_API SkDynamicMemoryWStream : public SkWStream {
283 : public:
284 : SkDynamicMemoryWStream();
285 : virtual ~SkDynamicMemoryWStream();
286 :
287 : virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
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);
292 : size_t getOffset() const { return fBytesWritten; }
293 : size_t bytesWritten() const { return fBytesWritten; }
294 :
295 : // copy what has been written to the stream into dst
296 : void copyTo(void* dst) const;
297 :
298 : /**
299 : * Return a copy of the data written so far. This call is responsible for
300 : * calling unref() when they are finished with the data.
301 : */
302 : SkData* copyToData() const;
303 :
304 : // reset the stream to its original state
305 : void reset();
306 : void padToAlign4();
307 : private:
308 : struct Block;
309 : Block* fHead;
310 : Block* fTail;
311 : size_t fBytesWritten;
312 : mutable SkData* fCopy; // is invalidated if we write after it is created
313 :
314 : void invalidateCopy();
315 : };
316 :
317 :
318 0 : class SkDebugWStream : public SkWStream {
319 : public:
320 : // overrides
321 : virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
322 : virtual void newline() SK_OVERRIDE;
323 : };
324 :
325 : // for now
326 : typedef SkFILEStream SkURLStream;
327 :
328 : #endif
|