doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
base64.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * $Id: base64.c,v 1.28 2004/03/01 12:54:59 bagder Exp $
22  ***************************************************************************/
23 
24 /* Base64 encoding/decoding
25  *
26  * Test harnesses down the bottom - compile with -DTEST_ENCODE for
27  * a program that will read in raw data from stdin and write out
28  * a base64-encoded version to stdout, and the length returned by the
29  * encoding function to stderr. Compile with -DTEST_DECODE for a program that
30  * will go the other way.
31  *
32  * This code will break if int is smaller than 32 bits
33  */
34 
35 #include "setup.h"
36 
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #define _MPRINTF_REPLACE /* use our functions only */
41 #include <curl/mprintf.h>
42 
43 #include "base64.h"
44 
45 #ifdef CURLDEBUG
46 #include "memdebug.h"
47 #endif
48 
49 static void decodeQuantum(unsigned char *dest, const char *src)
50 {
51  unsigned int x = 0;
52  int i;
53  for(i = 0; i < 4; i++) {
54  if(src[i] >= 'A' && src[i] <= 'Z')
55  x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
56  else if(src[i] >= 'a' && src[i] <= 'z')
57  x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
58  else if(src[i] >= '0' && src[i] <= '9')
59  x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
60  else if(src[i] == '+')
61  x = (x << 6) + 62;
62  else if(src[i] == '/')
63  x = (x << 6) + 63;
64  else if(src[i] == '=')
65  x = (x << 6);
66  }
67 
68  dest[2] = (unsigned char)(x & 255);
69  x >>= 8;
70  dest[1] = (unsigned char)(x & 255);
71  x >>= 8;
72  dest[0] = (unsigned char)(x & 255);
73 }
74 
75 /*
76  * Curl_base64_decode()
77  *
78  * Given a base64 string at src, decode it into the memory pointed to by
79  * dest. Returns the length of the decoded data.
80  */
81 size_t Curl_base64_decode(const char *src, char *dest)
82 {
83  int length = 0;
84  int equalsTerm = 0;
85  int i;
86  int numQuantums;
87  unsigned char lastQuantum[3];
88  size_t rawlen=0;
89 
90  while((src[length] != '=') && src[length])
91  length++;
92  while(src[length+equalsTerm] == '=')
93  equalsTerm++;
94 
95  numQuantums = (length + equalsTerm) / 4;
96 
97  rawlen = (numQuantums * 3) - equalsTerm;
98 
99  for(i = 0; i < numQuantums - 1; i++) {
100  decodeQuantum((unsigned char *)dest, src);
101  dest += 3; src += 4;
102  }
103 
104  decodeQuantum(lastQuantum, src);
105  for(i = 0; i < 3 - equalsTerm; i++)
106  dest[i] = lastQuantum[i];
107 
108  return rawlen;
109 }
110 
111 /* ---- Base64 Encoding --- */
112 static char table64[]=
113  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
114 
115 /*
116  * Curl_base64_encode()
117  *
118  * Returns the length of the newly created base64 string. The third argument
119  * is a pointer to an allocated area holding the base64 data. If something
120  * went wrong, -1 is returned.
121  *
122  */
123 size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
124 {
125  unsigned char ibuf[3];
126  unsigned char obuf[4];
127  int i;
128  int inputparts;
129  char *output;
130  char *base64data;
131 
132  char *indata = (char *)inp;
133 
134  if(0 == insize)
135  insize = strlen(indata);
136 
137  base64data = output = (char*)malloc(insize*4/3+4);
138  if(NULL == output)
139  return 0;
140 
141  while(insize > 0) {
142  for (i = inputparts = 0; i < 3; i++) {
143  if(insize > 0) {
144  inputparts++;
145  ibuf[i] = *indata;
146  indata++;
147  insize--;
148  }
149  else
150  ibuf[i] = 0;
151  }
152 
153  obuf [0] = (ibuf [0] & 0xFC) >> 2;
154  obuf [1] = ((ibuf [0] & 0x03) << 4) | ((ibuf [1] & 0xF0) >> 4);
155  obuf [2] = ((ibuf [1] & 0x0F) << 2) | ((ibuf [2] & 0xC0) >> 6);
156  obuf [3] = ibuf [2] & 0x3F;
157 
158  switch(inputparts) {
159  case 1: /* only one byte read */
160  sprintf(output, "%c%c==",
161  table64[obuf[0]],
162  table64[obuf[1]]);
163  break;
164  case 2: /* two bytes read */
165  sprintf(output, "%c%c%c=",
166  table64[obuf[0]],
167  table64[obuf[1]],
168  table64[obuf[2]]);
169  break;
170  default:
171  sprintf(output, "%c%c%c%c",
172  table64[obuf[0]],
173  table64[obuf[1]],
174  table64[obuf[2]],
175  table64[obuf[3]] );
176  break;
177  }
178  output += 4;
179  }
180  *output=0;
181  *outptr = base64data; /* make it return the actual data memory */
182 
183  return strlen(base64data); /* return the length of the new data */
184 }
185 /* ---- End of Base64 Encoding ---- */
186 
187 /************* TEST HARNESS STUFF ****************/
188 
189 
190 #ifdef TEST_ENCODE
191 /* encoding test harness. Read in standard input and write out the length
192  * returned by Curl_base64_encode, followed by the base64'd data itself
193  */
194 #include <stdio.h>
195 
196 #define TEST_NEED_SUCK
197 void *suck(int *);
198 
199 int main(int argc, char **argv, char **envp)
200 {
201  char *base64;
202  size_t base64Len;
203  unsigned char *data;
204  int dataLen;
205 
206  data = (unsigned char *)suck(&dataLen);
207  base64Len = Curl_base64_encode(data, dataLen, &base64);
208 
209  fprintf(stderr, "%d\n", base64Len);
210  fprintf(stdout, "%s", base64);
211 
212  free(base64); free(data);
213  return 0;
214 }
215 #endif
216 
217 #ifdef TEST_DECODE
218 /* decoding test harness. Read in a base64 string from stdin and write out the
219  * length returned by Curl_base64_decode, followed by the decoded data itself
220  *
221  * gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o
222  */
223 #include <stdio.h>
224 
225 #define TEST_NEED_SUCK
226 void *suck(int *);
227 
228 int main(int argc, char **argv, char **envp)
229 {
230  char *base64;
231  int base64Len;
232  unsigned char *data;
233  int dataLen;
234  int i, j;
235 
236  base64 = (char *)suck(&base64Len);
237  data = (unsigned char *)malloc(base64Len * 3/4 + 8);
238  dataLen = Curl_base64_decode(base64, data);
239 
240  fprintf(stderr, "%d\n", dataLen);
241 
242  for(i=0; i < dataLen; i+=0x10) {
243  printf("0x%02x: ", i);
244  for(j=0; j < 0x10; j++)
245  if((j+i) < dataLen)
246  printf("%02x ", data[i+j]);
247  else
248  printf(" ");
249 
250  printf(" | ");
251 
252  for(j=0; j < 0x10; j++)
253  if((j+i) < dataLen)
254  printf("%c", isgraph(data[i+j])?data[i+j]:'.');
255  else
256  break;
257  puts("");
258  }
259 
260  free(base64); free(data);
261  return 0;
262 }
263 #endif
264 
265 #ifdef TEST_NEED_SUCK
266 /* this function 'sucks' in as much as possible from stdin */
267 void *suck(int *lenptr)
268 {
269  int cursize = 8192;
270  unsigned char *buf = NULL;
271  int lastread;
272  int len = 0;
273 
274  do {
275  cursize *= 2;
276  buf = (unsigned char *)realloc(buf, cursize);
277  memset(buf + len, 0, cursize - len);
278  lastread = fread(buf + len, 1, cursize - len, stdin);
279  len += lastread;
280  } while(!feof(stdin));
281 
282  lenptr[0] = len;
283  return (void *)buf;
284 }
285 #endif
#define main(x, y)
Definition: config-mac.h:9
size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
Definition: base64.c:123
size_t Curl_base64_decode(const char *src, char *dest)
Definition: base64.c:81
GLuint src
Definition: glext.h:5390
GLenum GLsizei len
Definition: glext.h:3472
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
#define NULL
Definition: Lib.h:88
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
size_t fread(void *, size_t, size_t, FILE *)
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
GLint j
Definition: qgl.h:264
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528