ots-memory-stream.h (2582B)
1 // Copyright (c) 2009-2017 The OTS 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 OTS_MEMORY_STREAM_H_ 6 #define OTS_MEMORY_STREAM_H_ 7 8 #include <cstring> 9 #include <limits> 10 11 #include "opentype-sanitiser.h" 12 13 namespace ots { 14 15 class MemoryStream : public OTSStream { 16 public: 17 MemoryStream(void *ptr, size_t length) 18 : ptr_(ptr), length_(length), off_(0) { 19 } 20 21 size_t size() override { return length_; } 22 23 bool WriteRaw(const void *data, size_t length) override { 24 if ((off_ + length > length_) || 25 (length > std::numeric_limits<size_t>::max() - off_)) { 26 return false; 27 } 28 std::memcpy(static_cast<char*>(ptr_) + off_, data, length); 29 off_ += static_cast<off_t>(length); 30 return true; 31 } 32 33 bool Seek(off_t position) override { 34 if (position < 0) return false; 35 if (static_cast<size_t>(position) > length_) return false; 36 off_ = position; 37 return true; 38 } 39 40 off_t Tell() const override { 41 return off_; 42 } 43 44 private: 45 void* const ptr_; 46 size_t length_; 47 off_t off_; 48 }; 49 50 class ExpandingMemoryStream : public OTSStream { 51 public: 52 ExpandingMemoryStream(size_t initial, size_t limit) 53 : length_(initial), limit_(limit), off_(0) { 54 ptr_ = new uint8_t[length_]; 55 } 56 57 ~ExpandingMemoryStream() { 58 delete[] static_cast<uint8_t*>(ptr_); 59 } 60 61 void* get() const { 62 return ptr_; 63 } 64 65 size_t size() override { return limit_; } 66 67 bool WriteRaw(const void *data, size_t length) override { 68 if ((off_ + length > length_) || 69 (length > std::numeric_limits<size_t>::max() - off_)) { 70 if (length_ == limit_) 71 return false; 72 size_t new_length = (length_ + 1) * 2; 73 if (new_length < length_) 74 return false; 75 if (new_length > limit_) 76 new_length = limit_; 77 uint8_t* new_buf = new uint8_t[new_length]; 78 std::memcpy(new_buf, ptr_, length_); 79 length_ = new_length; 80 delete[] static_cast<uint8_t*>(ptr_); 81 ptr_ = new_buf; 82 return WriteRaw(data, length); 83 } 84 std::memcpy(static_cast<char*>(ptr_) + off_, data, length); 85 off_ += static_cast<off_t>(length); 86 return true; 87 } 88 89 bool Seek(off_t position) override { 90 if (position < 0) return false; 91 if (static_cast<size_t>(position) > length_) return false; 92 off_ = position; 93 return true; 94 } 95 96 off_t Tell() const override { 97 return off_; 98 } 99 100 private: 101 void* ptr_; 102 size_t length_; 103 const size_t limit_; 104 off_t off_; 105 }; 106 107 } // namespace ots 108 109 #endif // OTS_MEMORY_STREAM_H_