mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* pack.c: Support Q! and q! for long long.
(natstr): Moved to toplevel. Add q and Q if there is long long type. (endstr): Moved to toplevel. (NATINT_PACK): Consider long long. (NATINT_LEN_Q): New macro. (pack_pack): Support Q! and q!. (pack_unpack): Ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40067 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6d0c59f156
commit
583c8e8915
4 changed files with 65 additions and 17 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
Tue Apr 2 20:24:52 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* pack.c: Support Q! and q! for long long.
|
||||||
|
(natstr): Moved to toplevel. Add q and Q if there is long long type.
|
||||||
|
(endstr): Moved to toplevel.
|
||||||
|
(NATINT_PACK): Consider long long.
|
||||||
|
(NATINT_LEN_Q): New macro.
|
||||||
|
(pack_pack): Support Q! and q!.
|
||||||
|
(pack_unpack): Ditto.
|
||||||
|
|
||||||
Tue Apr 2 19:24:26 2013 Tanaka Akira <akr@fsij.org>
|
Tue Apr 2 19:24:26 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* ext/-test-/num2int/num2int.c: Define utility methods
|
* ext/-test-/num2int/num2int.c: Define utility methods
|
||||||
|
|
3
NEWS
3
NEWS
|
@ -22,6 +22,9 @@ with all sufficient information, see the ChangeLog file.
|
||||||
* misc
|
* misc
|
||||||
* Mutex#owned? is no longer experimental.
|
* Mutex#owned? is no longer experimental.
|
||||||
|
|
||||||
|
* pack/unpack (Array/String)
|
||||||
|
* Q! and q! directives for long long type if platform has the type.
|
||||||
|
|
||||||
=== Core classes compatibility issues (excluding feature bug fixes)
|
=== Core classes compatibility issues (excluding feature bug fixes)
|
||||||
|
|
||||||
* Module#ancestors
|
* Module#ancestors
|
||||||
|
|
62
pack.c
62
pack.c
|
@ -20,7 +20,23 @@
|
||||||
((__GNUC__ > (major)) || \
|
((__GNUC__ > (major)) || \
|
||||||
(__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \
|
(__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \
|
||||||
(__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))))
|
(__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))))
|
||||||
#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4
|
|
||||||
|
/*
|
||||||
|
* It is intentional that the condition for natstr is HAVE_LONG_LONG
|
||||||
|
* instead of LONG_LONG.
|
||||||
|
* This means q! and Q! means always the standard long long type and
|
||||||
|
* causes ArgumentError for platforms which has no long long type,
|
||||||
|
* even if the platform has an implementation specific 64bit type.
|
||||||
|
* This behavior is consistent with the document of pack/unpack.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
static const char natstr[] = "sSiIlLqQ";
|
||||||
|
#else
|
||||||
|
static const char natstr[] = "sSiIlL";
|
||||||
|
#endif
|
||||||
|
static const char endstr[] = "sSiIlLqQ";
|
||||||
|
|
||||||
|
#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG != 8)
|
||||||
# define NATINT_PACK
|
# define NATINT_PACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -52,6 +68,12 @@
|
||||||
# define NATINT_LEN(type,len) ((int)sizeof(type))
|
# define NATINT_LEN(type,len) ((int)sizeof(type))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
# define NATINT_LEN_Q NATINT_LEN(long long, 8)
|
||||||
|
#else
|
||||||
|
# define NATINT_LEN_Q 8
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SIZEOF_LONG == 8
|
#if SIZEOF_LONG == 8
|
||||||
# define INT64toNUM(x) LONG2NUM(x)
|
# define INT64toNUM(x) LONG2NUM(x)
|
||||||
# define UINT64toNUM(x) ULONG2NUM(x)
|
# define UINT64toNUM(x) ULONG2NUM(x)
|
||||||
|
@ -303,24 +325,30 @@ static unsigned long utf8_to_uv(const char*,long*);
|
||||||
* S_, S! | Integer | unsigned short, native endian
|
* S_, S! | Integer | unsigned short, native endian
|
||||||
* I, I_, I! | Integer | unsigned int, native endian
|
* I, I_, I! | Integer | unsigned int, native endian
|
||||||
* L_, L! | Integer | unsigned long, native endian
|
* L_, L! | Integer | unsigned long, native endian
|
||||||
|
* 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.)
|
||||||
* | |
|
* | |
|
||||||
* s_, s! | Integer | signed short, native endian
|
* s_, s! | Integer | signed short, native endian
|
||||||
* i, i_, i! | Integer | signed int, native endian
|
* i, i_, i! | Integer | signed int, native endian
|
||||||
* l_, l! | Integer | signed long, native endian
|
* l_, l! | Integer | signed long, native endian
|
||||||
|
* 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.)
|
||||||
* | |
|
* | |
|
||||||
* S> L> Q> | Integer | same as the directives without ">" except
|
* S> L> Q> | Integer | same as the directives without ">" except
|
||||||
* s> l> q> | | big endian
|
* s> l> q> | | big endian
|
||||||
* S!> I!> | | (available since Ruby 1.9.3)
|
* S!> I!> | | (available since Ruby 1.9.3)
|
||||||
* L!> | | "S>" is same as "n"
|
* L!> Q!> | | "S>" is same as "n"
|
||||||
* s!> i!> | | "L>" is same as "N"
|
* s!> i!> | | "L>" is same as "N"
|
||||||
* l!> | |
|
* l!> q!> | |
|
||||||
* | |
|
* | |
|
||||||
* S< L< Q< | Integer | same as the directives without "<" except
|
* S< L< Q< | Integer | same as the directives without "<" except
|
||||||
* s< l< q< | | little endian
|
* s< l< q< | | little endian
|
||||||
* S!< I!< | | (available since Ruby 1.9.3)
|
* S!< I!< | | (available since Ruby 1.9.3)
|
||||||
* L!< | | "S<" is same as "v"
|
* L!< Q!< | | "S<" is same as "v"
|
||||||
* s!< i!< | | "L<" is same as "V"
|
* s!< i!< | | "L<" is same as "V"
|
||||||
* l!< | |
|
* l!< q!< | |
|
||||||
* | |
|
* | |
|
||||||
* n | Integer | 16-bit unsigned, network (big-endian) byte order
|
* n | Integer | 16-bit unsigned, network (big-endian) byte order
|
||||||
* N | Integer | 32-bit unsigned, network (big-endian) byte order
|
* N | Integer | 32-bit unsigned, network (big-endian) byte order
|
||||||
|
@ -412,9 +440,6 @@ pack_pack(VALUE ary, VALUE fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
static const char natstr[] = "sSiIlL";
|
|
||||||
static const char endstr[] = "sSiIlLqQ";
|
|
||||||
|
|
||||||
modifiers:
|
modifiers:
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '_':
|
case '_':
|
||||||
|
@ -680,13 +705,13 @@ pack_pack(VALUE ary, VALUE fmt)
|
||||||
bigendian_p = BIGENDIAN_P();
|
bigendian_p = BIGENDIAN_P();
|
||||||
goto pack_integer;
|
goto pack_integer;
|
||||||
|
|
||||||
case 'q': /* signed quad (64bit) int */
|
case 'q': /* signed long long or int64_t */
|
||||||
integer_size = 8;
|
integer_size = NATINT_LEN_Q;
|
||||||
bigendian_p = BIGENDIAN_P();
|
bigendian_p = BIGENDIAN_P();
|
||||||
goto pack_integer;
|
goto pack_integer;
|
||||||
|
|
||||||
case 'Q': /* unsigned quad (64bit) int */
|
case 'Q': /* unsigned long long or uint64_t */
|
||||||
integer_size = 8;
|
integer_size = NATINT_LEN_Q;
|
||||||
bigendian_p = BIGENDIAN_P();
|
bigendian_p = BIGENDIAN_P();
|
||||||
goto pack_integer;
|
goto pack_integer;
|
||||||
|
|
||||||
|
@ -1249,10 +1274,16 @@ infected_str_new(const char *ptr, long len, VALUE str)
|
||||||
* S_, S! | Integer | unsigned short, native endian
|
* S_, S! | Integer | unsigned short, native endian
|
||||||
* I, I_, I! | Integer | unsigned int, native endian
|
* I, I_, I! | Integer | unsigned int, native endian
|
||||||
* L_, L! | Integer | unsigned long, native endian
|
* L_, L! | Integer | unsigned long, native endian
|
||||||
|
* 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.)
|
||||||
* | |
|
* | |
|
||||||
* s_, s! | Integer | signed short, native endian
|
* s_, s! | Integer | signed short, native endian
|
||||||
* i, i_, i! | Integer | signed int, native endian
|
* i, i_, i! | Integer | signed int, native endian
|
||||||
* l_, l! | Integer | signed long, native endian
|
* l_, l! | Integer | signed long, native endian
|
||||||
|
* 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.)
|
||||||
* | |
|
* | |
|
||||||
* S> L> Q> | Integer | same as the directives without ">" except
|
* S> L> Q> | Integer | same as the directives without ">" except
|
||||||
* s> l> q> | | big endian
|
* s> l> q> | | big endian
|
||||||
|
@ -1361,9 +1392,6 @@ pack_unpack(VALUE str, VALUE fmt)
|
||||||
|
|
||||||
star = 0;
|
star = 0;
|
||||||
{
|
{
|
||||||
static const char natstr[] = "sSiIlL";
|
|
||||||
static const char endstr[] = "sSiIlLqQ";
|
|
||||||
|
|
||||||
modifiers:
|
modifiers:
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '_':
|
case '_':
|
||||||
|
@ -1590,13 +1618,13 @@ pack_unpack(VALUE str, VALUE fmt)
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
signed_p = 1;
|
signed_p = 1;
|
||||||
integer_size = 8;
|
integer_size = NATINT_LEN_Q;
|
||||||
bigendian_p = BIGENDIAN_P();
|
bigendian_p = BIGENDIAN_P();
|
||||||
goto unpack_integer;
|
goto unpack_integer;
|
||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
signed_p = 0;
|
signed_p = 0;
|
||||||
integer_size = 8;
|
integer_size = NATINT_LEN_Q;
|
||||||
bigendian_p = BIGENDIAN_P();
|
bigendian_p = BIGENDIAN_P();
|
||||||
goto unpack_integer;
|
goto unpack_integer;
|
||||||
|
|
||||||
|
|
|
@ -403,8 +403,15 @@ class TestPack < Test::Unit::TestCase
|
||||||
assert_equal([578437695752307201, -506097522914230529], s2.unpack("q*"))
|
assert_equal([578437695752307201, -506097522914230529], s2.unpack("q*"))
|
||||||
assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q*"))
|
assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q*"))
|
||||||
|
|
||||||
|
s1 = [578437695752307201, -506097522914230529].pack("q!*")
|
||||||
|
s2 = [578437695752307201, 17940646550795321087].pack("Q!*")
|
||||||
|
assert_equal([578437695752307201, -506097522914230529], s2.unpack("q!*"))
|
||||||
|
assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q!*"))
|
||||||
|
|
||||||
assert_equal(8, [1].pack("q").bytesize)
|
assert_equal(8, [1].pack("q").bytesize)
|
||||||
assert_equal(8, [1].pack("Q").bytesize)
|
assert_equal(8, [1].pack("Q").bytesize)
|
||||||
|
assert_operator(8, :<=, [1].pack("q!").bytesize)
|
||||||
|
assert_operator(8, :<=, [1].pack("Q!").bytesize)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pack_unpack_nN
|
def test_pack_unpack_nN
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue