ASPiK SDK
base64codec.h
1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4 
5 #ifndef __base64codec__
6 #define __base64codec__
7 
8 #include "../lib/malloc.h"
9 
10 namespace VSTGUI {
11 
12 //-----------------------------------------------------------------------------
14 {
15 public:
16  struct Result
17  {
18  Malloc<uint8_t> data;
19  uint32_t dataSize {0};
20  };
21 
22  template<typename T>
23  static inline Result decode (const T& base64String)
24  {
25  return decode (base64String.data (), base64String.size ());
26  }
27 
28  template <typename T>
29  static inline Result decode (const T* inBuffer, size_t inBufferSize)
30  {
31  static_assert (sizeof (T) == 1, "T must be one byte type");
32  Result r;
33  r.data.allocate ((inBufferSize * 3 / 4) + 3);
34  uint8_t input1[4];
35  uint8_t input2[4];
36  auto input1Ptr = reinterpret_cast<uint32_t*>(&input1[0]);
37  auto input2Ptr = reinterpret_cast<uint32_t*>(&input2[0]);
38  auto buffer32Ptr = reinterpret_cast<const uint32_t*> (inBuffer);
39  while (inBufferSize > 8)
40  {
41  *input1Ptr = *buffer32Ptr++;
42  *input2Ptr = *buffer32Ptr++;
43  r.dataSize += decodeblock<false> (input1, r.data.get () + r.dataSize);
44  r.dataSize += decodeblock<false> (input2, r.data.get () + r.dataSize);
45  inBufferSize -= 8;
46  }
47  while (inBufferSize > 4)
48  {
49  *input1Ptr = *buffer32Ptr++;
50  r.dataSize += decodeblock<false> (input1, r.data.get () + r.dataSize);
51  inBufferSize -= 4;
52  }
53  if (inBufferSize > 0)
54  {
55  input1[0] = input1[1] = input1[2] = input1[3] = '=';
56  auto ptr = reinterpret_cast<const uint8_t*>(buffer32Ptr);
57  for (uint32_t j = 0; j < inBufferSize; j++)
58  {
59  input1[j] = *ptr++;
60  }
61  r.dataSize += decodeblock<true> (input1, r.data.get () + r.dataSize);
62  }
63  return r;
64  }
65 
66  static inline Result encode (const void* binaryData, size_t binaryDataSize)
67  {
68  Result r;
69  r.data.allocate ((binaryDataSize * 4) / 3 + 4);
70  auto ptr = reinterpret_cast<const uint8_t*> (binaryData);
71  uint8_t input[3];
72  uint32_t i;
73  for (i = 0; i < (binaryDataSize - 3); i += 3)
74  {
75  input[0] = *ptr++;
76  input[1] = *ptr++;
77  input[2] = *ptr++;
78  encodeblock (input, r.data.get () + r.dataSize, 3);
79  r.dataSize += 4;
80  }
81  if (i < binaryDataSize)
82  {
83  input[0] = input[1] = input[2] = 0;
84  uint32_t j;
85  for (j = 0; i < binaryDataSize; i++, j++)
86  {
87  input[j] = *ptr++;
88  }
89  encodeblock (input, r.data.get () + r.dataSize, j);
90  r.dataSize += 4;
91  }
92  return r;
93  }
94 
95 private:
96  template<bool finalBlock = true>
97  static inline uint32_t decodeblock (uint8_t input[4], uint8_t output[3])
98  {
99  static constexpr uint8_t cd64[] = {
100  62, 0xFF, 0xFF, 0xFF, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xFF,
101  0xFF, 0xFF, 0, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
102  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
103  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
104  36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
105 
106  uint32_t result = 3;
107  if (finalBlock)
108  {
109  if (input[2] == '=')
110  result = 1;
111  else if (input[3] == '=')
112  result = 2;
113  }
114  input[0] = cd64[input[0] - 43];
115  input[1] = cd64[input[1] - 43];
116  input[2] = cd64[input[2] - 43];
117  input[3] = cd64[input[3] - 43];
118  output[0] = static_cast<uint8_t> ((input[0] << 2) | ((input[1] & 0x30) >> 4));
119  output[1] = static_cast<uint8_t> (((input[1] & 0xF) << 4) | ((input[2] & 0x3C) >> 2));
120  output[2] = static_cast<uint8_t> (((input[2] & 0x03) << 6) | input[3]);
121  return result;
122  }
123 
124  static inline void encodeblock (uint8_t input[3], uint8_t output[4], uint32_t len)
125  {
126  static constexpr uint8_t cb64[] =
127  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
128 
129  output[0] = cb64[input[0] >> 2];
130  output[1] = cb64[((input[0] & 0x03) << 4) | ((input[1] & 0xf0) >> 4)];
131  output[2] = static_cast<uint8_t>
132  (len > 1 ? cb64[((input[1] & 0x0f) << 2) | ((input[2] & 0xc0) >> 6)] : '=');
133  output[3] = static_cast<uint8_t>(len > 2 ? cb64[input[2] & 0x3f] : '=');
134  }
135 };
136 
137 } // namespace VSTGUI
138 
139 #endif // __base64codec__
Definition: base64codec.h:13
Definition: customcontrols.cpp:8
Definition: base64codec.h:16