SkStream.h revision d877fdbb6e64692285c3e6532d88b9458f65b3cd
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    void skipToAlign4();
181    virtual bool rewind();
182    virtual size_t read(void* buffer, size_t size);
183    virtual const void* getMemoryBase();
184    const void* getAtPos();
185    size_t seek(size_t offset);
186    size_t peek() const { return fOffset; }
187
188private:
189    const void* fSrc;
190    size_t fSize, fOffset;
191    SkBool8 fWeOwnTheData;
192};
193
194/** \class SkBufferStream
195    This is a wrapper class that adds buffering to another stream.
196    The caller can provide the buffer, or ask SkBufferStream to allocated/free
197    it automatically.
198*/
199class SkBufferStream : public SkStream {
200public:
201    /** Provide the stream to be buffered (proxy), and the size of the buffer that
202        should be used. This will be allocated and freed automatically. If bufferSize is 0,
203        a default buffer size will be used.
204        The proxy stream is referenced, and will be unreferenced in when the
205        bufferstream is destroyed.
206    */
207    SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
208    /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
209        This buffer is owned by the caller, and must be at least bufferSize bytes big.
210        Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
211        If buffer is not NULL, it is an error for bufferSize to be 0.
212     The proxy stream is referenced, and will be unreferenced in when the
213     bufferstream is destroyed.
214    */
215    SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
216    virtual ~SkBufferStream();
217
218    virtual bool        rewind();
219    virtual const char* getFileName();
220    virtual size_t      read(void* buffer, size_t size);
221    virtual const void* getMemoryBase();
222
223private:
224    enum {
225        kDefaultBufferSize  = 128
226    };
227    // illegal
228    SkBufferStream(const SkBufferStream&);
229    SkBufferStream& operator=(const SkBufferStream&);
230
231    SkStream*   fProxy;
232    char*       fBuffer;
233    size_t      fOrigBufferSize, fBufferSize, fBufferOffset;
234    bool        fWeOwnTheBuffer;
235
236    void    init(void*, size_t);
237};
238
239/////////////////////////////////////////////////////////////////////////////////////////////
240
241class SkFILEWStream : public SkWStream {
242public:
243            SkFILEWStream(const char path[]);
244    virtual ~SkFILEWStream();
245
246    /** Returns true if the current path could be opened.
247    */
248    bool isValid() const { return fFILE != NULL; }
249
250    virtual bool write(const void* buffer, size_t size);
251    virtual void flush();
252private:
253    SkFILE* fFILE;
254};
255
256class SkMemoryWStream : public SkWStream {
257public:
258    SkMemoryWStream(void* buffer, size_t size);
259    virtual bool write(const void* buffer, size_t size);
260
261private:
262    char*   fBuffer;
263    size_t  fMaxLength;
264    size_t  fBytesWritten;
265};
266
267class SkDynamicMemoryWStream : public SkWStream {
268public:
269    SkDynamicMemoryWStream();
270    virtual ~SkDynamicMemoryWStream();
271    virtual bool write(const void* buffer, size_t size);
272    // random access write
273    // modifies stream and returns true if offset + size is less than or equal to getOffset()
274    bool write(const void* buffer, size_t offset, size_t size);
275    bool read(void* buffer, size_t offset, size_t size);
276    size_t getOffset() { return fBytesWritten; }
277
278    // copy what has been written to the stream into dst
279    void    copyTo(void* dst) const;
280    /*  return a cache of the flattened data returned by copyTo().
281        This copy is only valid until the next call to write().
282        The memory is managed by the stream class.
283    */
284    const char* getStream() const;
285
286    // same as getStream, but additionally detach the flattened datat
287    const char* detach();
288
289    // reset the stream to its original state
290    void reset();
291    void padToAlign4();
292private:
293    struct Block;
294    Block*  fHead;
295    Block*  fTail;
296    size_t  fBytesWritten;
297    mutable char*   fCopyToCache;
298};
299
300
301class SkDebugWStream : public SkWStream {
302public:
303    // overrides
304    virtual bool write(const void* buffer, size_t size);
305    virtual void newline();
306};
307
308// for now
309typedef SkFILEStream SkURLStream;
310
311#endif
312