Tileson 1.4.0
A helpful json parser for Tiled maps
Loading...
Searching...
No Matches
Base64Decompressor.hpp
Go to the documentation of this file.
1//
2// Created by robin on 29.07.2020.
3// The Base64 decoding logic is heavily based on: https://github.com/ReneNyffenegger/cpp-base64
4//
5
6#ifndef TILESON_BASE64DECOMPRESSOR_HPP
7#define TILESON_BASE64DECOMPRESSOR_HPP
8
9#include "../interfaces/IDecompressor.hpp"
10#include <string>
11
12namespace tson
13{
14 class Base64Decompressor : public IDecompressor<std::string_view, std::string>
15 {
16 public:
17 [[nodiscard]] inline const std::string &name() const override;
18
19 inline std::string decompress(const std::string_view &s) override;
20
21 inline std::string decompressFile(const fs::path &path) override;
22 inline std::string decompress(const void *data, size_t size) override;
23
24 private:
25 inline unsigned int pos_of_char(const unsigned char chr);
26 inline static const std::string NAME = "base64";
27 };
28
29 const std::string &Base64Decompressor::name() const
30 {
31 return NAME;
32 }
33
34 std::string Base64Decompressor::decompress(const std::string_view &s)
35 {
36
37 size_t length_of_string = s.length();
38 if (!length_of_string) return std::string("");
39
40 size_t in_len = length_of_string;
41 size_t pos = 0;
42
43 //
44 // The approximate length (bytes) of the decoded string might be one ore
45 // two bytes smaller, depending on the amount of trailing equal signs
46 // in the encoded string. This approximation is needed to reserve
47 // enough space in the string to be returned.
48 //
49 size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
50 std::string ret;
51 ret.reserve(approx_length_of_decoded_string);
52
53 while (pos < in_len) {
54
55 unsigned int pos_of_char_1 = pos_of_char(s[pos+1] );
56
57 ret.push_back(static_cast<std::string::value_type>( ( (pos_of_char(s[pos+0]) ) << 2 ) + ( (pos_of_char_1 & 0x30 ) >> 4)));
58
59 if (s[pos+2] != '=' && s[pos+2] != '.') { // accept URL-safe base 64 strings, too, so check for '.' also.
60
61 unsigned int pos_of_char_2 = pos_of_char(s[pos+2] );
62 ret.push_back(static_cast<std::string::value_type>( (( pos_of_char_1 & 0x0f) << 4) + (( pos_of_char_2 & 0x3c) >> 2)));
63
64 if (s[pos+3] != '=' && s[pos+3] != '.') {
65 ret.push_back(static_cast<std::string::value_type>( ( (pos_of_char_2 & 0x03 ) << 6 ) + pos_of_char(s[pos+3]) ));
66 }
67 }
68
69 pos += 4;
70 }
71
72 return ret;
73 }
74
75 unsigned int Base64Decompressor::pos_of_char(const unsigned char chr)
76 {
77 //
78 // Return the position of chr within base64_encode()
79 //
80
81 if (chr >= 'A' && chr <= 'Z') return chr - 'A';
82 else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1;
83 else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
84 else if (chr == '+' || chr == '-') return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters (
85 else if (chr == '/' || chr == '_') return 63; // Ditto for '/' and '_'
86
87 throw "If input is correct, this line should never be reached.";
88 }
89
95 std::string Base64Decompressor::decompressFile(const fs::path &)
96 {
97 return std::string();
98 }
99
105 std::string Base64Decompressor::decompress(const void *, size_t)
106 {
107 return std::string();
108 }
109}
110
111
112#endif //TILESON_BASE64DECOMPRESSOR_HPP
Definition Base64Decompressor.hpp:15
std::string decompressFile(const fs::path &path) override
Definition Base64Decompressor.hpp:95
std::string decompress(const std::string_view &s) override
Definition Base64Decompressor.hpp:34
const std::string & name() const override
Definition Base64Decompressor.hpp:29
Definition IDecompressor.hpp:14
Definition Base64.hpp:12