[前][次][番号順一覧][スレッド一覧]

ruby-changes:38768

From: usa <ko1@a...>
Date: Fri, 12 Jun 2015 21:22:49 +0900 (JST)
Subject: [ruby-changes:38768] usa:r50849 (trunk): * pack.c (pack_{un, }pack): new template character `j` and `J`, pointer

usa	2015-06-12 21:22:36 +0900 (Fri, 12 Jun 2015)

  New Revision: 50849

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50849

  Log:
    * 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]

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/pack.c
    trunk/test/ruby/test_pack.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50848)
+++ ChangeLog	(revision 50849)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jun 12 21:17:46 2015  NAKAMURA Usaku  <usa@r...>
+
+	* 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@r...>
 
 	* file.c (File::SHARE_DELETE): new flag to be able to delete opened file
Index: pack.c
===================================================================
--- pack.c	(revision 50848)
+++ pack.c	(revision 50849)
@@ -23,11 +23,11 @@ https://github.com/ruby/ruby/blob/trunk/pack.c#L23
  * 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) https://github.com/ruby/ruby/blob/trunk/pack.c#L264
  *      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) https://github.com/ruby/ruby/blob/trunk/pack.c#L280
  *      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) https://github.com/ruby/ruby/blob/trunk/pack.c#L289
  *      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) https://github.com/ruby/ruby/blob/trunk/pack.c#L670
             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) https://github.com/ruby/ruby/blob/trunk/pack.c#L1502
 	    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;
Index: NEWS
===================================================================
--- NEWS	(revision 50848)
+++ NEWS	(revision 50849)
@@ -48,6 +48,10 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L48
 * 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
Index: test/ruby/test_pack.rb
===================================================================
--- test/ruby/test_pack.rb	(revision 50848)
+++ test/ruby/test_pack.rb	(revision 50849)
@@ -78,6 +78,14 @@ class TestPack < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pack.rb#L78
     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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pack.rb#L94
     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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pack.rb#L126
     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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pack.rb#L142
     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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pack.rb#L447
     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*"))

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]