Home | History | Annotate | Download | only in woff2
      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>
     23 typedef signed char int8_t;
     24 typedef unsigned char uint8_t;
     25 typedef short int16_t;
     26 typedef unsigned short uint16_t;
     27 typedef int int32_t;
     28 typedef unsigned int uint32_t;
     29 typedef __int64 int64_t;
     30 typedef 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 
     44 namespace 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__)
     51 inline 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 // -----------------------------------------------------------------------------
     65 class 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