file_input_stream.cc revision fa606d4385cc0cc97f319dc25c97f46b2d44f1b9
173b526fb4af0f60634f0078583d92b931d5c0eebnethercote/* 273b526fb4af0f60634f0078583d92b931d5c0eebnethercote * Copyright 2011 Google Inc. All Rights Reserved. 34de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn * 473b526fb4af0f60634f0078583d92b931d5c0eebnethercote * Licensed under the Apache License, Version 2.0 (the "License"); 573b526fb4af0f60634f0078583d92b931d5c0eebnethercote * you may not use this file except in compliance with the License. 673b526fb4af0f60634f0078583d92b931d5c0eebnethercote * You may obtain a copy of the License at 7b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn * 8b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn * http://www.apache.org/licenses/LICENSE-2.0 973b526fb4af0f60634f0078583d92b931d5c0eebnethercote * 109f207460d70d38c46c9e81996a3dcdf90961c6dbnjn * Unless required by applicable law or agreed to in writing, software 1173b526fb4af0f60634f0078583d92b931d5c0eebnethercote * distributed under the License is distributed on an "AS IS" BASIS, 1273b526fb4af0f60634f0078583d92b931d5c0eebnethercote * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373b526fb4af0f60634f0078583d92b931d5c0eebnethercote * See the License for the specific language governing permissions and 1473b526fb4af0f60634f0078583d92b931d5c0eebnethercote * limitations under the License. 1573b526fb4af0f60634f0078583d92b931d5c0eebnethercote */ 1673b526fb4af0f60634f0078583d92b931d5c0eebnethercote 1773b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (WIN32) 1873b526fb4af0f60634f0078583d92b931d5c0eebnethercote#include <windows.h> 1973b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif 2073b526fb4af0f60634f0078583d92b931d5c0eebnethercote 2173b526fb4af0f60634f0078583d92b931d5c0eebnethercote#include "sfntly/port/file_input_stream.h" 2273b526fb4af0f60634f0078583d92b931d5c0eebnethercote#include "sfntly/port/exception_type.h" 2373b526fb4af0f60634f0078583d92b931d5c0eebnethercote 2473b526fb4af0f60634f0078583d92b931d5c0eebnethercotenamespace sfntly { 2573b526fb4af0f60634f0078583d92b931d5c0eebnethercote 2673b526fb4af0f60634f0078583d92b931d5c0eebnethercoteFileInputStream::FileInputStream() : file_(NULL), position_(0), length_(0) { 2773b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 2873b526fb4af0f60634f0078583d92b931d5c0eebnethercote 2973b526fb4af0f60634f0078583d92b931d5c0eebnethercoteFileInputStream::~FileInputStream() { 3073b526fb4af0f60634f0078583d92b931d5c0eebnethercote close(); 3173b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 3273b526fb4af0f60634f0078583d92b931d5c0eebnethercote 3373b526fb4af0f60634f0078583d92b931d5c0eebnethercoteint32_t FileInputStream::available() { 3473b526fb4af0f60634f0078583d92b931d5c0eebnethercote return length_ - position_; 3573b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 3673b526fb4af0f60634f0078583d92b931d5c0eebnethercote 3773b526fb4af0f60634f0078583d92b931d5c0eebnethercotebool FileInputStream::open(const char* file_path) { 3873b526fb4af0f60634f0078583d92b931d5c0eebnethercote assert(file_path); 3973b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (file_) { 4073b526fb4af0f60634f0078583d92b931d5c0eebnethercote close(); 4173b526fb4af0f60634f0078583d92b931d5c0eebnethercote } 4273b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (WIN32) 4373b526fb4af0f60634f0078583d92b931d5c0eebnethercote fopen_s(&file_, file_path, "rb"); 4473b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else 4573b526fb4af0f60634f0078583d92b931d5c0eebnethercote file_ = fopen(file_path, "rb"); 4673b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif 47ac7924c7eedce947578c571ae419c4c84eaa5aefnjn if (file_ == NULL) { 48edef146c47eda894495d2b3b71b32b10349f8d91sewardj return false; 494de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn } 504de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn 51ac7924c7eedce947578c571ae419c4c84eaa5aefnjn fseek(file_, 0, SEEK_END); 52ac7924c7eedce947578c571ae419c4c84eaa5aefnjn length_ = ftell(file_); 53ac7924c7eedce947578c571ae419c4c84eaa5aefnjn fseek(file_, 0, SEEK_SET); 54ac7924c7eedce947578c571ae419c4c84eaa5aefnjn return true; 55ac7924c7eedce947578c571ae419c4c84eaa5aefnjn} 5673b526fb4af0f60634f0078583d92b931d5c0eebnethercote 5773b526fb4af0f60634f0078583d92b931d5c0eebnethercotevoid FileInputStream::close() { 5873b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (file_) { 5973b526fb4af0f60634f0078583d92b931d5c0eebnethercote fclose(file_); 604cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj length_ = 0; 614cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj position_ = 0; 624cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj } 634cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj} 644cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj 654cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardjvoid FileInputStream::mark(int32_t readlimit) { 664cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj // NOP 674cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj UNREFERENCED_PARAMETER(readlimit); 684cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj} 694cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj 704cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardjbool FileInputStream::markSupported() { 714cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj return false; 724cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj} 734cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj 744cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardjint32_t FileInputStream::read() { 754de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn if (!file_) { 764de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn#if defined (SFNTLY_NO_EXCEPTION) 7773b526fb4af0f60634f0078583d92b931d5c0eebnethercote return 0; 7873b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else 7973b526fb4af0f60634f0078583d92b931d5c0eebnethercote throw IOException("no opened file"); 8073b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif 8173b526fb4af0f60634f0078583d92b931d5c0eebnethercote } 824de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn if (feof(file_)) { 834cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#if defined (SFNTLY_NO_EXCEPTION) 844de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn return 0; 854cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#else 8685665ca6fa29dd64754dabe50eb98f25896e752acerion throw IOException("eof reached"); 874cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#endif 882c48c7b0a453d32375a4df17e153011b797ef28csewardj } 894cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj byte_t value; 904de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn fread(&value, 1, 1, file_); 914de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn position_++; 924de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn return value; 9373b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 9473b526fb4af0f60634f0078583d92b931d5c0eebnethercote 9573b526fb4af0f60634f0078583d92b931d5c0eebnethercoteint32_t FileInputStream::read(ByteVector* b) { 9673b526fb4af0f60634f0078583d92b931d5c0eebnethercote return read(b, 0, b->capacity()); 9773b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 9873b526fb4af0f60634f0078583d92b931d5c0eebnethercote 9973b526fb4af0f60634f0078583d92b931d5c0eebnethercoteint32_t FileInputStream::read(ByteVector* b, int32_t offset, int32_t length) { 10073b526fb4af0f60634f0078583d92b931d5c0eebnethercote assert(b); 10173b526fb4af0f60634f0078583d92b931d5c0eebnethercote assert(b->size() >= (size_t)(offset + length)); 10273b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (!file_) { 10373b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (SFNTLY_NO_EXCEPTION) 10473b526fb4af0f60634f0078583d92b931d5c0eebnethercote return 0; 10573b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else 106f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote throw IOException("no opened file"); 107f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#endif 108f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote } 109f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote if (feof(file_)) { 110f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#if defined (SFNTLY_NO_EXCEPTION) 111f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote return 0; 112f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#else 113f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote throw IOException("eof reached"); 114f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#endif 115f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote } 116f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote size_t read_count = std::min<size_t>(length_ - position_, length); 117f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote int32_t actual_read = fread(&((*b)[offset]), 1, read_count, file_); 118f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote position_ += actual_read; 119f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote return actual_read; 120f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote} 121f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote 122f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercotevoid FileInputStream::reset() { 123f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote // NOP 124f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote} 12573b526fb4af0f60634f0078583d92b931d5c0eebnethercote 126330abb517e58fd0ee96fda7fb8563e32e029a63enethercoteint64_t FileInputStream::skip(int64_t n) { 12773b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (!file_) { 12873b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (SFNTLY_NO_EXCEPTION) 12973b526fb4af0f60634f0078583d92b931d5c0eebnethercote return 0; 13073b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else 13173b526fb4af0f60634f0078583d92b931d5c0eebnethercote throw IOException("no opened file"); 132f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#endif 13373b526fb4af0f60634f0078583d92b931d5c0eebnethercote } 13473b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (n < 0) { 13573b526fb4af0f60634f0078583d92b931d5c0eebnethercote return 0; 13673b526fb4af0f60634f0078583d92b931d5c0eebnethercote } 13773b526fb4af0f60634f0078583d92b931d5c0eebnethercote size_t skip_count = std::min<size_t>(length_ - position_, (size_t)n); 13873b526fb4af0f60634f0078583d92b931d5c0eebnethercote fseek(file_, skip_count, SEEK_CUR); 13992b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote position_ += skip_count; 140330abb517e58fd0ee96fda7fb8563e32e029a63enethercote return skip_count; 14173b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 14273b526fb4af0f60634f0078583d92b931d5c0eebnethercote 14373b526fb4af0f60634f0078583d92b931d5c0eebnethercotevoid FileInputStream::unread(ByteVector* b) { 14473b526fb4af0f60634f0078583d92b931d5c0eebnethercote unread(b, 0, b->capacity()); 14573b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 146c6851dde1b46166417a2bdb096c05818f5f07f09nethercote 147c6851dde1b46166417a2bdb096c05818f5f07f09nethercotevoid FileInputStream::unread(ByteVector* b, int32_t offset, int32_t length) { 148c6851dde1b46166417a2bdb096c05818f5f07f09nethercote assert(b); 14973b526fb4af0f60634f0078583d92b931d5c0eebnethercote assert(b->size() >= size_t(offset + length)); 15073b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (!file_) { 15173b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (SFNTLY_NO_EXCEPTION) 15273b526fb4af0f60634f0078583d92b931d5c0eebnethercote return; 15373b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else 15473b526fb4af0f60634f0078583d92b931d5c0eebnethercote throw IOException("no opened file"); 15573b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif 1565b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote } 1575b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote size_t unread_count = std::min<size_t>(position_, length); 1587f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote fseek(file_, position_ - unread_count, SEEK_SET); 1597f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote read(b, offset, length); 16073b526fb4af0f60634f0078583d92b931d5c0eebnethercote fseek(file_, position_ - unread_count, SEEK_SET); 16173b526fb4af0f60634f0078583d92b931d5c0eebnethercote} 16273b526fb4af0f60634f0078583d92b931d5c0eebnethercote 16373b526fb4af0f60634f0078583d92b931d5c0eebnethercote} // namespace sfntly 1644de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn