diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-11-28 12:33:50 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-11-28 12:33:50 +0100 |
commit | f140b49f5f631b09acf7811933d843fe17f06343 (patch) | |
tree | 97d5e77ed73a3864bd8ea4ca7b9ad0af8130e89a | |
parent | 7467e905e558228aab992f85406382518f2e1666 (diff) | |
download | busybox-w32-f140b49f5f631b09acf7811933d843fe17f06343.tar.gz busybox-w32-f140b49f5f631b09acf7811933d843fe17f06343.tar.bz2 busybox-w32-f140b49f5f631b09acf7811933d843fe17f06343.zip |
base32/64: code shrink
function old new delta
decode_base64 178 173 -5
decode_base32 217 186 -31
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-36) Total: -36 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | libbb/uuencode.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/libbb/uuencode.c b/libbb/uuencode.c index 0e6fc8a3c..6205af261 100644 --- a/libbb/uuencode.c +++ b/libbb/uuencode.c | |||
@@ -92,8 +92,8 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) | |||
92 | { | 92 | { |
93 | char *dst = *pp_dst; | 93 | char *dst = *pp_dst; |
94 | unsigned ch = 0; | 94 | unsigned ch = 0; |
95 | unsigned t; | ||
95 | int i = 0; | 96 | int i = 0; |
96 | int t; | ||
97 | 97 | ||
98 | while ((t = (unsigned char)*src) != '\0') { | 98 | while ((t = (unsigned char)*src) != '\0') { |
99 | src++; | 99 | src++; |
@@ -117,11 +117,11 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) | |||
117 | continue; | 117 | continue; |
118 | 118 | ||
119 | ch = (ch << 6) | t; | 119 | ch = (ch << 6) | t; |
120 | if (++i == 4) { | 120 | i = (i + 1) & 3; |
121 | if (i == 0) { | ||
121 | *dst++ = (char) (ch >> 16); | 122 | *dst++ = (char) (ch >> 16); |
122 | *dst++ = (char) (ch >> 8); | 123 | *dst++ = (char) (ch >> 8); |
123 | *dst++ = (char) ch; | 124 | *dst++ = (char) ch; |
124 | i = 0; | ||
125 | if (ch & 0x1000000) { /* was last input char '='? */ | 125 | if (ch & 0x1000000) { /* was last input char '='? */ |
126 | dst--; | 126 | dst--; |
127 | if (ch & (0x1000000 << 6)) /* was it "=="? */ | 127 | if (ch & (0x1000000 << 6)) /* was it "=="? */ |
@@ -140,9 +140,9 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) | |||
140 | const char* FAST_FUNC decode_base32(char **pp_dst, const char *src) | 140 | const char* FAST_FUNC decode_base32(char **pp_dst, const char *src) |
141 | { | 141 | { |
142 | char *dst = *pp_dst; | 142 | char *dst = *pp_dst; |
143 | uint64_t ch = 0; | 143 | int64_t ch = 0; |
144 | unsigned t; | ||
144 | int i = 0; | 145 | int i = 0; |
145 | int t; | ||
146 | 146 | ||
147 | while ((t = (unsigned char)*src) != '\0') { | 147 | while ((t = (unsigned char)*src) != '\0') { |
148 | src++; | 148 | src++; |
@@ -150,44 +150,52 @@ const char* FAST_FUNC decode_base32(char **pp_dst, const char *src) | |||
150 | /* "if" forest is faster than strchr(bb_uuenc_tbl_base32, t) */ | 150 | /* "if" forest is faster than strchr(bb_uuenc_tbl_base32, t) */ |
151 | if (t >= '2' && t <= '7') | 151 | if (t >= '2' && t <= '7') |
152 | t = t - '2' + 26; | 152 | t = t - '2' + 26; |
153 | else if ((t|0x20) >= 'a' && (t|0x20) <= 'z') | ||
154 | t = (t|0x20) - 'a'; | ||
155 | else if (t == '=' && i > 1) | 153 | else if (t == '=' && i > 1) |
156 | t = 0; | 154 | t = 0; |
157 | else | 155 | else { |
156 | t = (t | 0x20) - 'a'; | ||
157 | if (t > 25) | ||
158 | //TODO: add BASE64_FLAG_foo to die on bad char? | 158 | //TODO: add BASE64_FLAG_foo to die on bad char? |
159 | continue; | 159 | continue; |
160 | } | ||
160 | 161 | ||
161 | ch = (ch << 5) | (unsigned)t; /* cast prevents pointless sign-extension of t */ | 162 | ch = (ch << 5) | t; |
162 | if (++i == 8) { | 163 | i = (i + 1) & 7; |
163 | /* testcase: | 164 | if (i == 0) { |
164 | * echo ' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18' | base32 | base32 -d | ||
165 | * IOW, decoding of | ||
166 | * EAYSAMRAGMQDIIBVEA3CANZAHAQDSIBRGAQDCMJAGEZCAMJTEAYTIIBRGUQDCNRAGE3SAMJYBI== | ||
167 | * ==== | ||
168 | * should correctly stitch together the tail. | ||
169 | */ | ||
170 | if (t == 0) { | ||
171 | const char *s = src; | ||
172 | while (*--s == '=') | ||
173 | t--; | ||
174 | } | ||
175 | *dst++ = (char) (ch >> 32); | 165 | *dst++ = (char) (ch >> 32); |
166 | if (src[-1] == '=') /* was last input char '='? */ | ||
167 | goto tail; | ||
176 | *dst++ = (char) (ch >> 24); | 168 | *dst++ = (char) (ch >> 24); |
177 | *dst++ = (char) (ch >> 16); | 169 | *dst++ = (char) (ch >> 16); |
178 | *dst++ = (char) (ch >> 8); | 170 | *dst++ = (char) (ch >> 8); |
179 | *dst++ = (char) ch; | 171 | *dst++ = (char) ch; |
180 | i = 0; | ||
181 | if (t < 0) /* was last input char '='? */ | ||
182 | break; | ||
183 | } | 172 | } |
184 | } | 173 | } |
185 | if (t < 0) /* was last input char '='? */ | ||
186 | /* -t is the count of =, must be 1, 3, 4 or 6 */ | ||
187 | dst -= (-t + 1) * 2 / 3; /* discard last 1, 2, 3 or 4 bytes */ | ||
188 | *pp_dst = dst; | 174 | *pp_dst = dst; |
189 | /* i is zero here if full 8-char block was decoded */ | 175 | /* i is zero here if full 8-char block was decoded */ |
190 | return src - i; | 176 | return src - i; |
177 | tail: | ||
178 | { | ||
179 | const char *s = src; | ||
180 | while (*--s == '=') | ||
181 | i++; | ||
182 | /* Why duplicate the below code? Testcase: | ||
183 | * echo ' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18' | base32 | base32 -d | ||
184 | * IOW, decoding of | ||
185 | * EAYSAMRAGMQDIIBVEA3CANZAHAQDSIBRGAQDCMJAGEZCAMJTEAYTIIBRGUQDCNRAGE3SAMJYBI== | ||
186 | * ==== | ||
187 | * must correctly stitch together the tail, must not overwrite | ||
188 | * the tail before it is analyzed! (we can be decoding in-place) | ||
189 | * Else testcase fails, prints trailing extra NUL bytes. | ||
190 | */ | ||
191 | *dst++ = (char) (ch >> 24); | ||
192 | *dst++ = (char) (ch >> 16); | ||
193 | *dst++ = (char) (ch >> 8); | ||
194 | *dst++ = (char) ch; | ||
195 | dst -= (i+1) * 2 / 3; /* discard last 1, 2, 3 or 4 bytes */ | ||
196 | } | ||
197 | *pp_dst = dst; | ||
198 | return src; | ||
191 | } | 199 | } |
192 | #endif | 200 | #endif |
193 | 201 | ||