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*/
22class SkRBuffer : SkNoncopyable {
23public:
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    */
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    */
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
42    /** Return the number of bytes that have been read from the beginning
43        of the data pointer.
44    */
45    size_t  pos() const { return fPos - fData; }
46    /** Return the total size of the data pointer. Only defined if the length was
47        specified in the constructor or in a call to reset().
48    */
49    size_t  size() const { return fStop - fData; }
50    /** Return true if the buffer has read to the end of the data pointer.
51        Only defined if the length was specified in the constructor or in a call
52        to reset(). Always returns true if the length was not specified.
53    */
54    bool    eof() const { return fPos >= fStop; }
55
56    /** Read the specified number of bytes from the data pointer. If buffer is not
57        null, copy those bytes into buffer.
58    */
59    void read(void* buffer, size_t size) {
60        if (size) {
61            this->readNoSizeCheck(buffer, size);
62        }
63    }
64
65    const void* skip(size_t size); // return start of skipped data
66    size_t  skipToAlign4();
67
68    void*       readPtr() { void* ptr; read(&ptr, sizeof(ptr)); return ptr; }
69    SkScalar    readScalar() { SkScalar x; read(&x, 4); return x; }
70    uint32_t    readU32() { uint32_t x; read(&x, 4); return x; }
71    int32_t     readS32() { int32_t x; read(&x, 4); return x; }
72    uint16_t    readU16() { uint16_t x; read(&x, 2); return x; }
73    int16_t     readS16() { int16_t x; read(&x, 2); return x; }
74    uint8_t     readU8() { uint8_t x; read(&x, 1); return x; }
75    bool        readBool() { return this->readU8() != 0; }
76
77protected:
78    void    readNoSizeCheck(void* buffer, size_t size);
79
80    const char* fData;
81    const char* fPos;
82    const char* fStop;
83};
84
85/** \class SkWBuffer
86
87    Light weight class for writing data to a memory block.
88    The WBuffer is given the buffer to write into, with either a specified size
89    or no size, in which case no range checking is performed. An empty WBuffer
90    is legal, in which case no data is ever written, but the relative pos()
91    is updated.
92*/
93class SkWBuffer : SkNoncopyable {
94public:
95    SkWBuffer() : fData(0), fPos(0), fStop(0) {}
96    SkWBuffer(void* data) { reset(data); }
97    SkWBuffer(void* data, size_t size) { reset(data, size); }
98
99    void reset(void* data) {
100        fData = (char*)data;
101        fPos = (char*)data;
102        fStop = 0;  // no bounds checking
103    }
104
105    void reset(void* data, size_t size) {
106        SkASSERT(data != 0 || size == 0);
107        fData = (char*)data;
108        fPos = (char*)data;
109        fStop = (char*)data + size;
110    }
111
112    size_t  pos() const { return fPos - fData; }
113    void*   skip(size_t size); // return start of skipped data
114
115    void write(const void* buffer, size_t size) {
116        if (size) {
117            this->writeNoSizeCheck(buffer, size);
118        }
119    }
120
121    size_t  padToAlign4();
122
123    void    writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
124    void    writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
125    void    write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
126    void    write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
127    void    write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
128    void    writeBool(bool x) { this->write8(x); }
129
130protected:
131    void    writeNoSizeCheck(const void* buffer, size_t size);
132
133    char* fData;
134    char* fPos;
135    char* fStop;
136};
137
138#endif
139
140