Mercurial > projects > hoofbaby
comparison deps/Platinum/ThirdParty/Neptune/Source/Core/NptBase64.cpp @ 0:3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
author | fraserofthenight |
---|---|
date | Mon, 06 Jul 2009 08:06:28 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3425707ddbf6 |
---|---|
1 /***************************************************************** | |
2 | | |
3 | Neptune - Base64 | |
4 | | |
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC. | |
6 | All rights reserved. | |
7 | | |
8 | Redistribution and use in source and binary forms, with or without | |
9 | modification, are permitted provided that the following conditions are met: | |
10 | * Redistributions of source code must retain the above copyright | |
11 | notice, this list of conditions and the following disclaimer. | |
12 | * Redistributions in binary form must reproduce the above copyright | |
13 | notice, this list of conditions and the following disclaimer in the | |
14 | documentation and/or other materials provided with the distribution. | |
15 | * Neither the name of Axiomatic Systems nor the | |
16 | names of its contributors may be used to endorse or promote products | |
17 | derived from this software without specific prior written permission. | |
18 | | |
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY | |
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY | |
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 | | |
30 ****************************************************************/ | |
31 | |
32 /*---------------------------------------------------------------------- | |
33 | includes | |
34 +---------------------------------------------------------------------*/ | |
35 #include "NptBase64.h" | |
36 #include "NptUtils.h" | |
37 #include "NptResults.h" | |
38 | |
39 /*---------------------------------------------------------------------- | |
40 | constants | |
41 +---------------------------------------------------------------------*/ | |
42 static const signed char NPT_Base64_Bytes[128] = { | |
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
44 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
45 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x3E, -1, -1, -1, 0x3F, | |
46 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, -1, -1, -1, 0x7F, -1, -1, | |
47 -1, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, | |
48 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, -1, -1, -1, -1, -1, | |
49 -1, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | |
50 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, -1, -1, -1, -1, -1 | |
51 }; | |
52 | |
53 static const char NPT_Base64_Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
54 const char NPT_BASE64_PAD_CHAR = '='; | |
55 const char NPT_BASE64_PAD_BYTE = 0x7F; | |
56 | |
57 /*---------------------------------------------------------------------- | |
58 | NPT_Base64::Decode | |
59 +---------------------------------------------------------------------*/ | |
60 NPT_Result | |
61 NPT_Base64::Decode(const char* base64, | |
62 NPT_Size size, | |
63 NPT_DataBuffer& data, | |
64 bool url_safe /* = false */) | |
65 { | |
66 // estimate the data size | |
67 data.SetBufferSize(size); | |
68 | |
69 // reset the buffer | |
70 data.SetDataSize(0); | |
71 | |
72 // keep a pointer to the buffer | |
73 unsigned char* buffer = data.UseData(); | |
74 NPT_Size data_size = 0; | |
75 | |
76 // iterate over all characters | |
77 unsigned char codes[4]; | |
78 unsigned int code_count = 0; | |
79 while (size--) { | |
80 unsigned char c = *base64++; | |
81 if (c >= NPT_ARRAY_SIZE(NPT_Base64_Bytes)) continue; | |
82 if (url_safe) { | |
83 // remap some characters | |
84 if (c == '-') { | |
85 c = '+'; | |
86 } else if (c == '_') { | |
87 c = '/'; | |
88 } | |
89 } | |
90 signed char code = NPT_Base64_Bytes[c]; | |
91 if (code >= 0) { | |
92 // valid code | |
93 codes[code_count++] = code; | |
94 if (code_count == 4) { | |
95 // group complete | |
96 if (codes[0] == NPT_BASE64_PAD_BYTE || codes[1] == NPT_BASE64_PAD_BYTE) { | |
97 return NPT_ERROR_INVALID_FORMAT; | |
98 } | |
99 if (codes[2] == NPT_BASE64_PAD_BYTE) { | |
100 // pad at char 3 | |
101 if (codes[3] == NPT_BASE64_PAD_BYTE) { | |
102 // double padding | |
103 unsigned int packed = (codes[0]<<2)|(codes[1]>>4); | |
104 buffer[data_size++] = (unsigned char)packed; | |
105 } else { | |
106 // invalid padding | |
107 return NPT_ERROR_INVALID_FORMAT; | |
108 } | |
109 } else if (codes[3] == NPT_BASE64_PAD_BYTE) { | |
110 // single padding | |
111 unsigned int packed = (codes[0]<<10)|(codes[1]<<4)|(codes[2]>>2); | |
112 buffer[data_size++] = (unsigned char)(packed >> 8); | |
113 buffer[data_size++] = (unsigned char)(packed ); | |
114 } else { | |
115 // no padding | |
116 unsigned int packed = (codes[0]<<18)|(codes[1]<<12)|(codes[2]<<6)|codes[3]; | |
117 buffer[data_size++] = (unsigned char)(packed >> 16); | |
118 buffer[data_size++] = (unsigned char)(packed >> 8); | |
119 buffer[data_size++] = (unsigned char)(packed ); | |
120 } | |
121 code_count = 0; | |
122 } | |
123 } | |
124 } | |
125 | |
126 if (code_count) return NPT_ERROR_INVALID_FORMAT; | |
127 | |
128 // update the data size | |
129 data.SetDataSize(data_size); | |
130 | |
131 return NPT_SUCCESS; | |
132 } | |
133 | |
134 /*---------------------------------------------------------------------- | |
135 | NPT_Base64::Encode | |
136 +---------------------------------------------------------------------*/ | |
137 NPT_Result | |
138 NPT_Base64::Encode(const NPT_Byte* data, | |
139 NPT_Size size, | |
140 NPT_String& base64, | |
141 NPT_Cardinal max_blocks_per_line /* = 0 */, | |
142 bool url_safe /* = false */) | |
143 { | |
144 unsigned int block_count = 0; | |
145 unsigned int i = 0; | |
146 | |
147 // reserve space for the string | |
148 base64.Reserve(4*((size+3)/3) + 2*(max_blocks_per_line?(size/(3*max_blocks_per_line)):0)); | |
149 char* buffer = base64.UseChars(); | |
150 | |
151 // encode each byte | |
152 while (size >= 3) { | |
153 // output a block | |
154 *buffer++ = NPT_Base64_Chars[ (data[i ] >> 2) & 0x3F]; | |
155 *buffer++ = NPT_Base64_Chars[((data[i ] & 0x03) << 4) | ((data[i+1] >> 4) & 0x0F)]; | |
156 *buffer++ = NPT_Base64_Chars[((data[i+1] & 0x0F) << 2) | ((data[i+2] >> 6) & 0x03)]; | |
157 *buffer++ = NPT_Base64_Chars[ data[i+2] & 0x3F]; | |
158 | |
159 size -= 3; | |
160 i += 3; | |
161 if (++block_count == max_blocks_per_line) { | |
162 *buffer++ = '\r'; | |
163 *buffer++ = '\n'; | |
164 block_count = 0; | |
165 } | |
166 } | |
167 | |
168 // deal with the tail | |
169 if (size == 2) { | |
170 *buffer++ = NPT_Base64_Chars[ (data[i ] >> 2) & 0x3F]; | |
171 *buffer++ = NPT_Base64_Chars[((data[i ] & 0x03) << 4) | ((data[i+1] >> 4) & 0x0F)]; | |
172 *buffer++ = NPT_Base64_Chars[ (data[i+1] & 0x0F) << 2]; | |
173 *buffer++ = NPT_BASE64_PAD_CHAR; | |
174 } else if (size == 1) { | |
175 *buffer++ = NPT_Base64_Chars[(data[i] >> 2) & 0x3F]; | |
176 *buffer++ = NPT_Base64_Chars[(data[i] & 0x03) << 4]; | |
177 *buffer++ = NPT_BASE64_PAD_CHAR; | |
178 *buffer++ = NPT_BASE64_PAD_CHAR; | |
179 } | |
180 | |
181 // update the string size | |
182 NPT_ASSERT((NPT_Size)(buffer-base64.GetChars()) <= base64.GetCapacity()); | |
183 base64.SetLength((NPT_Size)(buffer-base64.GetChars())); | |
184 | |
185 // deal with url safe remapping | |
186 if (url_safe) { | |
187 base64.Replace('+','-'); | |
188 base64.Replace('/','_'); | |
189 } | |
190 | |
191 return NPT_SUCCESS; | |
192 } |