* pack.c (pack_unpack): execute block if given with unpacked value

instead of creating an array.  an idea from Tim Bray.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11175 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2006-10-15 22:57:37 +00:00
parent 499d04674c
commit eb68fb0c58
2 changed files with 51 additions and 37 deletions

View File

@ -1,3 +1,8 @@
Mon Oct 16 00:44:26 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* pack.c (pack_unpack): execute block if given with unpacked value
instead of creating an array. an idea from Tim Bray.
Sun Oct 15 01:03:08 2006 Nobuyoshi Nakada <nobu@ruby-lang.org> Sun Oct 15 01:03:08 2006 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/test/unit/collector/dir.rb (Collector::Dir#collect): append base * lib/test/unit/collector/dir.rb (Collector::Dir#collect): append base

83
pack.c
View File

@ -1297,6 +1297,16 @@ pack_unpack(VALUE str, VALUE fmt)
#ifdef NATINT_PACK #ifdef NATINT_PACK
int natint; /* native integer */ int natint; /* native integer */
#endif #endif
int block_p = rb_block_given_p();
#define UNPACK_PUSH(item) do {\
VALUE item_val = (item);\
if (block_p) {\
rb_yield(item_val);\
}\
else {\
rb_ary_push(ary, item_val);\
}\
} while (0)
StringValue(str); StringValue(str);
StringValue(fmt); StringValue(fmt);
@ -1305,7 +1315,7 @@ pack_unpack(VALUE str, VALUE fmt)
p = RSTRING_PTR(fmt); p = RSTRING_PTR(fmt);
pend = p + RSTRING_LEN(fmt); pend = p + RSTRING_LEN(fmt);
ary = rb_ary_new(); ary = block_p ? Qnil : rb_ary_new();
while (p < pend) { while (p < pend) {
type = *p++; type = *p++;
#ifdef NATINT_PACK #ifdef NATINT_PACK
@ -1362,7 +1372,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (*t != ' ' && *t != '\0') break; if (*t != ' ' && *t != '\0') break;
t--; len--; t--; len--;
} }
rb_ary_push(ary, infected_str_new(s, len, str)); UNPACK_PUSH(infected_str_new(s, len, str));
s += end; s += end;
} }
break; break;
@ -1373,7 +1383,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (len > send-s) len = send-s; if (len > send-s) len = send-s;
while (t < s+len && *t) t++; while (t < s+len && *t) t++;
rb_ary_push(ary, infected_str_new(s, t-s, str)); UNPACK_PUSH(infected_str_new(s, t-s, str));
if (t < send) t++; if (t < send) t++;
s = star ? t : s+len; s = star ? t : s+len;
} }
@ -1381,11 +1391,10 @@ pack_unpack(VALUE str, VALUE fmt)
case 'a': case 'a':
if (len > send - s) len = send - s; if (len > send - s) len = send - s;
rb_ary_push(ary, infected_str_new(s, len, str)); UNPACK_PUSH(infected_str_new(s, len, str));
s += len; s += len;
break; break;
case 'b': case 'b':
{ {
VALUE bitstr; VALUE bitstr;
@ -1396,7 +1405,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 8) if (p[-1] == '*' || len > (send - s) * 8)
len = (send - s) * 8; len = (send - s) * 8;
bits = 0; bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len)); UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 7) bits >>= 1; if (i & 7) bits >>= 1;
@ -1416,7 +1425,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 8) if (p[-1] == '*' || len > (send - s) * 8)
len = (send - s) * 8; len = (send - s) * 8;
bits = 0; bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len)); UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 7) bits <<= 1; if (i & 7) bits <<= 1;
@ -1436,7 +1445,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 2) if (p[-1] == '*' || len > (send - s) * 2)
len = (send - s) * 2; len = (send - s) * 2;
bits = 0; bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len)); UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 1) if (i & 1)
@ -1458,7 +1467,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 2) if (p[-1] == '*' || len > (send - s) * 2)
len = (send - s) * 2; len = (send - s) * 2;
bits = 0; bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len)); UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 1) if (i & 1)
@ -1475,7 +1484,7 @@ pack_unpack(VALUE str, VALUE fmt)
while (len-- > 0) { while (len-- > 0) {
int c = *s++; int c = *s++;
if (c > (char)127) c-=256; if (c > (char)127) c-=256;
rb_ary_push(ary, INT2FIX(c)); UNPACK_PUSH(INT2FIX(c));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1484,7 +1493,7 @@ pack_unpack(VALUE str, VALUE fmt)
PACK_LENGTH_ADJUST(unsigned char,sizeof(unsigned char)); PACK_LENGTH_ADJUST(unsigned char,sizeof(unsigned char));
while (len-- > 0) { while (len-- > 0) {
unsigned char c = *s++; unsigned char c = *s++;
rb_ary_push(ary, INT2FIX(c)); UNPACK_PUSH(INT2FIX(c));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1496,7 +1505,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(OFF16(&tmp), s, NATINT_LEN(short,2)); memcpy(OFF16(&tmp), s, NATINT_LEN(short,2));
EXTEND16(tmp); EXTEND16(tmp);
s += NATINT_LEN(short,2); s += NATINT_LEN(short,2);
rb_ary_push(ary, INT2FIX(tmp)); UNPACK_PUSH(INT2FIX(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1507,7 +1516,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned short tmp = 0; unsigned short tmp = 0;
memcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2)); memcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2));
s += NATINT_LEN(unsigned short,2); s += NATINT_LEN(unsigned short,2);
rb_ary_push(ary, INT2FIX(tmp)); UNPACK_PUSH(INT2FIX(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1518,7 +1527,7 @@ pack_unpack(VALUE str, VALUE fmt)
int tmp; int tmp;
memcpy(&tmp, s, sizeof(int)); memcpy(&tmp, s, sizeof(int));
s += sizeof(int); s += sizeof(int);
rb_ary_push(ary, INT2NUM(tmp)); UNPACK_PUSH(INT2NUM(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1529,7 +1538,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned int tmp; unsigned int tmp;
memcpy(&tmp, s, sizeof(unsigned int)); memcpy(&tmp, s, sizeof(unsigned int));
s += sizeof(unsigned int); s += sizeof(unsigned int);
rb_ary_push(ary, UINT2NUM(tmp)); UNPACK_PUSH(UINT2NUM(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1541,7 +1550,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(OFF32(&tmp), s, NATINT_LEN(long,4)); memcpy(OFF32(&tmp), s, NATINT_LEN(long,4));
EXTEND32(tmp); EXTEND32(tmp);
s += NATINT_LEN(long,4); s += NATINT_LEN(long,4);
rb_ary_push(ary, LONG2NUM(tmp)); UNPACK_PUSH(LONG2NUM(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1551,7 +1560,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned long tmp = 0; unsigned long tmp = 0;
memcpy(OFF32(&tmp), s, NATINT_LEN(unsigned long,4)); memcpy(OFF32(&tmp), s, NATINT_LEN(unsigned long,4));
s += NATINT_LEN(unsigned long,4); s += NATINT_LEN(unsigned long,4);
rb_ary_push(ary, ULONG2NUM(tmp)); UNPACK_PUSH(ULONG2NUM(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1561,7 +1570,7 @@ pack_unpack(VALUE str, VALUE fmt)
while (len-- > 0) { while (len-- > 0) {
char *tmp = (char*)s; char *tmp = (char*)s;
s += QUAD_SIZE; s += QUAD_SIZE;
rb_ary_push(ary, rb_quad_unpack(tmp, 1)); UNPACK_PUSH(rb_quad_unpack(tmp, 1));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1570,7 +1579,7 @@ pack_unpack(VALUE str, VALUE fmt)
while (len-- > 0) { while (len-- > 0) {
char *tmp = (char*)s; char *tmp = (char*)s;
s += QUAD_SIZE; s += QUAD_SIZE;
rb_ary_push(ary, rb_quad_unpack(tmp, 0)); UNPACK_PUSH(rb_quad_unpack(tmp, 0));
} }
break; break;
@ -1580,7 +1589,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned short tmp = 0; unsigned short tmp = 0;
memcpy(OFF16B(&tmp), s, NATINT_LEN(unsigned short,2)); memcpy(OFF16B(&tmp), s, NATINT_LEN(unsigned short,2));
s += NATINT_LEN(unsigned short,2); s += NATINT_LEN(unsigned short,2);
rb_ary_push(ary, UINT2NUM(ntohs(tmp))); UNPACK_PUSH(UINT2NUM(ntohs(tmp)));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1591,7 +1600,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned long tmp = 0; unsigned long tmp = 0;
memcpy(OFF32B(&tmp), s, NATINT_LEN(unsigned long,4)); memcpy(OFF32B(&tmp), s, NATINT_LEN(unsigned long,4));
s += NATINT_LEN(unsigned long,4); s += NATINT_LEN(unsigned long,4);
rb_ary_push(ary, ULONG2NUM(ntohl(tmp))); UNPACK_PUSH(ULONG2NUM(ntohl(tmp)));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1602,7 +1611,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned short tmp = 0; unsigned short tmp = 0;
memcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2)); memcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2));
s += NATINT_LEN(unsigned short,2); s += NATINT_LEN(unsigned short,2);
rb_ary_push(ary, UINT2NUM(vtohs(tmp))); UNPACK_PUSH(UINT2NUM(vtohs(tmp)));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1613,7 +1622,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned long tmp = 0; unsigned long tmp = 0;
memcpy(OFF32(&tmp), s, NATINT_LEN(long,4)); memcpy(OFF32(&tmp), s, NATINT_LEN(long,4));
s += NATINT_LEN(long,4); s += NATINT_LEN(long,4);
rb_ary_push(ary, ULONG2NUM(vtohl(tmp))); UNPACK_PUSH(ULONG2NUM(vtohl(tmp)));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1625,7 +1634,7 @@ pack_unpack(VALUE str, VALUE fmt)
float tmp; float tmp;
memcpy(&tmp, s, sizeof(float)); memcpy(&tmp, s, sizeof(float));
s += sizeof(float); s += sizeof(float);
rb_ary_push(ary, rb_float_new((double)tmp)); UNPACK_PUSH(rb_float_new((double)tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1639,7 +1648,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(float)); memcpy(&tmp, s, sizeof(float));
s += sizeof(float); s += sizeof(float);
tmp = VTOHF(tmp,ftmp); tmp = VTOHF(tmp,ftmp);
rb_ary_push(ary, rb_float_new((double)tmp)); UNPACK_PUSH(rb_float_new((double)tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1653,7 +1662,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(double)); memcpy(&tmp, s, sizeof(double));
s += sizeof(double); s += sizeof(double);
tmp = VTOHD(tmp,dtmp); tmp = VTOHD(tmp,dtmp);
rb_ary_push(ary, rb_float_new(tmp)); UNPACK_PUSH(rb_float_new(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1665,7 +1674,7 @@ pack_unpack(VALUE str, VALUE fmt)
double tmp; double tmp;
memcpy(&tmp, s, sizeof(double)); memcpy(&tmp, s, sizeof(double));
s += sizeof(double); s += sizeof(double);
rb_ary_push(ary, rb_float_new(tmp)); UNPACK_PUSH(rb_float_new(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1679,7 +1688,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(float)); memcpy(&tmp, s, sizeof(float));
s += sizeof(float); s += sizeof(float);
tmp = NTOHF(tmp,ftmp); tmp = NTOHF(tmp,ftmp);
rb_ary_push(ary, rb_float_new((double)tmp)); UNPACK_PUSH(rb_float_new((double)tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1693,7 +1702,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(double)); memcpy(&tmp, s, sizeof(double));
s += sizeof(double); s += sizeof(double);
tmp = NTOHD(tmp,dtmp); tmp = NTOHD(tmp,dtmp);
rb_ary_push(ary, rb_float_new(tmp)); UNPACK_PUSH(rb_float_new(tmp));
} }
PACK_ITEM_ADJUST(); PACK_ITEM_ADJUST();
break; break;
@ -1706,7 +1715,7 @@ pack_unpack(VALUE str, VALUE fmt)
l = utf8_to_uv(s, &alen); l = utf8_to_uv(s, &alen);
s += alen; len--; s += alen; len--;
rb_ary_push(ary, ULONG2NUM(l)); UNPACK_PUSH(ULONG2NUM(l));
} }
break; break;
@ -1761,7 +1770,7 @@ pack_unpack(VALUE str, VALUE fmt)
} }
rb_str_set_len(buf, total); rb_str_set_len(buf, total);
rb_ary_push(ary, buf); UNPACK_PUSH(buf);
} }
break; break;
@ -1804,7 +1813,7 @@ pack_unpack(VALUE str, VALUE fmt)
} }
} }
rb_str_set_len(buf, ptr - RSTRING_PTR(buf)); rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
rb_ary_push(ary, buf); UNPACK_PUSH(buf);
} }
break; break;
@ -1832,7 +1841,7 @@ pack_unpack(VALUE str, VALUE fmt)
s++; s++;
} }
rb_str_set_len(buf, ptr - RSTRING_PTR(buf)); rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
rb_ary_push(ary, buf); UNPACK_PUSH(buf);
} }
break; break;
@ -1890,7 +1899,7 @@ pack_unpack(VALUE str, VALUE fmt)
else { else {
tmp = Qnil; tmp = Qnil;
} }
rb_ary_push(ary, tmp); UNPACK_PUSH(tmp);
} }
break; break;
@ -1929,7 +1938,7 @@ pack_unpack(VALUE str, VALUE fmt)
else { else {
tmp = Qnil; tmp = Qnil;
} }
rb_ary_push(ary, tmp); UNPACK_PUSH(tmp);
} }
} }
break; break;
@ -1943,7 +1952,7 @@ pack_unpack(VALUE str, VALUE fmt)
ul <<= 7; ul <<= 7;
ul |= (*s & 0x7f); ul |= (*s & 0x7f);
if (!(*s++ & 0x80)) { if (!(*s++ & 0x80)) {
rb_ary_push(ary, ULONG2NUM(ul)); UNPACK_PUSH(ULONG2NUM(ul));
len--; len--;
ul = 0; ul = 0;
} }
@ -1954,7 +1963,7 @@ pack_unpack(VALUE str, VALUE fmt)
big = rb_big_mul(big, big128); big = rb_big_mul(big, big128);
big = rb_big_plus(big, rb_uint2big(*s & 0x7f)); big = rb_big_plus(big, rb_uint2big(*s & 0x7f));
if (!(*s++ & 0x80)) { if (!(*s++ & 0x80)) {
rb_ary_push(ary, big); UNPACK_PUSH(big);
len--; len--;
ul = 0; ul = 0;
break; break;