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  public:
22   enum DecodeOption {
23     DO_PARSE_STRICT = 1,  // Parse only base64 characters
24     DO_PARSE_WHITE = 2,   // Parse only base64 and whitespace characters
25     DO_PARSE_ANY = 3,     // Parse all characters
26     DO_PARSE_MASK = 3,
27 
28     DO_PAD_YES = 4,  // Padding is required
29     DO_PAD_ANY = 8,  // Padding is optional
30     DO_PAD_NO = 12,  // Padding is disallowed
31     DO_PAD_MASK = 12,
32 
33     DO_TERM_BUFFER = 16,  // Must termiante at end of buffer
34     DO_TERM_CHAR = 32,    // May terminate at any character boundary
35     DO_TERM_ANY = 48,     // May terminate at a sub-character bit offset
36     DO_TERM_MASK = 48,
37 
38     // Strictest interpretation
39     DO_STRICT = DO_PARSE_STRICT | DO_PAD_YES | DO_TERM_BUFFER,
40 
41     DO_LAX = DO_PARSE_ANY | DO_PAD_ANY | DO_TERM_CHAR,
42   };
43   typedef int DecodeFlags;
44 
45   static bool IsBase64Char(char ch);
46 
47   // Get the char next to the |ch| from the Base64Table.
48   // If the |ch| is the last one in the Base64Table then returns
49   // the first one from the table.
50   // Expects the |ch| be a base64 char.
51   // The result will be saved in |next_ch|.
52   // Returns true on success.
53   static bool GetNextBase64Char(char ch, char* next_ch);
54 
55   // Determines whether the given string consists entirely of valid base64
56   // encoded characters.
57   static bool IsBase64Encoded(const std::string& str);
58 
59   static void EncodeFromArray(const void* data,
60                               size_t len,
61                               std::string* result);
62   static bool DecodeFromArray(const char* data,
63                               size_t len,
64                               DecodeFlags flags,
65                               std::string* result,
66                               size_t* data_used);
67   static bool DecodeFromArray(const char* data,
68                               size_t len,
69                               DecodeFlags flags,
70                               std::vector<char>* result,
71                               size_t* data_used);
72   static bool DecodeFromArray(const char* data,
73                               size_t len,
74                               DecodeFlags flags,
75                               std::vector<uint8_t>* result,
76                               size_t* data_used);
77 
78   // Convenience Methods
Encode(const std::string & data)79   static inline std::string Encode(const std::string& data) {
80     std::string result;
81     EncodeFromArray(data.data(), data.size(), &result);
82     return result;
83   }
Decode(const std::string & data,DecodeFlags flags)84   static inline std::string Decode(const std::string& data, DecodeFlags flags) {
85     std::string result;
86     DecodeFromArray(data.data(), data.size(), flags, &result, NULL);
87     return result;
88   }
Decode(const std::string & data,DecodeFlags flags,std::string * result,size_t * data_used)89   static inline bool Decode(const std::string& data,
90                             DecodeFlags flags,
91                             std::string* result,
92                             size_t* data_used) {
93     return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
94   }
Decode(const std::string & data,DecodeFlags flags,std::vector<char> * result,size_t * data_used)95   static inline bool Decode(const std::string& data,
96                             DecodeFlags flags,
97                             std::vector<char>* result,
98                             size_t* data_used) {
99     return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
100   }
101 
102  private:
103   static const char Base64Table[];
104   static const unsigned char DecodeTable[];
105 
106   static size_t GetNextQuantum(DecodeFlags parse_flags,
107                                bool illegal_pads,
108                                const char* data,
109                                size_t len,
110                                size_t* dpos,
111                                unsigned char qbuf[4],
112                                bool* padded);
113   template <typename T>
114   static bool DecodeFromArrayTemplate(const char* data,
115                                       size_t len,
116                                       DecodeFlags flags,
117                                       T* result,
118                                       size_t* data_used);
119 };
120 
121 }  // namespace rtc
122 
123 #endif  // WEBRTC_BASE_BASE64_H__
124