OpenShot Library | libopenshot-audio 0.2.0
juce_Base64.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26bool Base64::convertToBase64 (OutputStream& base64Result, const void* sourceData, size_t sourceDataSize)
27{
28 static const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
29 auto* source = static_cast<const uint8*> (sourceData);
30
31 while (sourceDataSize > 0)
32 {
33 char frame[4];
34 auto byte0 = *source++;
35 frame[0] = lookup [(byte0 & 0xfcu) >> 2];
36 uint32 bits = (byte0 & 0x03u) << 4;
37
38 if (sourceDataSize > 1)
39 {
40 auto byte1 = *source++;
41 frame[1] = lookup[bits | ((byte1 & 0xf0u) >> 4)];
42 bits = (byte1 & 0x0fu) << 2;
43
44 if (sourceDataSize > 2)
45 {
46 auto byte2 = *source++;
47 frame[2] = lookup[bits | ((byte2 & 0xc0u) >> 6)];
48 frame[3] = lookup[byte2 & 0x3fu];
49 sourceDataSize -= 3;
50 }
51 else
52 {
53 frame[2] = lookup[bits];
54 frame[3] = '=';
55 sourceDataSize = 0;
56 }
57 }
58 else
59 {
60 frame[1] = lookup[bits];
61 frame[2] = '=';
62 frame[3] = '=';
63 sourceDataSize = 0;
64 }
65
66 if (! base64Result.write (frame, 4))
67 return false;
68 }
69
70 return true;
71}
72
73bool Base64::convertFromBase64 (OutputStream& binaryOutput, StringRef base64TextInput)
74{
75 for (auto s = base64TextInput.text; ! s.isEmpty();)
76 {
77 uint8 data[4];
78
79 for (int i = 0; i < 4; ++i)
80 {
81 auto c = (uint32) s.getAndAdvance();
82
83 if (c >= 'A' && c <= 'Z') c -= 'A';
84 else if (c >= 'a' && c <= 'z') c -= 'a' - 26;
85 else if (c >= '0' && c <= '9') c += 52 - '0';
86 else if (c == '+') c = 62;
87 else if (c == '/') c = 63;
88 else if (c == '=') { c = 64; if (i <= 1) return false; }
89 else return false;
90
91 data[i] = (uint8) c;
92 }
93
94 binaryOutput.writeByte ((char) ((data[0] << 2) | (data[1] >> 4)));
95
96 if (data[2] < 64)
97 {
98 binaryOutput.writeByte ((char) ((data[1] << 4) | (data[2] >> 2)));
99
100 if (data[3] < 64)
101 binaryOutput.writeByte ((char) ((data[2] << 6) | data[3]));
102 }
103 }
104
105 return true;
106}
107
108String Base64::toBase64 (const void* sourceData, size_t sourceDataSize)
109{
110 MemoryOutputStream m ((sourceDataSize * 4) / 3 + 3);
111 bool ok = convertToBase64 (m, sourceData, sourceDataSize);
112 jassert (ok); // should always succeed for this simple case
113 ignoreUnused (ok);
114 return m.toString();
115}
116
118{
119 return toBase64 (text.toRawUTF8(), strlen (text.toRawUTF8()));
120}
121
122
123//==============================================================================
124//==============================================================================
125#if JUCE_UNIT_TESTS
126
127class Base64Tests : public UnitTest
128{
129public:
130 Base64Tests() : UnitTest ("Base64 class", "Text") {}
131
132 static MemoryBlock createRandomData (Random& r)
133 {
134 MemoryOutputStream m;
135
136 for (int i = r.nextInt (400); --i >= 0;)
137 m.writeByte ((char) r.nextInt (256));
138
139 return m.getMemoryBlock();
140 }
141
142 void runTest() override
143 {
144 beginTest ("Base64");
145
146 auto r = getRandom();
147
148 for (int i = 1000; --i >= 0;)
149 {
150 auto original = createRandomData (r);
151 auto asBase64 = Base64::toBase64 (original.getData(), original.getSize());
152 MemoryOutputStream out;
153 expect (Base64::convertFromBase64 (out, asBase64));
154 auto result = out.getMemoryBlock();
155 expect (result == original);
156 }
157 }
158};
159
160static Base64Tests base64Tests;
161
162#endif
163
164} // namespace juce
Writes data to an internal memory buffer, which grows as required.
String toString() const
Attempts to detect the encoding of the data and convert it to a string.
The base class for streams that write data to some kind of destination.
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
Writes a block of data to the stream.
virtual bool writeByte(char byte)
Writes a single byte to the stream.
A simple class for holding temporary references to a string literal or String.
String::CharPointerType text
The text that is referenced.
The JUCE String class!
Definition juce_String.h:43
const char * toRawUTF8() const
Returns a pointer to a UTF-8 version of this string.
This is a base class for classes that perform a unit test.
static bool convertToBase64(OutputStream &base64Result, const void *sourceData, size_t sourceDataSize)
Converts a binary block of data into a base-64 string.
static String toBase64(const void *sourceData, size_t sourceDataSize)
Converts a block of binary data to a base-64 string.
static bool convertFromBase64(OutputStream &binaryOutput, StringRef base64TextInput)
Converts a base-64 string back to its binary representation.