xoreos  0.0.5
readfile.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <cassert>
26 
27 #include "src/common/readfile.h"
28 #include "src/common/error.h"
29 #include "src/common/ustring.h"
30 #include "src/common/platform.h"
31 
32 namespace Common {
33 
34 ReadFile::ReadFile() : _handle(0), _size(kSizeInvalid) {
35 }
36 
37 ReadFile::ReadFile(const UString &fileName) : _handle(0), _size(kSizeInvalid) {
38  if (!open(fileName))
39  throw Exception("Can't open file \"%s\"", fileName.c_str());
40 }
41 
43  close();
44 }
45 
46 static long getInitialSize(std::FILE *handle) {
47  if (!handle)
48  return -1;
49 
50  if (std::fseek(handle, 0, SEEK_END) != 0)
51  return -1;
52 
53  long fileSize = std::ftell(handle);
54 
55  if (std::fseek(handle, 0, SEEK_SET) != 0)
56  return -1;
57 
58  return fileSize;
59 }
60 
61 bool ReadFile::open(const UString &fileName) {
62  close();
63 
64  long fileSize = -1;
66  ((fileSize = getInitialSize(_handle)) < 0)) {
67 
68  close();
69  return false;
70  }
71 
72  if ((uint64)((unsigned long)fileSize) > (uint64)0x7FFFFFFFULL) {
73  warning("ReadFile \"%s\" is too big", fileName.c_str());
74 
75  close();
76  return false;
77  }
78 
79  _size = (size_t)fileSize;
80 
81  return true;
82 }
83 
85  if (_handle)
86  std::fclose(_handle);
87 
88  _handle = 0;
90 }
91 
92 bool ReadFile::isOpen() const {
93  return _handle != 0;
94 }
95 
96 bool ReadFile::eos() const {
97  if (!_handle)
98  return true;
99 
100  return std::feof(_handle) != 0;
101 }
102 
103 size_t ReadFile::pos() const {
104  if (!_handle)
105  return kPositionInvalid;
106 
107  return (size_t)std::ftell(_handle);
108 }
109 
110 size_t ReadFile::size() const {
111  return _size;
112 }
113 
114 size_t ReadFile::seek(ptrdiff_t offset, Origin whence) {
115  static const int kSeekToWhence[kOriginMAX] = { SEEK_SET, SEEK_CUR, SEEK_END };
116  if (((size_t) whence) >= kOriginMAX)
117  throw Exception(kSeekError);
118 
119  if (!_handle)
120  throw Exception(kSeekError);
121 
122  size_t oldPos = pos();
123 
124  if (std::fseek(_handle, offset, kSeekToWhence[whence]) != 0)
125  throw Exception(kSeekError);
126 
127  long p = std::ftell(_handle);
128  if ((p < 0) || ((size_t)p > _size))
129  throw Exception(kSeekError);
130 
131  return oldPos;
132 }
133 
134 size_t ReadFile::read(void *dataPtr, size_t dataSize) {
135  if (!_handle)
136  return 0;
137 
138  assert(dataPtr);
139  return std::fread(dataPtr, 1, dataSize, _handle);
140 }
141 
142 } // End of namespace Common
size_t pos() const
Obtains the current value of the stream position indicator of the stream.
Definition: readfile.cpp:103
static long getInitialSize(std::FILE *handle)
Definition: readfile.cpp:46
Definition: 2dafile.h:39
A class holding an UTF-8 string.
Definition: ustring.h:48
static const size_t kPositionInvalid
Definition: readstream.h:70
uint64_t uint64
Definition: types.h:206
Platform-dependant functions, mostly for internal use in the Common namespace.
size_t _size
The file&#39;s size.
Definition: readfile.h:72
bool eos() const
Returns true if a read failed because the stream has been reached.
Definition: readfile.cpp:96
size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)
Sets the stream position indicator for the stream.
Definition: readfile.cpp:114
Origin
The position a seeking offset takes as a base.
Definition: readstream.h:268
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
bool open(const UString &fileName)
Try to open the file with the given fileName.
Definition: readfile.cpp:61
size_t read(void *dataPtr, size_t dataSize)
Read data from the stream.
Definition: readfile.cpp:134
static std::FILE * openFile(const UString &fileName, FileMode mode)
Open a file with an UTF-8 encoded name.
Definition: platform.cpp:102
static const size_t kSizeInvalid
Definition: readstream.h:69
StackException Exception
Definition: error.h:59
void warning(const char *s,...)
Definition: util.cpp:33
Implementing the stream reading interfaces for files.
Unicode string handling.
std::FILE * _handle
The actual file handle.
Definition: readfile.h:71
size_t size() const
Obtains the total size of the stream, measured in bytes.
Definition: readfile.cpp:110
const Exception kSeekError("Seek error")
Exception when seeking a stream failed.
Definition: error.h:63
bool isOpen() const
Checks if the object opened a file successfully.
Definition: readfile.cpp:92
void close()
Close the file, if open.
Definition: readfile.cpp:84