Antkeeper  0.0.1
physfs-serialize-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 
23 physfs_serialize_context::physfs_serialize_context(const std::filesystem::path& path)
24 {
25  // Open file for writing using PhysicsFS
26  file = PHYSFS_openWrite(path.string().c_str());
27  if (!file)
28  {
29  throw serialize_error(PHYSFS_getLastError());
30  }
31 
32  // Store file path
33  m_path = path;
34 
35  // Set error flag if file not open.
36  m_error = !file;
37 }
38 
40 {
41  if (file)
42  {
43  PHYSFS_close(file);
44  }
45 }
46 
47 void physfs_serialize_context::open(const std::filesystem::path& path)
48 {
49  // Close file, if open
50  if (file)
51  {
52  PHYSFS_close(file);
53  }
54 
55  // Open file for writing using PhysicsFS
56  file = PHYSFS_openWrite(path.string().c_str());
57  if (!file)
58  {
59  throw serialize_error(PHYSFS_getLastError());
60  }
61 
62  // Store file path
63  m_path = path;
64 
65  // Set error flag if file not open.
66  m_error = !file;
67 }
68 
70 {
71  if (file)
72  {
73  m_error = !PHYSFS_close(file);
74  file = nullptr;
75  m_path.clear();
76  }
77 }
78 
79 bool physfs_serialize_context::is_open() const noexcept
80 {
81  return file;
82 }
83 
84 const std::filesystem::path& physfs_serialize_context::path() const noexcept
85 {
86  return m_path;
87 }
88 
89 bool physfs_serialize_context::error() const noexcept
90 {
91  return m_error;
92 }
93 
94 std::size_t physfs_serialize_context::write8(const std::byte* data, std::size_t count)
95 {
96  const PHYSFS_sint64 status = PHYSFS_writeBytes(file, data, count);
97 
98  if (status < 0)
99  {
100  m_error = true;
101  throw serialize_error(PHYSFS_getLastError());
102  //return 0;
103  }
104 
105  if (status != count)
106  {
107  m_error = true;
108  throw serialize_error(PHYSFS_getLastError());
109  //return static_cast<std::size_t>(count);
110  }
111 
112  return count;
113 }
114 
115 std::size_t physfs_serialize_context::write16_le(const std::byte* data, std::size_t count)
116 {
117  const PHYSFS_uint16* data16 = reinterpret_cast<const PHYSFS_uint16*>(data);
118 
119  for (std::size_t i = 0; i < count; ++i)
120  {
121  if (!PHYSFS_writeULE16(file, *data16))
122  {
123  m_error = true;
124  throw serialize_error(PHYSFS_getLastError());
125  //return i;
126  }
127 
128  ++data16;
129  }
130 
131  return count;
132 }
133 
134 std::size_t physfs_serialize_context::write16_be(const std::byte* data, std::size_t count)
135 {
136  const PHYSFS_uint16* data16 = reinterpret_cast<const PHYSFS_uint16*>(data);
137 
138  for (std::size_t i = 0; i < count; ++i)
139  {
140  if (!PHYSFS_writeUBE16(file, *data16))
141  {
142  m_error = true;
143  throw serialize_error(PHYSFS_getLastError());
144  //return i;
145  }
146 
147  ++data16;
148  }
149 
150  return count;
151 }
152 
153 std::size_t physfs_serialize_context::write32_le(const std::byte* data, std::size_t count)
154 {
155  const PHYSFS_uint32* data32 = reinterpret_cast<const PHYSFS_uint32*>(data);
156 
157  for (std::size_t i = 0; i < count; ++i)
158  {
159  if (!PHYSFS_writeULE32(file, *data32))
160  {
161  m_error = true;
162  throw serialize_error(PHYSFS_getLastError());
163  //return i;
164  }
165 
166  ++data32;
167  }
168 
169  return count;
170 }
171 
172 std::size_t physfs_serialize_context::write32_be(const std::byte* data, std::size_t count)
173 {
174  const PHYSFS_uint32* data32 = reinterpret_cast<const PHYSFS_uint32*>(data);
175 
176  for (std::size_t i = 0; i < count; ++i)
177  {
178  if (!PHYSFS_writeUBE32(file, *data32))
179  {
180  m_error = true;
181  throw serialize_error(PHYSFS_getLastError());
182  //return i;
183  }
184 
185  ++data32;
186  }
187 
188  return count;
189 }
190 
191 std::size_t physfs_serialize_context::write64_le(const std::byte* data, std::size_t count)
192 {
193  const PHYSFS_uint64* data64 = reinterpret_cast<const PHYSFS_uint64*>(data);
194 
195  for (std::size_t i = 0; i < count; ++i)
196  {
197  if (!PHYSFS_writeULE64(file, *data64))
198  {
199  m_error = true;
200  throw serialize_error(PHYSFS_getLastError());
201  //return i;
202  }
203 
204  ++data64;
205  }
206 
207  return count;
208 }
209 
210 std::size_t physfs_serialize_context::write64_be(const std::byte* data, std::size_t count)
211 {
212  const PHYSFS_uint64* data64 = reinterpret_cast<const PHYSFS_uint64*>(data);
213 
214  for (std::size_t i = 0; i < count; ++i)
215  {
216  if (!PHYSFS_writeUBE64(file, *data64))
217  {
218  m_error = true;
219  throw serialize_error(PHYSFS_getLastError());
220  //return i;
221  }
222 
223  ++data64;
224  }
225 
226  return count;
227 }
physfs_serialize_context() noexcept=default
Constructs a PhysicsFS serialize context.
std::size_t write8(const std::byte *data, std::size_t count) noexcept(false) override
Writes 8-bit (byte) data.
std::size_t write16_be(const std::byte *data, std::size_t count) noexcept(false) override
Writes 16-bit (word) big-endian data.
std::size_t write32_le(const std::byte *data, std::size_t count) noexcept(false) override
Writes 32-bit (double word) little-endian data.
void close() noexcept
Closes the associated file using PhysicsFS.
std::size_t write64_be(const std::byte *data, std::size_t count) noexcept(false) override
Writes 64-bit (quad word) big-endian data.
std::size_t write64_le(const std::byte *data, std::size_t count) noexcept(false) override
Writes 64-bit (quad word) little-endian data.
bool error() const noexcept override
Returns true if an error occured during a write operation or initialization, false otherwise.
std::size_t write16_le(const std::byte *data, std::size_t count) noexcept(false) override
Writes 16-bit (word) little-endian data.
void open(const std::filesystem::path &path) noexcept(false)
Opens a file using PhysicsFS and associates it with the serialize context.
bool is_open() const noexcept
Returns true if the PhysicsFS file associated with this serialize context is open,...
virtual ~physfs_serialize_context()
Destructs a PhysicsFS serialize context, internally closing a file using PhysicsFS.
const std::filesystem::path & path() const noexcept override
Returns the path associated with this serialize context.
std::size_t write32_be(const std::byte *data, std::size_t count) noexcept(false) override
Writes 32-bit (double word) big-endian data.
An exception of this type is thrown when an error occurs during serialization.
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