TNB Library
TnbBase64Str.h
[詳解]
1#pragma once
11#include "TnbStr.h"
12#include "TnbVector.h"
13
14
15
16//T-TestCaseコードカバレッジDisable
17#pragma comment(user,"T-Coverage Disable")
18
19
20
21//TNB Library
22namespace TNB
23{
24
25
26
41template<typename TYP>
43{
44public:
46 enum{
47 PADDING = 0x10000
48 };
49
50private:
51
52 const TYP* m_lpszResult;
53
54 /*
55 * BASE64文字を数値に変換
56 * @param c BASE64文字。
57 * @retval -1 Base64の文字ではなかった
58 * @retval PADDING パディング文字だった。
59 * @retval 0〜63 BASE64文字だ。
60 */
61 virtual int m_Base64ToInt(TYP c) = 0;
62
63 /*
64 * 数値をBASE64文字に変換
65 * @param i 数値。PADDING か 0〜63。
66 * @retval -1 範囲エラー(ASSERTされます)
67 * @retval 0以上 BASE64文字。
68 */
69 virtual TYP m_IntToBase64(int i) = 0;
70
71 /*
72 * パディングを表すBASE64文字
73 * @retval BASE64文字。
74 */
75 TYP m_PaddingCode(void)
76 {
77 return m_IntToBase64(PADDING);
78 }
79
80 /*
81 * 空白文字をスキップ
82 */
83 const TYP* m_SkipSpace(const TYP* P)
84 {
85 while ( *P == ' ' || *P == '\r' || *P == '\n' || *P == '\t' )
86 {
87 P++;
88 }
89 return P;
90 }
91
92public:
93
95 CAbstractBase64T(void) : m_lpszResult(NULL)
96 {
97 }
98
107 CVectorT<BYTE> Decode(const TYP* lpszBase64)
108 {
109 m_lpszResult = NULL;
110 CByteVector vb;
111 const TYP* P = m_SkipSpace(lpszBase64);
112 INT_PTR iLen = STRLIB::GetLen(P);
113 while ( iLen > 0 )
114 {
115 const TYP* Q = P;
116 if ( iLen < 4 )
117 {
118 if ( 0 <= m_Base64ToInt(*P) )
119 {
120 vb.Invalid();
121 }
122 break;
123 }
124 int r1 = m_Base64ToInt(*P);
125 if ( r1 < 0 )
126 {
127 break; //正常
128 }
129 P = m_SkipSpace(P + 1);
130 int r2 = m_Base64ToInt(*P);
131 P = m_SkipSpace(P + 1);
132 int r3 = m_Base64ToInt(*P);
133 P = m_SkipSpace(P + 1);
134 int r4 = m_Base64ToInt(*P);
135 P = m_SkipSpace(P + 1);
136 if ( r1 >= 0x100 || r2 >= 0x100 || r2 < 0 || r3 < 0 || r4 < 0 )
137 {
138 vb.Invalid();
139 break;
140 }
141 vb.Add(static_cast<BYTE>(((r1<<2)&0xFC) | ((r2>>4)&0x03)));
142 if ( r3 < 0x0100 )
143 {
144 vb.Add(static_cast<BYTE>(((r2<<4)&0xF0) | ((r3>>2)&0x0F)));
145 if ( r4 < 0x0100 )
146 {
147 vb.Add(static_cast<BYTE>(((r3<<6)&0xC0) | ((r4)&0x3F)));
148 }
149 }
150 iLen -= (P-Q);
151 if ( r3 >= 0x0100 || r4 >= 0x0100 )
152 {
153 break;
154 }
155 }
156 m_lpszResult = P;
157 return vb;
158 }
159
169 CAscii DecodeForStr(const TYP* lpszBase64)
170 {
171 CAscii asc;
172 CByteVector vb = Decode(lpszBase64);
173 if ( ! vb.IsEmpty() )
174 {
175 vb.Add(0); //NULL終端追加
176 asc = reinterpret_cast<LPCSTR>(vb.ReferBuffer());
177 }
178 return asc;
179 }
180
186 const TYP* GetDecodeEndPtr(void) const
187 {
188 return m_lpszResult;
189 }
190
197 virtual CStrT<TYP> Encode(size_t size, LPCVOID P)
198 {
199 CStrT<TYP> strRc;
200 const BYTE* B = static_cast<const BYTE*>(P);
201 int r;
202 while ( size > 0 )
203 {
204 if ( size == 1 )
205 {
206 r = B[0]>>2;
207 strRc += m_IntToBase64(r);
208 r = ((B[0]<<4)&0x30);
209 strRc += m_IntToBase64(r);
210 strRc += m_PaddingCode();
211 strRc += m_PaddingCode();
212 break;
213 }
214 else if ( size == 2 )
215 {
216 r = B[0]>>2;
217 strRc += m_IntToBase64(r);
218 r = ((B[0]<<4)&0x30) | ((B[1]>>4)&0x0F);
219 strRc += m_IntToBase64(r);
220 r = ((B[1]<<2)&0x3C);
221 strRc += m_IntToBase64(r);
222 strRc += m_PaddingCode();
223 break;
224 }
225 r = B[0]>>2;
226 strRc += m_IntToBase64(r);
227 r = ((B[0]<<4)&0x30) | ((B[1]>>4)&0x0F);
228 strRc += m_IntToBase64(r);
229 r = ((B[1]<<2)&0x3C) | ((B[2]>>6)&0x03);
230 strRc += m_IntToBase64(r);
231 r = B[2]&0x3F;
232 strRc += m_IntToBase64(r);
233 size -= 3;
234 B += 3;
235 }
236 return strRc;
237 }
238
244 CStrT<TYP> Encode(LPCSTR lpsz)
245 {
246 return Encode(STRLIB::GetLen(lpsz), lpsz);
247 }
248
255 {
256 return Encode(c.GetSize(), c.ReferBuffer());
257 }
258};
259
260
261
273class CBase64Str : public CAbstractBase64T<char>
274{
275 DEFSUPER(CAbstractBase64T<char>);
276
284 virtual int m_Base64ToInt(char c)
285 {
286 int r = -1;
287 if ( 'A' <= c && c <= 'Z' )
288 {
289 r = c - 'A';
290 }
291 else if ( 'a' <= c && c <= 'z' )
292 {
293 r = (c - 'a') +26;
294 }
295 else if ( '0' <= c && c <= '9' )
296 {
297 r = (c - '0') +52;
298 }
299 else if ( '+' == c )
300 {
301 r = 62;
302 }
303 else if ( '/' == c )
304 {
305 r = 63;
306 }
307 else if ( '=' == c )
308 {
309 r = PADDING;
310 }
311 ASSERTLIB(r < 0 || m_IntToBase64(r) == c);
312 return r;
313 }
314
321 virtual char m_IntToBase64(int i)
322 {
323 const char* acAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
324 ASSERTLIB(STRLIB::GetLen(acAlpha) == 64);
325 if ( i == PADDING )
326 {
327 return '=';
328 }
329 else if ( i >= 0 && i < 64 )
330 {
331 return acAlpha[i];
332 }
333 ASSERTLIB(false);
334 return -1;
335 }
336};
337
338
339
352class CDqSaveStr : public CAbstractBase64T<WCHAR>
353{
354 DEFSUPER(CAbstractBase64T<WCHAR>);
355
356 const WCHAR* m_list(void)
357 {
358 return L"あいうえおかきくけこ"
359 L"さしすせそたちつてと"
360 L"なにぬねのはひふへほ"
361 L"まみむめもやゆよらり"
362 L"るれろわがぎぐげござ"
363 L"じずぜぞだぢづでどば"
364 L"びぶべぼ";
365 }
366
374 virtual int m_Base64ToInt(WCHAR c)
375 {
376 const WCHAR* aa = m_list();
377 if ( L'ん' == c )
378 {
379 return PADDING;
380 }
381 loop ( i, 64 )
382 {
383 if ( *aa++ == c )
384 {
385 return static_cast<int>(i);
386 }
387 }
388 return -1;
389 }
390
397 virtual WCHAR m_IntToBase64(int i)
398 {
399 const WCHAR* aa = m_list();
400 ASSERTLIB(STRLIB::GetLen(aa) == 64);
401 if ( i == PADDING )
402 {
403 return L'ん';
404 }
405 else if ( i >= 0 && i < 64 )
406 {
407 return aa[i];
408 }
409 ASSERTLIB(false);
410 return 0xFFFF;
411 }
412public:
413#if 0
420 CUnicode Encode(size_t size, LPCVOID P)
421 {
422 CUnicode r;
423 CUnicode s = _super::Encode(size, P);
424 while ( ! s.IsEmpty() )
425 {
426 r += s.Left(3);
427 s = s.Mid(3);
428 if ( s.IsEmpty() )
429 {
430 break;
431 }
432 r += ' ';
433 r += s.Left(3);
434 s = s.Mid(3);
435 if ( s.IsEmpty() )
436 {
437 break;
438 }
439 r += ' ';
440 r += s.Left(4);
441 s = s.Mid(4);
442 if ( s.IsEmpty() )
443 {
444 break;
445 }
446 r += L"\r\n";
447 }
448 return r;
449 }
450#endif
451};
452
453
454
455}; // TNB
456
457
458
459//T-TestCaseコードカバレッジEnable
460#pragma comment(user,"T-Coverage Enable")
461
462
463
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
文字列管理関係のヘッダ
配列型情報管理関係のヘッダ
BASE64風文字列変換抽象クラス
Definition: TnbBase64Str.h:43
virtual CStrT< TYP > Encode(size_t size, LPCVOID P)
[変換] エンコード
Definition: TnbBase64Str.h:197
CVectorT< BYTE > Decode(const TYP *lpszBase64)
[変換] デコード
Definition: TnbBase64Str.h:107
CStrT< TYP > Encode(LPCSTR lpsz)
[変換] エンコード
Definition: TnbBase64Str.h:244
@ PADDING
パティングコード
Definition: TnbBase64Str.h:47
CAbstractBase64T(void)
コンストラクタ
Definition: TnbBase64Str.h:95
CStrT< TYP > Encode(const ISequenceCollectionT< BYTE > &c)
[変換] エンコード
Definition: TnbBase64Str.h:254
CAscii DecodeForStr(const TYP *lpszBase64)
[変換] デコード
Definition: TnbBase64Str.h:169
const TYP * GetDecodeEndPtr(void) const
[取得] デコード終了アドレス
Definition: TnbBase64Str.h:186
MIME BASE64型文字列変換
Definition: TnbBase64Str.h:274
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
DQ復活の呪文風文字列変換
Definition: TnbBase64Str.h:353
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
CStrT Left(size_t iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:801
CStrT Mid(INDEX iOffset, size_t iSize=INVALID_SIZE) const
[作成] 範囲取得.
Definition: TnbStr.h:766
void Invalid(void)
[操作] 無効状態にする
Definition: TnbVector.h:604
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
Definition: TnbVector.h:664
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
size_t GetLen(LPCSTR lpsz)
[計算] 文字列長計算(ASCII/SJIS用)
Definition: TnbStrLib.h:44
TNB Library
Definition: TnbDoxyTitle.txt:2
bool IsEmpty(void) const
[確認] 要素の有無確認.
virtual const TYP * ReferBuffer(void) const =0
[取得] データアドレス取得.
virtual size_t GetSize(void) const =0
[取得] 要素数取得.