summaryrefslogtreecommitdiff
path: root/pack.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-05-13 02:04:20 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-05-13 02:04:20 +0000
commitf667eda104abd5262c64be5eb6d4ae2c0b838b7a (patch)
treef1b1c9b475c9df71cd36b2e3b646478b92150f81 /pack.c
parentf061990c15f5b554287063239f48531594180643 (diff)
* pack.c (pack_pack): always add with null for 'Z'.
* pack.c (pack_unpack): terminated by null for 'Z'. [ruby-talk:98281] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6298 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/pack.c b/pack.c
index 4edffd3..33650aa 100644
--- a/pack.c
+++ b/pack.c
@@ -469,7 +469,7 @@ static unsigned long utf8_to_uv _((char*,long*));
* w | BER-compressed integer\fnm
* X | Back up a byte
* x | Null byte
- * Z | Same as ``A''
+ * Z | Same as ``a'', except that null is added with *
*/
static VALUE
@@ -558,8 +558,11 @@ pack_pack(ary, fmt)
case 'a': /* arbitrary binary string (null padded) */
case 'A': /* ASCII string (space padded) */
case 'Z': /* null terminated ASCII string */
- if (plen >= len)
+ if (plen >= len) {
rb_str_buf_cat(res, ptr, len);
+ if (p[-1] == '*' && type == 'Z')
+ rb_str_buf_cat(res, nul10, 1);
+ }
else {
rb_str_buf_cat(res, ptr, plen);
len -= plen;
@@ -1239,6 +1242,7 @@ infected_str_new(ptr, len, str)
*
* "abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]
* "abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"]
+ * "abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "]
* "aa".unpack('b8B8') #=> ["10000110", "01100001"]
* "aaa".unpack('h2H2c') #=> ["16", "61", 97]
* "\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534]
@@ -1350,6 +1354,7 @@ infected_str_new(ptr, len, str)
* x | --- | skip forward one character
* -------+---------+-----------------------------------------
* Z | String | with trailing nulls removed
+ * | | upto first null with *
* -------+---------+-----------------------------------------
* @ | --- | skip to the offset given by the
* | | length argument
@@ -1441,17 +1446,14 @@ pack_unpack(str, fmt)
break;
case 'Z':
- if (len > send - s) len = send - s;
{
- long end = len;
- char *t = s + len - 1;
+ char *t = s;
- while (t >= s) {
- if (*t) break;
- t--; len--;
- }
- rb_ary_push(ary, infected_str_new(s, len, str));
- s += end;
+ if (len > send-s) len = send-s;
+ while (t < s+len && *t) t++;
+ rb_ary_push(ary, infected_str_new(s, t-s, str));
+ if (t < send) t++;
+ s = star ? t : s+len;
}
break;