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