130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/* 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved. 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License"); 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License. 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * http://www.apache.org/licenses/LICENSE-2.0 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS, 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */ 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (WIN32) 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <windows.h> 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <string.h> 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/memory_input_stream.h" 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/exception_type.h" 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunMemoryInputStream::MemoryInputStream() 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : buffer_(NULL), 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun position_(0), 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun length_(0) { 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunMemoryInputStream::~MemoryInputStream() { 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Close(); 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t MemoryInputStream::Available() { 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return length_ - position_; 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid MemoryInputStream::Close() { 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid MemoryInputStream::Mark(int32_t readlimit) { 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // NOP 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(readlimit); 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool MemoryInputStream::MarkSupported() { 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t MemoryInputStream::Read() { 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!buffer_) { 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("no memory attached"); 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (position_ >= length_) { 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("eof reached"); 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun byte_t value = buffer_[position_++]; 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return value; 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t MemoryInputStream::Read(ByteVector* b) { 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Read(b, 0, b->size()); 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) { 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(b); 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!buffer_) { 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("no memory attached"); 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (position_ >= length_) { 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("eof reached"); 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size_t read_count = std::min<size_t>(length_ - position_, length); 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (b->size() < (size_t)(offset + read_count)) { 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b->resize((size_t)(offset + read_count)); 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun memcpy(&((*b)[offset]), buffer_ + position_, read_count); 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun position_ += read_count; 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return read_count; 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid MemoryInputStream::Reset() { 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // NOP 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint64_t MemoryInputStream::Skip(int64_t n) { 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!buffer_) { 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("no memory attached"); 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int64_t skip_count = 0; 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (n < 0) { // move backwards 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun skip_count = std::max<int64_t>(0 - (int64_t)position_, n); 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun position_ -= (size_t)(0 - skip_count); 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun skip_count = std::min<size_t>(length_ - position_, (size_t)n); 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun position_ += (size_t)skip_count; 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return skip_count; 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid MemoryInputStream::Unread(ByteVector* b) { 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Unread(b, 0, b->size()); 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) { 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(b); 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(b->size() >= size_t(offset + length)); 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!buffer_) { 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("no memory attached"); 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size_t unread_count = std::min<size_t>(position_, length); 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun position_ -= unread_count; 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Read(b, offset, length); 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun position_ -= unread_count; 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool MemoryInputStream::Attach(const byte_t* buffer, size_t length) { 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(buffer); 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(length); 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun buffer_ = buffer; 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun length_ = length; 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 148