aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-03-27 16:58:18 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2020-03-27 16:58:18 +0200
commit9c053ec1b1c7cd91ca6c0cc6f65803cc3f114c7f (patch)
tree70f49e064a00d3abdc0f6da3854a5b237ffc77ef /lib
parentInitial commit (diff)
downloadrcc-9c053ec1b1c7cd91ca6c0cc6f65803cc3f114c7f.tar.xz
Add namespace to format
rcc: - add -n/--namespace to command line - make default compression None - fix None compression not printing hexdumps libembed: - add a zstd decompression test
Diffstat (limited to 'lib')
-rw-r--r--lib/embed.cpp67
-rw-r--r--lib/embed.h29
-rw-r--r--lib/embed_zstd.cpp62
3 files changed, 81 insertions, 77 deletions
diff --git a/lib/embed.cpp b/lib/embed.cpp
index c3b0286..07af38f 100644
--- a/lib/embed.cpp
+++ b/lib/embed.cpp
@@ -1,70 +1,17 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
- * You may select, at your option, one of the above-listed licenses.
- */
-
#include "embed.h"
-#include <zstd.h> // presumes zstd library is installed
-#include <cassert>
using namespace embed;
-ZSTD_DDict* dictPtr = nullptr;
-
-Resources::Resources(const ResourceData &info)
- : m_info(info)
+template <>
+Resources<Compression::None>::Resources(const std::span<const unsigned char> &)
{
- if(!info.dictionary.empty()) {
- dictPtr = ZSTD_createDDict(info.dictionary.data(), info.dictionary.size());
- }
}
-Resources::~Resources()
-{
- if(dictPtr != nullptr) {
- ZSTD_freeDDict(dictPtr);
- }
-}
+template <>
+Resources<Compression::None>::~Resources() = default;
-[[nodiscard]] std::span<unsigned char> Resources::decompress(const std::span<const unsigned char> &entry)
+template <>
+[[nodiscard]] std::vector<unsigned char> Resources<Compression::None>::decompress(const std::span<const unsigned char> &entry)
{
- /* 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
- * in the header when it is known. If you can't guarantee that the frame
- * content size is always written into the header, either use streaming
- * decompression, or ZSTD_decompressBound().
- */
- 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);
- auto* rBuff = new unsigned char[(size_t) rSize];
-
- /* Check that the dictionary ID matches.
- * If a non-zstd dictionary is used, then both will be zero.
- * By default zstd always writes the dictionary ID into the frame.
- * Zstd will check if there is a dictionary ID mismatch as well.
- */
- unsigned const expectedDictID = ZSTD_getDictID_fromDDict(dictPtr);
- unsigned const actualDictID = ZSTD_getDictID_fromFrame(entry.data(), entry.size());
- assert(actualDictID == expectedDictID); //"DictID mismatch: expected %u got %u",
-
- /* Decompress using the dictionary.
- * If you need to control the decompression parameters, then use the
- * advanced API: ZSTD_DCtx_setParameter(), ZSTD_DCtx_refDDict(), and
- * ZSTD_decompressDCtx().
- */
- ZSTD_DCtx* const dctx = ZSTD_createDCtx();
- assert(dctx != NULL); //, "ZSTD_createDCtx() failed!");
- size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, entry.data(), entry.size(), dictPtr);
- /* When zstd knows the content size, it will error if it doesn't match. */
- assert(dSize == rSize); //, "Impossible because zstd will check this condition!");
-
- ZSTD_freeDCtx(dctx);
- return std::span(rBuff, rSize);
+ return { entry.begin(), entry.end() };
}
-
diff --git a/lib/embed.h b/lib/embed.h
index 566b14c..bd041ff 100644
--- a/lib/embed.h
+++ b/lib/embed.h
@@ -1,34 +1,29 @@
#pragma once
-#include <span>
-#include <string>
-#include <unordered_map>
-#include <frozen/unordered_map.h>
#include <frozen/string.h>
+#include <frozen/unordered_map.h>
+#include <span>
+#include <vector>
-namespace embed {
+namespace embed
+{
enum Compression {
None,
Zstd
};
-struct ResourceData {
- Compression compression = None;
- std::span<const unsigned char> dictionary;
-};
-
-class Resources {
+template <Compression c>
+class Resources
+{
public:
- explicit Resources(const ResourceData &info);
+ Resources() = default;
+ explicit Resources(const std::span<const unsigned char> &dictionary);
+
~Resources();
- [[nodiscard]]
- std::span<unsigned char> decompress(const std::span<const unsigned char> &entry);
+ [[nodiscard]] std::vector<unsigned char> decompress(const std::span<const unsigned char> &entry);
-private:
- const ResourceData m_info;
}; // class
}
-
diff --git a/lib/embed_zstd.cpp b/lib/embed_zstd.cpp
new file mode 100644
index 0000000..d9be35a
--- /dev/null
+++ b/lib/embed_zstd.cpp
@@ -0,0 +1,62 @@
+#include "embed.h"
+#include <cassert>
+#include <zstd.h>
+
+using namespace embed;
+
+ZSTD_DDict *dictPtr = nullptr;
+
+template <>
+Resources<Compression::Zstd>::Resources(const std::span<const unsigned char> &dictionary)
+{
+ if(!dictionary.empty()) {
+ dictPtr = ZSTD_createDDict(dictionary.data(), dictionary.size());
+ }
+}
+
+template <>
+Resources<Compression::Zstd>::~Resources()
+{
+ if(dictPtr != nullptr) {
+ ZSTD_freeDDict(dictPtr);
+ }
+}
+
+template <>
+[[nodiscard]] std::vector<unsigned char> Resources<Compression::Zstd>::decompress(const std::span<const unsigned char> &entry)
+{
+ /* 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
+ * in the header when it is known. If you can't guarantee that the frame
+ * content size is always written into the header, either use streaming
+ * decompression, or ZSTD_decompressBound().
+ */
+ 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);
+
+ /* Check that the dictionary ID matches.
+ * If a non-zstd dictionary is used, then both will be zero.
+ * By default zstd always writes the dictionary ID into the frame.
+ * Zstd will check if there is a dictionary ID mismatch as well.
+ */
+ unsigned const expectedDictID = ZSTD_getDictID_fromDDict(dictPtr);
+ unsigned const actualDictID = ZSTD_getDictID_fromFrame(entry.data(), entry.size());
+ assert(actualDictID == expectedDictID); //"DictID mismatch: expected %u got %u",
+
+ /* Decompress using the dictionary.
+ * If you need to control the decompression parameters, then use the
+ * advanced API: ZSTD_DCtx_setParameter(), ZSTD_DCtx_refDDict(), and
+ * ZSTD_decompressDCtx().
+ */
+ ZSTD_DCtx *const dctx = ZSTD_createDCtx();
+ assert(dctx != NULL); //, "ZSTD_createDCtx() failed!");
+ size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff.data(), rSize, entry.data(), entry.size(), dictPtr);
+ /* When zstd knows the content size, it will error if it doesn't match. */
+ assert(dSize == rSize); //, "Impossible because zstd will check this condition!");
+
+ ZSTD_freeDCtx(dctx);
+ return rBuff;
+}