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