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
18namespace rtc {
19
20class Base64
21{
22public:
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
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  }
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  }
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  }
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
89private:
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