| // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef OPENTYPE_SANITISER_H_ |
| #define OPENTYPE_SANITISER_H_ |
| |
| #if defined(STARBOARD) |
| #include "starboard/byte_swap.h" |
| #define ntohl(x) SB_NET_TO_HOST_U32(x) |
| #define ntohs(x) SB_NET_TO_HOST_U16(x) |
| #define htonl(x) SB_HOST_TO_NET_U32(x) |
| #define htons(x) SB_HOST_TO_NET_U16(x) |
| #elif defined(COBALT_WIN) |
| #elif defined(_WIN32) |
| #include <stdlib.h> |
| typedef signed char int8_t; |
| typedef unsigned char uint8_t; |
| typedef short int16_t; |
| typedef unsigned short uint16_t; |
| typedef int int32_t; |
| typedef unsigned int uint32_t; |
| typedef __int64 int64_t; |
| typedef unsigned __int64 uint64_t; |
| #define ntohl(x) _byteswap_ulong (x) |
| #define ntohs(x) _byteswap_ushort (x) |
| #define htonl(x) _byteswap_ulong (x) |
| #define htons(x) _byteswap_ushort (x) |
| #else |
| #include <arpa/inet.h> |
| #include <stdint.h> |
| #endif |
| |
| #include <algorithm> // for std::min |
| #include <cassert> |
| #include <cstddef> |
| #include <cstring> |
| |
| namespace ots { |
| |
| // ----------------------------------------------------------------------------- |
| // This is an interface for an abstract stream class which is used for writing |
| // the serialised results out. |
| // ----------------------------------------------------------------------------- |
| class OTSStream { |
| public: |
| OTSStream() { |
| ResetChecksum(); |
| } |
| |
| virtual ~OTSStream() {} |
| |
| // This should be implemented to perform the actual write. |
| virtual bool WriteRaw(const void *data, size_t length) = 0; |
| |
| bool Write(const void *data, size_t length) { |
| if (!length) return false; |
| |
| const size_t orig_length = length; |
| size_t offset = 0; |
| if (chksum_buffer_offset_) { |
| const size_t l = |
| std::min(length, static_cast<size_t>(4) - chksum_buffer_offset_); |
| std::memcpy(chksum_buffer_ + chksum_buffer_offset_, data, l); |
| #if defined(COBALT_WIN) |
| #pragma warning(push) |
| #pragma warning(disable : 4267) // possible loss of data |
| #endif |
| chksum_buffer_offset_ += l; |
| #if defined(COBALT_WIN) |
| #pragma warning(pop) |
| #endif |
| offset += l; |
| length -= l; |
| } |
| |
| if (chksum_buffer_offset_ == 4) { |
| uint32_t chksum; |
| std::memcpy(&chksum, chksum_buffer_, 4); |
| chksum_ += ntohl(chksum); |
| chksum_buffer_offset_ = 0; |
| } |
| |
| while (length >= 4) { |
| uint32_t tmp; |
| std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset, |
| sizeof(uint32_t)); |
| chksum_ += ntohl(tmp); |
| length -= 4; |
| offset += 4; |
| } |
| |
| if (length) { |
| if (chksum_buffer_offset_ != 0) return false; // not reached |
| if (length > 4) return false; // not reached |
| std::memcpy(chksum_buffer_, |
| reinterpret_cast<const uint8_t*>(data) + offset, length); |
| #if defined(COBALT_WIN) |
| #pragma warning(push) |
| #pragma warning(disable : 4267) // possible loss of data |
| #elif defined(__clang__) |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wshorten-64-to-32" |
| #endif |
| chksum_buffer_offset_ = length; |
| #if defined(COBALT_WIN) |
| #pragma warning(pop) |
| #elif defined(__clang__) |
| #pragma clang diagnostic pop |
| #endif |
| } |
| |
| return WriteRaw(data, orig_length); |
| } |
| |
| virtual bool Seek(off_t position) = 0; |
| virtual off_t Tell() const = 0; |
| |
| virtual bool Pad(size_t bytes) { |
| static const uint32_t kZero = 0; |
| while (bytes >= 4) { |
| if (!WriteTag(kZero)) return false; |
| bytes -= 4; |
| } |
| while (bytes) { |
| static const uint8_t kZerob = 0; |
| if (!Write(&kZerob, 1)) return false; |
| bytes--; |
| } |
| return true; |
| } |
| |
| bool WriteU8(uint8_t v) { |
| return Write(&v, sizeof(v)); |
| } |
| |
| bool WriteU16(uint16_t v) { |
| v = htons(v); |
| return Write(&v, sizeof(v)); |
| } |
| |
| bool WriteS16(int16_t v) { |
| #if defined(COBALT_WIN) |
| #pragma warning(push) |
| #pragma warning(disable : 4365) // signed/unsigned mismatch |
| #endif |
| v = htons(v); |
| #if defined(COBALT_WIN) |
| #pragma warning(pop) |
| #endif |
| return Write(&v, sizeof(v)); |
| } |
| |
| bool WriteU24(uint32_t v) { |
| v = htonl(v); |
| return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); |
| } |
| |
| bool WriteU32(uint32_t v) { |
| v = htonl(v); |
| return Write(&v, sizeof(v)); |
| } |
| |
| bool WriteS32(int32_t v) { |
| #if defined(COBALT_WIN) |
| #pragma warning(push) |
| #pragma warning(disable : 4365) // signed/unsigned mismatch |
| #endif |
| v = htonl(v); |
| #if defined(COBALT_WIN) |
| #pragma warning(pop) |
| #endif |
| return Write(&v, sizeof(v)); |
| } |
| |
| bool WriteR64(uint64_t v) { |
| return Write(&v, sizeof(v)); |
| } |
| |
| bool WriteTag(uint32_t v) { |
| return Write(&v, sizeof(v)); |
| } |
| |
| void ResetChecksum() { |
| chksum_ = 0; |
| chksum_buffer_offset_ = 0; |
| } |
| |
| uint32_t chksum() const { |
| assert(chksum_buffer_offset_ == 0); |
| return chksum_; |
| } |
| |
| struct ChecksumState { |
| uint32_t chksum; |
| uint8_t chksum_buffer[4]; |
| unsigned chksum_buffer_offset; |
| }; |
| |
| ChecksumState SaveChecksumState() const { |
| ChecksumState s; |
| s.chksum = chksum_; |
| s.chksum_buffer_offset = chksum_buffer_offset_; |
| std::memcpy(s.chksum_buffer, chksum_buffer_, 4); |
| |
| return s; |
| } |
| |
| void RestoreChecksum(const ChecksumState &s) { |
| assert(chksum_buffer_offset_ == 0); |
| chksum_ += s.chksum; |
| chksum_buffer_offset_ = s.chksum_buffer_offset; |
| std::memcpy(chksum_buffer_, s.chksum_buffer, 4); |
| } |
| |
| protected: |
| uint32_t chksum_; |
| uint8_t chksum_buffer_[4]; |
| unsigned chksum_buffer_offset_; |
| }; |
| |
| // ----------------------------------------------------------------------------- |
| // Process a given OpenType file and write out a sanitised version |
| // output: a pointer to an object implementing the OTSStream interface. The |
| // sanitisied output will be written to this. In the even of a failure, |
| // partial output may have been written. |
| // input: the OpenType file |
| // length: the size, in bytes, of |input| |
| // ----------------------------------------------------------------------------- |
| bool Process(OTSStream *output, const uint8_t *input, size_t length); |
| |
| // Force to disable debug output even when the library is compiled with |
| // -DOTS_DEBUG. |
| void DisableDebugOutput(); |
| |
| } // namespace ots |
| |
| #endif // OPENTYPE_SANITISER_H_ |