nlib
Base64.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_BASE64_H_
17 #define INCLUDE_NN_NLIB_BASE64_H_
18 
19 #include <utility>
20 #include "nn/nlib/UniquePtr.h"
21 #ifdef NLIB_CXX11_STDLIB_TUPLE
22 #include <tuple>
23 #endif
24 
25 NLIB_NAMESPACE_BEGIN
26 
28  public:
29  enum CharOption {
30  kBase64PlusSlash = 0,
38  kBase64Max,
39  kBase64Default = kBase64PlusSlash,
40  kBase64UrlSafe = kBase64MinusUnderscore,
41  BASE64_PLUS_SLASH = kBase64PlusSlash,
42  BASE64_PLUS_MINUS = kBase64PlusMinus,
43  BASE64_MINUS_UNDERSCORE = kBase64MinusUnderscore,
44  BASE64_DOT_MINUS = kBase64DotMinus,
45  BASE64_UNDERSCORE_COLON = kBase64UnderscoreColon,
46  BASE64_UNDERSCORE_MINUS = kBase64UnderscoreMinus,
47  BASE64_DOT_UNDERSCORE = kBase64DotUnderscore,
48  BASE64_EXCLAMATION_MINUS = kBase64ExclamationMinus,
49  _BASE64_MAX = kBase64Max,
50  BASE64_DEFAULT = kBase64PlusSlash,
51  BASE64_URL_SAFE = kBase64MinusUnderscore
52  };
53 
54  public:
55  static size_t GetRequiredSize(size_t srcsize) NLIB_NOEXCEPT {
56  return ((srcsize + 2) / 3) * 4 + 1;
57  }
58  static errno_t
59  Encode(char* dst, size_t dstsize, const void* src, size_t srcsize,
60  CharOption char_option = kBase64Default, bool padding = false) NLIB_NOEXCEPT;
61  template<size_t N>
62  static errno_t
63  Encode(char (&dst)[N], const void* src, size_t srcsize,
64  CharOption char_option = kBase64Default, bool padding = false) NLIB_NOEXCEPT {
65  return Encode(dst, N, src, srcsize, char_option, padding);
66  }
67 
68 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
69  template<class DUMMY = void>
70 #endif
71  static errno_t Encode(UniquePtr<char[]>& dst, // NOLINT
72  const void* src,
73  size_t srcsize,
74  CharOption char_option = kBase64Default,
75  bool padding = false) NLIB_NOEXCEPT {
76  // to avoid crossing the DLL boundary
77  size_t dstsize = GetRequiredSize(srcsize);
78  // do not use UniquePtr to avoid C4714
79  char* p = new (std::nothrow) char[dstsize];
80  if (!p) return ENOMEM;
81  errno_t e = Encode(p, dstsize, src, srcsize, char_option, padding);
82  if (e == 0)
83  dst.reset(p);
84  else
85  delete[] p;
86  return e;
87  }
88 #ifdef __cpp_rvalue_references
89  static ::std::pair<errno_t, UniquePtr<char[]> >
90  Encode(const void* src, size_t srcsize,
91  CharOption char_option = kBase64Default, bool padding = false) NLIB_NOEXCEPT {
92  size_t dstsize = GetRequiredSize(srcsize);
93  char* p = new (std::nothrow) char[dstsize];
94  if (!p) return ::std::make_pair(ENOMEM, nullptr);
95  errno_t e = Encode(p, dstsize, src, srcsize, char_option, padding);
96  if (e == 0) {
97  return ::std::make_pair(0, UniquePtr<char[]>(p));
98  } else {
99  return ::std::make_pair(e, nullptr);
100  }
101  }
102 #endif
103  NLIB_CEXPR Base64Encoder() NLIB_NOEXCEPT : rem_(-1), buf_(), table_() {}
104  errno_t Init(CharOption char_option = kBase64Default) NLIB_NOEXCEPT;
105 
106  // note that dst is NOT null terminated
107  errno_t StepEncode(size_t* written, char* dst, size_t dstsize, const void* src,
108  size_t srcsize) NLIB_NOEXCEPT NLIB_NONNULL;
109  // note that dst is NOT null terminated
110  template<size_t N>
111  errno_t StepEncode(size_t* written, char (&dst)[N], const void* src,
112  size_t srcsize) NLIB_NOEXCEPT {
113  return StepEncode(written, dst, N, src, srcsize);
114  }
115  std::pair<errno_t, size_t>
116  StepEncode(char* dst, size_t dstsize, const void* src, size_t srcsize) NLIB_NOEXCEPT {
117  size_t written;
118  errno_t e = StepEncode(&written, dst, dstsize, src, srcsize);
119  return std::make_pair(e, written);
120  }
121  template<size_t N>
122  std::pair<errno_t, size_t>
123  StepEncode(char (&dst)[N], const void* src, size_t srcsize) NLIB_NOEXCEPT {
124  return StepEncode(&dst[0], N, src, srcsize);
125  }
126 
127  // note that dst is NOT null terminated
128  errno_t Close(size_t* written, char* dst, size_t dstsize,
129  bool padding) NLIB_NOEXCEPT NLIB_NONNULL;
130  // note that dst is NOT null terminated
131  template<size_t N>
132  errno_t Close(size_t* written, char (&dst)[N], bool padding) NLIB_NOEXCEPT {
133  return Close(written, dst, N, padding);
134  }
135  std::pair<errno_t, size_t>
136  Close(char* dst, size_t dstsize, bool padding) NLIB_NOEXCEPT {
137  size_t written;
138  errno_t e = Close(&written, dst, dstsize, padding);
139  return std::make_pair(e, written);
140  }
141  template<size_t N>
142  std::pair<errno_t, size_t>
143  Close(char (&dst)[N], bool padding) NLIB_NOEXCEPT { return Close(dst, N, padding); }
144  NLIB_SAFE_BOOL(Base64Encoder, (rem_ >= 0))
145 
146  private:
147  int rem_;
148  uint8_t buf_[2];
149  char table_[64];
151 };
152 
154  public:
155  enum CharOption {
156  kBase64PlusSlash = 0,
157  kBase64PlusMinus,
158  kBase64MinusUnderscore,
159  kBase64DotMinus,
160  kBase64UnderscoreColon,
161  kBase64UnderscoreMinus,
162  kBase64DotUnderscore,
163  kBase64ExclamationMinus,
164  kBase64Max,
165  kBase64Default = kBase64PlusSlash,
166  kBase64UrlSafe = kBase64MinusUnderscore,
167  BASE64_PLUS_SLASH = kBase64PlusSlash,
168  BASE64_PLUS_MINUS = kBase64PlusMinus,
169  BASE64_MINUS_UNDERSCORE = kBase64MinusUnderscore,
170  BASE64_DOT_MINUS = kBase64DotMinus,
171  BASE64_UNDERSCORE_COLON = kBase64UnderscoreColon,
172  BASE64_UNDERSCORE_MINUS = kBase64UnderscoreMinus,
173  BASE64_DOT_UNDERSCORE = kBase64DotUnderscore,
174  BASE64_EXCLAMATION_MINUS = kBase64ExclamationMinus,
175  _BASE64_MAX = kBase64Max,
176  BASE64_DEFAULT = kBase64PlusSlash,
177  BASE64_URL_SAFE = kBase64MinusUnderscore
178  };
179 
180  public:
181  static size_t GetRequiredSize(size_t srcsize) NLIB_NOEXCEPT {
182  return ((srcsize + 3) / 4) * 3;
183  }
184  static errno_t Decode(size_t* written, void* dst, size_t dstsize, const char* src,
185  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
186  return Decode_(written, static_cast<nlib_byte_t*>(dst), dstsize,
187  src, nlib_strlen(src), char_option);
188  }
189  template<size_t N>
190  static errno_t Decode(size_t* written, nlib_byte_t (&dst)[N], const char* src,
191  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
192  return Decode_(written, dst, N, src, nlib_strlen(src), char_option);
193  }
194  static std::pair<errno_t, size_t>
195  Decode(void* dst, size_t dstsize, const char* src,
196  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
197  size_t written;
198  errno_t e = Decode(&written, dst, dstsize, src, char_option);
199  return std::make_pair(e, written);
200  }
201  template<size_t N>
202  static std::pair<errno_t, size_t>
203  Decode(nlib_byte_t (&dst)[N], const char* src,
204  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
205  return Decode(dst, N, src, char_option);
206  }
207 #if defined(_MSC_VER) || __cplusplus >= 201103L
208  NLIB_DEPRECATED static errno_t
209  Decode(size_t* written, uint8_t* dst, size_t dstsize, const char* src,
210  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
211  return Decode_(written, reinterpret_cast<nlib_byte_t*>(dst),
212  dstsize, src, nlib_strlen(src), char_option);
213  }
214  template<size_t N>
215  NLIB_DEPRECATED static errno_t
216  Decode(size_t* written, uint8_t (&dst)[N], const char* src,
217  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
218  return Decode_(written, reinterpret_cast<nlib_byte_t*>(dst),
219  N, src, nlib_strlen(src), char_option);
220  }
221 #endif
222 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
223  template<class DUMMY = void>
224 #endif
225  static errno_t Decode(UniquePtr<nlib_byte_t[]>& dst, // NOLINT
226  size_t* dstsize, const char* src,
227  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
228  // to avoid crossing the DLL boundary
229  size_t srcsize = nlib_strlen(src);
230  size_t dstsize_ = GetRequiredSize(srcsize);
231  // do not use UniquePtr to avoid C4714
232  nlib_byte_t* p = new (std::nothrow) nlib_byte_t[dstsize_];
233  if (!p) return ENOMEM;
234  size_t written;
235  errno_t e = Decode_(&written, p, dstsize_, src, srcsize, char_option);
236  if (e == 0) {
237  dst.reset(p);
238  *dstsize = written;
239  } else {
240  delete[] p;
241  }
242  return e;
243  }
244 #if defined(_MSC_VER) || __cplusplus >= 201103L
245 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
246  template<class DUMMY = void>
247 #endif
248  static errno_t Decode(UniquePtr<uint8_t[]>& dst, // NOLINT
249  size_t* dstsize, const char* src,
250  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
251  // to avoid crossing the DLL boundary
252  size_t srcsize = nlib_strlen(src);
253  size_t dstsize_ = GetRequiredSize(srcsize);
254  // do not use UniquePtr to avoid C4714
255  uint8_t* p = new (std::nothrow) uint8_t[dstsize_];
256  if (!p) return ENOMEM;
257  size_t written;
258  errno_t e = Decode_(&written, reinterpret_cast<nlib_byte_t*>(p),
259  dstsize_, src, srcsize, char_option);
260  if (e == 0) {
261  dst.reset(p);
262  *dstsize = written;
263  } else {
264  delete[] p;
265  }
266  return e;
267  }
268 #endif
269 #ifdef NLIB_CXX11_STDLIB_TUPLE
270  static ::std::tuple<errno_t, UniquePtr<nlib_byte_t[]>, size_t>
271  Decode(const char* src, CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
272  size_t srcsize = nlib_strlen(src);
273  size_t dstsize = GetRequiredSize(srcsize);
274  nlib_byte_t* p = new (std::nothrow) nlib_byte_t[dstsize];
275  if (!p) return ::std::make_tuple(ENOMEM, nullptr, 0);
276  size_t written;
277  errno_t e = Decode_(&written, p, dstsize, src, srcsize, char_option);
278  if (e == 0) {
279  return ::std::make_tuple(0, UniquePtr<nlib_byte_t[]>(p), dstsize);
280  } else {
281  delete[] p;
282  return ::std::make_tuple(e, nullptr, 0);
283  }
284  }
285 #endif
286  static errno_t DecodeInplace(
287  size_t* written,
288  char* src,
289  CharOption char_option = kBase64Default) NLIB_NOEXCEPT NLIB_NONNULL;
290 
291 #if defined(NLIB_SIMD) && defined(NLIB_LITTLE_ENDIAN)
292  NLIB_CEXPR Base64Decoder() NLIB_NOEXCEPT : rem_(-1), buf_(), c62_(), c63_(), table_() {}
293 #else
294  NLIB_CEXPR Base64Decoder() NLIB_NOEXCEPT : rem_(-1), buf_(), table_() {}
295 #endif
296  errno_t Init(CharOption char_option = kBase64Default) NLIB_NOEXCEPT;
297 
298  errno_t StepDecode(size_t* written, void* dst, size_t dstsize, const char* src,
299  size_t srcsize) NLIB_NOEXCEPT NLIB_NONNULL;
300  template<size_t N>
301  errno_t StepDecode(size_t* written, nlib_byte_t (&dst)[N], const char* src,
302  size_t srcsize) NLIB_NOEXCEPT {
303  return StepDecode(written, dst, N, src, srcsize);
304  }
305  std::pair<errno_t, size_t>
306  StepDecode(void* dst, size_t dstsize, const char* src, size_t srcsize) NLIB_NOEXCEPT {
307  size_t written;
308  errno_t e = StepDecode(&written, dst, dstsize, src, srcsize);
309  return std::make_pair(e, written);
310  }
311  template<size_t N>
312  std::pair<errno_t, size_t>
313  StepDecode(nlib_byte_t (&dst)[N], const char* src, size_t srcsize) NLIB_NOEXCEPT {
314  return StepDecode(dst, N, src, srcsize);
315  }
316 #if defined(_MSC_VER) || __cplusplus >= 201103L
317  template<size_t N>
318  NLIB_DEPRECATED errno_t StepDecode(size_t* written, uint8_t (&dst)[N], const char* src,
319  size_t srcsize) NLIB_NOEXCEPT {
320  return StepDecode(written, static_cast<nlib_byte_t*>(dst), N, src, srcsize);
321  }
322 #endif
323 
324  errno_t Close(size_t* written, void* dst, size_t dstsize) NLIB_NOEXCEPT NLIB_NONNULL;
325  template<size_t N>
326  errno_t Close(size_t* written, nlib_byte_t (&dst)[N]) NLIB_NOEXCEPT {
327  return Close(written, dst, N);
328  }
329  std::pair<errno_t, size_t>
330  Close(void* dst, size_t dstsize) NLIB_NOEXCEPT {
331  size_t written;
332  errno_t e = Close(&written, dst, dstsize);
333  return std::make_pair(e, written);
334  }
335  template<size_t N>
336  std::pair<errno_t, size_t>
337  Close(nlib_byte_t (&dst)[N]) NLIB_NOEXCEPT { return Close(&dst[0], N); }
338 #if defined(_MSC_VER) || __cplusplus >= 201103L
339  template<size_t N>
340  NLIB_DEPRECATED errno_t Close(size_t* written, uint8_t (&dst)[N]) NLIB_NOEXCEPT {
341  return Close(written, reinterpret_cast<nlib_byte_t*>(&dst[0]), N);
342  }
343 #endif
344  NLIB_SAFE_BOOL(Base64Decoder, (rem_ >= 0))
345 
346  private:
347  static errno_t Decode_(size_t* written, nlib_byte_t* dst, size_t dstsize, const char* src,
348  size_t srcsize, CharOption char_option) NLIB_NOEXCEPT NLIB_NONNULL;
349 
350  int rem_;
351  int8_t buf_[4];
352 #if defined(NLIB_SIMD) && defined(NLIB_LITTLE_ENDIAN)
353  char c62_;
354  char c63_;
355 #endif
356  int8_t table_[256];
358 };
359 
360 NLIB_NAMESPACE_END
361 
362 #endif // INCLUDE_NN_NLIB_BASE64_H_
errno_t StepEncode(size_t *written, char(&dst)[N], const void *src, size_t srcsize) noexcept
Runs StepEncode(written, dst, N, src, srcsize).
Definition: Base64.h:111
CharOption
For more information, see Base64Encoder::CharOption.
Definition: Base64.h:155
Specifies &#39;.&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:33
Decodes Base64. This class supports various variants of Base64.
Definition: Base64.h:153
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:179
#define NLIB_SAFE_BOOL(class_name, exp)
Defines a safe operator bool function in the class. Uses the C++11 explicit bool if it is available f...
Definition: Config.h:194
static errno_t Encode(UniquePtr< char[]> &dst, const void *src, size_t srcsize, CharOption char_option=kBase64Default, bool padding=false) noexcept
Encodes data in batch.
Definition: Base64.h:71
static errno_t Decode(UniquePtr< uint8_t[]> &dst, size_t *dstsize, const char *src, CharOption char_option=kBase64Default) noexcept
Decodes data in batch.
Definition: Base64.h:248
static errno_t Encode(char(&dst)[N], const void *src, size_t srcsize, CharOption char_option=kBase64Default, bool padding=false) noexcept
Runs Encode(dst, N, src, srcsize, char_option, padding).
Definition: Base64.h:63
UniquePtr owns the pointer, and when it goes out of scope, the pointer is released by the destructor ...
Definition: UniquePtr.h:109
Defines that class that is corresponding to std::unique_ptr.
#define NLIB_DEPRECATED
Indicates that a function or something has been deprecated.
Definition: Config.h:109
CharOption
Variations for the 62nd and 63rd characters in Base64 can be specified.
Definition: Base64.h:29
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:89
errno_t StepDecode(size_t *written, nlib_byte_t(&dst)[N], const char *src, size_t srcsize) noexcept
Runs StepDecode(written, dst, N, src, srcsize).
Definition: Base64.h:301
errno_t Close(size_t *written, char(&dst)[N], bool padding) noexcept
Runs Base64Encoder::Close(written, dst, N, padding).
Definition: Base64.h:132
Encodes Base64. This class supports various variants of Base64.
Definition: Base64.h:27
Specifies &#39;.&#39; for the 62nd character and &#39;_&#39; for the 63rd character.
Definition: Base64.h:36
errno_t Close(size_t *written, nlib_byte_t(&dst)[N]) noexcept
Runs Close(written, dst, N).
Definition: Base64.h:326
static errno_t Decode(size_t *written, nlib_byte_t(&dst)[N], const char *src, CharOption char_option=kBase64Default) noexcept
Runs Decode(written, dst, N, src, srcsize, char_option).
Definition: Base64.h:190
Specifies &#39;-&#39; for the 62nd character and &#39;_&#39; for the 63rd character.
Definition: Base64.h:32
Specifies &#39;_&#39; for the 62nd character and &#39;:&#39; for the 63rd character.
Definition: Base64.h:34
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:105
static size_t GetRequiredSize(size_t srcsize) noexcept
Calculates the size of the memory space required for decoding the data.
Definition: Base64.h:181
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
Definition: Config.h:107
static errno_t Decode(size_t *written, void *dst, size_t dstsize, const char *src, CharOption char_option=kBase64Default) noexcept
Decodes data in batch.
Definition: Base64.h:184
Specifies &#39;+&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:31
size_t nlib_strlen(const char *s)
Internally calls strlen(). In some cases, it may operate as an independent implementation.
Specifies &#39;_&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:35
Specifies &#39;!&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:37
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
Definition: Config.h:245
unsigned char nlib_byte_t
This type will be defined as std::byte in a typedef of C++17 or later.
Definition: Platform.h:319
constexpr Base64Decoder() noexcept
Instantiates the object with default parameters (default constructor).
Definition: Base64.h:294
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
static size_t GetRequiredSize(size_t srcsize) noexcept
Calculates the size of the memory space required for encoding the data.
Definition: Base64.h:55
constexpr Base64Encoder() noexcept
Instantiates the object with default parameters (default constructor).
Definition: Base64.h:103
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37