annotate C++/Base64.h @ 242:a9883eeb9757

Add tests for Base64
author David Demelier <markand@malikania.fr>
date Thu, 11 Sep 2014 21:09:58 +0200
parents b97d75a78e22
children 73e5381d7baf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
238
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * Base64.h -- base64 encoding and decoding
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #ifndef _BASE_64_H_
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #define _BASE_64_H_
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
21
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 * @file Base64.h
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 * @brief Base64 encoding and decoding
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <stdexcept>
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 #include <string>
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
29
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 * @class Base64
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 * @brief Encode and decode Base64 data
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 class Base64 {
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 public:
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 * Get the base 64 character from the 6-bits value.
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 * @param value the value
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 static char lookup(int value) noexcept;
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
42
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 * Get the integer value from the base 64 character.
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 * @param ch the base64 character
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 static int rlookup(char ch);
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
49
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 * Encode the input to the output. Requirements:
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 * InputIt must be InputIterator
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 * OutputIt must be OutputIterator
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 * @param input the beginning
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 * @param end the end of the data
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 * @output the output destination
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 template <typename InputIt, typename OutputIt>
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 static void encode(InputIt input, InputIt end, OutputIt output)
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 {
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 while (input != end) {
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 char inputbuf[3] = { 0, 0, 0 };
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 int count;
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
65
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 for (count = 0; count < 3 && input != end; ++count)
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 inputbuf[count] = *input++;
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 *output++ = lookup(inputbuf[0] >> 2 & 0x3f);
242
a9883eeb9757 Add tests for Base64
David Demelier <markand@malikania.fr>
parents: 238
diff changeset
70 *output++ = lookup((inputbuf[0] << 4 & 0x3f) | (inputbuf[1] >> 4 & 0x0f));
a9883eeb9757 Add tests for Base64
David Demelier <markand@malikania.fr>
parents: 238
diff changeset
71 *output++ = (count < 2) ? '=' : lookup((inputbuf[1] << 2 & 0x3c) | (inputbuf[2] >> 6 & 0x03));
238
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 *output++ = (count < 3) ? '=' : lookup(inputbuf[2] & 0x3f);
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 }
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 }
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 * Decode the input to the output. Requirements:
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 * InputIt must be InputIterator
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 * OutputIt must be OutputIterator
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 * @param input the beginning
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 * @param end the end of the data
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 * @output the output destination
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 * @throw std::invalid_argument on bad base64 string
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 template <typename InputIt, typename OutputIt>
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 static void decode(InputIt input, InputIt end, OutputIt output)
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 {
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 while (input != end) {
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 char inputbuf[4] = { 0, 0, 0, 0 };
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 int count;
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
92
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 for (count = 0; count < 4 && input != end; ++count) {
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 inputbuf[count] = (*input == '=') ? '=' : rlookup(*input);
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 input++;
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 }
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 if (count != 4)
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 throw std::invalid_argument("truncated string");
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
100
242
a9883eeb9757 Add tests for Base64
David Demelier <markand@malikania.fr>
parents: 238
diff changeset
101 *output++ = (inputbuf[0] << 2 & 0xfc) | (inputbuf[1] >> 4 & 0x03);
238
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 if (inputbuf[2] != '=')
242
a9883eeb9757 Add tests for Base64
David Demelier <markand@malikania.fr>
parents: 238
diff changeset
104 *output++ = (inputbuf[1] << 4 & 0xf0) | (inputbuf[2] >> 2 & 0x0f);
238
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 if (inputbuf[3] != '=')
242
a9883eeb9757 Add tests for Base64
David Demelier <markand@malikania.fr>
parents: 238
diff changeset
106 *output++ = (inputbuf[2] << 6 & 0xc0) | (inputbuf[3] & 0x3f);
238
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 }
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 }
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
109
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 * Encode a string.
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 * @param input the input string
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 * @return the base64 formatted string
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 static std::string encode(const std::string &input);
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 /**
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 * Decode a string.
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 *
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 * @param input the base64 formatted string
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 * @return the original string
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 * @throw std::invalid_argument on bad base64 string
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 */
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 static std::string decode(const std::string &input);
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 };
b97d75a78e22 Add Base64, base64 encoding and decoding
David Demelier <markand@malikania.fr>
parents:
diff changeset
127
242
a9883eeb9757 Add tests for Base64
David Demelier <markand@malikania.fr>
parents: 238
diff changeset
128 #endif // !_BASE_64_H_