added functions for base64 en/decoding (replaces patch 1739431)
[wxWidgets.git] / tests / base64 / base64.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/base64/base64.cpp
3 // Purpose: wxBase64Encode/Decode unit test
4 // Author: Charles Reimers
5 // Created: 2007-06-22
6 // RCS-ID: $Id$
7 ///////////////////////////////////////////////////////////////////////////////
8
9 // ----------------------------------------------------------------------------
10 // headers
11 // ----------------------------------------------------------------------------
12
13 #include "testprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif // WX_PRECOMP
22
23 #if wxUSE_BASE64
24
25 #include "wx/base64.h"
26
27 static const char encoded0to255[] =
28 "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj"
29 "JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH"
30 "SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr"
31 "bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P"
32 "kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz"
33 "tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX"
34 "2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7"
35 "/P3+/w==";
36
37 static void
38 generatePatternedData(void* buff, size_t len, unsigned char startVal,
39 unsigned char addVal, unsigned char multVal = 1,
40 unsigned char xorMask = 0, unsigned char andMask = 255)
41 {
42 unsigned char *cbuff = (unsigned char *)buff;
43 unsigned char curval = startVal;
44 while(len--)
45 {
46 *(cbuff++) = curval;
47 curval = (((curval + addVal) * multVal) ^ xorMask) & andMask;
48 }
49 }
50
51 static void generateRandomData(void* buff, size_t len)
52 {
53 unsigned char *cbuff = (unsigned char *)buff;
54 while(len--)
55 {
56 *(cbuff++) = (unsigned char)(((rand() * 255) / RAND_MAX));
57 }
58 }
59
60 static void generateGibberish(void* buff, size_t len)
61 {
62 static const unsigned char cb64[] =
63 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
64
65 unsigned char *cbuff = (unsigned char *)buff;
66 while(len--)
67 {
68 *(cbuff++) = cb64[((rand() * 64) / RAND_MAX)];
69 }
70 }
71
72 // --------------------------------------------------------------------------
73 // test class
74 // --------------------------------------------------------------------------
75
76 class Base64TestCase : public CppUnit::TestCase
77 {
78 public:
79 Base64TestCase() { }
80
81 private:
82 CPPUNIT_TEST_SUITE( Base64TestCase );
83 CPPUNIT_TEST( EncodeDecodeEmpty );
84 CPPUNIT_TEST( EncodeDecodeA );
85 CPPUNIT_TEST( EncodeDecodeAB );
86 CPPUNIT_TEST( EncodeDecodeABC );
87 CPPUNIT_TEST( EncodeDecodeABCD );
88 CPPUNIT_TEST( EncodeDecode0to255 );
89 CPPUNIT_TEST( EncodeDecodePatternA );
90 CPPUNIT_TEST( EncodeDecodePatternB );
91 CPPUNIT_TEST( EncodeDecodePatternC );
92 CPPUNIT_TEST( EncodeDecodeRandom );
93 CPPUNIT_TEST_SUITE_END();
94
95 void EncodeDecodeEmpty();
96 void EncodeDecodeA();
97 void EncodeDecodeAB();
98 void EncodeDecodeABC();
99 void EncodeDecodeABCD();
100 void EncodeDecode0to255();
101 void EncodeDecodePatternA();
102 void EncodeDecodePatternB();
103 void EncodeDecodePatternC();
104 void EncodeDecodeRandom();
105
106 DECLARE_NO_COPY_CLASS(Base64TestCase)
107 };
108
109 // register in the unnamed registry so that these tests are run by default
110 CPPUNIT_TEST_SUITE_REGISTRATION( Base64TestCase );
111
112 // also include in it's own registry so that these tests can be run alone
113 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( Base64TestCase, "Base64TestCase" );
114
115 void Base64TestCase::EncodeDecodeEmpty()
116 {
117 char shouldBeEmpty[10];
118 shouldBeEmpty[0] = '\0';
119 size_t len = 10;
120
121 CPPUNIT_ASSERT(wxBase64Encode(shouldBeEmpty, len, "", 0) != wxCONV_FAILED);
122 CPPUNIT_ASSERT_EQUAL('\0', shouldBeEmpty[0]);
123
124 CPPUNIT_ASSERT(wxBase64Decode(shouldBeEmpty, len, "") != wxCONV_FAILED);
125 CPPUNIT_ASSERT_EQUAL('\0', shouldBeEmpty[0]);
126
127 wxMemoryBuffer bufmt;
128 wxString resultmt = wxBase64Encode(bufmt);
129 CPPUNIT_ASSERT(resultmt.empty());
130
131 bufmt = wxBase64Decode(resultmt);
132 CPPUNIT_ASSERT_EQUAL(0u, bufmt.GetDataLen());
133 }
134
135 void Base64TestCase::EncodeDecodeA()
136 {
137 const wxString str = wxBase64Encode("A", 1);
138 CPPUNIT_ASSERT_EQUAL(wxString("QQ=="), str);
139
140 wxMemoryBuffer buf = wxBase64Decode(str);
141 CPPUNIT_ASSERT_EQUAL(1u, buf.GetDataLen());
142 CPPUNIT_ASSERT_EQUAL('A', *(char *)buf.GetData());
143 }
144
145 void Base64TestCase::EncodeDecodeAB()
146 {
147 const wxString str = wxBase64Encode("AB", 2);
148 CPPUNIT_ASSERT_EQUAL(wxString("QUI="), str);
149
150 wxMemoryBuffer buf = wxBase64Decode(str);
151 CPPUNIT_ASSERT_EQUAL(2u, buf.GetDataLen());
152 CPPUNIT_ASSERT_EQUAL('A', buf[0]);
153 CPPUNIT_ASSERT_EQUAL('B', buf[1]);
154 }
155
156 void Base64TestCase::EncodeDecodeABC()
157 {
158 const wxString str = wxBase64Encode("ABC", 3);
159 CPPUNIT_ASSERT_EQUAL(wxString("QUJD"), str);
160
161 wxMemoryBuffer buf = wxBase64Decode(str);
162 CPPUNIT_ASSERT_EQUAL(3u, buf.GetDataLen());
163 CPPUNIT_ASSERT_EQUAL('A', buf[0]);
164 CPPUNIT_ASSERT_EQUAL('B', buf[1]);
165 CPPUNIT_ASSERT_EQUAL('C', buf[2]);
166 }
167
168 void Base64TestCase::EncodeDecodeABCD()
169 {
170 const wxString str = wxBase64Encode("ABCD", 4);
171 CPPUNIT_ASSERT_EQUAL(wxString("QUJDRA=="), str);
172
173 wxMemoryBuffer buf = wxBase64Decode(str);
174 CPPUNIT_ASSERT_EQUAL(4u, buf.GetDataLen());
175 CPPUNIT_ASSERT_EQUAL('A', buf[0]);
176 CPPUNIT_ASSERT_EQUAL('B', buf[1]);
177 CPPUNIT_ASSERT_EQUAL('C', buf[2]);
178 CPPUNIT_ASSERT_EQUAL('D', buf[3]);
179 }
180
181 void Base64TestCase::EncodeDecode0to255()
182 {
183 unsigned char buff[256];
184 generatePatternedData(buff, 256, 0, 1);
185 wxString str = wxBase64Encode(buff, 256);
186 wxMemoryBuffer mbuff = wxBase64Decode(str);
187 CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
188
189 mbuff = wxBase64Decode(encoded0to255);
190 CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
191 }
192
193 void Base64TestCase::EncodeDecodePatternA()
194 {
195 unsigned char buff[350];
196 generatePatternedData(buff, 350, 24, 5, 3);
197 wxString str = wxBase64Encode(buff, 350);
198 wxMemoryBuffer mbuff = wxBase64Decode(str);
199 CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
200 }
201
202 void Base64TestCase::EncodeDecodePatternB()
203 {
204 unsigned char buff[350];
205 generatePatternedData(buff, 350, 0, 1, 1, 0xAA);
206 wxString str = wxBase64Encode(buff, 350);
207 wxMemoryBuffer mbuff = wxBase64Decode(str);
208 CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
209 }
210
211 void Base64TestCase::EncodeDecodePatternC()
212 {
213 unsigned char buff[11];
214 generatePatternedData(buff, 11, 1, 0, 2);
215 wxString str = wxBase64Encode(buff, 11);
216 wxMemoryBuffer mbuff = wxBase64Decode(str);
217 CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
218 }
219
220 void Base64TestCase::EncodeDecodeRandom()
221 {
222 size_t size = rand() * 3000 / RAND_MAX + 11;
223 unsigned char *buff = new unsigned char[size];
224 generateRandomData(buff, size);
225 wxString str = wxBase64Encode(buff, size);
226 wxMemoryBuffer mbuff = wxBase64Decode(str);
227 CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
228
229 generateGibberish(buff, size);
230 char *buff2 = new char[size];
231 size_t realsize = size;
232 CPPUNIT_ASSERT(wxBase64Decode(buff2, realsize, (char *)buff, size));
233 CPPUNIT_ASSERT(wxBase64Encode(buff2, size, buff2, realsize));
234 }
235
236 #endif // wxUSE_BASE64