version 0.0.1
[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         while(currentdatapos<data.size())\r
17         {\r
18                 encoded.push_back(base64chars[(data[currentdatapos]>>2 & 0x3F)]);\r
19                 if(currentdatapos+1<data.size())\r
20                 {\r
21                         encoded.push_back(base64chars[(data[currentdatapos]<<4 & 0x30) | (data[currentdatapos+1]>>4 & 0x0F)]);\r
22                         if(currentdatapos+2<data.size())\r
23                         {\r
24                                 encoded.push_back(base64chars[(data[currentdatapos+1]<<2 & 0x3C) | (data[currentdatapos+2]>>6 & 0x03)]);\r
25                                 encoded.push_back(base64chars[(data[currentdatapos+2] & 0x3F)]);\r
26                         }\r
27                         else\r
28                         {\r
29                                 encoded.push_back(base64chars[(data[currentdatapos+1]<<2 & 0x3C)]);\r
30                                 encoded.append("=");\r
31                         }\r
32                 }\r
33                 else\r
34                 {\r
35                         encoded.push_back(base64chars[(data[currentdatapos]<<4 & 0x30)]);\r
36                         encoded.append("==");\r
37                 }\r
38                 currentdatapos+=3;\r
39         }\r
40         return true;\r
41 }\r
42 \r
43 const bool Decode(const std::string &encoded, std::vector<unsigned char> &data)\r
44 {\r
45         std::string::size_type charpos=0;\r
46         std::string::size_type encodedpos=0;\r
47         unsigned char currentbyte=0;\r
48 \r
49         // loop while encoded pos fits in current size\r
50         while(encodedpos+3<encoded.size())\r
51         {\r
52                 currentbyte=0;\r
53                 charpos=base64chars.find(encoded[encodedpos]);\r
54                 if(charpos==std::string::npos)\r
55                 {\r
56                         return false;\r
57                 }\r
58                 currentbyte=(charpos<<2 & 0xFC);\r
59                 charpos=base64chars.find(encoded[encodedpos+1]);\r
60                 if(charpos==std::string::npos)\r
61                 {\r
62                         return false;\r
63                 }\r
64                 currentbyte|=(charpos>>4 & 0x03);\r
65                 data.push_back(currentbyte);\r
66                 currentbyte=(charpos<<4 & 0xF0);\r
67 \r
68                 if(encoded[encodedpos+2]!='=')\r
69                 {\r
70                         charpos=base64chars.find(encoded[encodedpos+2]);\r
71                         if(charpos==std::string::npos)\r
72                         {\r
73                                 return false;\r
74                         }\r
75                         currentbyte|=(charpos>>2 & 0x0F);\r
76                         data.push_back(currentbyte);\r
77                         currentbyte=(charpos<<6 & 0xC0);\r
78                 }\r
79                 \r
80                 if(encoded[encodedpos+2]!='=')\r
81                 {\r
82                         charpos=base64chars.find(encoded[encodedpos+3]);\r
83                         if(charpos==std::string::npos)\r
84                         {\r
85                                 return false;\r
86                         }\r
87                         currentbyte|=(charpos & 0x3F);\r
88                         data.push_back(currentbyte);\r
89                 }\r
90 \r
91                 encodedpos+=4;\r
92         }\r
93 \r
94         return true;\r
95 }\r
96 \r
97 }       // namespace\r