• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
FileInputStream()26 FileInputStream::FileInputStream()
27     : file_(NULL),
28       position_(0),
29       length_(0) {
30 }
31 
~FileInputStream()32 FileInputStream::~FileInputStream() {
33   Close();
34 }
35 
Available()36 int32_t FileInputStream::Available() {
37   return length_ - position_;
38 }
39 
Close()40 void FileInputStream::Close() {
41   if (file_) {
42     fclose(file_);
43     length_ = 0;
44     position_ = 0;
45     file_ = NULL;
46   }
47 }
48 
Mark(int32_t readlimit)49 void FileInputStream::Mark(int32_t readlimit) {
50   // NOP
51   UNREFERENCED_PARAMETER(readlimit);
52 }
53 
MarkSupported()54 bool FileInputStream::MarkSupported() {
55   return false;
56 }
57 
Read()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 
Read(ByteVector * b)77 int32_t FileInputStream::Read(ByteVector* b) {
78   return Read(b, 0, b->size());
79 }
80 
Read(ByteVector * b,int32_t offset,int32_t length)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 
Reset()104 void FileInputStream::Reset() {
105   // NOP
106 }
107 
Skip(int64_t n)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 
Unread(ByteVector * b)128 void FileInputStream::Unread(ByteVector* b) {
129   Unread(b, 0, b->size());
130 }
131 
Unread(ByteVector * b,int32_t offset,int32_t length)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 
Open(const char * file_path)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