Home | History | Annotate | Download | only in port
      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