1// Copyright 2013 Google Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15// The parts of ots.h & opentype-sanitiser.h that we need, taken from the 16// https://code.google.com/p/ots/ project. 17 18#ifndef WOFF2_BUFFER_H_ 19#define WOFF2_BUFFER_H_ 20 21#if defined(_WIN32) 22#include <stdlib.h> 23typedef signed char int8_t; 24typedef unsigned char uint8_t; 25typedef short int16_t; 26typedef unsigned short uint16_t; 27typedef int int32_t; 28typedef unsigned int uint32_t; 29typedef __int64 int64_t; 30typedef unsigned __int64 uint64_t; 31#define ntohl(x) _byteswap_ulong (x) 32#define ntohs(x) _byteswap_ushort (x) 33#define htonl(x) _byteswap_ulong (x) 34#define htons(x) _byteswap_ushort (x) 35#else 36#include <arpa/inet.h> 37#include <stdint.h> 38#endif 39 40#include <cstdlib> 41#include <cstring> 42#include <limits> 43 44namespace woff2 { 45 46#if defined(_MSC_VER) || !defined(FONT_COMPRESSION_DEBUG) 47#define FONT_COMPRESSION_FAILURE() false 48#else 49#define FONT_COMPRESSION_FAILURE() \ 50 util::compression::font::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__) 51inline bool Failure(const char *f, int l, const char *fn) { 52 std::fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn); 53 std::fflush(stderr); 54 return false; 55} 56#endif 57 58// ----------------------------------------------------------------------------- 59// Buffer helper class 60// 61// This class perform some trival buffer operations while checking for 62// out-of-bounds errors. As a family they return false if anything is amiss, 63// updating the current offset otherwise. 64// ----------------------------------------------------------------------------- 65class Buffer { 66 public: 67 Buffer(const uint8_t *buffer, size_t len) 68 : buffer_(buffer), 69 length_(len), 70 offset_(0) { } 71 72 bool Skip(size_t n_bytes) { 73 return Read(NULL, n_bytes); 74 } 75 76 bool Read(uint8_t *buffer, size_t n_bytes) { 77 if (n_bytes > 1024 * 1024 * 1024) { 78 return FONT_COMPRESSION_FAILURE(); 79 } 80 if ((offset_ + n_bytes > length_) || 81 (offset_ > length_ - n_bytes)) { 82 return FONT_COMPRESSION_FAILURE(); 83 } 84 if (buffer) { 85 std::memcpy(buffer, buffer_ + offset_, n_bytes); 86 } 87 offset_ += n_bytes; 88 return true; 89 } 90 91 inline bool ReadU8(uint8_t *value) { 92 if (offset_ + 1 > length_) { 93 return FONT_COMPRESSION_FAILURE(); 94 } 95 *value = buffer_[offset_]; 96 ++offset_; 97 return true; 98 } 99 100 bool ReadU16(uint16_t *value) { 101 if (offset_ + 2 > length_) { 102 return FONT_COMPRESSION_FAILURE(); 103 } 104 std::memcpy(value, buffer_ + offset_, sizeof(uint16_t)); 105 *value = ntohs(*value); 106 offset_ += 2; 107 return true; 108 } 109 110 bool ReadS16(int16_t *value) { 111 return ReadU16(reinterpret_cast<uint16_t*>(value)); 112 } 113 114 bool ReadU24(uint32_t *value) { 115 if (offset_ + 3 > length_) { 116 return FONT_COMPRESSION_FAILURE(); 117 } 118 *value = static_cast<uint32_t>(buffer_[offset_]) << 16 | 119 static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 | 120 static_cast<uint32_t>(buffer_[offset_ + 2]); 121 offset_ += 3; 122 return true; 123 } 124 125 bool ReadU32(uint32_t *value) { 126 if (offset_ + 4 > length_) { 127 return FONT_COMPRESSION_FAILURE(); 128 } 129 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); 130 *value = ntohl(*value); 131 offset_ += 4; 132 return true; 133 } 134 135 bool ReadS32(int32_t *value) { 136 return ReadU32(reinterpret_cast<uint32_t*>(value)); 137 } 138 139 bool ReadTag(uint32_t *value) { 140 if (offset_ + 4 > length_) { 141 return FONT_COMPRESSION_FAILURE(); 142 } 143 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); 144 offset_ += 4; 145 return true; 146 } 147 148 bool ReadR64(uint64_t *value) { 149 if (offset_ + 8 > length_) { 150 return FONT_COMPRESSION_FAILURE(); 151 } 152 std::memcpy(value, buffer_ + offset_, sizeof(uint64_t)); 153 offset_ += 8; 154 return true; 155 } 156 157 const uint8_t *buffer() const { return buffer_; } 158 size_t offset() const { return offset_; } 159 size_t length() const { return length_; } 160 161 void set_offset(size_t newoffset) { offset_ = newoffset; } 162 163 private: 164 const uint8_t * const buffer_; 165 const size_t length_; 166 size_t offset_; 167}; 168 169} // namespace woff2 170 171#endif // WOFF2_BUFFER_H_ 172