OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef OPENTYPE_SANITISER_H_ |
| 6 #define OPENTYPE_SANITISER_H_ |
| 7 |
| 8 #if defined(_WIN32) |
| 9 #include <stdlib.h> |
| 10 typedef signed char int8_t; |
| 11 typedef unsigned char uint8_t; |
| 12 typedef short int16_t; |
| 13 typedef unsigned short uint16_t; |
| 14 typedef int int32_t; |
| 15 typedef unsigned int uint32_t; |
| 16 typedef __int64 int64_t; |
| 17 typedef unsigned __int64 uint64_t; |
| 18 #define ntohl(x) _byteswap_ulong (x) |
| 19 #define ntohs(x) _byteswap_ushort (x) |
| 20 #define htonl(x) _byteswap_ulong (x) |
| 21 #define htons(x) _byteswap_ushort (x) |
| 22 #else |
| 23 #include <arpa/inet.h> |
| 24 #include <stdint.h> |
| 25 #endif |
| 26 |
| 27 #include <algorithm> |
| 28 #include <cassert> |
| 29 #include <cstddef> |
| 30 #include <cstring> |
| 31 |
| 32 namespace ots { |
| 33 |
| 34 // ----------------------------------------------------------------------------- |
| 35 // This is an interface for an abstract stream class which is used for writing |
| 36 // the serialised results out. |
| 37 // ----------------------------------------------------------------------------- |
| 38 class OTSStream { |
| 39 public: |
| 40 OTSStream() { |
| 41 ResetChecksum(); |
| 42 } |
| 43 |
| 44 virtual ~OTSStream() {} |
| 45 |
| 46 // This should be implemented to perform the actual write. |
| 47 virtual bool WriteRaw(const void *data, size_t length) = 0; |
| 48 |
| 49 bool Write(const void *data, size_t length) { |
| 50 if (!length) return false; |
| 51 |
| 52 const size_t orig_length = length; |
| 53 size_t offset = 0; |
| 54 if (chksum_buffer_offset_) { |
| 55 const size_t l = |
| 56 std::min(length, static_cast<size_t>(4) - chksum_buffer_offset_); |
| 57 std::memcpy(chksum_buffer_ + chksum_buffer_offset_, data, l); |
| 58 chksum_buffer_offset_ += l; |
| 59 offset += l; |
| 60 length -= l; |
| 61 } |
| 62 |
| 63 if (chksum_buffer_offset_ == 4) { |
| 64 uint32_t tmp; |
| 65 std::memcpy(&tmp, chksum_buffer_, 4); |
| 66 chksum_ += ntohl(tmp); |
| 67 chksum_buffer_offset_ = 0; |
| 68 } |
| 69 |
| 70 while (length >= 4) { |
| 71 uint32_t tmp; |
| 72 std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset, |
| 73 sizeof(uint32_t)); |
| 74 chksum_ += ntohl(tmp); |
| 75 length -= 4; |
| 76 offset += 4; |
| 77 } |
| 78 |
| 79 if (length) { |
| 80 if (chksum_buffer_offset_ != 0) return false; // not reached |
| 81 if (length > 4) return false; // not reached |
| 82 std::memcpy(chksum_buffer_, |
| 83 reinterpret_cast<const uint8_t*>(data) + offset, length); |
| 84 chksum_buffer_offset_ = length; |
| 85 } |
| 86 |
| 87 return WriteRaw(data, orig_length); |
| 88 } |
| 89 |
| 90 virtual bool Seek(off_t position) = 0; |
| 91 virtual off_t Tell() const = 0; |
| 92 |
| 93 virtual bool Pad(size_t bytes) { |
| 94 static const uint32_t kZero = 0; |
| 95 while (bytes >= 4) { |
| 96 if (!WriteTag(kZero)) return false; |
| 97 bytes -= 4; |
| 98 } |
| 99 while (bytes) { |
| 100 static const uint8_t kZerob = 0; |
| 101 if (!Write(&kZerob, 1)) return false; |
| 102 bytes--; |
| 103 } |
| 104 return true; |
| 105 } |
| 106 |
| 107 bool WriteU8(uint8_t v) { |
| 108 return Write(&v, sizeof(v)); |
| 109 } |
| 110 |
| 111 bool WriteU16(uint16_t v) { |
| 112 v = htons(v); |
| 113 return Write(&v, sizeof(v)); |
| 114 } |
| 115 |
| 116 bool WriteS16(int16_t v) { |
| 117 v = htons(v); |
| 118 return Write(&v, sizeof(v)); |
| 119 } |
| 120 |
| 121 bool WriteU24(uint32_t v) { |
| 122 v = htonl(v); |
| 123 return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); |
| 124 } |
| 125 |
| 126 bool WriteU32(uint32_t v) { |
| 127 v = htonl(v); |
| 128 return Write(&v, sizeof(v)); |
| 129 } |
| 130 |
| 131 bool WriteS32(int32_t v) { |
| 132 v = htonl(v); |
| 133 return Write(&v, sizeof(v)); |
| 134 } |
| 135 |
| 136 bool WriteR64(uint64_t v) { |
| 137 return Write(&v, sizeof(v)); |
| 138 } |
| 139 |
| 140 bool WriteTag(uint32_t v) { |
| 141 return Write(&v, sizeof(v)); |
| 142 } |
| 143 |
| 144 void ResetChecksum() { |
| 145 chksum_ = 0; |
| 146 chksum_buffer_offset_ = 0; |
| 147 } |
| 148 |
| 149 uint32_t chksum() const { |
| 150 assert(chksum_buffer_offset_ == 0); |
| 151 return chksum_; |
| 152 } |
| 153 |
| 154 struct ChecksumState { |
| 155 uint32_t chksum; |
| 156 uint8_t chksum_buffer[4]; |
| 157 unsigned chksum_buffer_offset; |
| 158 }; |
| 159 |
| 160 ChecksumState SaveChecksumState() const { |
| 161 ChecksumState s; |
| 162 s.chksum = chksum_; |
| 163 s.chksum_buffer_offset = chksum_buffer_offset_; |
| 164 std::memcpy(s.chksum_buffer, chksum_buffer_, 4); |
| 165 |
| 166 return s; |
| 167 } |
| 168 |
| 169 void RestoreChecksum(const ChecksumState &s) { |
| 170 assert(chksum_buffer_offset_ == 0); |
| 171 chksum_ += s.chksum; |
| 172 chksum_buffer_offset_ = s.chksum_buffer_offset; |
| 173 std::memcpy(chksum_buffer_, s.chksum_buffer, 4); |
| 174 } |
| 175 |
| 176 protected: |
| 177 uint32_t chksum_; |
| 178 uint8_t chksum_buffer_[4]; |
| 179 unsigned chksum_buffer_offset_; |
| 180 }; |
| 181 |
| 182 #ifdef __GCC__ |
| 183 #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3))) |
| 184 #else |
| 185 #define MSGFUNC_FMT_ATTR |
| 186 #endif |
| 187 |
| 188 enum TableAction { |
| 189 TABLE_ACTION_DEFAULT, // Use OTS's default action for that table |
| 190 TABLE_ACTION_SANITIZE, // Sanitize the table, potentially droping it |
| 191 TABLE_ACTION_PASSTHRU, // Serialize the table unchanged |
| 192 TABLE_ACTION_DROP // Drop the table |
| 193 }; |
| 194 |
| 195 class OTSContext { |
| 196 public: |
| 197 OTSContext() {} |
| 198 virtual ~OTSContext() {} |
| 199 |
| 200 // Process a given OpenType file and write out a sanitised version |
| 201 // output: a pointer to an object implementing the OTSStream interface. Th
e |
| 202 // sanitisied output will be written to this. In the even of a failure, |
| 203 // partial output may have been written. |
| 204 // input: the OpenType file |
| 205 // length: the size, in bytes, of |input| |
| 206 // context: optional context that holds various OTS settings like user cal
lbacks |
| 207 bool Process(OTSStream *output, const uint8_t *input, size_t length); |
| 208 |
| 209 // This function will be called when OTS is reporting an error. |
| 210 // level: the severity of the generated message: |
| 211 // 0: error messages in case OTS fails to sanitize the font. |
| 212 // 1: warning messages about issue OTS fixed in the sanitized font. |
| 213 virtual void Message(int level, const char *format, ...) MSGFUNC_FMT_ATTR {} |
| 214 |
| 215 // This function will be called when OTS needs to decide what to do for a |
| 216 // font table. |
| 217 // tag: table tag as an integer in big-endian byte order, independent of |
| 218 // platform endianness |
| 219 virtual TableAction GetTableAction(uint32_t tag) { return ots::TABLE_ACTION_
DEFAULT; } |
| 220 }; |
| 221 |
| 222 // For backward compatibility - remove once Chrome switches over to the new API. |
| 223 bool Process(OTSStream *output, const uint8_t *input, size_t length); |
| 224 |
| 225 // For backward compatibility - remove once https://codereview.chromium.org/7742
53008/ |
| 226 // is submitted. |
| 227 void EnableWOFF2(); |
| 228 |
| 229 } // namespace ots |
| 230 |
| 231 #endif // OPENTYPE_SANITISER_H_ |
OLD | NEW |