Flutter Engine
The Flutter Engine
base64.cc
Go to the documentation of this file.
1// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/base64.h"
6
8#include "vm/os.h"
9
10namespace dart {
11
12// Taken from lib/_http/crypto.dart
13
14// Lookup table used for finding Base 64 alphabet index of a given byte.
15// -2 : Outside Base 64 alphabet.
16// -1 : '\r' or '\n'
17// 0 : = (Padding character).
18// >0 : Base 64 alphabet index of given byte.
19static const int8_t decode_table[] = {
20 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2, //
21 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
22 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63, //
23 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, 00, -2, -2, //
24 -2, 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, 10, 11, 12, 13, 14, //
25 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63, //
26 -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //
27 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, //
28 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
29 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
30 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
31 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
32 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
33 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
34 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
35 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2};
36
37static const char PAD = '=';
38
39uint8_t* DecodeBase64(const char* str, intptr_t* out_decoded_len) {
40 intptr_t len = strlen(str);
41 if (len == 0 || (len % 4 != 0)) {
42 return nullptr;
43 }
44
45 int pad_length = 0;
46 for (intptr_t i = len - 1; i >= 0; i--) {
47 const uint8_t current_code_unit = str[i];
48 if (decode_table[current_code_unit] > 0) break;
49 if (current_code_unit == PAD) pad_length++;
50 }
51 intptr_t decoded_en = ((len * 6) >> 3) - pad_length;
52 uint8_t* bytes = static_cast<uint8_t*>(malloc(decoded_en));
53
54 for (int i = 0, o = 0; o < decoded_en;) {
55 // Accumulate 4 valid 6 bit Base 64 characters into an int.
56 int x = 0;
57 for (int j = 4; j > 0;) {
58 int c = decode_table[(uint8_t)str[i++]];
59 if (c >= 0) {
60 x = ((x << 6) & 0xFFFFFF) | c;
61 j--;
62 }
63 }
64 bytes[o++] = x >> 16;
65 if (o < decoded_en) {
66 bytes[o++] = (x >> 8) & 0xFF;
67 if (o < decoded_en) bytes[o++] = x & 0xFF;
68 }
69 }
70 if (out_decoded_len != nullptr) {
71 *out_decoded_len = decoded_en;
72 }
73 return bytes;
74}
75
76} // namespace dart
double x
Definition: dart_vm.cc:33
void * malloc(size_t size)
Definition: allocation.cc:19
static const int8_t decode_table[]
Definition: base64.cc:19
static const char PAD
Definition: base64.cc:37
uint8_t * DecodeBase64(const char *str, intptr_t *out_decoded_len)
Definition: base64.cc:39