blob: 5111c651a58a4a793ef67436ce3b5fdd0eca248c [file] [log] [blame]
Roderick Sheeter437bbad2013-11-19 14:32:56 -08001// 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
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090018#ifndef WOFF2_BUFFER_H_
19#define WOFF2_BUFFER_H_
Roderick Sheeter437bbad2013-11-19 14:32:56 -080020
Kenichi Ishibashi6cef4962014-06-06 17:39:02 +090021#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
Roderick Sheeter2e5995b2013-12-12 10:43:05 -080036#include <arpa/inet.h>
Kenichi Ishibashi6cef4962014-06-06 17:39:02 +090037#include <stdint.h>
38#endif
39
Roderick Sheeter437bbad2013-11-19 14:32:56 -080040#include <cstdlib>
41#include <cstring>
42#include <limits>
43
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090044namespace woff2 {
Roderick Sheeter437bbad2013-11-19 14:32:56 -080045
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090046#if defined(_MSC_VER) || !defined(FONT_COMPRESSION_DEBUG)
47#define FONT_COMPRESSION_FAILURE() false
Roderick Sheeter437bbad2013-11-19 14:32:56 -080048#else
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090049#define FONT_COMPRESSION_FAILURE() \
50 util::compression::font::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
Roderick Sheeter437bbad2013-11-19 14:32:56 -080051inline 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) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090078 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080079 }
80 if ((offset_ + n_bytes > length_) ||
81 (offset_ > length_ - n_bytes)) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090082 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080083 }
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_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090093 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080094 }
95 *value = buffer_[offset_];
96 ++offset_;
97 return true;
98 }
99
100 bool ReadU16(uint16_t *value) {
101 if (offset_ + 2 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900102 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800103 }
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_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900116 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800117 }
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_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900127 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800128 }
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_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900141 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800142 }
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_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900150 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800151 }
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
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900169} // namespace woff2
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800170
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900171#endif // WOFF2_BUFFER_H_