From: WATANABE Hirofumi Date: 1997-10-06T18:38:17+09:00 Subject: [ruby-dev:650] Re: pack/unpack base64 わたなべです. Yukihiro Matsumoto writes: :パッチください.1.1には取り込みましょう. unpack のほうはひとつにするのは難しいので, 別々になってます. もうちょっといじるかもしれない. -- わたなべひろふみ --- pack.c.orig Tue Aug 19 16:23:58 1997 +++ pack.c Mon Oct 6 18:29:50 1997 @@ -444,2 +444,3 @@ case 'u': + case 'm': from = obj_as_string(NEXTFROM); @@ -459,3 +460,3 @@ todo = plen; - encodes(res, ptr, todo); + encodes(res, ptr, todo, type); plen -= todo; @@ -473,4 +474,9 @@ +static char uu_table[64] = +"`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; +static char b64_table[64] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + static void -encodes(str, s, len) +encodes(str, s, len, type) struct RString *str; @@ -478,2 +484,3 @@ int len; + int type; { @@ -481,10 +488,13 @@ UCHAR *p, *pend; + char *trans = type == 'u' ? uu_table : b64_table; - *hunk = len + ' '; - str_cat(str, hunk, 1); + if (type == 'u') { + *hunk = len + ' '; + str_cat(str, hunk, 1); + } while (len > 0) { - hunk[0] = ' ' + (077 & (*s >> 2)); - hunk[1] = ' ' + (077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))); - hunk[2] = ' ' + (077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))); - hunk[3] = ' ' + (077 & (s[2] & 077)); + hunk[0] = trans[077 & (*s >> 2)]; + hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; + hunk[3] = trans[077 & s[2]]; str_cat(str, hunk, 4); @@ -495,6 +505,10 @@ pend = str->ptr + str->len; - while (p < pend) { - if (*p == ' ') - *p = '`'; - p++; + if (type != 'u') { + if (len == -1) { + pend[-1] = '='; + } + else if (len == -2) { + pend[-2] = '='; + pend[-1] = '='; + } } @@ -849,2 +863,53 @@ RSTRING(str)->len = total; + ary_push(ary, str); + } + break; + + case 'm': + { + VALUE str = str_new(0, (send - s)*3/4); + UCHAR *ptr = RSTRING(str)->ptr; + int total = 0; + int a,b,c,d; + static int first = 1; + static int b64_xtable[256]; + + if (first) { + int i; + first = 0; + + for (i = 0; i < 256; i++) { + b64_xtable[i] = -1; + } + for (i = 0; i < 64; i++) { + b64_xtable[b64_table[i]] = i; + } + } + for (;;) { + char hunk[3]; + while (*s == '\r' || *s == '\n') { s++; } + if ((a = b64_xtable[s[0]]) == -1) break; + while (*s == '\r' || *s == '\n') { s++; } + if ((b = b64_xtable[s[1]]) == -1) break; + while (*s == '\r' || *s == '\n') { s++; } + if ((c = b64_xtable[s[2]]) == -1) break; + while (*s == '\r' || *s == '\n') { s++; } + if ((d = b64_xtable[s[3]]) == -1) break; + hunk[0] = a << 2 | b >> 4; + hunk[1] = b << 4 | c >> 2; + hunk[2] = c << 6 | d; + memcpy(ptr, hunk, 3); + ptr += 3; + s += 4; + } + if (a != -1 && b != -1 && s[2] == '=') { + ptr[0] = a << 2 | b >> 4; + ptr++; + } + if (a != -1 && b != -1 && c != -1 && s[3] == '=') { + ptr[0] = a << 2 | b >> 4; + ptr[1] = b << 4 | c >> 2; + ptr += 2; + } + RSTRING(str)->len = ptr - RSTRING(str)->ptr; ary_push(ary, str);