• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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     */
getLength()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 
readU8()59     uint8_t  readU8() { return (uint8_t)this->readS8(); }
readU16()60     uint16_t readU16() { return (uint16_t)this->readS16(); }
readU32()61     uint32_t readU32() { return (uint32_t)this->readS32(); }
62 
readBool()63     bool     readBool() { return this->readU8() != 0; }
64     SkScalar readScalar();
65     size_t   readPackedUInt();
66 };
67 
68 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 
writeBool(bool v)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);
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     */
isValid()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() 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      */
isValid()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;
getFileName()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);
peek()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     */
isValid()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 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;
bytesWritten()275     size_t bytesWritten() const { return fBytesWritten; }
276 
277 private:
278     char*   fBuffer;
279     size_t  fMaxLength;
280     size_t  fBytesWritten;
281 };
282 
283 class SK_API SkDynamicMemoryWStream : public SkWStream {
284 public:
285     SkDynamicMemoryWStream();
286     virtual ~SkDynamicMemoryWStream();
287 
288     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
289     // random access write
290     // modifies stream and returns true if offset + size is less than or equal to getOffset()
291     bool write(const void* buffer, size_t offset, size_t size);
292     bool read(void* buffer, size_t offset, size_t size);
getOffset()293     size_t getOffset() const { return fBytesWritten; }
bytesWritten()294     size_t bytesWritten() const { return fBytesWritten; }
295 
296     // copy what has been written to the stream into dst
297     void copyTo(void* dst) const;
298 
299     /**
300      *  Return a copy of the data written so far. This call is responsible for
301      *  calling unref() when they are finished with the data.
302      */
303     SkData* copyToData() const;
304 
305     // reset the stream to its original state
306     void reset();
307     void padToAlign4();
308 private:
309     struct Block;
310     Block*  fHead;
311     Block*  fTail;
312     size_t  fBytesWritten;
313     mutable SkData* fCopy;  // is invalidated if we write after it is created
314 
315     void invalidateCopy();
316 };
317 
318 
319 class SkDebugWStream : public SkWStream {
320 public:
321     // overrides
322     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
323     virtual void newline() SK_OVERRIDE;
324 };
325 
326 // for now
327 typedef SkFILEStream SkURLStream;
328 
329 #endif
330