Antkeeper  0.0.1
physfs-deserialize-context.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
22 
24 {
25  // Open file for reading using PhysicsFS
26  m_file = PHYSFS_openRead(path.string().c_str());
27  if (!m_file)
28  {
29  throw deserialize_error(PHYSFS_getLastError());
30  }
31 
32  // Store file path
33  m_path = path;
34 
35  // Set EOF and error flags if file not open.
36  m_eof = !m_file;
37  m_error = !m_file;
38 }
39 
41 {
42  if (m_file)
43  {
44  PHYSFS_close(m_file);
45  }
46 }
47 
48 void physfs_deserialize_context::open(const std::filesystem::path& path)
49 {
50  // Close file, if open
51  if (m_file)
52  {
53  PHYSFS_close(m_file);
54  }
55 
56  // Open file for reading using PhysicsFS
57  m_file = PHYSFS_openRead(path.string().c_str());
58  if (!m_file)
59  {
60  throw deserialize_error(PHYSFS_getLastError());
61  }
62 
63  // Store file path
64  m_path = path;
65 
66  // Set EOF and error flags if file not open.
67  m_eof = !m_file;
68  m_error = !m_file;
69 }
70 
72 {
73  if (m_file)
74  {
75  m_error = !PHYSFS_close(m_file);
76  m_file = nullptr;
77  m_path.clear();
78  m_eof = true;
79  }
80 }
81 
83 {
84  return m_file;
85 }
86 
87 const std::filesystem::path& physfs_deserialize_context::path() const noexcept
88 {
89  return m_path;
90 }
91 
92 bool physfs_deserialize_context::error() const noexcept
93 {
94  return m_error;
95 }
96 
97 bool physfs_deserialize_context::eof() const noexcept
98 {
99  return m_eof;
100 }
101 
102 std::size_t physfs_deserialize_context::size() const noexcept
103 {
104  const PHYSFS_sint64 length = PHYSFS_fileLength(m_file);
105  if (length >= 0)
106  {
107  return static_cast<std::size_t>(length);
108  }
109 
110  return 0;
111 };
112 
114 {
115  const PHYSFS_sint64 offset = PHYSFS_tell(m_file);
116  if (offset < 0)
117  {
118  // m_error = true;
119  throw deserialize_error(PHYSFS_getLastError());
120  }
121 
122  return static_cast<std::size_t>(offset);
123 }
124 
126 {
127  if (!PHYSFS_seek(m_file, static_cast<PHYSFS_uint64>(offset)))
128  {
129  m_error = true;
130  throw deserialize_error(PHYSFS_getLastError());
131  }
132 
133  m_eof = (PHYSFS_eof(m_file) != 0);
134 }
135 
136 std::size_t physfs_deserialize_context::read8(std::byte* data, std::size_t count)
137 {
138  const PHYSFS_sint64 status = PHYSFS_readBytes(m_file, data, count);
139 
140  if (status != count)
141  {
142  if (status < 0 || !PHYSFS_eof(m_file))
143  {
144  m_error = true;
145  throw deserialize_error(PHYSFS_getLastError());
146  }
147 
148  m_eof = true;
149 
150  return static_cast<std::size_t>(status);
151  }
152  else
153  {
154  return count;
155  }
156 }
157 
158 std::size_t physfs_deserialize_context::read16_le(std::byte* data, std::size_t count)
159 {
160  PHYSFS_uint16* data16 = reinterpret_cast<PHYSFS_uint16*>(data);
161 
162  for (std::size_t i = 0; i < count; ++i)
163  {
164  if (!PHYSFS_readULE16(m_file, data16))
165  {
166  m_error = true;
167  m_eof = (PHYSFS_eof(m_file) != 0);
168  throw deserialize_error(PHYSFS_getLastError());
169  }
170 
171  ++data16;
172  }
173 
174  return count;
175 }
176 
177 std::size_t physfs_deserialize_context::read16_be(std::byte* data, std::size_t count)
178 {
179  PHYSFS_uint16* data16 = reinterpret_cast<PHYSFS_uint16*>(data);
180 
181  for (std::size_t i = 0; i < count; ++i)
182  {
183  if (!PHYSFS_readUBE16(m_file, data16))
184  {
185  m_error = true;
186  m_eof = (PHYSFS_eof(m_file) != 0);
187  throw deserialize_error(PHYSFS_getLastError());
188  }
189 
190  ++data16;
191  }
192 
193  return count;
194 }
195 
196 std::size_t physfs_deserialize_context::read32_le(std::byte* data, std::size_t count)
197 {
198  PHYSFS_uint32* data32 = reinterpret_cast<PHYSFS_uint32*>(data);
199 
200  for (std::size_t i = 0; i < count; ++i)
201  {
202  if (!PHYSFS_readULE32(m_file, data32))
203  {
204  m_error = true;
205  m_eof = (PHYSFS_eof(m_file) != 0);
206  throw deserialize_error(PHYSFS_getLastError());
207  }
208 
209  ++data32;
210  }
211 
212  return count;
213 }
214 
215 std::size_t physfs_deserialize_context::read32_be(std::byte* data, std::size_t count)
216 {
217  PHYSFS_uint32* data32 = reinterpret_cast<PHYSFS_uint32*>(data);
218 
219  for (std::size_t i = 0; i < count; ++i)
220  {
221  if (!PHYSFS_readUBE32(m_file, data32))
222  {
223  m_error = true;
224  m_eof = (PHYSFS_eof(m_file) != 0);
225  throw deserialize_error(PHYSFS_getLastError());
226  }
227 
228  ++data32;
229  }
230 
231  return count;
232 }
233 
234 std::size_t physfs_deserialize_context::read64_le(std::byte* data, std::size_t count)
235 {
236  PHYSFS_uint64* data64 = reinterpret_cast<PHYSFS_uint64*>(data);
237 
238  for (std::size_t i = 0; i < count; ++i)
239  {
240  if (!PHYSFS_readULE64(m_file, data64))
241  {
242  m_error = true;
243  m_eof = (PHYSFS_eof(m_file) != 0);
244  throw deserialize_error(PHYSFS_getLastError());
245  }
246 
247  ++data64;
248  }
249 
250  return count;
251 }
252 
253 std::size_t physfs_deserialize_context::read64_be(std::byte* data, std::size_t count)
254 {
255  PHYSFS_uint64* data64 = reinterpret_cast<PHYSFS_uint64*>(data);
256 
257  for (std::size_t i = 0; i < count; ++i)
258  {
259  if (!PHYSFS_readUBE64(m_file, data64))
260  {
261  m_error = true;
262  m_eof = (PHYSFS_eof(m_file) != 0);
263  throw deserialize_error(PHYSFS_getLastError());
264  }
265 
266  ++data64;
267  }
268 
269  return count;
270 }
An exception of this type is thrown when an error occurs during deserialization.
physfs_deserialize_context() noexcept=default
Constructs a PhysicsFS deserialize context.
std::size_t read16_be(std::byte *data, std::size_t count) noexcept(false) override
Reads 16-bit (word) big-endian data.
void close() noexcept
Closes the associated file using PhysicsFS.
std::size_t read32_be(std::byte *data, std::size_t count) noexcept(false) override
Reads 32-bit (double word) big-endian data.
void open(const std::filesystem::path &path) noexcept(false)
Opens a file using PhysicsFS and associates it with the deserialize context.
const std::filesystem::path & path() const noexcept override
Returns the path associated with this deserialize context.
void seek(std::size_t offset) override
Seeks to a position in the file.
std::size_t tell() const override
Returns the offsets from the start of the file to the current position, in bytes.
std::size_t read8(std::byte *data, std::size_t count) noexcept(false) override
Reads 8-bit (byte) data.
std::size_t read32_le(std::byte *data, std::size_t count) noexcept(false) override
Reads 32-bit (double word) little-endian data.
std::size_t read64_le(std::byte *data, std::size_t count) noexcept(false) override
Reads 64-bit (quad word) little-endian data.
bool error() const noexcept override
Returns true if an error occured during a read operation or initialization, false otherwise.
bool eof() const noexcept override
Returns true if the end of a file was reached.
std::size_t size() const noexcept override
Returns the size of the file, in bytes.
std::size_t read16_le(std::byte *data, std::size_t count) noexcept(false) override
Reads 16-bit (word) little-endian data.
std::size_t read64_be(std::byte *data, std::size_t count) noexcept(false) override
Reads 64-bit (quad word) big-endian data.
virtual ~physfs_deserialize_context()
Destructs a PhysicsFS deserialize context, internally closing a file using PhysicsFS.
bool is_open() const noexcept
Returns true if the PhysicsFS file associated with this deserialize context is open,...
status
Behavior tree node return status enumerations.
Definition: status.hpp:28
constexpr int count(T x) noexcept
Returns the number of set bits in a value, known as a population count or Hamming weight.
Definition: bit-math.hpp:211
T length(const quaternion< T > &q)
Calculates the length of a quaternion.
Definition: quaternion.hpp:602
T offset(T longitude)
Calculates the UTC offset at a given longitude.
Definition: utc.hpp:38