ini
[aversive.git] / modules / encoding / base64 / base64.c
1 /*  
2  *  Copyright Droids Corporation, Microb Technology, Eirbot (2005)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: base64.c,v 1.2.4.3 2009-03-15 21:37:55 zer0 Exp $
19  *
20  */
21
22 #include <string.h>
23
24 char my_base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
25
26 /* return -1 if out buffer is too small */
27 /* else return number of written bytes in out buffer */
28 int  base64_to_raw(char * in, int len_in, char * out, int len_out)
29 {
30         int n_in;
31         int counter=0;
32         int n_out=0;
33         char* c;
34         unsigned int buf=0;
35         for (n_in=0 ; n_in<len_in && n_out<len_out ; n_in++)    {
36                 /* this is the end as it is padding */
37                 if (in[n_in] == '=')
38                         break;
39
40                 c = strchr(my_base64, in[n_in]);
41                 
42                 /* ignore bad chars */
43                 if (c == NULL)
44                         continue;
45
46                 buf <<= 6;
47                 buf += (int)(c-my_base64);
48                 counter+=6;
49
50                 if (counter < 8)
51                         continue;
52
53                 if (n_out >= len_out)
54                         return -1;
55
56                 out[n_out++] = (buf>>(counter-8)) & 0xFF;
57                 counter -= 8;
58         }
59
60         /* no padding at the end, ok */
61         if (counter == 0 && (n_in+1 >= len_in || in[n_in] != '=')) {
62                 return n_out;
63         }
64
65         /* one '=' padding, ok  */
66         if (counter == 2 && (in[n_in] == '=') && 
67             (n_in+1 >= len_in || in[n_in] != '=')) {
68                 return n_out;
69         }
70
71         /* two '=' padding, ok  */
72         if (counter == 4 && (in[n_in] == '=') && 
73             n_in+1 < len_in && in[n_in+1] == '=') {
74                 return n_out;
75         }
76
77         /* bad padding */
78         return -1;
79 }
80
81
82 /* return -1 if out buffer is too small */
83 /* else return number of written bytes in out buffer */
84 int raw_to_base64(char *in, int len_in, char * out, int len_out)
85 {
86         int n_in;
87         int counter=0;
88         int n_out=0;
89         unsigned int buf=0;
90
91         for (n_in=0 ; n_in<len_in && n_out<len_out ; n_in++)    {
92                 buf <<= 8;
93                 buf += (unsigned char)(in[n_in]);
94                 counter+=8;
95                 
96                 while(counter>=6) {
97                         if (n_out>=len_out)
98                                 return -1;
99                         out[n_out++] = my_base64[(buf>>(counter-6)) & 0x3F];
100                         counter-=6;
101                 }
102         }
103
104         /* should we add padding ? */
105         if (counter) {
106                 if (n_out >= len_out)
107                         return -1;
108
109                 out[n_out++] =  my_base64[(buf<<(6-counter)) & 0x3F];
110                 
111                 if (n_out >= len_out)
112                         return -1;
113
114                 /* one '=' if counter==4 (counter can be 4 or 2) */
115                 out[n_out++] = '=';
116
117                 if (n_out >= len_out)
118                         return -1;
119
120                 /* two '=' if cpt==2 */
121                 if (counter==2) {
122                         out[n_out++] = '=';
123                 }
124         }
125         
126         return n_out;
127 }