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