@@ -90,180 +90,3 @@ llvm::Error llvm::decodeBase64(llvm::StringRef Input,
9090 }
9191 return Error::success ();
9292}
93-
94- using namespace llvm ;
95-
96- namespace {
97-
98- using byte = std::byte;
99-
100- ::llvm::Error makeError (const Twine &Msg) {
101- return createStringError (std::error_code{}, Msg);
102- }
103-
104- class Base64Impl {
105- private:
106- static constexpr char EncodingTable[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
107- " abcdefghijklmnopqrstuvwxyz"
108- " 0123456789+/" ;
109-
110- static_assert (sizeof (EncodingTable) == 65 , " " );
111-
112- // Compose an index into the encoder table from two bytes and the number of
113- // significant bits in the lower byte until the byte boundary.
114- static inline int composeInd (byte ByteLo, byte ByteHi, int BitsLo) {
115- int Res = (int )((ByteHi << BitsLo) | (ByteLo >> (8 - BitsLo))) & 0x3F ;
116- return Res;
117- }
118-
119- // Decode a single character.
120- static inline int decode (char Ch) {
121- if (Ch >= ' A' && Ch <= ' Z' ) // 0..25
122- return Ch - ' A' ;
123- if (Ch >= ' a' && Ch <= ' z' ) // 26..51
124- return Ch - ' a' + 26 ;
125- if (Ch >= ' 0' && Ch <= ' 9' ) // 52..61
126- return Ch - ' 0' + 52 ;
127- if (Ch == ' +' ) // 62
128- return 62 ;
129- if (Ch == ' /' ) // 63
130- return 63 ;
131- return -1 ;
132- }
133-
134- // Decode a quadruple of characters.
135- static inline Expected<bool > decode4 (const char *Src, byte *Dst) {
136- int BadCh = -1 ;
137-
138- for (auto I = 0 ; I < 4 ; ++I) {
139- char Ch = Src[I];
140- int Byte = decode (Ch);
141-
142- if (Byte < 0 ) {
143- BadCh = Ch;
144- break ;
145- }
146- Dst[I] = (byte)Byte;
147- }
148- if (BadCh == -1 )
149- return true ;
150- return makeError (" invalid char in Base64Impl encoding: 0x" + Twine (BadCh));
151- }
152-
153- public:
154- static size_t getEncodedSize (size_t SrcSize) {
155- constexpr int ByteSizeInBits = 8 ;
156- constexpr int EncBitsPerChar = 6 ;
157- return (SrcSize * ByteSizeInBits + (EncBitsPerChar - 1 )) / EncBitsPerChar;
158- }
159-
160- static size_t encode (const byte *Src, raw_ostream &Out, size_t SrcSize) {
161- size_t Off = 0 ;
162-
163- // Encode full byte triples
164- for (size_t TriB = 0 ; TriB < SrcSize / 3 ; ++TriB) {
165- Off = TriB * 3 ;
166- byte Byte0 = Src[Off++];
167- byte Byte1 = Src[Off++];
168- byte Byte2 = Src[Off++];
169-
170- Out << EncodingTable[(int )Byte0 & 0x3F ];
171- Out << EncodingTable[composeInd (Byte0, Byte1, 2 )];
172- Out << EncodingTable[composeInd (Byte1, Byte2, 4 )];
173- Out << EncodingTable[(int )(Byte2 >> 2 ) & 0x3F ];
174- }
175- // Encode the remainder
176- int RemBytes = SrcSize - Off;
177-
178- if (RemBytes > 0 ) {
179- byte Byte0 = Src[Off + 0 ];
180- Out << EncodingTable[(int )Byte0 & 0x3F ];
181-
182- if (RemBytes > 1 ) {
183- byte Byte1 = Src[Off + 1 ];
184- Out << EncodingTable[composeInd (Byte0, Byte1, 2 )];
185- Out << EncodingTable[(int )(Byte1 >> 4 ) & 0x3F ];
186- } else {
187- Out << EncodingTable[(int )(Byte0 >> 6 ) & 0x3F ];
188- }
189- }
190- return getEncodedSize (SrcSize);
191- }
192-
193- static size_t getDecodedSize (size_t SrcSize) { return (SrcSize * 3 + 3 ) / 4 ; }
194-
195- static Expected<size_t > decode (const char *Src, byte *Dst, size_t SrcSize) {
196- size_t SrcOff = 0 ;
197- size_t DstOff = 0 ;
198-
199- // Decode full quads.
200- for (size_t Qch = 0 ; Qch < SrcSize / 4 ; ++Qch, SrcOff += 4 , DstOff += 3 ) {
201- byte Ch[4 ];
202- Expected<bool > TrRes = decode4 (Src + SrcOff, Ch);
203-
204- if (!TrRes)
205- return TrRes.takeError ();
206- // Each quad of chars produces three bytes of output.
207- Dst[DstOff + 0 ] = Ch[0 ] | (Ch[1 ] << 6 );
208- Dst[DstOff + 1 ] = (Ch[1 ] >> 2 ) | (Ch[2 ] << 4 );
209- Dst[DstOff + 2 ] = (Ch[2 ] >> 4 ) | (Ch[3 ] << 2 );
210- }
211- auto RemChars = SrcSize - SrcOff;
212-
213- if (RemChars == 0 )
214- return DstOff;
215- // Decode the remainder; variants:
216- // 2 chars remain - produces single byte
217- // 3 chars remain - produces two bytes
218-
219- if (RemChars != 2 && RemChars != 3 )
220- return makeError (" invalid encoded sequence length" );
221-
222- int Ch0 = decode (Src[SrcOff++]);
223- int Ch1 = decode (Src[SrcOff++]);
224- int Ch2 = RemChars == 3 ? decode (Src[SrcOff]) : 0 ;
225-
226- if (Ch0 < 0 || Ch1 < 0 || Ch2 < 0 )
227- return makeError (" invalid characters in the encoded sequence remainder" );
228- Dst[DstOff++] = (byte)Ch0 | (byte)((Ch1 << 6 ));
229-
230- if (RemChars == 3 )
231- Dst[DstOff++] = (byte)(Ch1 >> 2 ) | (byte)(Ch2 << 4 );
232- return DstOff;
233- }
234-
235- static Expected<std::unique_ptr<byte[]>> decode (const char *Src,
236- size_t SrcSize) {
237- size_t DstSize = getDecodedSize (SrcSize);
238- std::unique_ptr<byte[]> Dst (new byte[DstSize]);
239- Expected<size_t > Res = decode (Src, Dst.get (), SrcSize);
240- if (!Res)
241- return Res.takeError ();
242- return Expected<std::unique_ptr<byte[]>>(std::move (Dst));
243- }
244- };
245-
246- constexpr char Base64Impl::EncodingTable[];
247-
248- } // anonymous namespace
249-
250- size_t Base64::getEncodedSize (size_t SrcSize) {
251- return Base64Impl::getEncodedSize (SrcSize);
252- }
253-
254- size_t Base64::encode (const byte *Src, raw_ostream &Out, size_t SrcSize) {
255- return Base64Impl::encode (Src, Out, SrcSize);
256- }
257-
258- size_t Base64::getDecodedSize (size_t SrcSize) {
259- return Base64Impl::getDecodedSize (SrcSize);
260- }
261-
262- Expected<size_t > Base64::decode (const char *Src, byte *Dst, size_t SrcSize) {
263- return Base64Impl::decode (Src, Dst, SrcSize);
264- }
265-
266- Expected<std::unique_ptr<byte[]>> Base64::decode (const char *Src,
267- size_t SrcSize) {
268- return Base64Impl::decode (Src, SrcSize);
269- }
0 commit comments