180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkBuffer_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkBuffer_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkScalar.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** \class SkRBuffer
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Light weight class for reading data from a memory block.
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    The RBuffer is given the buffer to read from, with either a specified size
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    or no size (in which case no range checking is performed). It is iillegal
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    to attempt to read a value from an empty RBuffer (data == null).
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkRBuffer : SkNoncopyable {
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRBuffer() : fData(0), fPos(0), fStop(0) {}
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Initialize RBuffer with a data pointer, but no specified length.
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        This signals the RBuffer to not perform range checks during reading.
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRBuffer(const void* data) {
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData = (const char*)data;
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPos = (const char*)data;
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStop = 0;  // no bounds checking
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Initialize RBuffer with a data point and length.
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRBuffer(const void* data, size_t size) {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(data != 0 || size == 0);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData = (const char*)data;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPos = (const char*)data;
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStop = (const char*)data + size;
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual ~SkRBuffer() { }
43910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the number of bytes that have been read from the beginning
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        of the data pointer.
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t  pos() const { return fPos - fData; }
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the total size of the data pointer. Only defined if the length was
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        specified in the constructor or in a call to reset().
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t  size() const { return fStop - fData; }
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return true if the buffer has read to the end of the data pointer.
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Only defined if the length was specified in the constructor or in a call
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        to reset(). Always returns true if the length was not specified.
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool    eof() const { return fPos >= fStop; }
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Read the specified number of bytes from the data pointer. If buffer is not
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        null, copy those bytes into buffer.
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
61910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual bool read(void* buffer, size_t size) {
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (size) {
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->readNoSizeCheck(buffer, size);
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
65910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        return true;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const void* skip(size_t size); // return start of skipped data
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t  skipToAlign4();
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
71910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readPtr(void** ptr) { return read(ptr, sizeof(void*)); }
72910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readScalar(SkScalar* x) { return read(x, 4); }
73910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readU32(uint32_t* x) { return read(x, 4); }
74910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readS32(int32_t* x) { return read(x, 4); }
75910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readU16(uint16_t* x) { return read(x, 2); }
76910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readS16(int16_t* x) { return read(x, 2); }
77910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readU8(uint8_t* x) { return read(x, 1); }
78910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool readBool(bool* x) {
79910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        uint8_t u8;
80910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        if (this->readU8(&u8)) {
81910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            *x = (u8 != 0);
82910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            return true;
83910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        }
84910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        return false;
85910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    }
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
87910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerprotected:
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    readNoSizeCheck(void* buffer, size_t size);
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* fData;
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* fPos;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* fStop;
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
95910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger/** \class SkRBufferWithSizeCheck
96910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
97910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    Same as SkRBuffer, except that a size check is performed before the read operation and an
98910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    error is set if the read operation is attempting to read past the end of the data.
99910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger*/
100910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerclass SkRBufferWithSizeCheck : public SkRBuffer {
101910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerpublic:
102910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkRBufferWithSizeCheck(const void* data, size_t size) : SkRBuffer(data, size), fError(false) {}
103910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
104910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    /** Read the specified number of bytes from the data pointer. If buffer is not
105910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        null and the number of bytes to read does not overflow this object's data,
106910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        copy those bytes into buffer.
107910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    */
108910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual bool read(void* buffer, size_t size) SK_OVERRIDE;
109910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
110910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    /** Returns whether or not a read operation attempted to read past the end of the data.
111910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    */
112910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool isValid() const { return !fError; }
113910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerprivate:
114910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool fError;
115910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger};
116910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** \class SkWBuffer
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Light weight class for writing data to a memory block.
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    The WBuffer is given the buffer to write into, with either a specified size
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    or no size, in which case no range checking is performed. An empty WBuffer
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    is legal, in which case no data is ever written, but the relative pos()
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    is updated.
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkWBuffer : SkNoncopyable {
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkWBuffer() : fData(0), fPos(0), fStop(0) {}
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkWBuffer(void* data) { reset(data); }
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkWBuffer(void* data, size_t size) { reset(data, size); }
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void reset(void* data) {
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData = (char*)data;
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPos = (char*)data;
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStop = 0;  // no bounds checking
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void reset(void* data, size_t size) {
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(data != 0 || size == 0);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData = (char*)data;
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPos = (char*)data;
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStop = (char*)data + size;
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t  pos() const { return fPos - fData; }
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void*   skip(size_t size); // return start of skipped data
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void write(const void* buffer, size_t size) {
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (size) {
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->writeNoSizeCheck(buffer, size);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t  padToAlign4();
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    writeBool(bool x) { this->write8(x); }
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    writeNoSizeCheck(const void* buffer, size_t size);
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* fData;
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* fPos;
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* fStop;
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
171