1 
2 //*********************************************************************
3 //* C_Base64 - a simple base64 encoder and decoder.
4 //*
5 //*     Copyright (c) 1999, Bob Withers - bwit@pobox.com
6 //*
7 //* This code may be freely used for any purpose, either personal
8 //* or commercial, provided the authors copyright notice remains
9 //* intact.
10 //*********************************************************************
11 
12 #ifndef WEBRTC_BASE_BASE64_H__
13 #define WEBRTC_BASE_BASE64_H__
14 
15 #include <string>
16 #include <vector>
17 
18 namespace rtc {
19 
20 class Base64
21 {
22 public:
23   enum DecodeOption {
24     DO_PARSE_STRICT =  1,  // Parse only base64 characters
25     DO_PARSE_WHITE  =  2,  // Parse only base64 and whitespace characters
26     DO_PARSE_ANY    =  3,  // Parse all characters
27     DO_PARSE_MASK   =  3,
28 
29     DO_PAD_YES      =  4,  // Padding is required
30     DO_PAD_ANY      =  8,  // Padding is optional
31     DO_PAD_NO       = 12,  // Padding is disallowed
32     DO_PAD_MASK     = 12,
33 
34     DO_TERM_BUFFER  = 16,  // Must termiante at end of buffer
35     DO_TERM_CHAR    = 32,  // May terminate at any character boundary
36     DO_TERM_ANY     = 48,  // May terminate at a sub-character bit offset
37     DO_TERM_MASK    = 48,
38 
39     // Strictest interpretation
40     DO_STRICT = DO_PARSE_STRICT | DO_PAD_YES | DO_TERM_BUFFER,
41 
42     DO_LAX    = DO_PARSE_ANY | DO_PAD_ANY | DO_TERM_CHAR,
43   };
44   typedef int DecodeFlags;
45 
46   static bool IsBase64Char(char ch);
47 
48   // Get the char next to the |ch| from the Base64Table.
49   // If the |ch| is the last one in the Base64Table then returns
50   // the first one from the table.
51   // Expects the |ch| be a base64 char.
52   // The result will be saved in |next_ch|.
53   // Returns true on success.
54   static bool GetNextBase64Char(char ch, char* next_ch);
55 
56   // Determines whether the given string consists entirely of valid base64
57   // encoded characters.
58   static bool IsBase64Encoded(const std::string& str);
59 
60   static void EncodeFromArray(const void* data, size_t len,
61                               std::string* result);
62   static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
63                               std::string* result, size_t* data_used);
64   static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
65                               std::vector<char>* result, size_t* data_used);
66 
67   // Convenience Methods
Encode(const std::string & data)68   static inline std::string Encode(const std::string& data) {
69     std::string result;
70     EncodeFromArray(data.data(), data.size(), &result);
71     return result;
72   }
Decode(const std::string & data,DecodeFlags flags)73   static inline std::string Decode(const std::string& data, DecodeFlags flags) {
74     std::string result;
75     DecodeFromArray(data.data(), data.size(), flags, &result, NULL);
76     return result;
77   }
Decode(const std::string & data,DecodeFlags flags,std::string * result,size_t * data_used)78   static inline bool Decode(const std::string& data, DecodeFlags flags,
79                             std::string* result, size_t* data_used)
80   {
81     return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
82   }
Decode(const std::string & data,DecodeFlags flags,std::vector<char> * result,size_t * data_used)83   static inline bool Decode(const std::string& data, DecodeFlags flags,
84                             std::vector<char>* result, size_t* data_used)
85   {
86     return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
87   }
88 
89 private:
90   static const char Base64Table[];
91   static const unsigned char DecodeTable[];
92 
93   static size_t GetNextQuantum(DecodeFlags parse_flags, bool illegal_pads,
94                                const char* data, size_t len, size_t* dpos,
95                                unsigned char qbuf[4], bool* padded);
96   template<typename T>
97   static bool DecodeFromArrayTemplate(const char* data, size_t len,
98                                       DecodeFlags flags, T* result,
99                                       size_t* data_used);
100 };
101 
102 } // namespace rtc
103 
104 #endif // WEBRTC_BASE_BASE64_H__
105