• 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 SkBuffer_DEFINED
11 #define SkBuffer_DEFINED
12 
13 #include "SkScalar.h"
14 
15 /** \class SkRBuffer
16 
17     Light weight class for reading data from a memory block.
18     The RBuffer is given the buffer to read from, with either a specified size
19     or no size (in which case no range checking is performed). It is iillegal
20     to attempt to read a value from an empty RBuffer (data == null).
21 */
22 class SkRBuffer : SkNoncopyable {
23 public:
SkRBuffer()24     SkRBuffer() : fData(0), fPos(0), fStop(0) {}
25     /** Initialize RBuffer with a data pointer, but no specified length.
26         This signals the RBuffer to not perform range checks during reading.
27     */
SkRBuffer(const void * data)28     SkRBuffer(const void* data) {
29         fData = (const char*)data;
30         fPos = (const char*)data;
31         fStop = 0;  // no bounds checking
32     }
33     /** Initialize RBuffer with a data point and length.
34     */
SkRBuffer(const void * data,size_t size)35     SkRBuffer(const void* data, size_t size) {
36         SkASSERT(data != 0 || size == 0);
37         fData = (const char*)data;
38         fPos = (const char*)data;
39         fStop = (const char*)data + size;
40     }
41 
~SkRBuffer()42     virtual ~SkRBuffer() { }
43 
44     /** Return the number of bytes that have been read from the beginning
45         of the data pointer.
46     */
pos()47     size_t  pos() const { return fPos - fData; }
48     /** Return the total size of the data pointer. Only defined if the length was
49         specified in the constructor or in a call to reset().
50     */
size()51     size_t  size() const { return fStop - fData; }
52     /** Return true if the buffer has read to the end of the data pointer.
53         Only defined if the length was specified in the constructor or in a call
54         to reset(). Always returns true if the length was not specified.
55     */
eof()56     bool    eof() const { return fPos >= fStop; }
57 
58     /** Read the specified number of bytes from the data pointer. If buffer is not
59         null, copy those bytes into buffer.
60     */
read(void * buffer,size_t size)61     virtual bool read(void* buffer, size_t size) {
62         if (size) {
63             this->readNoSizeCheck(buffer, size);
64         }
65         return true;
66     }
67 
68     const void* skip(size_t size); // return start of skipped data
69     size_t  skipToAlign4();
70 
readPtr(void ** ptr)71     bool readPtr(void** ptr) { return read(ptr, sizeof(void*)); }
readScalar(SkScalar * x)72     bool readScalar(SkScalar* x) { return read(x, 4); }
readU32(uint32_t * x)73     bool readU32(uint32_t* x) { return read(x, 4); }
readS32(int32_t * x)74     bool readS32(int32_t* x) { return read(x, 4); }
readU16(uint16_t * x)75     bool readU16(uint16_t* x) { return read(x, 2); }
readS16(int16_t * x)76     bool readS16(int16_t* x) { return read(x, 2); }
readU8(uint8_t * x)77     bool readU8(uint8_t* x) { return read(x, 1); }
readBool(bool * x)78     bool readBool(bool* x) {
79         uint8_t u8;
80         if (this->readU8(&u8)) {
81             *x = (u8 != 0);
82             return true;
83         }
84         return false;
85     }
86 
87 protected:
88     void    readNoSizeCheck(void* buffer, size_t size);
89 
90     const char* fData;
91     const char* fPos;
92     const char* fStop;
93 };
94 
95 /** \class SkRBufferWithSizeCheck
96 
97     Same as SkRBuffer, except that a size check is performed before the read operation and an
98     error is set if the read operation is attempting to read past the end of the data.
99 */
100 class SkRBufferWithSizeCheck : public SkRBuffer {
101 public:
SkRBufferWithSizeCheck(const void * data,size_t size)102     SkRBufferWithSizeCheck(const void* data, size_t size) : SkRBuffer(data, size), fError(false) {}
103 
104     /** Read the specified number of bytes from the data pointer. If buffer is not
105         null and the number of bytes to read does not overflow this object's data,
106         copy those bytes into buffer.
107     */
108     virtual bool read(void* buffer, size_t size) SK_OVERRIDE;
109 
110     /** Returns whether or not a read operation attempted to read past the end of the data.
111     */
isValid()112     bool isValid() const { return !fError; }
113 private:
114     bool fError;
115 };
116 
117 /** \class SkWBuffer
118 
119     Light weight class for writing data to a memory block.
120     The WBuffer is given the buffer to write into, with either a specified size
121     or no size, in which case no range checking is performed. An empty WBuffer
122     is legal, in which case no data is ever written, but the relative pos()
123     is updated.
124 */
125 class SkWBuffer : SkNoncopyable {
126 public:
SkWBuffer()127     SkWBuffer() : fData(0), fPos(0), fStop(0) {}
SkWBuffer(void * data)128     SkWBuffer(void* data) { reset(data); }
SkWBuffer(void * data,size_t size)129     SkWBuffer(void* data, size_t size) { reset(data, size); }
130 
reset(void * data)131     void reset(void* data) {
132         fData = (char*)data;
133         fPos = (char*)data;
134         fStop = 0;  // no bounds checking
135     }
136 
reset(void * data,size_t size)137     void reset(void* data, size_t size) {
138         SkASSERT(data != 0 || size == 0);
139         fData = (char*)data;
140         fPos = (char*)data;
141         fStop = (char*)data + size;
142     }
143 
pos()144     size_t  pos() const { return fPos - fData; }
145     void*   skip(size_t size); // return start of skipped data
146 
write(const void * buffer,size_t size)147     void write(const void* buffer, size_t size) {
148         if (size) {
149             this->writeNoSizeCheck(buffer, size);
150         }
151     }
152 
153     size_t  padToAlign4();
154 
writePtr(const void * x)155     void    writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
writeScalar(SkScalar x)156     void    writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
write32(int32_t x)157     void    write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
write16(int16_t x)158     void    write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
write8(int8_t x)159     void    write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
writeBool(bool x)160     void    writeBool(bool x) { this->write8(x); }
161 
162 private:
163     void    writeNoSizeCheck(const void* buffer, size_t size);
164 
165     char* fData;
166     char* fPos;
167     char* fStop;
168 };
169 
170 #endif
171