Mercurial > hg > orthanc
comparison Resources/ThirdParty/base64/base64.cpp @ 3325:2e7c5c15ba25
reserve size for base64 decoding + avoid copy. In a test in WASM, encoding 3MB took 110ms instead of 1400ms previously
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Thu, 21 Mar 2019 09:57:31 +0100 |
parents | f0544ab9396b |
children | b21d4cc8e5d1 |
comparison
equal
deleted
inserted
replaced
3323:a15a4b9d8c00 | 3325:2e7c5c15ba25 |
---|---|
36 | 36 |
37 static inline bool is_base64(unsigned char c) { | 37 static inline bool is_base64(unsigned char c) { |
38 return (isalnum(c) || (c == '+') || (c == '/')); | 38 return (isalnum(c) || (c == '+') || (c == '/')); |
39 } | 39 } |
40 | 40 |
41 std::string base64_encode(const std::string& stringToEncode) | 41 void base64_encode(std::string& result, const std::string& stringToEncode) |
42 { | 42 { |
43 const unsigned char* bytes_to_encode = reinterpret_cast<const unsigned char*> | 43 const unsigned char* bytes_to_encode = reinterpret_cast<const unsigned char*> |
44 (stringToEncode.size() > 0 ? &stringToEncode[0] : NULL); | 44 (stringToEncode.size() > 0 ? &stringToEncode[0] : NULL); |
45 unsigned int in_len = stringToEncode.size(); | 45 size_t in_len = stringToEncode.size(); |
46 | 46 |
47 std::string ret; | 47 result.reserve(result.size() + in_len * 4 / 3 + 10); |
48 | |
48 int i = 0; | 49 int i = 0; |
49 int j = 0; | 50 int j = 0; |
50 unsigned char char_array_3[3]; | 51 unsigned char char_array_3[3]; |
51 unsigned char char_array_4[4]; | 52 unsigned char char_array_4[4]; |
52 | 53 |
57 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); | 58 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); |
58 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); | 59 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); |
59 char_array_4[3] = char_array_3[2] & 0x3f; | 60 char_array_4[3] = char_array_3[2] & 0x3f; |
60 | 61 |
61 for(i = 0; (i <4) ; i++) | 62 for(i = 0; (i <4) ; i++) |
62 ret += base64_chars[char_array_4[i]]; | 63 result += base64_chars[char_array_4[i]]; |
63 i = 0; | 64 i = 0; |
64 } | 65 } |
65 } | 66 } |
66 | 67 |
67 if (i) | 68 if (i) |
73 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); | 74 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); |
74 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); | 75 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); |
75 char_array_4[3] = char_array_3[2] & 0x3f; | 76 char_array_4[3] = char_array_3[2] & 0x3f; |
76 | 77 |
77 for (j = 0; (j < i + 1); j++) | 78 for (j = 0; (j < i + 1); j++) |
78 ret += base64_chars[char_array_4[j]]; | 79 result += base64_chars[char_array_4[j]]; |
79 | 80 |
80 while((i++ < 3)) | 81 while((i++ < 3)) |
81 ret += '='; | 82 result += '='; |
82 | 83 |
83 } | 84 } |
84 | |
85 return ret; | |
86 } | 85 } |
87 | 86 |
88 | 87 |
89 std::string base64_decode(const std::string& encoded_string) { | 88 void base64_decode(std::string& result, const std::string& encoded_string) { |
90 int in_len = encoded_string.size(); | 89 size_t in_len = encoded_string.size(); |
91 int i = 0; | 90 int i = 0; |
92 int j = 0; | 91 int j = 0; |
93 int in_ = 0; | 92 int in_ = 0; |
94 unsigned char char_array_4[4], char_array_3[3]; | 93 unsigned char char_array_4[4], char_array_3[3]; |
95 std::string ret; | 94 |
95 result.reserve(result.size() + in_len * 3 / 4 + 10); | |
96 | 96 |
97 while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { | 97 while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { |
98 char_array_4[i++] = encoded_string[in_]; in_++; | 98 char_array_4[i++] = encoded_string[in_]; in_++; |
99 if (i ==4) { | 99 if (i ==4) { |
100 for (i = 0; i <4; i++) | 100 for (i = 0; i <4; i++) |
103 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); | 103 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); |
104 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); | 104 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); |
105 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; | 105 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; |
106 | 106 |
107 for (i = 0; (i < 3); i++) | 107 for (i = 0; (i < 3); i++) |
108 ret += char_array_3[i]; | 108 result += char_array_3[i]; |
109 i = 0; | 109 i = 0; |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 if (i) { | 113 if (i) { |
119 | 119 |
120 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); | 120 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); |
121 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); | 121 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); |
122 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; | 122 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; |
123 | 123 |
124 for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; | 124 for (j = 0; (j < i - 1); j++) |
125 result += char_array_3[j]; | |
125 } | 126 } |
126 | |
127 return ret; | |
128 } | 127 } |