blob: 17aa125e3fdfff0763a34ae4e9563911a839751c [file] [log] [blame]
Brian Silvermanf7bd1c22015-12-24 16:07:11 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2015. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8/* ====================================================================
9 * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in
20 * the documentation and/or other materials provided with the
21 * distribution.
22 *
23 * 3. All advertising materials mentioning features or use of this
24 * software must display the following acknowledgment:
25 * "This product includes software developed by the Apache Group
26 * for use in the Apache HTTP server project (http://www.apache.org/)."
27 *
28 * 4. The names "Apache Server" and "Apache Group" must not be used to
29 * endorse or promote products derived from this software without
30 * prior written permission. For written permission, please contact
31 * apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache"
34 * nor may "Apache" appear in their names without prior written
35 * permission of the Apache Group.
36 *
37 * 6. Redistributions of any form whatsoever must retain the following
38 * acknowledgment:
39 * "This product includes software developed by the Apache Group
40 * for use in the Apache HTTP server project (http://www.apache.org/)."
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
43 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
45 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
46 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
51 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
53 * OF THE POSSIBILITY OF SUCH DAMAGE.
54 * ====================================================================
55 *
56 * This software consists of voluntary contributions made by many
57 * individuals on behalf of the Apache Group and was originally based
58 * on public domain software written at the National Center for
59 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
60 * For more information on the Apache Group and the Apache HTTP server
61 * project, please see <http://www.apache.org/>.
62 *
63 */
64
65#include "Base64.h"
66
67namespace nt {
68
69// aaaack but it's fast and const should make it shared text page.
70static const unsigned char pr2six[256] =
71{
72 // ASCII table
73 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
74 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
75 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
76 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
77 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
78 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
79 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
80 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
81 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
82 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
83 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
84 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
85 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
86 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
87 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
88 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
89};
90
91std::size_t Base64Decode(llvm::StringRef encoded, std::string* plain) {
92 const unsigned char *end = encoded.bytes_begin();
93 while (pr2six[*end] <= 63 && end != encoded.bytes_end()) ++end;
94 std::size_t nprbytes = end - encoded.bytes_begin();
95
96 plain->clear();
97 if (nprbytes == 0)
98 return 0;
99 plain->reserve(((nprbytes + 3) / 4) * 3);
100
101 const unsigned char *cur = encoded.bytes_begin();
102
103 while (nprbytes > 4) {
104 (*plain) += (pr2six[cur[0]] << 2 | pr2six[cur[1]] >> 4);
105 (*plain) += (pr2six[cur[1]] << 4 | pr2six[cur[2]] >> 2);
106 (*plain) += (pr2six[cur[2]] << 6 | pr2six[cur[3]]);
107 cur += 4;
108 nprbytes -= 4;
109 }
110
111 // Note: (nprbytes == 1) would be an error, so just ignore that case
112 if (nprbytes > 1) (*plain) += (pr2six[cur[0]] << 2 | pr2six[cur[1]] >> 4);
113 if (nprbytes > 2) (*plain) += (pr2six[cur[1]] << 4 | pr2six[cur[2]] >> 2);
114 if (nprbytes > 3) (*plain) += (pr2six[cur[2]] << 6 | pr2six[cur[3]]);
115
116 return (end - encoded.bytes_begin()) + ((4 - nprbytes) & 3);
117}
118
119static const char basis_64[] =
120 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
121
122void Base64Encode(llvm::StringRef plain, std::string* encoded) {
123 encoded->clear();
124 if (plain.empty())
125 return;
126 std::size_t len = plain.size();
127 encoded->reserve(((len + 2) / 3 * 4) + 1);
128
129 std::size_t i;
130 for (i = 0; (i + 2) < len; i += 3) {
131 (*encoded) += basis_64[(plain[i] >> 2) & 0x3F];
132 (*encoded) +=
133 basis_64[((plain[i] & 0x3) << 4) | ((int)(plain[i + 1] & 0xF0) >> 4)];
134 (*encoded) += basis_64[((plain[i + 1] & 0xF) << 2) |
135 ((int)(plain[i + 2] & 0xC0) >> 6)];
136 (*encoded) += basis_64[plain[i + 2] & 0x3F];
137 }
138 if (i < len) {
139 (*encoded) += basis_64[(plain[i] >> 2) & 0x3F];
140 if (i == (len - 1)) {
141 (*encoded) += basis_64[((plain[i] & 0x3) << 4)];
142 (*encoded) += '=';
143 } else {
144 (*encoded) +=
145 basis_64[((plain[i] & 0x3) << 4) | ((int)(plain[i + 1] & 0xF0) >> 4)];
146 (*encoded) += basis_64[((plain[i + 1] & 0xF) << 2)];
147 }
148 (*encoded) += '=';
149 }
150}
151
152} // namespace nt