Remove offset: from Array#pack

* pack.c (pack_pack): can use `@` instead of `offset:`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56958 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2016-12-01 13:20:47 +00:00
parent 0dd9c302d9
commit b6e137e93c
3 changed files with 11 additions and 42 deletions

3
NEWS
View File

@ -42,8 +42,7 @@ with all sufficient information, see the ChangeLog file or Redmine
Now takes multiple arguments. Now takes multiple arguments.
* Array#pack [Feature #12754] * Array#pack [Feature #12754]
Now takes optional arguments `buffer' and `offset' to reuse already Now takes optional argument `buffer:' to reuse already allocated buffer.
allocated buffer.
* Comparable * Comparable

37
pack.c
View File

@ -142,7 +142,6 @@ rb_str_associated(VALUE str)
* call-seq: * call-seq:
* arr.pack( aTemplateString ) -> aBinaryString * arr.pack( aTemplateString ) -> aBinaryString
* arr.pack( aTemplateString, buffer: aBufferString ) -> aBufferString * arr.pack( aTemplateString, buffer: aBufferString ) -> aBufferString
* arr.pack( aTemplateString, buffer: aBufferString, offset: offsetOfBuffer ) -> aBufferString
* *
* Packs the contents of <i>arr</i> into a binary sequence according to * Packs the contents of <i>arr</i> into a binary sequence according to
* the directives in <i>aTemplateString</i> (see the table below) * the directives in <i>aTemplateString</i> (see the table below)
@ -166,10 +165,10 @@ rb_str_associated(VALUE str)
* *
* If <i>aBufferString</i> is specified and its capacity is enough, * If <i>aBufferString</i> is specified and its capacity is enough,
* +pack+ uses it as the buffer and returns it. * +pack+ uses it as the buffer and returns it.
* User can also specify <i>offsetOfBuffer</i>, then the result of +pack+ * When the offset is specified by the beginning of <i>aTemplateString</i>,
* is filled after <i>offsetOfBuffer</i> bytes. * the result is filled after the offset.
* If original contents of <i>aBufferString</i> exists and it's longer than * If original contents of <i>aBufferString</i> exists and it's longer than
* <i>offsetOfBuffer</i>, the rest of <i>offsetOfBuffer</i> are cut. * the offset, the rest of <i>offsetOfBuffer</i> are overwritten by the result.
* If it's shorter, the gap is filled with ``<code>\0</code>''. * If it's shorter, the gap is filled with ``<code>\0</code>''.
* *
* Note that ``buffer:'' option does not guarantee not to allocate memory * Note that ``buffer:'' option does not guarantee not to allocate memory
@ -290,36 +289,16 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
p = RSTRING_PTR(fmt); p = RSTRING_PTR(fmt);
pend = p + RSTRING_LEN(fmt); pend = p + RSTRING_LEN(fmt);
if (!NIL_P(opt)) { if (!NIL_P(opt)) {
static ID keyword_ids[2]; static ID keyword_ids[1];
VALUE kwargs[2];
VALUE voff;
long offset; long offset;
if (!keyword_ids[0]) { if (!keyword_ids[0])
CONST_ID(keyword_ids[0], "buffer"); CONST_ID(keyword_ids[0], "buffer");
CONST_ID(keyword_ids[1], "offset");
}
rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs); rb_get_kwargs(opt, keyword_ids, 0, 1, &buffer);
buffer = kwargs[0];
voff = kwargs[1];
if (buffer == Qundef && !NIL_P(voff)) if (buffer != Qundef && !RB_TYPE_P(buffer, T_STRING))
rb_raise(rb_eArgError, "offset is specified without buffer"); rb_raise(rb_eTypeError, "buffer must be String, not %s", rb_obj_classname(buffer));
if (buffer != Qundef) {
long len;
if (!RB_TYPE_P(buffer, T_STRING))
rb_raise(rb_eTypeError, "buffer must be String, not %s", rb_obj_classname(buffer));
if (voff != Qundef) {
offset = NUM2LONG(voff);
if (rb_str_capacity(buffer) < offset)
rb_raise(rb_eArgError, "buffer is too small for offset");
len = RSTRING_LEN(buffer);
rb_str_set_len(buffer, offset);
if (len < offset)
memset(RSTRING_PTR(buffer) + len, '\0', offset - len);
}
}
} }
if (buffer) if (buffer)
res = buffer; res = buffer;

View File

@ -816,18 +816,9 @@ EXPECTED
def test_pack_with_buffer def test_pack_with_buffer
buf = String.new(capacity: 100) buf = String.new(capacity: 100)
assert_raise_with_message(ArgumentError, /without buffer/) {
[0xDEAD_BEEF].pack('N', offset: 10)
}
assert_raise_with_message(ArgumentError, /too small/) {
[0xDEAD_BEEF].pack('N', buffer: buf, offset: 200)
}
assert_raise_with_message(RuntimeError, /frozen/) { assert_raise_with_message(RuntimeError, /frozen/) {
[0xDEAD_BEEF].pack('N', buffer: 'foo'.freeze) [0xDEAD_BEEF].pack('N', buffer: 'foo'.freeze)
} }
assert_raise_with_message(TypeError, /into Integer/) {
[0xDEAD_BEEF].pack('N', buffer: buf, offset: '10')
}
assert_raise_with_message(TypeError, /must be String/) { assert_raise_with_message(TypeError, /must be String/) {
[0xDEAD_BEEF].pack('N', buffer: Object.new) [0xDEAD_BEEF].pack('N', buffer: Object.new)
} }
@ -837,11 +828,11 @@ EXPECTED
[0xDEAD_BEEF].pack('N', buffer: buf) [0xDEAD_BEEF].pack('N', buffer: buf)
assert_equal "\xDE\xAD\xBE\xEF", buf assert_equal "\xDE\xAD\xBE\xEF", buf
[0xBABE_F00D].pack('N', buffer: buf, offset: 4) [0xBABE_F00D].pack('@4N', buffer: buf)
assert_equal "\xDE\xAD\xBE\xEF\xBA\xBE\xF0\x0D", buf assert_equal "\xDE\xAD\xBE\xEF\xBA\xBE\xF0\x0D", buf
assert_equal addr, [buf].pack('p') assert_equal addr, [buf].pack('p')
[0xBAAD_FACE].pack('N', buffer: buf, offset: 10) [0xBAAD_FACE].pack('@10N', buffer: buf)
assert_equal "\xDE\xAD\xBE\xEF\xBA\xBE\xF0\x0D\0\0\xBA\xAD\xFA\xCE", buf assert_equal "\xDE\xAD\xBE\xEF\xBA\xBE\xF0\x0D\0\0\xBA\xAD\xFA\xCE", buf
assert_equal addr, [buf].pack('p') assert_equal addr, [buf].pack('p')