1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkBuffer_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkBuffer_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h" 142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkTypes.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkRBuffer 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Light weight class for reading data from a memory block. 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The RBuffer is given the buffer to read from, with either a specified size 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or no size (in which case no range checking is performed). It is iillegal 21fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com to attempt to read a value from an empty RBuffer (data == null). 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkRBuffer : SkNoncopyable { 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRBuffer() : fData(0), fPos(0), fStop(0) {} 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Initialize RBuffer with a data pointer, but no specified length. 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This signals the RBuffer to not perform range checks during reading. 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 297894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com SkRBuffer(const void* data) { 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fData = (const char*)data; 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPos = (const char*)data; 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = 0; // no bounds checking 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Initialize RBuffer with a data point and length. 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 367894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com SkRBuffer(const void* data, size_t size) { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(data != 0 || size == 0); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fData = (const char*)data; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPos = (const char*)data; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = (const char*)data + size; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 42fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 43f1077f916427c99bdec655da4c3b9eea70423685mtklein@google.com virtual ~SkRBuffer() { } 44f1077f916427c99bdec655da4c3b9eea70423685mtklein@google.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the number of bytes that have been read from the beginning 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com of the data pointer. 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t pos() const { return fPos - fData; } 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the total size of the data pointer. Only defined if the length was 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com specified in the constructor or in a call to reset(). 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t size() const { return fStop - fData; } 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return true if the buffer has read to the end of the data pointer. 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Only defined if the length was specified in the constructor or in a call 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to reset(). Always returns true if the length was not specified. 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool eof() const { return fPos >= fStop; } 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Read the specified number of bytes from the data pointer. If buffer is not 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com null, copy those bytes into buffer. 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 628f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org virtual bool read(void* buffer, size_t size) { 637894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com if (size) { 647894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com this->readNoSizeCheck(buffer, size); 657894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com } 668f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org return true; 677894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com } 687894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const void* skip(size_t size); // return start of skipped data 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t skipToAlign4(); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readPtr(void** ptr) { return read(ptr, sizeof(void*)); } 738f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readScalar(SkScalar* x) { return read(x, 4); } 748f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readU32(uint32_t* x) { return read(x, 4); } 758f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readS32(int32_t* x) { return read(x, 4); } 768f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readU16(uint16_t* x) { return read(x, 2); } 778f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readS16(int16_t* x) { return read(x, 2); } 788f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readU8(uint8_t* x) { return read(x, 1); } 798f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org bool readBool(bool* x) { 808f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org uint8_t u8; 818f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org if (this->readU8(&u8)) { 828f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org *x = (u8 != 0); 838f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org return true; 848f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org } 858f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org return false; 868f457e3230f1a4ce737f512ffbb5c919b8d02407commit-bot@chromium.org } 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 884faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.orgprotected: 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void readNoSizeCheck(void* buffer, size_t size); 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fData; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fPos; 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fStop; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 964faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org/** \class SkRBufferWithSizeCheck 974faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org 984faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org Same as SkRBuffer, except that a size check is performed before the read operation and an 994faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org error is set if the read operation is attempting to read past the end of the data. 1004faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org*/ 1014faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.orgclass SkRBufferWithSizeCheck : public SkRBuffer { 1024faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.orgpublic: 1034faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org SkRBufferWithSizeCheck(const void* data, size_t size) : SkRBuffer(data, size), fError(false) {} 1044faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org 1054faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org /** Read the specified number of bytes from the data pointer. If buffer is not 1064faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org null and the number of bytes to read does not overflow this object's data, 1074faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org copy those bytes into buffer. 1084faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org */ 10936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool read(void* buffer, size_t size) override; 1104faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org 1114faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org /** Returns whether or not a read operation attempted to read past the end of the data. 1124faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org */ 1134faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org bool isValid() const { return !fError; } 1144faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.orgprivate: 1154faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org bool fError; 1164faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org}; 1174faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkWBuffer 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Light weight class for writing data to a memory block. 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The WBuffer is given the buffer to write into, with either a specified size 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or no size, in which case no range checking is performed. An empty WBuffer 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is legal, in which case no data is ever written, but the relative pos() 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is updated. 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWBuffer : SkNoncopyable { 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkWBuffer() : fData(0), fPos(0), fStop(0) {} 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkWBuffer(void* data) { reset(data); } 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkWBuffer(void* data, size_t size) { reset(data, size); } 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1327894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com void reset(void* data) { 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fData = (char*)data; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPos = (char*)data; 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = 0; // no bounds checking 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1377894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com 1387894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com void reset(void* data, size_t size) { 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(data != 0 || size == 0); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fData = (char*)data; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPos = (char*)data; 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = (char*)data + size; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 144fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t pos() const { return fPos - fData; } 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* skip(size_t size); // return start of skipped data 1477894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com 1487894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com void write(const void* buffer, size_t size) { 1497894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com if (size) { 1507894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com this->writeNoSizeCheck(buffer, size); 1517894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com } 1527894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com } 1537894b92b57b19d0e80e2e0187064fc9e8862d621reed@google.com 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t padToAlign4(); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); } 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); } 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void write32(int32_t x) { this->writeNoSizeCheck(&x, 4); } 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void write16(int16_t x) { this->writeNoSizeCheck(&x, 2); } 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void write8(int8_t x) { this->writeNoSizeCheck(&x, 1); } 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeBool(bool x) { this->write8(x); } 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 163bc4b66f42c169b03559773f2b7181b2b95cbe8cdreed@google.comprivate: 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeNoSizeCheck(const void* buffer, size_t size); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* fData; 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* fPos; 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* fStop; 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 172