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 <algorithm> 24 25#include "sfntly/port/memory_input_stream.h" 26#include "sfntly/port/exception_type.h" 27 28namespace sfntly { 29 30MemoryInputStream::MemoryInputStream() 31 : buffer_(NULL), 32 position_(0), 33 length_(0) { 34} 35 36MemoryInputStream::~MemoryInputStream() { 37 Close(); 38} 39 40int32_t MemoryInputStream::Available() { 41 return length_ - position_; 42} 43 44void MemoryInputStream::Close() { 45} 46 47void MemoryInputStream::Mark(int32_t readlimit) { 48 // NOP 49 UNREFERENCED_PARAMETER(readlimit); 50} 51 52bool MemoryInputStream::MarkSupported() { 53 return false; 54} 55 56int32_t MemoryInputStream::Read() { 57 if (!buffer_) { 58#if !defined (SFNTLY_NO_EXCEPTION) 59 throw IOException("no memory attached"); 60#endif 61 return 0; 62 } 63 if (position_ >= length_) { 64#if !defined (SFNTLY_NO_EXCEPTION) 65 throw IOException("eof reached"); 66#endif 67 return 0; 68 } 69 byte_t value = buffer_[position_++]; 70 return value; 71} 72 73int32_t MemoryInputStream::Read(ByteVector* b) { 74 return Read(b, 0, b->size()); 75} 76 77int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) { 78 assert(b); 79 if (!buffer_) { 80#if !defined (SFNTLY_NO_EXCEPTION) 81 throw IOException("no memory attached"); 82#endif 83 return 0; 84 } 85 if (position_ >= length_) { 86#if !defined (SFNTLY_NO_EXCEPTION) 87 throw IOException("eof reached"); 88#endif 89 return 0; 90 } 91 size_t read_count = std::min<size_t>(length_ - position_, length); 92 if (b->size() < (size_t)(offset + read_count)) { 93 b->resize((size_t)(offset + read_count)); 94 } 95 memcpy(&((*b)[offset]), buffer_ + position_, read_count); 96 position_ += read_count; 97 return read_count; 98} 99 100void MemoryInputStream::Reset() { 101 // NOP 102} 103 104int64_t MemoryInputStream::Skip(int64_t n) { 105 if (!buffer_) { 106#if !defined (SFNTLY_NO_EXCEPTION) 107 throw IOException("no memory attached"); 108#endif 109 return 0; 110 } 111 int64_t skip_count = 0; 112 if (n < 0) { // move backwards 113 skip_count = std::max<int64_t>(0 - (int64_t)position_, n); 114 position_ -= (size_t)(0 - skip_count); 115 } else { 116 skip_count = std::min<size_t>(length_ - position_, (size_t)n); 117 position_ += (size_t)skip_count; 118 } 119 return skip_count; 120} 121 122void MemoryInputStream::Unread(ByteVector* b) { 123 Unread(b, 0, b->size()); 124} 125 126void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) { 127 assert(b); 128 assert(b->size() >= size_t(offset + length)); 129 if (!buffer_) { 130#if !defined (SFNTLY_NO_EXCEPTION) 131 throw IOException("no memory attached"); 132#endif 133 return; 134 } 135 size_t unread_count = std::min<size_t>(position_, length); 136 position_ -= unread_count; 137 Read(b, offset, length); 138 position_ -= unread_count; 139} 140 141bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) { 142 assert(buffer); 143 assert(length); 144 buffer_ = buffer; 145 length_ = length; 146 return true; 147} 148 149} // namespace sfntly 150