]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/apr/encoding/apr_encode.c
bhnd(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / contrib / apr / encoding / apr_encode.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* encode/decode functions.
18  *
19  * These functions perform various encoding operations, and are provided in
20  * pairs, a function to query the length of and encode existing buffers, as
21  * well as companion functions to perform the same process to memory
22  * allocated from a pool.
23  *
24  * The API is designed to have the smallest possible RAM footprint, and so
25  * will only allocate the exact amount of RAM needed for each conversion.
26  */
27
28 #include "apr_encode.h"
29 #include "apr_lib.h"
30 #include "apr_strings.h"
31 #include "apr_encode_private.h"
32
33 /* lookup table: fast and const should make it shared text page. */
34 static const unsigned char pr2six[256] =
35 {
36 #if !APR_CHARSET_EBCDIC
37     /* ASCII table */
38     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
39     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
40     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 62, 64, 63,
41     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 128, 64, 64,
42     64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
43     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 63,
44     64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
45     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
46     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
47     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
48     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
49     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
50     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
51     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
52     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
53     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
54 #else                           /* APR_CHARSET_EBCDIC */
55     /* EBCDIC table */
56     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
57     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
58     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
59     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
60     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64,
61     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
62     62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 64, 64,
63     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64,
64     64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,
65     64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,
66     64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64,
67     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
68     64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64,
69     64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,
70     64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,
71     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64
72 #endif                          /* APR_CHARSET_EBCDIC */
73 };
74
75 static const unsigned char pr2five[256] =
76 {
77 #if !APR_CHARSET_EBCDIC
78     /* ASCII table */
79     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
80     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
81     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
82     32, 32, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 128, 32, 32,
83     32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
84     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32, 32, 32, 32, 32,
85     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
86     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
87     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
88     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
89     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
90     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
91     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
92     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
93     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
94     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
95 #else                           /* APR_CHARSET_EBCDIC */
96     /* EBCDIC table */
97     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
98     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
99     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
100     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
101     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
102     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
103     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
104     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 128, 32,
105     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
106     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
107     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
108     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
109     32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 32, 32, 32, 32, 32, 32,
110     32, 9, 10, 11, 12, 13, 14, 15, 16, 17, 32, 32, 32, 32, 32, 32,
111     32, 32, 18, 19, 20, 21, 22, 23, 24, 25, 32, 32, 32, 32, 32, 32,
112     32, 32, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32
113 #endif                          /* APR_CHARSET_EBCDIC */
114 };
115
116 static const unsigned char pr2fivehex[256] =
117 {
118 #if !APR_CHARSET_EBCDIC
119     /* ASCII table */
120     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
121     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
122     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
123     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 32, 32, 128, 32, 32,
124     32, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
125     25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
126     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
127     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
128     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
129     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
130     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
131     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
132     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
133     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
134     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
135     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
136 #else                           /* APR_CHARSET_EBCDIC */
137     /* EBCDIC table */
138     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
139     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
140     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
141     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
142     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
143     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
144     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
145     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 128, 32,
146     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
147     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
148     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
149     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
150     32, 10, 11, 12, 13, 14, 15, 16, 17, 18, 32, 32, 32, 32, 32, 32,
151     32, 19, 20, 21, 22, 23, 24, 25, 26, 27, 32, 32, 32, 32, 32, 32,
152     32, 32, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
153     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 32, 32, 32, 32, 32
154 #endif                          /* APR_CHARSET_EBCDIC */
155 };
156
157 static const unsigned char pr2two[256] =
158 {
159 #if !APR_CHARSET_EBCDIC
160     /* ASCII table */
161     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
162     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
163     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
164     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 16, 16, 16, 16, 16,
165     16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
166     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
167     16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
168     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
169     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
170     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
171     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
172     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
173     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
174     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
175     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
176     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
177 #else                           /* APR_CHARSET_EBCDIC */
178     /* EBCDIC table */
179     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
180     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
181     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
182     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
183     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
184     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
185     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
186     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 32, 16, 16, 16, 16, 16,
187     16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
188     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
189     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
190     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
191     16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
192     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
193     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
194     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 16, 16, 16, 16, 16
195 #endif                          /* APR_CHARSET_EBCDIC */
196 };
197
198 static const char base64[] =
199 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
200 static const char base64url[] =
201 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
202
203 static const char base32[] =
204 "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
205 static const char base32hex[] =
206 "0123456789ABCDEFGHIJKLMNOPQRSTUV";
207
208 static const char base16[] = "0123456789ABCDEF";
209 static const char base16lower[] = "0123456789abcdef";
210
211 APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
212                               apr_ssize_t slen, int flags, apr_size_t * len)
213 {
214     const char *base;
215
216     if (!src) {
217         return APR_NOTFOUND;
218     }
219
220     if (APR_ENCODE_STRING == slen) {
221         slen = strlen(src);
222     }
223
224     if (dest) {
225         register char *bufout = dest;
226         int i;
227
228         if (0 == ((flags & APR_ENCODE_BASE64URL))) {
229             base = base64;
230         }
231         else {
232             base = base64url;
233         }
234
235         for (i = 0; i < slen - 2; i += 3) {
236             *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)];
237             *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4)
238                                       | ((int)((src[i + 1]) & 0xF0) >> 4))];
239             *bufout++ = base[ENCODE_TO_ASCII((((src[i + 1]) & 0xF) << 2)
240                        | ((int)(ENCODE_TO_ASCII(src[i + 2]) & 0xC0) >> 6))];
241             *bufout++ = base[ENCODE_TO_ASCII((src[i + 2]) & 0x3F)];
242         }
243         if (i < slen) {
244             *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)];
245             if (i == (slen - 1)) {
246                 *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4))];
247                 if (!(flags & APR_ENCODE_NOPADDING)) {
248                     *bufout++ = '=';
249                 }
250             }
251             else {
252                 *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4)
253                                       | ((int)((src[i + 1]) & 0xF0) >> 4))];
254                 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1]) & 0xF) << 2)];
255             }
256             if (!(flags & APR_ENCODE_NOPADDING)) {
257                 *bufout++ = '=';
258             }
259         }
260
261         if (len) {
262             *len = bufout - dest;
263         }
264
265         *bufout++ = '\0';
266
267         return APR_SUCCESS;
268     }
269
270     if (len) {
271         *len = ((slen + 2) / 3 * 4) + 1;
272     }
273
274     return APR_SUCCESS;
275 }
276
277 APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
278                               apr_ssize_t slen, int flags, apr_size_t * len)
279 {
280     const char *base;
281
282     if (!src) {
283         return APR_NOTFOUND;
284     }
285
286     if (dest) {
287         register char *bufout = dest;
288         int i;
289
290         if (0 == ((flags & APR_ENCODE_BASE64URL))) {
291             base = base64;
292         }
293         else {
294             base = base64url;
295         }
296
297         for (i = 0; i < slen - 2; i += 3) {
298             *bufout++ = base[(src[i] >> 2) & 0x3F];
299             *bufout++ = base[((src[i] & 0x3) << 4)
300                              | ((int)(src[i + 1] & 0xF0) >> 4)];
301             *bufout++ = base[((src[i + 1] & 0xF) << 2)
302                              | ((int)(src[i + 2] & 0xC0) >> 6)];
303             *bufout++ = base[src[i + 2] & 0x3F];
304         }
305         if (i < slen) {
306             *bufout++ = base[(src[i] >> 2) & 0x3F];
307             if (i == (slen - 1)) {
308                 *bufout++ = base[((src[i] & 0x3) << 4)];
309                 if (!(flags & APR_ENCODE_NOPADDING)) {
310                     *bufout++ = '=';
311                 }
312             }
313             else {
314                 *bufout++ = base[((src[i] & 0x3) << 4)
315                                  | ((int)(src[i + 1] & 0xF0) >> 4)];
316                 *bufout++ = base[((src[i + 1] & 0xF) << 2)];
317             }
318             if (!(flags & APR_ENCODE_NOPADDING)) {
319                 *bufout++ = '=';
320             }
321         }
322
323         if (len) {
324             *len = bufout - dest;
325         }
326
327         *bufout++ = '\0';
328
329         return APR_SUCCESS;
330     }
331
332     if (len) {
333         *len = ((slen + 2) / 3 * 4) + 1;
334     }
335
336     return APR_SUCCESS;
337 }
338
339 APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
340                               apr_ssize_t slen, int flags, apr_size_t * len)
341 {
342     apr_size_t size;
343
344     switch (apr_encode_base64(NULL, src, slen, flags, &size)) {
345     case APR_SUCCESS:{
346             char *cmd = apr_palloc(p, size);
347             apr_encode_base64(cmd, src, slen, flags, len);
348             return cmd;
349         }
350     case APR_NOTFOUND:{
351             break;
352         }
353     }
354
355     return NULL;
356 }
357
358 APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigned char *src,
359                               apr_ssize_t slen, int flags, apr_size_t * len)
360 {
361     apr_size_t size;
362
363     switch (apr_encode_base64_binary(NULL, src, slen, flags, &size)) {
364     case APR_SUCCESS:{
365             char *cmd = apr_palloc(p, size);
366             apr_encode_base64_binary(cmd, src, slen, flags, len);
367             return cmd;
368         }
369     case APR_NOTFOUND:{
370             break;
371         }
372     }
373
374     return NULL;
375 }
376
377 APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
378                               apr_ssize_t slen, int flags, apr_size_t * len)
379 {
380     if (!src) {
381         return APR_NOTFOUND;
382     }
383
384     if (APR_ENCODE_STRING == slen) {
385         slen = strlen(src);
386     }
387
388     if (dest) {
389         register const unsigned char *bufin;
390         register unsigned char *bufout;
391         register apr_size_t nprbytes;
392         register apr_size_t count = slen;
393
394         apr_status_t status;
395
396         bufin = (const unsigned char *)src;
397         while (pr2six[*(bufin++)] < 64 && count)
398             count--;
399         nprbytes = (bufin - (const unsigned char *)src) - 1;
400         while (pr2six[*(bufin++)] > 64 && count)
401             count--;
402
403         status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
404             count ? APR_BADCH : APR_SUCCESS;
405
406         bufout = (unsigned char *)dest;
407         bufin = (const unsigned char *)src;
408
409         while (nprbytes > 4) {
410             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2six[bufin[0]] << 2
411                                                    | pr2six[bufin[1]] >> 4);
412             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
413                              pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
414             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
415                                   pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
416             bufin += 4;
417             nprbytes -= 4;
418         }
419
420         if (nprbytes == 1) {
421             status = APR_BADCH;
422         }
423         if (nprbytes > 1) {
424             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
425                                pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
426         }
427         if (nprbytes > 2) {
428             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
429                              pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
430         }
431         if (nprbytes > 3) {
432             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
433                                   pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
434         }
435
436         if (len) {
437             *len = bufout - (unsigned char *)dest;
438         }
439
440         *(bufout++) = 0;
441
442         return status;
443     }
444
445     if (len) {
446         *len = (((int)slen + 3) / 4) * 3 + 1;
447     }
448
449     return APR_SUCCESS;
450 }
451
452 APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
453              const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
454 {
455     if (!src) {
456         return APR_NOTFOUND;
457     }
458
459     if (APR_ENCODE_STRING == slen) {
460         slen = strlen(src);
461     }
462
463     if (dest) {
464         register const unsigned char *bufin;
465         register unsigned char *bufout;
466         register apr_size_t nprbytes;
467         register apr_size_t count = slen;
468
469         apr_status_t status;
470
471         bufin = (const unsigned char *)src;
472         while (pr2six[*(bufin++)] < 64 && count)
473             count--;
474         nprbytes = (bufin - (const unsigned char *)src) - 1;
475         while (pr2six[*(bufin++)] > 64 && count)
476             count--;
477
478         status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
479             count ? APR_BADCH : APR_SUCCESS;
480
481         bufout = (unsigned char *)dest;
482         bufin = (const unsigned char *)src;
483
484         while (nprbytes > 4) {
485             *(bufout++) = (unsigned char)(pr2six[bufin[0]] << 2
486                                           | pr2six[bufin[1]] >> 4);
487             *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4
488                                           | pr2six[bufin[2]] >> 2);
489             *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6
490                                           | pr2six[bufin[3]]);
491             bufin += 4;
492             nprbytes -= 4;
493         }
494
495         if (nprbytes == 1) {
496             status = APR_BADCH;
497         }
498         if (nprbytes > 1) {
499             *(bufout++) = (unsigned char)(pr2six[bufin[0]] << 2
500                                           | pr2six[bufin[1]] >> 4);
501         }
502         if (nprbytes > 2) {
503             *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4
504                                           | pr2six[bufin[2]] >> 2);
505         }
506         if (nprbytes > 3) {
507             *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6
508                                           | pr2six[bufin[3]]);
509         }
510
511         if (len) {
512             *len = bufout - dest;
513         }
514
515         return status;
516     }
517
518     if (len) {
519         *len = (((int)slen + 3) / 4) * 3;
520     }
521
522     return APR_SUCCESS;
523 }
524
525 APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *str,
526                               apr_ssize_t slen, int flags, apr_size_t * len)
527 {
528     apr_size_t size;
529
530     switch (apr_decode_base64(NULL, str, slen, flags, &size)) {
531     case APR_SUCCESS:{
532             void *cmd = apr_palloc(p, size);
533             apr_decode_base64(cmd, str, slen, flags, len);
534             return cmd;
535         }
536     case APR_BADCH:
537     case APR_NOTFOUND:{
538             break;
539         }
540     }
541
542     return NULL;
543 }
544
545 APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p,
546              const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
547 {
548     apr_size_t size;
549
550     switch (apr_decode_base64_binary(NULL, str, slen, flags, &size)) {
551     case APR_SUCCESS:{
552             unsigned char *cmd = apr_palloc(p, size + 1);
553             cmd[size] = 0;
554             apr_decode_base64_binary(cmd, str, slen, flags, len);
555             return cmd;
556         }
557     case APR_BADCH:
558     case APR_NOTFOUND:{
559             break;
560         }
561     }
562
563     return NULL;
564 }
565
566 APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
567                               apr_ssize_t slen, int flags, apr_size_t * len)
568 {
569     const char *base;
570
571     if (!src) {
572         return APR_NOTFOUND;
573     }
574
575     if (APR_ENCODE_STRING == slen) {
576         slen = strlen(src);
577     }
578
579     if (dest) {
580         register char *bufout = dest;
581         int i;
582
583         if (!((flags & APR_ENCODE_BASE32HEX))) {
584             base = base32;
585         }
586         else {
587             base = base32hex;
588         }
589
590         for (i = 0; i < slen - 4; i += 5) {
591             *bufout++ = base[ENCODE_TO_ASCII((src[i] >> 3) & 0x1F)];
592             *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
593                                              | ((src[i + 1] >> 6) & 0x3))];
594             *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
595             *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
596                                              | ((src[i + 2] >> 4) & 0xF))];
597             *bufout++ = base[ENCODE_TO_ASCII(((src[i + 2] << 1) & 0x1E)
598                                              | ((src[i + 3] >> 7) & 0x1))];
599             *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] >> 2) & 0x1F)];
600             *bufout++ = base[ENCODE_TO_ASCII(((src[i + 3] << 3) & 0x18)
601                                              | ((src[i + 4] >> 5) & 0x7))];
602             *bufout++ = base[ENCODE_TO_ASCII(src[i + 4] & 0x1F)];
603         }
604         if (i < slen) {
605             *bufout++ = base[ENCODE_TO_ASCII(src[i] >> 3) & 0x1F];
606             if (i == (slen - 1)) {
607                 *bufout++ = base[ENCODE_TO_ASCII((src[i] << 2) & 0x1C)];
608                 if (!(flags & APR_ENCODE_NOPADDING)) {
609                     *bufout++ = '=';
610                     *bufout++ = '=';
611                     *bufout++ = '=';
612                     *bufout++ = '=';
613                     *bufout++ = '=';
614                     *bufout++ = '=';
615                 }
616             }
617             else if (i == (slen - 2)) {
618                 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
619                                               | ((src[i + 1] >> 6) & 0x3))];
620                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
621                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] << 4) & 0x10)];
622                 if (!(flags & APR_ENCODE_NOPADDING)) {
623                     *bufout++ = '=';
624                     *bufout++ = '=';
625                     *bufout++ = '=';
626                     *bufout++ = '=';
627                 }
628             }
629             else if (i == (slen - 3)) {
630                 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
631                                               | ((src[i + 1] >> 6) & 0x3))];
632                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
633                 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
634                                               | ((src[i + 2] >> 4) & 0xF))];
635                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 2] << 1) & 0x1E)];
636                 if (!(flags & APR_ENCODE_NOPADDING)) {
637                     *bufout++ = '=';
638                     *bufout++ = '=';
639                     *bufout++ = '=';
640                 }
641             }
642             else {
643                 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
644                                               | ((src[i + 1] >> 6) & 0x3))];
645                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
646                 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
647                                               | ((src[i + 2] >> 4) & 0xF))];
648                 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 2] << 1) & 0x1E)
649                                               | ((src[i + 3] >> 7) & 0x1))];
650                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] >> 2) & 0x1F)];
651                 *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] << 3) & 0x18)];
652                 if (!(flags & APR_ENCODE_NOPADDING)) {
653                     *bufout++ = '=';
654                 }
655             }
656         }
657
658         if (len) {
659             *len = bufout - dest;
660         }
661
662         *bufout++ = '\0';
663
664         return APR_SUCCESS;
665     }
666
667     if (len) {
668         *len = ((slen + 2) / 3 * 4) + 1;
669     }
670
671     return APR_SUCCESS;
672 }
673
674 APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
675                               apr_ssize_t slen, int flags, apr_size_t * len)
676 {
677     const char *base;
678
679     if (!src) {
680         return APR_NOTFOUND;
681     }
682
683     if (dest) {
684         register char *bufout = dest;
685         int i;
686
687         if (!((flags & APR_ENCODE_BASE32HEX))) {
688             base = base32;
689         }
690         else {
691             base = base32hex;
692         }
693
694         for (i = 0; i < slen - 4; i += 5) {
695             *bufout++ = base[((src[i] >> 3) & 0x1F)];
696             *bufout++ = base[(((src[i] << 2) & 0x1C)
697                               | ((src[i + 1] >> 6) & 0x3))];
698             *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
699             *bufout++ = base[(((src[i + 1] << 4) & 0x10)
700                               | ((src[i + 2] >> 4) & 0xF))];
701             *bufout++ = base[(((src[i + 2] << 1) & 0x1E)
702                               | ((src[i + 3] >> 7) & 0x1))];
703             *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
704             *bufout++ = base[(((src[i + 3] << 3) & 0x18)
705                               | ((src[i + 4] >> 5) & 0x7))];
706             *bufout++ = base[(src[i + 4] & 0x1F)];
707         }
708         if (i < slen) {
709             *bufout++ = base[(src[i] >> 3) & 0x1F];
710             if (i == (slen - 1)) {
711                 *bufout++ = base[((src[i] << 2) & 0x1C)];
712                 if (!(flags & APR_ENCODE_NOPADDING)) {
713                     *bufout++ = '=';
714                     *bufout++ = '=';
715                     *bufout++ = '=';
716                     *bufout++ = '=';
717                     *bufout++ = '=';
718                     *bufout++ = '=';
719                 }
720             }
721             else if (i == (slen - 2)) {
722                 *bufout++ = base[(((src[i] << 2) & 0x1C)
723                                   | ((src[i + 1] >> 6) & 0x3))];
724                 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
725                 *bufout++ = base[((src[i + 1] << 4) & 0x10)];
726                 if (!(flags & APR_ENCODE_NOPADDING)) {
727                     *bufout++ = '=';
728                     *bufout++ = '=';
729                     *bufout++ = '=';
730                     *bufout++ = '=';
731                 }
732             }
733             else if (i == (slen - 3)) {
734                 *bufout++ = base[(((src[i] << 2) & 0x1C)
735                                   | ((src[i + 1] >> 6) & 0x3))];
736                 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
737                 *bufout++ = base[(((src[i + 1] << 4) & 0x10)
738                                   | ((int)(src[i + 2] >> 4) & 0xF))];
739                 *bufout++ = base[((src[i + 2] << 1) & 0x1E)];
740                 if (!(flags & APR_ENCODE_NOPADDING)) {
741                     *bufout++ = '=';
742                     *bufout++ = '=';
743                     *bufout++ = '=';
744                 }
745             }
746             else {
747                 *bufout++ = base[(((src[i] << 2) & 0x1C)
748                                   | ((src[i + 1] >> 6) & 0x3))];
749                 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
750                 *bufout++ = base[(((src[i + 1] << 4) & 0x10)
751                                   | ((src[i + 2] >> 4) & 0xF))];
752                 *bufout++ = base[(((src[i + 2] << 1) & 0x1E)
753                                   | ((src[i + 3] >> 7) & 0x1))];
754                 *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
755                 *bufout++ = base[((src[i + 3] << 3) & 0x18)];
756                 if (!(flags & APR_ENCODE_NOPADDING)) {
757                     *bufout++ = '=';
758                 }
759             }
760         }
761
762         if (len) {
763             *len = bufout - dest;
764         }
765
766         *bufout++ = '\0';
767
768         return APR_SUCCESS;
769     }
770
771     if (len) {
772         *len = ((slen + 4) / 5 * 8) + 1;
773     }
774
775     return APR_SUCCESS;
776 }
777
778 APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
779                               apr_ssize_t slen, int flags, apr_size_t * len)
780 {
781     apr_size_t size;
782
783     switch (apr_encode_base32(NULL, src, slen, flags, &size)) {
784     case APR_SUCCESS:{
785             char *cmd = apr_palloc(p, size);
786             apr_encode_base32(cmd, src, slen, flags, len);
787             return cmd;
788         }
789     case APR_NOTFOUND:{
790             break;
791         }
792     }
793
794     return NULL;
795 }
796
797 APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigned char *src,
798                               apr_ssize_t slen, int flags, apr_size_t * len)
799 {
800     apr_size_t size;
801
802     switch (apr_encode_base32_binary(NULL, src, slen, flags, &size)) {
803     case APR_SUCCESS:{
804             char *cmd = apr_palloc(p, size);
805             apr_encode_base32_binary(cmd, src, slen, flags, len);
806             return cmd;
807         }
808     case APR_NOTFOUND:{
809             break;
810         }
811     }
812
813     return NULL;
814 }
815
816 APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
817                               apr_ssize_t slen, int flags, apr_size_t * len)
818 {
819     if (!src) {
820         return APR_NOTFOUND;
821     }
822
823     if (APR_ENCODE_STRING == slen) {
824         slen = strlen(src);
825     }
826
827     if (dest) {
828         register const unsigned char *bufin;
829         register unsigned char *bufout;
830         register apr_size_t nprbytes;
831         register apr_size_t count = slen;
832
833         const unsigned char *pr2;
834
835         apr_status_t status;
836
837         if ((flags & APR_ENCODE_BASE32HEX)) {
838             pr2 = pr2fivehex;
839         }
840         else {
841             pr2 = pr2five;
842         }
843
844         bufin = (const unsigned char *)src;
845         while (pr2[*(bufin++)] < 32 && count)
846             count--;
847         nprbytes = (bufin - (const unsigned char *)src) - 1;
848         while (pr2[*(bufin++)] > 32 && count)
849             count--;
850
851         status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
852             count ? APR_BADCH : APR_SUCCESS;
853
854         bufout = (unsigned char *)dest;
855         bufin = (const unsigned char *)src;
856
857         while (nprbytes > 8) {
858             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[0]] << 3
859                                                       | pr2[bufin[1]] >> 2);
860             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[1]] << 6
861                                  | pr2[bufin[2]] << 1 | pr2[bufin[3]] >> 4);
862             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[3]] << 4
863                                                       | pr2[bufin[4]] >> 1);
864             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[4]] << 7
865                                  | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
866             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[6]] << 5
867                                                           | pr2[bufin[7]]);
868             bufin += 8;
869             nprbytes -= 8;
870         }
871
872         if (nprbytes == 1) {
873             status = APR_BADCH;
874         }
875         if (nprbytes >= 2) {
876             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
877                                    pr2[bufin[0]] << 3 | pr2[bufin[1]] >> 2);
878         }
879         if (nprbytes == 3) {
880             status = APR_BADCH;
881         }
882         if (nprbytes >= 4) {
883             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
884                                      pr2[bufin[1]] << 6 | pr2[bufin[2]] << 1
885                                                       | pr2[bufin[3]] >> 4);
886         }
887         if (nprbytes >= 5) {
888             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[3]] << 4
889                                                       | pr2[bufin[4]] >> 1);
890         }
891         if (nprbytes == 6) {
892             status = APR_BADCH;
893         }
894         if (nprbytes >= 7) {
895             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[4]] << 7
896                                  | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
897         }
898         if (nprbytes == 8) {
899             *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[6]] << 5
900                                                           | pr2[bufin[7]]);
901         }
902
903         if (len) {
904             *len = bufout - (unsigned char *)dest;
905         }
906
907         *(bufout++) = 0;
908
909         return status;
910     }
911
912     if (len) {
913         *len = (((int)slen + 7) / 8) * 5 + 1;
914     }
915
916     return APR_SUCCESS;
917 }
918
919 APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
920              const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
921 {
922     if (!src) {
923         return APR_NOTFOUND;
924     }
925
926     if (APR_ENCODE_STRING == slen) {
927         slen = strlen(src);
928     }
929
930     if (dest) {
931         register const unsigned char *bufin;
932         register unsigned char *bufout;
933         register apr_size_t nprbytes;
934         register apr_size_t count = slen;
935
936         const unsigned char *pr2;
937
938         apr_status_t status;
939
940         if ((flags & APR_ENCODE_BASE32HEX)) {
941             pr2 = pr2fivehex;
942         }
943         else {
944             pr2 = pr2five;
945         }
946
947         bufin = (const unsigned char *)src;
948         while (pr2[*(bufin++)] < 32 && count)
949             count--;
950         nprbytes = (bufin - (const unsigned char *)src) - 1;
951         while (pr2[*(bufin++)] > 32 && count)
952             count--;
953
954         status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
955             count ? APR_BADCH : APR_SUCCESS;
956
957         bufout = (unsigned char *)dest;
958         bufin = (const unsigned char *)src;
959
960         while (nprbytes > 8) {
961             *(bufout++) = (unsigned char)(pr2[bufin[0]] << 3
962                                           | pr2[bufin[1]] >> 2);
963             *(bufout++) = (unsigned char)(pr2[bufin[1]] << 6
964                                  | pr2[bufin[2]] << 1 | pr2[bufin[3]] >> 4);
965             *(bufout++) = (unsigned char)(pr2[bufin[3]] << 4
966                                           | pr2[bufin[4]] >> 1);
967             *(bufout++) = (unsigned char)(pr2[bufin[4]] << 7
968                                  | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
969             *(bufout++) = (unsigned char)(pr2[bufin[6]] << 5
970                                           | pr2[bufin[7]]);
971             bufin += 8;
972             nprbytes -= 8;
973         }
974
975         if (nprbytes == 1) {
976             status = APR_BADCH;
977         }
978         if (nprbytes >= 2) {
979             *(bufout++) = (unsigned char)(
980                                    pr2[bufin[0]] << 3 | pr2[bufin[1]] >> 2);
981         }
982         if (nprbytes == 3) {
983             status = APR_BADCH;
984         }
985         if (nprbytes >= 4) {
986             *(bufout++) = (unsigned char)(
987                                      pr2[bufin[1]] << 6 | pr2[bufin[2]] << 1
988                                           | pr2[bufin[3]] >> 4);
989         }
990         if (nprbytes >= 5) {
991             *(bufout++) = (unsigned char)(pr2[bufin[3]] << 4
992                                           | pr2[bufin[4]] >> 1);
993         }
994         if (nprbytes == 6) {
995             status = APR_BADCH;
996         }
997         if (nprbytes >= 7) {
998             *(bufout++) = (unsigned char)(pr2[bufin[4]] << 7
999                                  | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
1000         }
1001         if (nprbytes == 8) {
1002             *(bufout++) = (unsigned char)(pr2[bufin[6]] << 5
1003                                           | pr2[bufin[7]]);
1004         }
1005
1006         if (len) {
1007             *len = bufout - dest;
1008         }
1009
1010         return status;
1011     }
1012
1013     if (len) {
1014         *len = (((int)slen + 7) / 8) * 5;
1015     }
1016
1017     return APR_SUCCESS;
1018 }
1019
1020 APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *str,
1021                               apr_ssize_t slen, int flags, apr_size_t * len)
1022 {
1023     apr_size_t size;
1024
1025     switch (apr_decode_base32(NULL, str, slen, flags, &size)) {
1026     case APR_SUCCESS:{
1027             void *cmd = apr_palloc(p, size);
1028             apr_decode_base32(cmd, str, slen, flags, len);
1029             return cmd;
1030         }
1031     case APR_BADCH:
1032     case APR_NOTFOUND:{
1033             break;
1034         }
1035     }
1036
1037     return NULL;
1038 }
1039
1040 APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p,
1041              const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
1042 {
1043     apr_size_t size;
1044
1045     switch (apr_decode_base32_binary(NULL, str, slen, flags, &size)) {
1046     case APR_SUCCESS:{
1047             unsigned char *cmd = apr_palloc(p, size + 1);
1048             cmd[size] = 0;
1049             apr_decode_base32_binary(cmd, str, slen, flags, len);
1050             return cmd;
1051         }
1052     case APR_BADCH:
1053     case APR_NOTFOUND:{
1054             break;
1055         }
1056     }
1057
1058     return NULL;
1059 }
1060
1061 APR_DECLARE(apr_status_t) apr_encode_base16(char *dest,
1062              const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1063 {
1064     const char *in = src;
1065     apr_size_t size;
1066
1067     if (!src) {
1068         return APR_NOTFOUND;
1069     }
1070
1071     if (dest) {
1072         register char *bufout = dest;
1073         const char *base;
1074
1075         if ((flags & APR_ENCODE_LOWER)) {
1076             base = base16lower;
1077         }
1078         else {
1079             base = base16;
1080         }
1081
1082         for (size = 0; (APR_ENCODE_STRING == slen) ? in[size] : size < slen; size++) {
1083             if ((flags & APR_ENCODE_COLON) && size) {
1084                 *(bufout++) = ':';
1085             }
1086             *(bufout++) = base[(const unsigned char)(ENCODE_TO_ASCII(in[size])) >> 4];
1087             *(bufout++) = base[(const unsigned char)(ENCODE_TO_ASCII(in[size])) & 0xf];
1088         }
1089
1090         if (len) {
1091             *len = bufout - dest;
1092         }
1093
1094         *bufout = '\0';
1095
1096         return APR_SUCCESS;
1097     }
1098
1099     if (len) {
1100         if (APR_ENCODE_STRING == slen) {
1101             slen = strlen(src);
1102         }
1103         if ((flags & APR_ENCODE_COLON) && slen) {
1104             *len = slen * 3;
1105         }
1106         else {
1107             *len = slen * 2 + 1;
1108         }
1109     }
1110
1111     return APR_SUCCESS;
1112 }
1113
1114 APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
1115     const unsigned char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1116 {
1117     const unsigned char *in = src;
1118     apr_size_t size;
1119
1120     if (!src) {
1121         return APR_NOTFOUND;
1122     }
1123
1124     if (dest) {
1125         register char *bufout = dest;
1126         const char *base;
1127
1128         if ((flags & APR_ENCODE_LOWER)) {
1129             base = base16lower;
1130         }
1131         else {
1132             base = base16;
1133         }
1134
1135         for (size = 0; size < slen; size++) {
1136             if ((flags & APR_ENCODE_COLON) && size) {
1137                 *(bufout++) = ':';
1138             }
1139             *(bufout++) = base[in[size] >> 4];
1140             *(bufout++) = base[in[size] & 0xf];
1141         }
1142
1143         if (len) {
1144             *len = bufout - dest;
1145         }
1146
1147         *bufout = 0;
1148
1149         return APR_SUCCESS;
1150     }
1151
1152     if (len) {
1153         if ((flags & APR_ENCODE_COLON) && slen) {
1154             *len = slen * 3;
1155         }
1156         else {
1157             *len = slen * 2 + 1;
1158         }
1159     }
1160
1161     return APR_SUCCESS;
1162 }
1163
1164 APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p,
1165              const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1166 {
1167     apr_size_t size;
1168
1169     switch (apr_encode_base16(NULL, src, slen, flags, &size)) {
1170     case APR_SUCCESS:{
1171             char *cmd = apr_palloc(p, size);
1172             apr_encode_base16(cmd, src, slen, flags, len);
1173             return cmd;
1174         }
1175     case APR_NOTFOUND:{
1176             break;
1177         }
1178     }
1179
1180     return NULL;
1181 }
1182
1183 APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p,
1184                       const unsigned char *src, apr_ssize_t slen, int flags,
1185                                                    apr_size_t * len)
1186 {
1187     apr_size_t size;
1188
1189     switch (apr_encode_base16_binary(NULL, src, slen, flags, &size)) {
1190     case APR_SUCCESS:{
1191             char *cmd = apr_palloc(p, size);
1192             apr_encode_base16_binary(cmd, src, slen, flags, len);
1193             return cmd;
1194         }
1195     case APR_NOTFOUND:{
1196             break;
1197         }
1198     }
1199
1200     return NULL;
1201 }
1202
1203 APR_DECLARE(apr_status_t) apr_decode_base16(char *dest,
1204              const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1205 {
1206     register const unsigned char *bufin;
1207     register unsigned char *bufout;
1208     register apr_size_t nprbytes;
1209     register apr_size_t count;
1210
1211     apr_status_t status;
1212
1213     if (!src) {
1214         return APR_NOTFOUND;
1215     }
1216
1217     if (APR_ENCODE_STRING == slen) {
1218         slen = strlen(src);
1219     }
1220
1221     count = slen;
1222     bufin = (const unsigned char *)src;
1223     while (pr2two[*(bufin++)] != 16 && count)
1224         count--;
1225     nprbytes = (bufin - (const unsigned char *)src) - 1;
1226     while (pr2two[*(bufin++)] > 16 && count)
1227         count--;
1228
1229     status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
1230         count ? APR_BADCH : APR_SUCCESS;
1231
1232     if (dest) {
1233
1234         bufout = (unsigned char *)dest;
1235         bufin = (const unsigned char *)src;
1236
1237         while (nprbytes >= 2) {
1238             if (pr2two[bufin[0]] > 16) {
1239                 bufin += 1;
1240                 nprbytes -= 1;
1241             }
1242             else {
1243                 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
1244                                   pr2two[bufin[0]] << 4 | pr2two[bufin[1]]);
1245                 bufin += 2;
1246                 nprbytes -= 2;
1247             }
1248         }
1249
1250         if (nprbytes == 1) {
1251             status = APR_BADCH;
1252         }
1253
1254         if (len) {
1255             *len = bufout - (unsigned char *)dest;
1256         }
1257
1258         *(bufout++) = 0;
1259
1260         return status;
1261     }
1262
1263     else {
1264
1265         count = 0;
1266         bufin = (const unsigned char *)src;
1267
1268         while (nprbytes >= 2) {
1269             if (pr2two[bufin[0]] > 16) {
1270                 bufin += 1;
1271                 nprbytes -= 1;
1272             }
1273             else {
1274                 count++;
1275                 bufin += 2;
1276                 nprbytes -= 2;
1277             }
1278         }
1279
1280         if (nprbytes == 1) {
1281             status = APR_BADCH;
1282         }
1283
1284         if (len) {
1285             *len = count + 1;
1286         }
1287
1288         return status;
1289     }
1290
1291 }
1292
1293 APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
1294              const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1295 {
1296     register const unsigned char *bufin;
1297     register unsigned char *bufout;
1298     register apr_size_t nprbytes;
1299     register apr_size_t count;
1300
1301     apr_status_t status;
1302
1303     if (!src) {
1304         return APR_NOTFOUND;
1305     }
1306
1307     if (APR_ENCODE_STRING == slen) {
1308         slen = strlen(src);
1309     }
1310
1311     count = slen;
1312     bufin = (const unsigned char *)src;
1313     while (pr2two[*(bufin++)] != 16 && count)
1314         count--;
1315     nprbytes = (bufin - (const unsigned char *)src) - 1;
1316     while (pr2two[*(bufin++)] > 16 && count)
1317         count--;
1318
1319     status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
1320         count ? APR_BADCH : APR_SUCCESS;
1321
1322     if (dest) {
1323
1324         bufout = (unsigned char *)dest;
1325         bufin = (const unsigned char *)src;
1326
1327         while (nprbytes >= 2) {
1328             if (pr2two[bufin[0]] > 16) {
1329                 bufin += 1;
1330                 nprbytes -= 1;
1331             }
1332             else {
1333                 *(bufout++) = (unsigned char)(
1334                                   pr2two[bufin[0]] << 4 | pr2two[bufin[1]]);
1335                 bufin += 2;
1336                 nprbytes -= 2;
1337             }
1338         }
1339
1340         if (nprbytes == 1) {
1341             status = APR_BADCH;
1342         }
1343
1344         if (len) {
1345             *len = bufout - (unsigned char *)dest;
1346         }
1347
1348         return status;
1349     }
1350
1351     else {
1352
1353         count = 0;
1354         bufin = (const unsigned char *)src;
1355
1356         while (nprbytes >= 2) {
1357             if (pr2two[bufin[0]] > 16) {
1358                 bufin += 1;
1359                 nprbytes -= 1;
1360             }
1361             else {
1362                 count++;
1363                 bufin += 2;
1364                 nprbytes -= 2;
1365             }
1366         }
1367
1368         if (nprbytes == 1) {
1369             status = APR_BADCH;
1370         }
1371
1372         if (len) {
1373             *len = count;
1374         }
1375
1376         return status;
1377     }
1378 }
1379
1380 APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p,
1381              const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
1382 {
1383     apr_size_t size;
1384
1385     switch (apr_decode_base16(NULL, str, slen, flags, &size)) {
1386     case APR_SUCCESS:{
1387             void *cmd = apr_palloc(p, size);
1388             apr_decode_base16(cmd, str, slen, flags, len);
1389             return cmd;
1390         }
1391     case APR_BADCH:
1392     case APR_NOTFOUND:{
1393             break;
1394         }
1395     }
1396
1397     return NULL;
1398 }
1399
1400 APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p,
1401              const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
1402 {
1403     apr_size_t size;
1404
1405     switch (apr_decode_base16_binary(NULL, str, slen, flags, &size)) {
1406     case APR_SUCCESS:{
1407             unsigned char *cmd = apr_palloc(p, size + 1);
1408             cmd[size] = 0;
1409             apr_decode_base16_binary(cmd, str, slen, flags, len);
1410             return cmd;
1411         }
1412     case APR_BADCH:
1413     case APR_NOTFOUND:{
1414             break;
1415         }
1416     }
1417
1418     return NULL;
1419 }