CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
ZIP.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2023 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "FilePath.hpp"
11
13
21
22#include <chrono>
23
24#if defined(libzip_FOUND)
25
26using zip_t = struct zip;
27
28namespace CeresEngine {
29
30 CE_EXCEPTION_DECL2(ZIPException, IOException);
31
32 class ZIPArchive {
33 public:
36 struct Compression final : public StructEnum<Compression> {
37 enum : UnderlyingType {
39 Default = 0,
40
42 Store,
43
45 BZIP2,
46
48 Deflate,
49
51 XZ,
52
54 ZSTD,
55 } raw;
56
63 UInt32 level = 0;
64
65 CE_STRUCT_ENUM_DECL(Compression);
66 explicit Compression(const decltype(raw) raw, const UInt32 level) : raw(raw), level(level) {}
67
69 [[nodiscard]] bool isCompressionSupported() const noexcept;
70
72 [[nodiscard]] bool isDecompressionSupported() const noexcept;
73 };
74
77 struct Encryption final : public StructEnum<Encryption> {
78 enum : UnderlyingType {
80 None = 0,
81
83 AES128,
84
86 AES192,
87
89 AES256,
90 } raw;
91
92 CE_STRUCT_ENUM_DECL(Encryption);
93 explicit Encryption(const decltype(raw) raw, UInt32 level) : raw(raw) {}
94
96 [[nodiscard]] bool isEncryptionSupported() const noexcept;
97
99 [[nodiscard]] bool isDecryptionSupported() const noexcept;
100 };
101
103 enum class OpenFlag {
105 Create = (1u << 0u),
106
109 Truncate = (1u << 1u),
110
112 ReadOnly = (1u << 2u),
113
116 Strict = (1u << 3u),
117
119 FailIfExists = (1u << 4u),
120
121 Default = 0,
122 };
123
125 using OpenFlags = Flags<OpenFlag>;
126
128 enum class LocateFlag {
132 IgnoreCase = (1u << 0u),
133
136 IgnoreDirectories = (1u << 1u),
137
138 Default = 0,
139 };
140
142 using LocateFlags = Flags<LocateFlag>;
143
146 enum class CreateFlag {
148 Overwrite = (1u << 0u),
149
150 Default = 0,
151 };
152
154 using CreateFlags = Flags<CreateFlag>;
155
158 enum class OpenStreamFlag {
160 Compressed = (1u << 0u),
161
164 OriginalData = (1u << 1u),
165
166 Default = 0,
167 };
168
170 using OpenStreamFlags = Flags<OpenStreamFlag>;
171
173 using ExtraFieldID = UInt16;
174
176 enum class ExtraFieldLocation {
178 Local,
179
181 Central,
182 };
183
184 private:
185 struct Pimpl;
186 UPtr<Pimpl> m;
187
188 public:
189 class Entry {
190 friend class ZIPArchive;
191
192 private:
193 ZIPArchive* mArchive = nullptr;
194 Int64 mIndex = -1;
195
196 public:
197 Entry() = default;
198
199 Entry(const Entry&) = default;
200 Entry& operator=(const Entry&) = default;
201 Entry(Entry&&) noexcept = default;
202 Entry& operator=(Entry&&) noexcept = default;
203
204 private:
205 explicit Entry(ZIPArchive* archive, const UInt32 index) : mArchive(archive), mIndex(index) {}
206
207 public:
209 void remove();
210
212 void setContent(InputStream stream);
213
215 [[nodiscard]] Compression getCompression() const;
216
219 void setCompression(const Compression& compression);
220
222 [[nodiscard]] bool isCompressed() const;
223
225 [[nodiscard]] Encryption getEncryption() const;
226
229 void setEncryption(const Encryption& encryption, const String& password);
230
232 [[nodiscard]] bool isEncrypted();
233
235 [[nodiscard]] UInt64 getCompressedSize() const;
236
238 [[nodiscard]] UInt64 getSize() const;
239
241 [[nodiscard]] FilePath getPath() const;
242
244 void setPath(const FilePath& path);
245
247 [[nodiscard]] StringView getName() const;
248
251 [[nodiscard]] StringView getComment() const;
252
254 void setComment(StringView comment);
255
256 // Gets the last modification time (mtime) for the file in the zip.
257 [[nodiscard]] Date getModificationDate() const;
258
262 void setModificationDate(const Date& modificationDate);
263
264 public: // Entra fields
270 [[nodiscard]] bool hasExtraField(ExtraFieldID id, UInt16 index = 0, ExtraFieldLocation location = ExtraFieldLocation::Local) const;
271
277 [[nodiscard]] MemoryView<const Byte> getExtraField(ExtraFieldID id, UInt16 index = 0, ExtraFieldLocation location = ExtraFieldLocation::Local) const;
278
280 template<typename T> [[nodiscard]] Optional<T> getExtraField(const ExtraFieldID id, const UInt16 index = 0, const ExtraFieldLocation location = ExtraFieldLocation::Local) const {
281 static_assert(std::is_trivially_copyable_v<T>);
282 const MemoryView<const T> memoryView = getExtraField(id, index, location).as<const T>();
283 if(memoryView.empty()) {
284 return {};
285 }
286 return memoryView[0];
287 }
288
290 template<> [[nodiscard]] Optional<String> getExtraField(const ExtraFieldID id, const UInt16 index, const ExtraFieldLocation location) const {
291 const MemoryView<const char> memoryView = getExtraField(id, index, location).as<const char>();
292 if(memoryView.empty()) {
293 return {};
294 }
295 return String(memoryView.data(), memoryView.size());
296 }
297
304 void setExtraField(MemoryView<const Byte> data, ExtraFieldID id, UInt16 index = 0, ExtraFieldLocation location = ExtraFieldLocation::Local);
305
307 template<typename T> void setExtraField(const T& data, const ExtraFieldID id, const UInt16 index = 0, const ExtraFieldLocation location = ExtraFieldLocation::Local) {
308 static_assert(std::is_trivially_copyable_v<T>);
309 setExtraField(make_memory_view(&data, 1).template as<const Byte>(), id, index, location);
310 }
311
313 template<> void setExtraField(const String& data, const ExtraFieldID id, const UInt16 index, const ExtraFieldLocation location) {
314 setExtraField(make_memory_view(data.data(), data.size()).template as<const Byte>(), id, index, location);
315 }
316
321 [[nodiscard]] UInt16 getExtraFieldCount(ExtraFieldID id, ExtraFieldLocation location = ExtraFieldLocation::Local) const;
322
328 void removeExtraField(ExtraFieldID id, UInt16 index = 0, ExtraFieldLocation location = ExtraFieldLocation::Local);
329
330 public:
332 [[nodiscard]] InputStream openInputStream(const OpenStreamFlags& flags = OpenStreamFlag::Default) const;
333
335 [[nodiscard]] InputStream openInputStream(const String& password, const OpenStreamFlags& flags = OpenStreamFlag::Default) const;
336
337 public:
338 explicit operator bool() const { return mArchive != nullptr && mIndex != -1; }
339 };
340
341 public:
345 explicit ZIPArchive(const FilePath& path, const OpenFlags& flags = OpenFlag::Default);
346
350 explicit ZIPArchive(DataStream dataStream, const OpenFlags& flags = OpenFlag::Create);
351
355 explicit ZIPArchive(InputStream inputStream, const OpenFlags& flags = OpenFlag::ReadOnly);
356
359 ~ZIPArchive() noexcept;
360
361 public:
365 [[nodiscard]] Entry locate(const FilePath& path, const LocateFlags& flags = LocateFlag::Default);
366
369 [[nodiscard]] Generator<Entry> entries();
370
372 Entry createDirectory(const FilePath& path, const CreateFlags& flags = CreateFlag::Default);
373
376 Entry createFile(const FilePath& path, InputStream stream, const Compression& compression = Compression::Default,
377 const CreateFlags& flags = CreateFlag::Default);
378
380 [[nodiscard]] StringView getComment() const;
381
384 void setComment(StringView comment);
385
386 public:
389 using ProgressCallbackFunctionView = FunctionView<void(double) const>;
390
392 void commit(ProgressCallbackFunctionView progressCallback = nullptr, double precision = 0.01);
393
395 void rollback();
396
398 void rollback(const Entry& entry);
399
400 public:
402 [[nodiscard]] Pimpl* pimpl() const noexcept { return m.get(); };
403 };
404
405 CE_FLAGS_OPERATORS(ZIPArchive::OpenFlag)
406 CE_FLAGS_OPERATORS(ZIPArchive::LocateFlag)
407 CE_FLAGS_OPERATORS(ZIPArchive::CreateFlag)
408 CE_FLAGS_OPERATORS(ZIPArchive::OpenStreamFlag)
409
410} // namespace CeresEngine
411#endif
#define CE_FLAGS_OPERATORS(Enum)
Defines global operators for a Flags<Enum, Storage> implementation.
Definition Flags.hpp:216
#define CE_EXCEPTION_DECL2(Name, Parent)
Definition Exception.hpp:100
#define CE_STRUCT_ENUM_DECL(T)
Definition StructEnum.hpp:49
Definition Application.hpp:19
TDate< SystemClock, TimeInterval > Date
Represents a point in time.
Definition Chrono.hpp:83
std::uint64_t UInt64
Definition DataTypes.hpp:26
BasicStringView< char > StringView
Narrow string view used for handling narrow encoded text in UTF-8.
Definition String.hpp:190
auto zip(Args &&... args)
Returns an iterable object where all argument iterators are traversed simultaneously.
Definition Iterator.hpp:369
@ Store
Stores the outcome in the respective render target attachment.
std::uint16_t UInt16
Definition DataTypes.hpp:20
std::int64_t Int64
Definition DataTypes.hpp:24
MemoryView< T > make_memory_view(T *ptr, size_t size)
Makes a new memory from a raw pointer and length.
Definition MemoryView.hpp:359
@ Create
Creates the file if it doesn't exist.
@ Compressed
If set, the texture is compressed on the GPU.
std::uint32_t UInt32
Definition DataTypes.hpp:23
BasicString< char > String
Narrow string used for handling narrow encoded text in UTF-8.
Definition String.hpp:163
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25