File: compression.cpp

package info (click to toggle)
openmw 0.50.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 37,076 kB
  • sloc: cpp: 380,958; xml: 2,192; sh: 1,449; python: 911; makefile: 26; javascript: 5
file content (43 lines) | stat: -rw-r--r-- 1,823 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "compression.hpp"

#include <lz4.h>

#include <cstddef>
#include <cstring>
#include <stdexcept>
#include <string>
#include <vector>

namespace Misc
{
    std::vector<std::byte> compress(const std::vector<std::byte>& data)
    {
        const std::size_t originalSize = data.size();
        std::vector<std::byte> result(
            static_cast<std::size_t>(LZ4_compressBound(static_cast<int>(originalSize)) + sizeof(originalSize)));
        const int size = LZ4_compress_default(reinterpret_cast<const char*>(data.data()),
            reinterpret_cast<char*>(result.data()) + sizeof(originalSize), static_cast<int>(data.size()),
            static_cast<int>(result.size() - sizeof(originalSize)));
        if (size == 0)
            throw std::runtime_error("Failed to compress");
        std::memcpy(result.data(), &originalSize, sizeof(originalSize));
        result.resize(static_cast<std::size_t>(size) + sizeof(originalSize));
        return result;
    }

    std::vector<std::byte> decompress(const std::vector<std::byte>& data)
    {
        std::size_t originalSize;
        std::memcpy(&originalSize, data.data(), sizeof(originalSize));
        std::vector<std::byte> result(originalSize);
        const int size = LZ4_decompress_safe(reinterpret_cast<const char*>(data.data()) + sizeof(originalSize),
            reinterpret_cast<char*>(result.data()), static_cast<int>(data.size() - sizeof(originalSize)),
            static_cast<int>(result.size()));
        if (size < 0)
            throw std::runtime_error("Failed to decompress");
        if (originalSize != static_cast<std::size_t>(size))
            throw std::runtime_error("Size of decompressed data (" + std::to_string(size) + ") doesn't match stored ("
                + std::to_string(originalSize) + ")");
        return result;
    }
}