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 __cpp_rvalue_references
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  };
42 
43  public:
44  static size_t GetRequiredSize(size_t srcsize) NLIB_NOEXCEPT {
45  return ((srcsize + 2) / 3) * 4 + 1;
46  }
47  static errno_t
48  Encode(char* dst, size_t dstsize, const void* src, size_t srcsize,
49  CharOption char_option = kBase64Default, bool padding = false) NLIB_NOEXCEPT;
50  template<size_t N>
51  static errno_t
52  Encode(char (&dst)[N], const void* src, size_t srcsize, CharOption char_option = kBase64Default,
53  bool padding = false) NLIB_NOEXCEPT {
54  return Encode(dst, N, src, srcsize, char_option, padding);
55  }
56 
57 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
58  template<class DUMMY = void>
59 #endif
60  static errno_t
61  Encode(UniquePtr<char[]>& dst, const void* src, size_t srcsize,
62  CharOption char_option = kBase64Default, bool padding = false) NLIB_NOEXCEPT {
63  // to avoid crossing the DLL boundary
64  size_t dstsize = GetRequiredSize(srcsize);
65  // do not use UniquePtr to avoid C4714
66  char* p = new (std::nothrow) char[dstsize];
67  if (!p) return ENOMEM;
68  errno_t e = Encode(p, dstsize, src, srcsize, char_option, padding);
69  if (e == 0)
70  dst.reset(p);
71  else
72  delete[] p;
73  return e;
74  }
75 #ifdef __cpp_rvalue_references
76  static std::pair<errno_t, std::unique_ptr<char[]> >
77  Encode(const void* src, size_t srcsize, CharOption char_option = kBase64Default,
78  bool padding = false) NLIB_NOEXCEPT {
79  size_t dstsize = GetRequiredSize(srcsize);
80  char* p = new (std::nothrow) char[dstsize];
81  if (!p) return ::std::make_pair(ENOMEM, nullptr);
82  errno_t e = Encode(p, dstsize, src, srcsize, char_option, padding);
83  if (e == 0) {
84  return ::std::make_pair(0, UniquePtr<char[]>(p));
85  } else {
86  return ::std::make_pair(e, nullptr);
87  }
88  }
89 #endif
90  NLIB_CEXPR Base64Encoder() NLIB_NOEXCEPT : rem_(-1), buf_(), table_() {}
91  errno_t Init(CharOption char_option = kBase64Default) NLIB_NOEXCEPT;
92 
93  // note that dst is NOT null terminated
94  errno_t StepEncode(size_t* written, char* dst, size_t dstsize, const void* src,
95  size_t srcsize) NLIB_NOEXCEPT NLIB_NONNULL;
96  // note that dst is NOT null terminated
97  template<size_t N>
98  errno_t
99  StepEncode(size_t* written, char (&dst)[N], const void* src, size_t srcsize) NLIB_NOEXCEPT {
100  return StepEncode(written, dst, N, src, srcsize);
101  }
102  std::pair<errno_t, size_t>
103  StepEncode(char* dst, size_t dstsize, const void* src, size_t srcsize) NLIB_NOEXCEPT {
104  size_t written;
105  errno_t e = StepEncode(&written, dst, dstsize, src, srcsize);
106  return std::make_pair(e, written);
107  }
108  template<size_t N>
109  std::pair<errno_t, size_t>
110  StepEncode(char (&dst)[N], const void* src, size_t srcsize) NLIB_NOEXCEPT {
111  return StepEncode(&dst[0], N, src, srcsize);
112  }
113 
114  // note that dst is NOT null terminated
115  errno_t
116  Close(size_t* written, char* dst, size_t dstsize, bool padding) NLIB_NOEXCEPT NLIB_NONNULL;
117  // note that dst is NOT null terminated
118  template<size_t N>
119  errno_t Close(size_t* written, char (&dst)[N], bool padding) NLIB_NOEXCEPT {
120  return Close(written, dst, N, padding);
121  }
122  std::pair<errno_t, size_t> Close(char* dst, size_t dstsize, bool padding) NLIB_NOEXCEPT {
123  size_t written;
124  errno_t e = Close(&written, dst, dstsize, padding);
125  return std::make_pair(e, written);
126  }
127  template<size_t N>
128  std::pair<errno_t, size_t> Close(char (&dst)[N], bool padding) NLIB_NOEXCEPT {
129  return Close(dst, N, padding);
130  }
131  NLIB_SAFE_BOOL(Base64Encoder, (rem_ >= 0))
132 
133  private:
134  int rem_;
135  uint8_t buf_[2];
136  char table_[64];
138 };
139 
141  public:
142  enum CharOption {
143  kBase64PlusSlash = 0,
151  kBase64Max,
152  kBase64Default = kBase64PlusSlash,
153  kBase64UrlSafe = kBase64MinusUnderscore
154  };
155 
156  public:
157  static size_t GetRequiredSize(size_t srcsize) NLIB_NOEXCEPT { return ((srcsize + 3) / 4) * 3; }
158  static errno_t Decode(size_t* written, void* dst, size_t dstsize, const char* src,
159  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
160  return Decode_(written, static_cast<nlib_byte_t*>(dst), dstsize, src, nlib_strlen(src),
161  char_option);
162  }
163  template<size_t N>
164  static errno_t Decode(size_t* written, nlib_byte_t (&dst)[N], const char* src,
165  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
166  return Decode_(written, dst, N, src, nlib_strlen(src), char_option);
167  }
168  static std::pair<errno_t, size_t>
169  Decode(void* dst, size_t dstsize, const char* src,
170  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
171  size_t written;
172  errno_t e = Decode(&written, dst, dstsize, src, char_option);
173  return std::make_pair(e, written);
174  }
175  template<size_t N>
176  static std::pair<errno_t, size_t>
177  Decode(nlib_byte_t (&dst)[N], const char* src,
178  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
179  return Decode(dst, N, src, char_option);
180  }
181 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
182  template<class DUMMY = void>
183 #endif
184  static errno_t Decode(UniquePtr<uint8_t[]>& dst, size_t* dstsize, const char* src,
185  CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
186  // to avoid crossing the DLL boundary
187  size_t srcsize = nlib_strlen(src);
188  size_t dstsize_ = GetRequiredSize(srcsize);
189  // do not use UniquePtr to avoid C4714
190  uint8_t* p = new (std::nothrow) uint8_t[dstsize_];
191  if (!p) return ENOMEM;
192  size_t written;
193  errno_t e = Decode_(&written, reinterpret_cast<nlib_byte_t*>(p), dstsize_, src, srcsize,
194  char_option);
195  if (e == 0) {
196  dst.reset(p);
197  *dstsize = written;
198  } else {
199  delete[] p;
200  }
201  return e;
202  }
203 #ifdef __cpp_rvalue_references
204  static std::tuple<errno_t, std::unique_ptr<nlib_byte_t[]>, size_t>
205  Decode(const char* src, CharOption char_option = kBase64Default) NLIB_NOEXCEPT {
206  size_t srcsize = nlib_strlen(src);
207  size_t dstsize = GetRequiredSize(srcsize);
208  nlib_byte_t* p = new (std::nothrow) nlib_byte_t[dstsize];
209  if (!p) return ::std::make_tuple(ENOMEM, nullptr, 0);
210  size_t written;
211  errno_t e = Decode_(&written, p, dstsize, src, srcsize, char_option);
212  if (e == 0) {
213  return ::std::make_tuple(0, UniquePtr<nlib_byte_t[]>(p), written);
214  } else {
215  delete[] p;
216  return ::std::make_tuple(e, nullptr, 0);
217  }
218  }
219 #endif
220  static errno_t
221  DecodeInplace(size_t* written, char* src,
222  CharOption char_option = kBase64Default) NLIB_NOEXCEPT NLIB_NONNULL;
223 
224 #if defined(NLIB_SIMD) && defined(NLIB_LITTLE_ENDIAN)
225  NLIB_CEXPR Base64Decoder() NLIB_NOEXCEPT : rem_(-1), buf_(), c62_(), c63_(), table_() {}
226 #else
227  NLIB_CEXPR Base64Decoder() NLIB_NOEXCEPT : rem_(-1), buf_(), table_() {}
228 #endif
229  errno_t Init(CharOption char_option = kBase64Default) NLIB_NOEXCEPT;
230 
231  errno_t StepDecode(size_t* written, void* dst, size_t dstsize, const char* src,
232  size_t srcsize) NLIB_NOEXCEPT NLIB_NONNULL;
233  template<size_t N>
234  errno_t StepDecode(size_t* written, nlib_byte_t (&dst)[N], const char* src,
235  size_t srcsize) NLIB_NOEXCEPT {
236  return StepDecode(written, dst, N, src, srcsize);
237  }
238  std::pair<errno_t, size_t>
239  StepDecode(void* dst, size_t dstsize, const char* src, size_t srcsize) NLIB_NOEXCEPT {
240  size_t written;
241  errno_t e = StepDecode(&written, dst, dstsize, src, srcsize);
242  return std::make_pair(e, written);
243  }
244  template<size_t N>
245  std::pair<errno_t, size_t>
246  StepDecode(nlib_byte_t (&dst)[N], const char* src, size_t srcsize) NLIB_NOEXCEPT {
247  return StepDecode(dst, N, src, srcsize);
248  }
249  errno_t Close(size_t* written, void* dst, size_t dstsize) NLIB_NOEXCEPT NLIB_NONNULL;
250  template<size_t N>
251  errno_t Close(size_t* written, nlib_byte_t (&dst)[N]) NLIB_NOEXCEPT {
252  return Close(written, dst, N);
253  }
254  std::pair<errno_t, size_t> Close(void* dst, size_t dstsize) NLIB_NOEXCEPT {
255  size_t written;
256  errno_t e = Close(&written, dst, dstsize);
257  return std::make_pair(e, written);
258  }
259  template<size_t N>
260  std::pair<errno_t, size_t> Close(nlib_byte_t (&dst)[N]) NLIB_NOEXCEPT {
261  return Close(&dst[0], N);
262  }
263  NLIB_SAFE_BOOL(Base64Decoder, (rem_ >= 0))
264 
265  private:
266  static errno_t Decode_(size_t* written, nlib_byte_t* dst, size_t dstsize, const char* src,
267  size_t srcsize, CharOption char_option) NLIB_NOEXCEPT NLIB_NONNULL;
268 
269  int rem_;
270  int8_t buf_[4];
271 #if defined(NLIB_SIMD) && defined(NLIB_LITTLE_ENDIAN)
272  char c62_;
273  char c63_;
274 #endif
275  int8_t table_[256];
277 };
278 
279 NLIB_NAMESPACE_END
280 
281 #endif // INCLUDE_NN_NLIB_BASE64_H_
errno_t StepEncode(size_t *written, char(&dst)[N], const void *src, size_t srcsize) noexcept
A template overload of the above function.
Definition: Base64.h:99
CharOption
Variations for the 62nd and 63rd characters in Base64 can be specified.
Definition: Base64.h:142
Specifies &#39;-&#39; for the 62nd character and &#39;_&#39; for the 63rd character.
Definition: Base64.h:145
Specifies &#39;.&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:33
std::pair< errno_t, size_t > StepDecode(nlib_byte_t(&dst)[N], const char *src, size_t srcsize) noexcept
A template overload of the above function.
Definition: Base64.h:246
Decodes Base64. This class supports various variants of Base64.
Definition: Base64.h:140
#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:183
#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:199
static std::tuple< errno_t, std::unique_ptr< nlib_byte_t[]>, size_t > Decode(const char *src, CharOption char_option=kBase64Default) noexcept
Decodes the data at a time and returns them after allocating memory inside.
Definition: Base64.h:205
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:61
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:184
std::pair< errno_t, size_t > Close(char(&dst)[N], bool padding) noexcept
A template overload of the above function.
Definition: Base64.h:128
std::pair< errno_t, size_t > StepEncode(char *dst, size_t dstsize, const void *src, size_t srcsize) noexcept
Runs split encoding of Base64. No null character will be appended to the end. Returns a pair of the e...
Definition: Base64.h:103
Specifies &#39;.&#39; for the 62nd character and &#39;_&#39; for the 63rd character.
Definition: Base64.h:149
Specifies &#39;!&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:150
In the C++11 environment (which supports alias templates), std::unique_ptr is made an alias template...
Definition: UniquePtr.h:108
Defines that class that is corresponding to std::unique_ptr.
Specifies &#39;_&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:148
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:87
errno_t StepDecode(size_t *written, nlib_byte_t(&dst)[N], const char *src, size_t srcsize) noexcept
A template overload of the above function.
Definition: Base64.h:234
errno_t Close(size_t *written, char(&dst)[N], bool padding) noexcept
A template overload of the above function.
Definition: Base64.h:119
static std::pair< errno_t, size_t > Decode(nlib_byte_t(&dst)[N], const char *src, CharOption char_option=kBase64Default) noexcept
A template overload of the above function.
Definition: Base64.h:177
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
A template overload of the above function.
Definition: Base64.h:251
Specifies &#39;_&#39; for the 62nd character and &#39;:&#39; for the 63rd character.
Definition: Base64.h:147
static errno_t Decode(size_t *written, nlib_byte_t(&dst)[N], const char *src, CharOption char_option=kBase64Default) noexcept
A template overload of the above function.
Definition: Base64.h:164
std::pair< errno_t, size_t > Close(void *dst, size_t dstsize) noexcept
Finishes split decoding of Base64. Returns a pair of the error value and the number of bytes written ...
Definition: Base64.h:254
Specifies &#39;.&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:146
std::pair< errno_t, size_t > StepEncode(char(&dst)[N], const void *src, size_t srcsize) noexcept
A template overload of the above function.
Definition: Base64.h:110
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:109
static size_t GetRequiredSize(size_t srcsize) noexcept
Calculates the size of the memory space required for decoding the data.
Definition: Base64.h:157
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
Definition: Config.h:111
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:158
static std::pair< errno_t, std::unique_ptr< char[]> > Encode(const void *src, size_t srcsize, CharOption char_option=kBase64Default, bool padding=false) noexcept
Encodes the data at a time and returns them after allocating memory inside.
Definition: Base64.h:77
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.
static std::pair< errno_t, size_t > Decode(void *dst, size_t dstsize, const char *src, CharOption char_option=kBase64Default) noexcept
Decodes data in batch. Returns a pair of the error value and the output data size.
Definition: Base64.h:169
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
Specifies &#39;+&#39; for the 62nd character and &#39;-&#39; for the 63rd character.
Definition: Base64.h:144
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
Definition: Config.h:250
unsigned char nlib_byte_t
This type will be defined as std::byte in a typedef of C++17 or later.
Definition: Platform.h:314
constexpr Base64Decoder() noexcept
Instantiates the object with default parameters (default constructor).
Definition: Base64.h:227
std::pair< errno_t, size_t > Close(nlib_byte_t(&dst)[N]) noexcept
A template overload of the above function.
Definition: Base64.h:260
#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:44
constexpr Base64Encoder() noexcept
Instantiates the object with default parameters (default constructor).
Definition: Base64.h:90
std::pair< errno_t, size_t > StepDecode(void *dst, size_t dstsize, const char *src, size_t srcsize) noexcept
Runs split decoding of Base64. Returns a pair of the error value and the number of bytes written to d...
Definition: Base64.h:239
std::pair< errno_t, size_t > Close(char *dst, size_t dstsize, bool padding) noexcept
Finishes split encoding of Base64. No null character will be appended to the end. Returns a pair of t...
Definition: Base64.h:122
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37