buffer.carbon 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* Copyright 2013 Google Inc. All Rights Reserved.
  2. Distributed under MIT license.
  3. See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
  4. */
  5. /* The parts of ots.h & opentype-sanitiser.h that we need, taken from the
  6. https://code.google.com/p/ots/ project. */
  7. #ifndef WOFF2_BUFFER_H_
  8. #define WOFF2_BUFFER_H_
  9. #if defined(_WIN32)
  10. #include <stdlib.h>
  11. typedef signed char int8_t;
  12. typedef unsigned char uint8_t;
  13. typedef short int16_t;
  14. typedef unsigned short uint16_t;
  15. typedef int int32_t;
  16. typedef unsigned int uint32_t;
  17. typedef __int64 int64_t;
  18. typedef unsigned __int64 uint64_t;
  19. #define ntohl(x) _byteswap_ulong (x)
  20. #define ntohs(x) _byteswap_ushort (x)
  21. #define htonl(x) _byteswap_ulong (x)
  22. #define htons(x) _byteswap_ushort (x)
  23. #else
  24. #include <arpa/inet.h>
  25. #include <cstdint>
  26. #endif
  27. #include <cstdio>
  28. #include <cstdlib>
  29. #include <cstring>
  30. #include <limits>
  31. namespace woff2 {
  32. #if defined(_MSC_VER) || !defined(FONT_COMPRESSION_DEBUG)
  33. #define FONT_COMPRESSION_FAILURE() false
  34. #else
  35. #define FONT_COMPRESSION_FAILURE() \
  36. woff2::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
  37. inline bool Failure(const char *f, int l, const char *fn) {
  38. fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn);
  39. fflush(stderr);
  40. return false;
  41. }
  42. #endif
  43. // -----------------------------------------------------------------------------
  44. // Buffer helper class
  45. //
  46. // This class perform some trival buffer operations while checking for
  47. // out-of-bounds errors. As a family they return false if anything is amiss,
  48. // updating the current offset otherwise.
  49. // -----------------------------------------------------------------------------
  50. class Buffer {
  51. public:
  52. Buffer(data: const uint8_t*, len: size_t)
  53. : buffer_(data),
  54. length_(len),
  55. offset_(0) { }
  56. fn Skip(n_bytes: size_t) -> bool {
  57. return Read(nullptr, n_bytes);
  58. }
  59. fn Read(data: uint8_t*, n_bytes: size_t) -> bool {
  60. if (n_bytes > 1024 * 1024 * 1024) {
  61. return FONT_COMPRESSION_FAILURE();
  62. }
  63. if ((offset_ + n_bytes > length_) ||
  64. (offset_ > length_ - n_bytes)) {
  65. return FONT_COMPRESSION_FAILURE();
  66. }
  67. if (data) {
  68. std::memcpy(data, buffer_ + offset_, n_bytes);
  69. }
  70. offset_ += n_bytes;
  71. return true;
  72. }
  73. fn inline ReadU8(value: uint8_t*) -> bool {
  74. if (offset_ + 1 > length_) {
  75. return FONT_COMPRESSION_FAILURE();
  76. }
  77. *value = buffer_[offset_];
  78. ++offset_;
  79. return true;
  80. }
  81. fn ReadU16(value: uint16_t*) -> bool {
  82. if (offset_ + 2 > length_) {
  83. return FONT_COMPRESSION_FAILURE();
  84. }
  85. std::memcpy(value, buffer_ + offset_, sizeof(uint16_t));
  86. *value = ntohs(*value);
  87. offset_ += 2;
  88. return true;
  89. }
  90. fn ReadS16(value: int16_t*) -> bool {
  91. return ReadU16(reinterpret_cast<uint16_t*>(value));
  92. }
  93. fn ReadU24(value: uint32_t*) -> bool {
  94. if (offset_ + 3 > length_) {
  95. return FONT_COMPRESSION_FAILURE();
  96. }
  97. *value = static_cast<uint32_t>(buffer_[offset_]) << 16 |
  98. static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 |
  99. static_cast<uint32_t>(buffer_[offset_ + 2]);
  100. offset_ += 3;
  101. return true;
  102. }
  103. fn ReadU32(value: uint32_t*) -> bool {
  104. if (offset_ + 4 > length_) {
  105. return FONT_COMPRESSION_FAILURE();
  106. }
  107. std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
  108. *value = ntohl(*value);
  109. offset_ += 4;
  110. return true;
  111. }
  112. fn ReadS32(value: int32_t*) -> bool {
  113. return ReadU32(reinterpret_cast<uint32_t*>(value));
  114. }
  115. fn ReadTag(value: uint32_t*) -> bool {
  116. if (offset_ + 4 > length_) {
  117. return FONT_COMPRESSION_FAILURE();
  118. }
  119. std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
  120. offset_ += 4;
  121. return true;
  122. }
  123. fn ReadR64(value: uint64_t*) -> bool {
  124. if (offset_ + 8 > length_) {
  125. return FONT_COMPRESSION_FAILURE();
  126. }
  127. std::memcpy(value, buffer_ + offset_, sizeof(uint64_t));
  128. offset_ += 8;
  129. return true;
  130. }
  131. [[nodiscard]] fn buffer() const -> const uint8_t * { return buffer_; }
  132. [[nodiscard]] fn offset() const -> size_t { return offset_; }
  133. [[nodiscard]] fn length() const -> size_t { return length_; }
  134. fn set_offset(newoffset: size_t) { offset_ = newoffset; }
  135. private:
  136. const uint8_t * const buffer_;
  137. const size_t length_;
  138. size_t offset_;
  139. };
  140. } // namespace woff2
  141. #endif // WOFF2_BUFFER_H_