version 0.1.9
[fms.git] / src / base64.cpp
1 #include "../include/base64.h"\r
2 \r
3 #ifdef XMEM\r
4         #include <xmem.h>\r
5 #endif\r
6 \r
7 namespace Base64\r
8 {\r
9 \r
10 static const std::string base64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\r
11 \r
12 const bool Encode(const std::vector<unsigned char> &data, std::string &encoded)\r
13 {\r
14         std::vector<unsigned char>::size_type currentdatapos=0;\r
15 \r
16         //reserve space for encoded data 4*input/3\r
17         encoded.reserve((4L*data.size())/3L);\r
18         while(currentdatapos<data.size())\r
19         {\r
20                 encoded.push_back(base64chars[(data[currentdatapos]>>2 & 0x3F)]);\r
21                 if(currentdatapos+1<data.size())\r
22                 {\r
23                         encoded.push_back(base64chars[(data[currentdatapos]<<4 & 0x30) | (data[currentdatapos+1]>>4 & 0x0F)]);\r
24                         if(currentdatapos+2<data.size())\r
25                         {\r
26                                 encoded.push_back(base64chars[(data[currentdatapos+1]<<2 & 0x3C) | (data[currentdatapos+2]>>6 & 0x03)]);\r
27                                 encoded.push_back(base64chars[(data[currentdatapos+2] & 0x3F)]);\r
28                         }\r
29                         else\r
30                         {\r
31                                 encoded.push_back(base64chars[(data[currentdatapos+1]<<2 & 0x3C)]);\r
32                                 encoded.append("=");\r
33                         }\r
34                 }\r
35                 else\r
36                 {\r
37                         encoded.push_back(base64chars[(data[currentdatapos]<<4 & 0x30)]);\r
38                         encoded.append("==");\r
39                 }\r
40                 currentdatapos+=3;\r
41         }\r
42         return true;\r
43 }\r
44 \r
45 const bool Decode(const std::string &encoded, std::vector<unsigned char> &data)\r
46 {\r
47         std::string::size_type charpos=0;\r
48         std::string::size_type encodedpos=0;\r
49         unsigned char currentbyte=0;\r
50 \r
51         // reserve space for decoded data (encoded size*3/4)\r
52         if(encoded.size()>1)\r
53         {\r
54                 data.reserve((encoded.size()*3)/4);\r
55         }\r
56 \r
57         // loop while encoded pos fits in current size\r
58         while(encodedpos+3<encoded.size())\r
59         {\r
60                 currentbyte=0;\r
61                 charpos=base64chars.find(encoded[encodedpos]);\r
62                 if(charpos==std::string::npos)\r
63                 {\r
64                         return false;\r
65                 }\r
66                 currentbyte=(charpos<<2 & 0xFC);\r
67                 charpos=base64chars.find(encoded[encodedpos+1]);\r
68                 if(charpos==std::string::npos)\r
69                 {\r
70                         return false;\r
71                 }\r
72                 currentbyte|=(charpos>>4 & 0x03);\r
73                 data.push_back(currentbyte);\r
74                 currentbyte=(charpos<<4 & 0xF0);\r
75 \r
76                 if(encoded[encodedpos+2]!='=')\r
77                 {\r
78                         charpos=base64chars.find(encoded[encodedpos+2]);\r
79                         if(charpos==std::string::npos)\r
80                         {\r
81                                 return false;\r
82                         }\r
83                         currentbyte|=(charpos>>2 & 0x0F);\r
84                         data.push_back(currentbyte);\r
85                         currentbyte=(charpos<<6 & 0xC0);\r
86                 }\r
87                 \r
88                 if(encoded[encodedpos+2]!='=')\r
89                 {\r
90                         charpos=base64chars.find(encoded[encodedpos+3]);\r
91                         if(charpos==std::string::npos)\r
92                         {\r
93                                 return false;\r
94                         }\r
95                         currentbyte|=(charpos & 0x3F);\r
96                         data.push_back(currentbyte);\r
97                 }\r
98 \r
99                 encodedpos+=4;\r
100         }\r
101 \r
102         return true;\r
103 }\r
104 \r
105 }       // namespace\r