1/* 2 * Copyright 2011 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#if defined (WIN32) 18#include <windows.h> 19#endif 20 21#include <string.h> 22 23#include "sfntly/port/memory_input_stream.h" 24#include "sfntly/port/exception_type.h" 25 26namespace sfntly { 27 28MemoryInputStream::MemoryInputStream() 29 : buffer_(NULL), 30 position_(0), 31 length_(0) { 32} 33 34MemoryInputStream::~MemoryInputStream() { 35 Close(); 36} 37 38int32_t MemoryInputStream::Available() { 39 return length_ - position_; 40} 41 42void MemoryInputStream::Close() { 43} 44 45void MemoryInputStream::Mark(int32_t readlimit) { 46 // NOP 47 UNREFERENCED_PARAMETER(readlimit); 48} 49 50bool MemoryInputStream::MarkSupported() { 51 return false; 52} 53 54int32_t MemoryInputStream::Read() { 55 if (!buffer_) { 56#if !defined (SFNTLY_NO_EXCEPTION) 57 throw IOException("no memory attached"); 58#endif 59 return 0; 60 } 61 if (position_ >= length_) { 62#if !defined (SFNTLY_NO_EXCEPTION) 63 throw IOException("eof reached"); 64#endif 65 return 0; 66 } 67 byte_t value = buffer_[position_++]; 68 return value; 69} 70 71int32_t MemoryInputStream::Read(ByteVector* b) { 72 return Read(b, 0, b->size()); 73} 74 75int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) { 76 assert(b); 77 if (!buffer_) { 78#if !defined (SFNTLY_NO_EXCEPTION) 79 throw IOException("no memory attached"); 80#endif 81 return 0; 82 } 83 if (position_ >= length_) { 84#if !defined (SFNTLY_NO_EXCEPTION) 85 throw IOException("eof reached"); 86#endif 87 return 0; 88 } 89 size_t read_count = std::min<size_t>(length_ - position_, length); 90 if (b->size() < (size_t)(offset + read_count)) { 91 b->resize((size_t)(offset + read_count)); 92 } 93 memcpy(&((*b)[offset]), buffer_ + position_, read_count); 94 position_ += read_count; 95 return read_count; 96} 97 98void MemoryInputStream::Reset() { 99 // NOP 100} 101 102int64_t MemoryInputStream::Skip(int64_t n) { 103 if (!buffer_) { 104#if !defined (SFNTLY_NO_EXCEPTION) 105 throw IOException("no memory attached"); 106#endif 107 return 0; 108 } 109 int64_t skip_count = 0; 110 if (n < 0) { // move backwards 111 skip_count = std::max<int64_t>(0 - (int64_t)position_, n); 112 position_ -= (size_t)(0 - skip_count); 113 } else { 114 skip_count = std::min<size_t>(length_ - position_, (size_t)n); 115 position_ += (size_t)skip_count; 116 } 117 return skip_count; 118} 119 120void MemoryInputStream::Unread(ByteVector* b) { 121 Unread(b, 0, b->size()); 122} 123 124void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) { 125 assert(b); 126 assert(b->size() >= size_t(offset + length)); 127 if (!buffer_) { 128#if !defined (SFNTLY_NO_EXCEPTION) 129 throw IOException("no memory attached"); 130#endif 131 return; 132 } 133 size_t unread_count = std::min<size_t>(position_, length); 134 position_ -= unread_count; 135 Read(b, offset, length); 136 position_ -= unread_count; 137} 138 139bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) { 140 assert(buffer); 141 assert(length); 142 buffer_ = buffer; 143 length_ = length; 144 return true; 145} 146 147} // namespace sfntly 148