зеркало из https://github.com/github/ruby.git
* pack.c (pack_{un,}pack): new template character `j` and `J`, pointer
with signed and unsigned integers. * NEWS: mention bout this featre. [Feature #11215] [ruby-dev:49015] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50849 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
2bc2802096
Коммит
dc0d502b71
|
@ -1,3 +1,11 @@
|
|||
Fri Jun 12 21:17:46 2015 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* pack.c (pack_{un,}pack): new template character `j` and `J`, pointer
|
||||
with signed and unsigned integers.
|
||||
|
||||
* NEWS: mention bout this featre.
|
||||
[Feature #11215] [ruby-dev:49015]
|
||||
|
||||
Fri Jun 12 21:01:44 2015 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* file.c (File::SHARE_DELETE): new flag to be able to delete opened file
|
||||
|
|
4
NEWS
4
NEWS
|
@ -48,6 +48,10 @@ with all sufficient information, see the ChangeLog file.
|
|||
* IO
|
||||
* IO#close doesn't raise when the IO object is closed. [Feature #10718]
|
||||
|
||||
* pack/unpack (Array/String)
|
||||
* j and J directives for pointer width integer type. [Feature #11215]
|
||||
|
||||
|
||||
=== Stdlib updates (outstanding ones only)
|
||||
|
||||
* Socket
|
||||
|
|
60
pack.c
60
pack.c
|
@ -23,11 +23,11 @@
|
|||
* This behavior is consistent with the document of pack/unpack.
|
||||
*/
|
||||
#ifdef HAVE_TRUE_LONG_LONG
|
||||
static const char natstr[] = "sSiIlLqQ";
|
||||
static const char natstr[] = "sSiIlLqQjJ";
|
||||
#else
|
||||
static const char natstr[] = "sSiIlL";
|
||||
static const char natstr[] = "sSiIlLjJ";
|
||||
#endif
|
||||
static const char endstr[] = "sSiIlLqQ";
|
||||
static const char endstr[] = "sSiIlLqQjJ";
|
||||
|
||||
#ifdef HAVE_TRUE_LONG_LONG
|
||||
/* It is intentional to use long long instead of LONG_LONG. */
|
||||
|
@ -264,11 +264,15 @@ rb_str_associated(VALUE str)
|
|||
* S | Integer | 16-bit unsigned, native endian (uint16_t)
|
||||
* L | Integer | 32-bit unsigned, native endian (uint32_t)
|
||||
* Q | Integer | 64-bit unsigned, native endian (uint64_t)
|
||||
* J | Integer | pointer width unsigned, native endian (uintptr_t)
|
||||
* | | (J is available since Ruby 2.3.)
|
||||
* | |
|
||||
* c | Integer | 8-bit signed (signed char)
|
||||
* s | Integer | 16-bit signed, native endian (int16_t)
|
||||
* l | Integer | 32-bit signed, native endian (int32_t)
|
||||
* q | Integer | 64-bit signed, native endian (int64_t)
|
||||
* j | Integer | pointer width signed, native endian (intptr_t)
|
||||
* | | (j is available since Ruby 2.3.)
|
||||
* | |
|
||||
* S_, S! | Integer | unsigned short, native endian
|
||||
* I, I_, I! | Integer | unsigned int, native endian
|
||||
|
@ -276,6 +280,8 @@ rb_str_associated(VALUE str)
|
|||
* Q_, Q! | Integer | unsigned long long, native endian (ArgumentError
|
||||
* | | if the platform has no long long type.)
|
||||
* | | (Q_ and Q! is available since Ruby 2.1.)
|
||||
* J! | Integer | uintptr_t, native endian (same with J)
|
||||
* | | (J! is available since Ruby 2.3.)
|
||||
* | |
|
||||
* s_, s! | Integer | signed short, native endian
|
||||
* i, i_, i! | Integer | signed int, native endian
|
||||
|
@ -283,20 +289,26 @@ rb_str_associated(VALUE str)
|
|||
* q_, q! | Integer | signed long long, native endian (ArgumentError
|
||||
* | | if the platform has no long long type.)
|
||||
* | | (q_ and q! is available since Ruby 2.1.)
|
||||
* j! | Integer | intptr_t, native endian (same with j)
|
||||
* | | (j! is available since Ruby 2.3.)
|
||||
* | |
|
||||
* S> L> Q> | Integer | same as the directives without ">" except
|
||||
* s> l> q> | | big endian
|
||||
* S!> I!> | | (available since Ruby 1.9.3)
|
||||
* L!> Q!> | | "S>" is same as "n"
|
||||
* s!> i!> | | "L>" is same as "N"
|
||||
* l!> q!> | |
|
||||
* J> s> l> | | big endian
|
||||
* q> j> | | (available since Ruby 1.9.3)
|
||||
* S!> I!> | | "S>" is same as "n"
|
||||
* L!> Q!> | | "L>" is same as "N"
|
||||
* J!> s!> | |
|
||||
* i!> l!> | |
|
||||
* q!> j!> | |
|
||||
* | |
|
||||
* S< L< Q< | Integer | same as the directives without "<" except
|
||||
* s< l< q< | | little endian
|
||||
* S!< I!< | | (available since Ruby 1.9.3)
|
||||
* L!< Q!< | | "S<" is same as "v"
|
||||
* s!< i!< | | "L<" is same as "V"
|
||||
* l!< q!< | |
|
||||
* J< s< l< | | little endian
|
||||
* q< j< | | (available since Ruby 1.9.3)
|
||||
* S!< I!< | | "S<" is same as "v"
|
||||
* L!< Q!< | | "L<" is same as "V"
|
||||
* J!< s!< | |
|
||||
* i!< l!< | |
|
||||
* q!< j!< | |
|
||||
* | |
|
||||
* n | Integer | 16-bit unsigned, network (big-endian) byte order
|
||||
* N | Integer | 32-bit unsigned, network (big-endian) byte order
|
||||
|
@ -658,6 +670,16 @@ pack_pack(VALUE ary, VALUE fmt)
|
|||
bigendian_p = BIGENDIAN_P();
|
||||
goto pack_integer;
|
||||
|
||||
case 'j': /* j for intptr_t */
|
||||
integer_size = sizeof(intptr_t);
|
||||
bigendian_p = BIGENDIAN_P();
|
||||
goto pack_integer;
|
||||
|
||||
case 'J': /* J for uintptr_t */
|
||||
integer_size = sizeof(uintptr_t);
|
||||
bigendian_p = BIGENDIAN_P();
|
||||
goto pack_integer;
|
||||
|
||||
case 'n': /* 16 bit (2 bytes) integer (network byte-order) */
|
||||
integer_size = 2;
|
||||
bigendian_p = 1;
|
||||
|
@ -1480,6 +1502,18 @@ pack_unpack(VALUE str, VALUE fmt)
|
|||
bigendian_p = BIGENDIAN_P();
|
||||
goto unpack_integer;
|
||||
|
||||
case 'j':
|
||||
signed_p = 1;
|
||||
integer_size = sizeof(intptr_t);
|
||||
bigendian_p = BIGENDIAN_P();
|
||||
goto unpack_integer;
|
||||
|
||||
case 'J':
|
||||
signed_p = 0;
|
||||
integer_size = sizeof(uintptr_t);
|
||||
bigendian_p = BIGENDIAN_P();
|
||||
goto unpack_integer;
|
||||
|
||||
case 'n':
|
||||
signed_p = 0;
|
||||
integer_size = 2;
|
||||
|
|
|
@ -78,6 +78,14 @@ class TestPack < Test::Unit::TestCase
|
|||
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("L"+mod))
|
||||
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("q"+mod))
|
||||
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("Q"+mod))
|
||||
psize = [nil].pack('p').bytesize
|
||||
if psize == 4
|
||||
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("j"+mod))
|
||||
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("J"+mod))
|
||||
elsif psize == 8
|
||||
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("j"+mod))
|
||||
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("J"+mod))
|
||||
end
|
||||
assert_match(/\A\x00*\x01\x02\z/, [0x0102].pack("s!"+mod))
|
||||
assert_match(/\A\x00*\x01\x02\z/, [0x0102].pack("S!"+mod))
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("i"+mod))
|
||||
|
@ -86,7 +94,14 @@ class TestPack < Test::Unit::TestCase
|
|||
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("I!"+mod))
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("l!"+mod))
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("L!"+mod))
|
||||
%w[s S l L q Q s! S! i I i! I! l! L!].each {|fmt|
|
||||
if psize == 4
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("j!"+mod))
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("J!"+mod))
|
||||
elsif psize == 8
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\x05\x06\x07\x08\z/, [0x0102030405060708].pack("j!"+mod))
|
||||
assert_match(/\A\x00*\x01\x02\x03\x04\x05\x06\x07\x08\z/, [0x0102030405060708].pack("J!"+mod))
|
||||
end
|
||||
%w[s S l L q Q j J s! S! i I i! I! l! L! j! J!].each {|fmt|
|
||||
fmt += mod
|
||||
nuls = [0].pack(fmt)
|
||||
v = 0
|
||||
|
@ -111,6 +126,14 @@ class TestPack < Test::Unit::TestCase
|
|||
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("L"+mod))
|
||||
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("q"+mod))
|
||||
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("Q"+mod))
|
||||
psize = [nil].pack('p').bytesize
|
||||
if psize == 4
|
||||
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("j"+mod))
|
||||
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("J"+mod))
|
||||
elsif psize == 8
|
||||
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("j"+mod))
|
||||
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("J"+mod))
|
||||
end
|
||||
assert_match(/\A\x02\x01\x00*\z/, [0x0102].pack("s!"+mod))
|
||||
assert_match(/\A\x02\x01\x00*\z/, [0x0102].pack("S!"+mod))
|
||||
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("i"+mod))
|
||||
|
@ -119,7 +142,14 @@ class TestPack < Test::Unit::TestCase
|
|||
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("I!"+mod))
|
||||
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("l!"+mod))
|
||||
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("L!"+mod))
|
||||
%w[s S l L q Q s! S! i I i! I! l! L!].each {|fmt|
|
||||
if psize == 4
|
||||
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("j!"+mod))
|
||||
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("J!"+mod))
|
||||
elsif psize == 8
|
||||
assert_match(/\A\x08\x07\x06\x05\x04\x03\x02\x01\x00*\z/, [0x0102030405060708].pack("j!"+mod))
|
||||
assert_match(/\A\x08\x07\x06\x05\x04\x03\x02\x01\x00*\z/, [0x0102030405060708].pack("J!"+mod))
|
||||
end
|
||||
%w[s S l L q Q j J s! S! i I i! I! l! L! j! J!].each {|fmt|
|
||||
fmt += mod
|
||||
nuls = [0].pack(fmt)
|
||||
v = 0
|
||||
|
@ -417,6 +447,43 @@ class TestPack < Test::Unit::TestCase
|
|||
assert_operator(8, :<=, [1].pack("Q!").bytesize)
|
||||
end
|
||||
|
||||
def test_pack_unpack_jJ
|
||||
# Note: we assume that the size of intptr_t and uintptr_t equals to the size
|
||||
# of real pointer.
|
||||
psize = [nil].pack("p").bytesize
|
||||
if psize == 4
|
||||
s1 = [67305985, -50462977].pack("j*")
|
||||
s2 = [67305985, 4244504319].pack("J*")
|
||||
assert_equal(s1, s2)
|
||||
assert_equal([67305985, -50462977], s2.unpack("j*"))
|
||||
assert_equal([67305985, 4244504319], s1.unpack("J*"))
|
||||
|
||||
s1 = [67305985, -50462977].pack("j!*")
|
||||
s2 = [67305985, 4244504319].pack("J!*")
|
||||
assert_equal([67305985, -50462977], s1.unpack("j!*"))
|
||||
assert_equal([67305985, 4244504319], s2.unpack("J!*"))
|
||||
|
||||
assert_equal(4, [1].pack("j").bytesize)
|
||||
assert_equal(4, [1].pack("J").bytesize)
|
||||
elsif psize == 8
|
||||
s1 = [578437695752307201, -506097522914230529].pack("j*")
|
||||
s2 = [578437695752307201, 17940646550795321087].pack("J*")
|
||||
assert_equal(s1, s2)
|
||||
assert_equal([578437695752307201, -506097522914230529], s2.unpack("j*"))
|
||||
assert_equal([578437695752307201, 17940646550795321087], s1.unpack("J*"))
|
||||
|
||||
s1 = [578437695752307201, -506097522914230529].pack("j!*")
|
||||
s2 = [578437695752307201, 17940646550795321087].pack("J!*")
|
||||
assert_equal([578437695752307201, -506097522914230529], s2.unpack("j!*"))
|
||||
assert_equal([578437695752307201, 17940646550795321087], s1.unpack("J!*"))
|
||||
|
||||
assert_equal(8, [1].pack("j").bytesize)
|
||||
assert_equal(8, [1].pack("J").bytesize)
|
||||
else
|
||||
assert false, "we don't know such platform now."
|
||||
end
|
||||
end
|
||||
|
||||
def test_pack_unpack_nN
|
||||
assert_equal("\000\000\000\001\377\377\177\377\200\000\377\377", [0,1,-1,32767,-32768,65535].pack("n*"))
|
||||
assert_equal("\000\000\000\000\000\000\000\001\377\377\377\377", [0,1,-1].pack("N*"))
|
||||
|
|
Загрузка…
Ссылка в новой задаче