nlib
Base64.h
[詳解]
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
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:99
CharOption
Base64の62番目と63番目の文字のバリエーションを指定できます。
Definition: Base64.h:142
62番目の文字に&#39;-&#39;、63番目の文字に&#39;_&#39;を指定します。
Definition: Base64.h:145
62番目の文字に&#39;.&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:33
std::pair< errno_t, size_t > StepDecode(nlib_byte_t(&dst)[N], const char *src, size_t srcsize) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:246
Base64のデコードを行います。Base64の各種変形版をサポートします。
Definition: Base64.h:140
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:183
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
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
データを一括してデコードし、内部でメモリを割り当てて返します。
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
データを一括してエンコードします。
Definition: Base64.h:61
static errno_t Decode(UniquePtr< uint8_t[]> &dst, size_t *dstsize, const char *src, CharOption char_option=kBase64Default) noexcept
データを一括してデコードします。
Definition: Base64.h:184
std::pair< errno_t, size_t > Close(char(&dst)[N], bool padding) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:128
std::pair< errno_t, size_t > StepEncode(char *dst, size_t dstsize, const void *src, size_t srcsize) noexcept
Base64の分割エンコードを行います。末尾にヌル文字は追加されません。エラー値とdstに書き込まれたバイト数...
Definition: Base64.h:103
62番目の文字に&#39;.&#39;、63番目の文字に&#39;_&#39;を指定します。
Definition: Base64.h:149
62番目の文字に&#39;!&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:150
C++11環境(エイリアステンプレートが可能な環境)においてはstd::unique_ptrにエイリアステンプレートされま...
Definition: UniquePtr.h:108
std::unique_ptrに相当するクラスが定義されています。
62番目の文字に&#39;_&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:148
CharOption
Base64の62番目と63番目の文字のバリエーションを指定できます。
Definition: Base64.h:29
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:87
errno_t StepDecode(size_t *written, nlib_byte_t(&dst)[N], const char *src, size_t srcsize) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:234
errno_t Close(size_t *written, char(&dst)[N], bool padding) noexcept
上記関数のテンプレートオーバーロードです。
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
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:177
Base64のエンコードを行います。Base64の各種変形版をサポートします。
Definition: Base64.h:27
62番目の文字に&#39;.&#39;、63番目の文字に&#39;_&#39;を指定します。
Definition: Base64.h:36
errno_t Close(size_t *written, nlib_byte_t(&dst)[N]) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:251
62番目の文字に&#39;_&#39;、63番目の文字に&#39;:&#39;を指定します。
Definition: Base64.h:147
static errno_t Decode(size_t *written, nlib_byte_t(&dst)[N], const char *src, CharOption char_option=kBase64Default) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:164
std::pair< errno_t, size_t > Close(void *dst, size_t dstsize) noexcept
Base64の分割デコードを終了します。エラー値とdstに書き込まれたバイト数のペアを返します。 ...
Definition: Base64.h:254
62番目の文字に&#39;.&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:146
std::pair< errno_t, size_t > StepEncode(char(&dst)[N], const void *src, size_t srcsize) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:110
62番目の文字に&#39;-&#39;、63番目の文字に&#39;_&#39;を指定します。
Definition: Base64.h:32
62番目の文字に&#39;_&#39;、63番目の文字に&#39;:&#39;を指定します。
Definition: Base64.h:34
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Config.h:109
static size_t GetRequiredSize(size_t srcsize) noexcept
データのデコードに必要な領域のサイズを計算します。
Definition: Base64.h:157
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
Definition: Config.h:111
static errno_t Decode(size_t *written, void *dst, size_t dstsize, const char *src, CharOption char_option=kBase64Default) noexcept
データを一括してデコードします。
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
データを一括でエンコードし、内部でメモリを割り当てて返します。
Definition: Base64.h:77
62番目の文字に&#39;+&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:31
size_t nlib_strlen(const char *s)
内部でstrlen()を呼び出します。独自の実装が動作する場合もあります。
static std::pair< errno_t, size_t > Decode(void *dst, size_t dstsize, const char *src, CharOption char_option=kBase64Default) noexcept
データを一括してデコードします。エラー値と出力されたデータサイズのペアを返します。 ...
Definition: Base64.h:169
62番目の文字に&#39;_&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:35
62番目の文字に&#39;!&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:37
62番目の文字に&#39;+&#39;、63番目の文字に&#39;-&#39;を指定します。
Definition: Base64.h:144
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
Definition: Config.h:250
unsigned char nlib_byte_t
C++17以降でstd::byteにtypedefされる型です。
Definition: Platform.h:314
constexpr Base64Decoder() noexcept
デフォルトコンストラクタです。
Definition: Base64.h:227
std::pair< errno_t, size_t > Close(nlib_byte_t(&dst)[N]) noexcept
上記関数のテンプレートオーバーロードです。
Definition: Base64.h:260
#define NLIB_NONNULL
全ての引数にNULLを指定することができないことを示します。
static size_t GetRequiredSize(size_t srcsize) noexcept
データのエンコードに必要な領域のサイズを計算します。
Definition: Base64.h:44
constexpr Base64Encoder() noexcept
デフォルトコンストラクタです。
Definition: Base64.h:90
std::pair< errno_t, size_t > StepDecode(void *dst, size_t dstsize, const char *src, size_t srcsize) noexcept
Base64の分割デコードを行います。エラー値とdstに書き込まれたバイト数のペアを返します。 ...
Definition: Base64.h:239
std::pair< errno_t, size_t > Close(char *dst, size_t dstsize, bool padding) noexcept
Base64の分割エンコードを終了します。末端にヌル文字は追加されません。エラー値とdstに書き込まれたバイト...
Definition: Base64.h:122
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:37