15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//*********************************************************************
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//* C_Base64 - a simple base64 encoder and decoder.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//*
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//*     Copyright (c) 1999, Bob Withers - bwit@pobox.com
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//*
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//* This code may be freely used for any purpose, either personal
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//* or commercial, provided the authors copyright notice remains
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//* intact.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//*********************************************************************
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef WEBRTC_BASE_BASE64_H__
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define WEBRTC_BASE_BASE64_H__
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string>
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <vector>
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace rtc {
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Base64
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  enum DecodeOption {
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    DO_PARSE_STRICT =  1,  // Parse only base64 characters
25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DO_PARSE_WHITE  =  2,  // Parse only base64 and whitespace characters
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    DO_PARSE_ANY    =  3,  // Parse all characters
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    DO_PARSE_MASK   =  3,
28d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
29d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    DO_PAD_YES      =  4,  // Padding is required
3006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    DO_PAD_ANY      =  8,  // Padding is optional
3106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    DO_PAD_NO       = 12,  // Padding is disallowed
328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    DO_PAD_MASK     = 12,
33e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
34a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    DO_TERM_BUFFER  = 16,  // Must termiante at end of buffer
35e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    DO_TERM_CHAR    = 32,  // May terminate at any character boundary
36d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    DO_TERM_ANY     = 48,  // May terminate at a sub-character bit offset
37d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    DO_TERM_MASK    = 48,
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Strictest interpretation
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    DO_STRICT = DO_PARSE_STRICT | DO_PAD_YES | DO_TERM_BUFFER,
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DO_LAX    = DO_PARSE_ANY | DO_PAD_ANY | DO_TERM_CHAR,
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  };
44c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  typedef int DecodeFlags;
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  static bool IsBase64Char(char ch);
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Get the char next to the |ch| from the Base64Table.
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // If the |ch| is the last one in the Base64Table then returns
501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // the first one from the table.
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Expects the |ch| be a base64 char.
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // The result will be saved in |next_ch|.
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Returns true on success.
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool GetNextBase64Char(char ch, char* next_ch);
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  // Determines whether the given string consists entirely of valid base64
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // encoded characters.
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool IsBase64Encoded(const std::string& str);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  static void EncodeFromArray(const void* data, size_t len,
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                              std::string* result);
62e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)  static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                              std::string* result, size_t* data_used);
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                              std::vector<char>* result, size_t* data_used);
66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch  // Convenience Methods
68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch  static inline std::string Encode(const std::string& data) {
69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    std::string result;
70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EncodeFromArray(data.data(), data.size(), &result);
71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return result;
72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch  }
73197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch  static inline std::string Decode(const std::string& data, DecodeFlags flags) {
74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    std::string result;
75d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    DecodeFromArray(data.data(), data.size(), flags, &result, NULL);
76d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return result;
77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch  static inline bool Decode(const std::string& data, DecodeFlags flags,
79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                            std::string* result, size_t* data_used)
80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch  {
81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
83d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  static inline bool Decode(const std::string& data, DecodeFlags flags,
84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                            std::vector<char>* result, size_t* data_used)
85d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  {
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
87d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  }
88d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)private:
90d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  static const char Base64Table[];
91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  static const unsigned char DecodeTable[];
92d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
93c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  static size_t GetNextQuantum(DecodeFlags parse_flags, bool illegal_pads,
94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                               const char* data, size_t len, size_t* dpos,
95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                               unsigned char qbuf[4], bool* padded);
96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  template<typename T>
97d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)  static bool DecodeFromArrayTemplate(const char* data, size_t len,
98d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                                      DecodeFlags flags, T* result,
99d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                                      size_t* data_used);
100d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)};
101d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
102d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} // namespace rtc
103d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif // WEBRTC_BASE_BASE64_H__
105d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)