aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-03-29 22:59:04 +0300
committerAqua-sama <aqua@iserlohn-fortress.net>2020-03-29 22:59:04 +0300
commit13771971cfaef6356ba47668cae6ce25c5c2071f (patch)
treef2706c35edb06cbf43fc18a7c30608dfea67587f /lib
parentChange rcc command line (diff)
downloadrcc-13771971cfaef6356ba47668cae6ce25c5c2071f.tar.xz
Drop dependency on serge-sans-paille/frozen
format: - instead of frozen::unordered_map, create two std::arrays with the aliased names (entries) and respective data (values) libembed: - Resources and CompressedResources convenience classes for raw and compressed resources respectively - Resources can be constexpr in regular usage - Annotate Resources::decompress accordingly
Diffstat (limited to 'lib')
-rw-r--r--lib/compressionctx.h40
-rw-r--r--lib/embed.cpp17
-rw-r--r--lib/embed.h91
-rw-r--r--lib/zstd.cpp (renamed from lib/embed_zstd.cpp)15
4 files changed, 121 insertions, 42 deletions
diff --git a/lib/compressionctx.h b/lib/compressionctx.h
new file mode 100644
index 0000000..2f3946a
--- /dev/null
+++ b/lib/compressionctx.h
@@ -0,0 +1,40 @@
+#include <span>
+#include <vector>
+
+#pragma once
+
+namespace embed
+{
+
+enum Compression {
+ None,
+ Zstd
+};
+
+class CompressionCtx
+{
+public:
+ virtual ~CompressionCtx() = default;
+ [[nodiscard]] virtual std::vector<uint8_t> decompress(const std::span<const uint8_t> &entry) const = 0;
+};
+
+class ZstdCompressionCtx final : public CompressionCtx
+{
+public:
+ ZstdCompressionCtx(const std::span<const uint8_t> &dictionary);
+ ~ZstdCompressionCtx();
+ [[nodiscard]] std::vector<uint8_t> decompress(const std::span<const uint8_t> &entry) const override;
+};
+
+std::unique_ptr<CompressionCtx> make_compression_ctx(const Compression algo, const std::span<const uint8_t> &dict)
+{
+ switch(algo)
+ {
+ case None:
+ return nullptr;
+ case Zstd:
+ return std::make_unique<ZstdCompressionCtx>(dict);
+ }
+}
+
+} // namespace embed
diff --git a/lib/embed.cpp b/lib/embed.cpp
deleted file mode 100644
index 07af38f..0000000
--- a/lib/embed.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "embed.h"
-
-using namespace embed;
-
-template <>
-Resources<Compression::None>::Resources(const std::span<const unsigned char> &)
-{
-}
-
-template <>
-Resources<Compression::None>::~Resources() = default;
-
-template <>
-[[nodiscard]] std::vector<unsigned char> Resources<Compression::None>::decompress(const std::span<const unsigned char> &entry)
-{
- return { entry.begin(), entry.end() };
-}
diff --git a/lib/embed.h b/lib/embed.h
index bd041ff..b57d830 100644
--- a/lib/embed.h
+++ b/lib/embed.h
@@ -1,29 +1,88 @@
#pragma once
-#include <frozen/string.h>
-#include <frozen/unordered_map.h>
-#include <span>
-#include <vector>
+#include <array>
+#include <string_view>
+#include "compressionctx.h"
namespace embed
{
-enum Compression {
- None,
- Zstd
-};
-
-template <Compression c>
+template <std::size_t N>
class Resources
{
public:
- Resources() = default;
- explicit Resources(const std::span<const unsigned char> &dictionary);
+ constexpr explicit Resources(
+ const std::array<const char *, N> &entries,
+ const std::array<std::span<const uint8_t>, N> &values)
+ : m_entries(entries)
+ , m_values(values)
+ {
+ }
- ~Resources();
+ [[nodiscard]] constexpr int id(const std::string_view &path) const
+ {
+ for(std::size_t i = 0; i < m_entries.size(); ++i) {
+ if(m_entries.at(i) == path)
+ return i;
+ }
+ return -1;
+ }
+ [[nodiscard]] constexpr std::span<const uint8_t> value(const int id_) const
+ {
+ if(id_ == -1)
+ return {};
+ else
+ return m_values.at(id_);
+ }
+ [[nodiscard]] constexpr std::span<const uint8_t> value(const std::string_view &path) const
+ {
+ return value(id(path));
+ }
- [[nodiscard]] std::vector<unsigned char> decompress(const std::span<const unsigned char> &entry);
+ [[deprecated("With no compression, this function returns a copy; use ::value instead")]]
+ [[nodiscard]] std::vector<uint8_t> decompress(const int id_) const
+ {
+ const auto v = value(id_);
+ return { v.begin(), v.end() };
+ }
+ [[deprecated("With no compression, this function returns a copy; use ::value instead")]]
+ [[nodiscard]] std::vector<uint8_t> decompress(const std::string_view &path) const
+ {
+ const auto v = value(path);
+ return { v.begin(), v.end() };
+ }
-}; // class
+protected:
+ const std::array<const char *, N> m_entries;
+ const std::array<std::span<const uint8_t>, N> m_values;
+};
+
+template <std::size_t N>
+class CompressedResources final : public Resources<N>
+{
+public:
+ explicit CompressedResources(
+ const std::array<const char *, N> &entries,
+ const std::array<std::span<const uint8_t>, N> &values,
+ const Compression algo,
+ const std::span<const uint8_t> &dictionary = {})
+ : Resources<N>(entries, values)
+ , m_compression(make_compression_ctx(algo, dictionary))
+ {
+ }
+ ~CompressedResources() = default;
+
+ [[nodiscard]] std::vector<uint8_t> decompress(const int id_) const
+ {
+ return m_compression->decompress(Resources<N>::value(id_));
+ }
+ [[nodiscard]] std::vector<uint8_t> decompress(const std::string_view &path) const
+ {
+ return m_compression->decompress(Resources<N>::value(path));
+ }
+
+protected:
+ const std::unique_ptr<CompressionCtx> m_compression;
+};
-}
+} // namespace embed
diff --git a/lib/embed_zstd.cpp b/lib/zstd.cpp
index d9be35a..d2c27bc 100644
--- a/lib/embed_zstd.cpp
+++ b/lib/zstd.cpp
@@ -1,4 +1,4 @@
-#include "embed.h"
+#include "compressionctx.h"
#include <cassert>
#include <zstd.h>
@@ -6,24 +6,22 @@ using namespace embed;
ZSTD_DDict *dictPtr = nullptr;
-template <>
-Resources<Compression::Zstd>::Resources(const std::span<const unsigned char> &dictionary)
+ZstdCompressionCtx::ZstdCompressionCtx(const std::span<const uint8_t> &dictionary)
{
if(!dictionary.empty()) {
dictPtr = ZSTD_createDDict(dictionary.data(), dictionary.size());
}
}
-template <>
-Resources<Compression::Zstd>::~Resources()
+ZstdCompressionCtx::~ZstdCompressionCtx()
{
if(dictPtr != nullptr) {
ZSTD_freeDDict(dictPtr);
}
}
-template <>
-[[nodiscard]] std::vector<unsigned char> Resources<Compression::Zstd>::decompress(const std::span<const unsigned char> &entry)
+[[nodiscard]]
+std::vector<uint8_t> ZstdCompressionCtx::decompress(const std::span<const uint8_t> &entry) const
{
/* Read the content size from the frame header. For simplicity we require
* that it is always present. By default, zstd will write the content size
@@ -34,8 +32,7 @@ template <>
unsigned long long const rSize = ZSTD_getFrameContentSize(entry.data(), entry.size());
assert(rSize != ZSTD_CONTENTSIZE_ERROR); //, "%s: not compressed by zstd!", fname);
assert(rSize != ZSTD_CONTENTSIZE_UNKNOWN); //, "%s: original size unknown!", fname);
- //data<unsigned char> rBuff(new unsigned char[rSize], rSize, true);
- std::vector<unsigned char> rBuff(rSize);
+ std::vector<uint8_t> rBuff(rSize);
/* Check that the dictionary ID matches.
* If a non-zstd dictionary is used, then both will be zero.