SkStream.h revision 57f4969724a1dd88c8d9ae35a863e6cf621181d5
1/*
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
73class SkWStream : SkNoncopyable {
74public:
75    virtual ~SkWStream();
76
77    /** Called to write bytes to a SkWStream. Returns true on success
78        @param buffer the address of at least size bytes to be written to the stream
79        @param size The number of bytes in buffer to write to the stream
80        @return true on success
81    */
82    virtual bool write(const void* buffer, size_t size) = 0;
83    virtual void newline();
84    virtual void flush();
85
86    // helpers
87
88    bool    write8(U8CPU);
89    bool    write16(U16CPU);
90    bool    write32(uint32_t);
91
92    bool    writeText(const char text[]);
93    bool    writeDecAsText(int32_t);
94    bool    writeBigDecAsText(int64_t, int minDigits = 0);
95    bool    writeHexAsText(uint32_t, int minDigits = 0);
96    bool    writeScalarAsText(SkScalar);
97
98    bool    writeBool(bool v) { return this->write8(v); }
99    bool    writeScalar(SkScalar);
100    bool    writePackedUInt(size_t);
101
102    bool writeStream(SkStream* input, size_t length);
103};
104
105////////////////////////////////////////////////////////////////////////////////////////
106
107#include "SkString.h"
108
109struct SkFILE;
110
111/** A stream that reads from a FILE*, which is opened in the constructor and
112    closed in the destructor
113 */
114class SkFILEStream : public SkStream {
115public:
116    /** Initialize the stream by calling fopen on the specified path. Will be
117        closed in the destructor.
118     */
119    explicit SkFILEStream(const char path[] = NULL);
120    virtual ~SkFILEStream();
121
122    /** Returns true if the current path could be opened.
123    */
124    bool isValid() const { return fFILE != NULL; }
125    /** Close the current file, and open a new file with the specified
126        path. If path is NULL, just close the current file.
127    */
128    void setPath(const char path[]);
129
130    virtual bool rewind();
131    virtual size_t read(void* buffer, size_t size);
132    virtual const char* getFileName();
133
134private:
135    SkFILE*     fFILE;
136    SkString    fName;
137};
138
139/** A stream that reads from a file descriptor
140 */
141class SkFDStream : public SkStream {
142public:
143    /** Initialize the stream with a dup() of the specified file descriptor.
144        If closeWhenDone is true, then the descriptor will be closed in the
145        destructor.
146     */
147    SkFDStream(int fileDesc, bool closeWhenDone);
148    virtual ~SkFDStream();
149
150    /** Returns true if the current path could be opened.
151     */
152    bool isValid() const { return fFD >= 0; }
153
154    virtual bool rewind();
155    virtual size_t read(void* buffer, size_t size);
156    virtual const char* getFileName() { return NULL; }
157
158private:
159    int     fFD;
160    bool    fCloseWhenDone;
161};
162
163class SkMemoryStream : public SkStream {
164public:
165    SkMemoryStream();
166    /** We allocate (and free) the memory. Write to it via getMemoryBase()
167    */
168    SkMemoryStream(size_t length);
169    /** if copyData is true, the stream makes a private copy of the data
170    */
171    SkMemoryStream(const void* data, size_t length, bool copyData = false);
172    virtual ~SkMemoryStream();
173
174    /** Resets the stream to the specified data and length,
175        just like the constructor.
176        if copyData is true, the stream makes a private copy of the data
177    */
178    virtual void setMemory(const void* data, size_t length,
179                           bool copyData = false);
180    /** Replace any memory buffer with the specified buffer. The caller
181        must have allocated data with sk_malloc or sk_realloc, since it
182        will be freed with sk_free.
183    */
184    void setMemoryOwned(const void* data, size_t length);
185    void skipToAlign4();
186    virtual bool rewind();
187    virtual size_t read(void* buffer, size_t size);
188    virtual const void* getMemoryBase();
189    const void* getAtPos();
190    size_t seek(size_t offset);
191    size_t peek() const { return fOffset; }
192
193private:
194    const void* fSrc;
195    size_t fSize, fOffset;
196    SkBool8 fWeOwnTheData;
197};
198
199/** \class SkBufferStream
200    This is a wrapper class that adds buffering to another stream.
201    The caller can provide the buffer, or ask SkBufferStream to allocated/free
202    it automatically.
203*/
204class SkBufferStream : public SkStream {
205public:
206    /** Provide the stream to be buffered (proxy), and the size of the buffer that
207        should be used. This will be allocated and freed automatically. If bufferSize is 0,
208        a default buffer size will be used.
209        The proxy stream is referenced, and will be unreferenced in when the
210        bufferstream is destroyed.
211    */
212    SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
213    /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
214        This buffer is owned by the caller, and must be at least bufferSize bytes big.
215        Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
216        If buffer is not NULL, it is an error for bufferSize to be 0.
217     The proxy stream is referenced, and will be unreferenced in when the
218     bufferstream is destroyed.
219    */
220    SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
221    virtual ~SkBufferStream();
222
223    virtual bool        rewind();
224    virtual const char* getFileName();
225    virtual size_t      read(void* buffer, size_t size);
226    virtual const void* getMemoryBase();
227
228private:
229    enum {
230        kDefaultBufferSize  = 128
231    };
232    // illegal
233    SkBufferStream(const SkBufferStream&);
234    SkBufferStream& operator=(const SkBufferStream&);
235
236    SkStream*   fProxy;
237    char*       fBuffer;
238    size_t      fOrigBufferSize, fBufferSize, fBufferOffset;
239    bool        fWeOwnTheBuffer;
240
241    void    init(void*, size_t);
242};
243
244/////////////////////////////////////////////////////////////////////////////////////////////
245
246class SkFILEWStream : public SkWStream {
247public:
248            SkFILEWStream(const char path[]);
249    virtual ~SkFILEWStream();
250
251    /** Returns true if the current path could be opened.
252    */
253    bool isValid() const { return fFILE != NULL; }
254
255    virtual bool write(const void* buffer, size_t size);
256    virtual void flush();
257private:
258    SkFILE* fFILE;
259};
260
261class SkMemoryWStream : public SkWStream {
262public:
263    SkMemoryWStream(void* buffer, size_t size);
264    virtual bool write(const void* buffer, size_t size);
265
266private:
267    char*   fBuffer;
268    size_t  fMaxLength;
269    size_t  fBytesWritten;
270};
271
272class SkDynamicMemoryWStream : public SkWStream {
273public:
274    SkDynamicMemoryWStream();
275    virtual ~SkDynamicMemoryWStream();
276    virtual bool write(const void* buffer, size_t size);
277    // random access write
278    // modifies stream and returns true if offset + size is less than or equal to getOffset()
279    bool write(const void* buffer, size_t offset, size_t size);
280    bool read(void* buffer, size_t offset, size_t size);
281    size_t getOffset() const { return fBytesWritten; }
282
283    // copy what has been written to the stream into dst
284    void    copyTo(void* dst) const;
285    /*  return a cache of the flattened data returned by copyTo().
286        This copy is only valid until the next call to write().
287        The memory is managed by the stream class.
288    */
289    const char* getStream() const;
290
291    // same as getStream, but additionally detach the flattened datat
292    const char* detach();
293
294    // reset the stream to its original state
295    void reset();
296    void padToAlign4();
297private:
298    struct Block;
299    Block*  fHead;
300    Block*  fTail;
301    size_t  fBytesWritten;
302    mutable char*   fCopyToCache;
303};
304
305
306class SkDebugWStream : public SkWStream {
307public:
308    // overrides
309    virtual bool write(const void* buffer, size_t size);
310    virtual void newline();
311};
312
313// for now
314typedef SkFILEStream SkURLStream;
315
316#endif
317