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