summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-10-15 22:57:37 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-10-15 22:57:37 +0000
commiteb68fb0c58a435b06e01f574cafcaf8150f54aeb (patch)
tree4470b324a84bf333b18394bf33a18640e176ada2
parent499d04674c64e71afd7350648803513d183d1afe (diff)
* 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
-rw-r--r--ChangeLog5
-rw-r--r--pack.c83
2 files changed, 51 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index 1c43ed680f..3b2ce6eb13 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* lib/test/unit/collector/dir.rb (Collector::Dir#collect): append base
diff --git a/pack.c b/pack.c
index 7cb6848143..fd0fbd6ac9 100644
--- a/pack.c
+++ b/pack.c
@@ -1297,6 +1297,16 @@ pack_unpack(VALUE str, VALUE fmt)
#ifdef NATINT_PACK
int natint; /* native integer */
#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(fmt);
@@ -1305,7 +1315,7 @@ pack_unpack(VALUE str, VALUE fmt)
p = RSTRING_PTR(fmt);
pend = p + RSTRING_LEN(fmt);
- ary = rb_ary_new();
+ ary = block_p ? Qnil : rb_ary_new();
while (p < pend) {
type = *p++;
#ifdef NATINT_PACK
@@ -1362,7 +1372,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (*t != ' ' && *t != '\0') break;
t--; len--;
}
- rb_ary_push(ary, infected_str_new(s, len, str));
+ UNPACK_PUSH(infected_str_new(s, len, str));
s += end;
}
break;
@@ -1373,7 +1383,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (len > send-s) len = send-s;
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++;
s = star ? t : s+len;
}
@@ -1381,11 +1391,10 @@ pack_unpack(VALUE str, VALUE fmt)
case 'a':
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;
break;
-
case 'b':
{
VALUE bitstr;
@@ -1396,7 +1405,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 8)
len = (send - s) * 8;
bits = 0;
- rb_ary_push(ary, bitstr = rb_str_new(0, len));
+ UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 7) bits >>= 1;
@@ -1416,7 +1425,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 8)
len = (send - s) * 8;
bits = 0;
- rb_ary_push(ary, bitstr = rb_str_new(0, len));
+ UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 7) bits <<= 1;
@@ -1436,7 +1445,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 2)
len = (send - s) * 2;
bits = 0;
- rb_ary_push(ary, bitstr = rb_str_new(0, len));
+ UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 1)
@@ -1458,7 +1467,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (p[-1] == '*' || len > (send - s) * 2)
len = (send - s) * 2;
bits = 0;
- rb_ary_push(ary, bitstr = rb_str_new(0, len));
+ UNPACK_PUSH(bitstr = rb_str_new(0, len));
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 1)
@@ -1475,7 +1484,7 @@ pack_unpack(VALUE str, VALUE fmt)
while (len-- > 0) {
int c = *s++;
if (c > (char)127) c-=256;
- rb_ary_push(ary, INT2FIX(c));
+ UNPACK_PUSH(INT2FIX(c));
}
PACK_ITEM_ADJUST();
break;
@@ -1484,7 +1493,7 @@ pack_unpack(VALUE str, VALUE fmt)
PACK_LENGTH_ADJUST(unsigned char,sizeof(unsigned char));
while (len-- > 0) {
unsigned char c = *s++;
- rb_ary_push(ary, INT2FIX(c));
+ UNPACK_PUSH(INT2FIX(c));
}
PACK_ITEM_ADJUST();
break;
@@ -1496,7 +1505,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(OFF16(&tmp), s, NATINT_LEN(short,2));
EXTEND16(tmp);
s += NATINT_LEN(short,2);
- rb_ary_push(ary, INT2FIX(tmp));
+ UNPACK_PUSH(INT2FIX(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1507,7 +1516,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned short tmp = 0;
memcpy(OFF16(&tmp), 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();
break;
@@ -1518,7 +1527,7 @@ pack_unpack(VALUE str, VALUE fmt)
int tmp;
memcpy(&tmp, s, sizeof(int));
s += sizeof(int);
- rb_ary_push(ary, INT2NUM(tmp));
+ UNPACK_PUSH(INT2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1529,7 +1538,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned int tmp;
memcpy(&tmp, s, sizeof(unsigned int));
s += sizeof(unsigned int);
- rb_ary_push(ary, UINT2NUM(tmp));
+ UNPACK_PUSH(UINT2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1541,7 +1550,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(OFF32(&tmp), s, NATINT_LEN(long,4));
EXTEND32(tmp);
s += NATINT_LEN(long,4);
- rb_ary_push(ary, LONG2NUM(tmp));
+ UNPACK_PUSH(LONG2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1551,7 +1560,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned long tmp = 0;
memcpy(OFF32(&tmp), 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();
break;
@@ -1561,7 +1570,7 @@ pack_unpack(VALUE str, VALUE fmt)
while (len-- > 0) {
char *tmp = (char*)s;
s += QUAD_SIZE;
- rb_ary_push(ary, rb_quad_unpack(tmp, 1));
+ UNPACK_PUSH(rb_quad_unpack(tmp, 1));
}
PACK_ITEM_ADJUST();
break;
@@ -1570,7 +1579,7 @@ pack_unpack(VALUE str, VALUE fmt)
while (len-- > 0) {
char *tmp = (char*)s;
s += QUAD_SIZE;
- rb_ary_push(ary, rb_quad_unpack(tmp, 0));
+ UNPACK_PUSH(rb_quad_unpack(tmp, 0));
}
break;
@@ -1580,7 +1589,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned short tmp = 0;
memcpy(OFF16B(&tmp), 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();
break;
@@ -1591,7 +1600,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned long tmp = 0;
memcpy(OFF32B(&tmp), 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();
break;
@@ -1602,7 +1611,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned short tmp = 0;
memcpy(OFF16(&tmp), 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();
break;
@@ -1613,7 +1622,7 @@ pack_unpack(VALUE str, VALUE fmt)
unsigned long tmp = 0;
memcpy(OFF32(&tmp), 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();
break;
@@ -1625,7 +1634,7 @@ pack_unpack(VALUE str, VALUE fmt)
float tmp;
memcpy(&tmp, 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();
break;
@@ -1639,7 +1648,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(float));
s += sizeof(float);
tmp = VTOHF(tmp,ftmp);
- rb_ary_push(ary, rb_float_new((double)tmp));
+ UNPACK_PUSH(rb_float_new((double)tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1653,7 +1662,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(double));
s += sizeof(double);
tmp = VTOHD(tmp,dtmp);
- rb_ary_push(ary, rb_float_new(tmp));
+ UNPACK_PUSH(rb_float_new(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1665,7 +1674,7 @@ pack_unpack(VALUE str, VALUE fmt)
double tmp;
memcpy(&tmp, s, sizeof(double));
s += sizeof(double);
- rb_ary_push(ary, rb_float_new(tmp));
+ UNPACK_PUSH(rb_float_new(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1679,7 +1688,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(float));
s += sizeof(float);
tmp = NTOHF(tmp,ftmp);
- rb_ary_push(ary, rb_float_new((double)tmp));
+ UNPACK_PUSH(rb_float_new((double)tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1693,7 +1702,7 @@ pack_unpack(VALUE str, VALUE fmt)
memcpy(&tmp, s, sizeof(double));
s += sizeof(double);
tmp = NTOHD(tmp,dtmp);
- rb_ary_push(ary, rb_float_new(tmp));
+ UNPACK_PUSH(rb_float_new(tmp));
}
PACK_ITEM_ADJUST();
break;
@@ -1706,7 +1715,7 @@ pack_unpack(VALUE str, VALUE fmt)
l = utf8_to_uv(s, &alen);
s += alen; len--;
- rb_ary_push(ary, ULONG2NUM(l));
+ UNPACK_PUSH(ULONG2NUM(l));
}
break;
@@ -1761,7 +1770,7 @@ pack_unpack(VALUE str, VALUE fmt)
}
rb_str_set_len(buf, total);
- rb_ary_push(ary, buf);
+ UNPACK_PUSH(buf);
}
break;
@@ -1804,7 +1813,7 @@ pack_unpack(VALUE str, VALUE fmt)
}
}
rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
- rb_ary_push(ary, buf);
+ UNPACK_PUSH(buf);
}
break;
@@ -1832,7 +1841,7 @@ pack_unpack(VALUE str, VALUE fmt)
s++;
}
rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
- rb_ary_push(ary, buf);
+ UNPACK_PUSH(buf);
}
break;
@@ -1890,7 +1899,7 @@ pack_unpack(VALUE str, VALUE fmt)
else {
tmp = Qnil;
}
- rb_ary_push(ary, tmp);
+ UNPACK_PUSH(tmp);
}
break;
@@ -1929,7 +1938,7 @@ pack_unpack(VALUE str, VALUE fmt)
else {
tmp = Qnil;
}
- rb_ary_push(ary, tmp);
+ UNPACK_PUSH(tmp);
}
}
break;
@@ -1943,7 +1952,7 @@ pack_unpack(VALUE str, VALUE fmt)
ul <<= 7;
ul |= (*s & 0x7f);
if (!(*s++ & 0x80)) {
- rb_ary_push(ary, ULONG2NUM(ul));
+ UNPACK_PUSH(ULONG2NUM(ul));
len--;
ul = 0;
}
@@ -1954,7 +1963,7 @@ pack_unpack(VALUE str, VALUE fmt)
big = rb_big_mul(big, big128);
big = rb_big_plus(big, rb_uint2big(*s & 0x7f));
if (!(*s++ & 0x80)) {
- rb_ary_push(ary, big);
+ UNPACK_PUSH(big);
len--;
ul = 0;
break;