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