Tileson  1.3.0
A helpful json parser for Tiled maps
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 
12 namespace 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 &path)
96  {
97  return std::string();
98  }
99 
105  std::string Base64Decompressor::decompress(const void *data, size_t size)
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