ruby-changes:14892
From: akr <ko1@a...>
Date: Thu, 25 Feb 2010 23:01:07 +0900 (JST)
Subject: [ruby-changes:14892] Ruby:r26761 (trunk): * pack.c: consider DYNAMIC_ENDIAN. refactored.
akr 2010-02-25 23:00:48 +0900 (Thu, 25 Feb 2010) New Revision: 26761 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26761 Log: * pack.c: consider DYNAMIC_ENDIAN. refactored. Modified files: trunk/ChangeLog trunk/pack.c trunk/test/ruby/test_integer_comb.rb trunk/test/ruby/test_pack.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 26760) +++ ChangeLog (revision 26761) @@ -1,3 +1,7 @@ +Thu Feb 25 22:59:46 2010 Tanaka Akira <akr@f...> + + * pack.c: consider DYNAMIC_ENDIAN. refactored. + Thu Feb 25 11:17:01 2010 NARUSE, Yui <naruse@r...> * rational.c (nurat_expt): use Float#** when Rational ** Float. Index: pack.c =================================================================== --- pack.c (revision 26760) +++ pack.c (revision 26761) @@ -22,41 +22,33 @@ # define NATINT_PACK #endif -#ifdef WORDS_BIGENDIAN -# define BIGENDIAN_P 1 +#ifdef DYNAMIC_ENDIAN + /* for universal binary of NEXTSTEP and MacOS X */ + static int + is_bigendian(void) + { + static int init = 0; + static int endian_value; + char *p; + + if (init) return endian_value; + init = 1; + p = (char*)&init; + return endian_value = p[0]?0:1; + } +# define BIGENDIAN_P() (is_bigendian()) +#elif defined(WORDS_BIGENDIAN) +# define BIGENDIAN_P() 1 #else -# define BIGENDIAN_P 0 +# define BIGENDIAN_P() 0 #endif #ifdef NATINT_PACK -# define OFF16B(p) ((char*)(p) + (natint?0:(sizeof(short) - SIZE16))) -# define OFF32B(p) ((char*)(p) + (natint?0:(sizeof(long) - SIZE32))) # define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len)) -# ifdef WORDS_BIGENDIAN -# define OFF16(p) OFF16B(p) -# define OFF32(p) OFF32B(p) -# endif -# define NATINT_HTOVS(x) (natint?htovs(x):htov16(x)) -# define NATINT_HTOVL(x) (natint?htovl(x):htov32(x)) -# define NATINT_HTONS(x) (natint?htons(x):hton16(x)) -# define NATINT_HTONL(x) (natint?htonl(x):hton32(x)) #else # define NATINT_LEN(type,len) ((int)sizeof(type)) -# define NATINT_HTOVS(x) htovs(x) -# define NATINT_HTOVL(x) htovl(x) -# define NATINT_HTONS(x) htons(x) -# define NATINT_HTONL(x) htonl(x) #endif -#ifndef OFF16 -# define OFF16(p) (char*)(p) -# define OFF32(p) (char*)(p) -#endif -#ifndef OFF16B -# define OFF16B(p) (char*)(p) -# define OFF32B(p) (char*)(p) -#endif - #define define_swapx(x, xtype) \ static xtype \ TOKEN_PASTE(swap,x)(xtype z) \ @@ -80,295 +72,187 @@ } #ifndef swap16 -#define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) +# define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) #endif #ifndef swap32 -#define swap32(x) ((((x)&0xFF)<<24) \ +# define swap32(x) ((((x)&0xFF)<<24) \ |(((x)>>24)&0xFF) \ |(((x)&0x0000FF00)<<8) \ |(((x)&0x00FF0000)>>8) ) #endif #ifndef swap64 -#if SIZEOF_LONG == 8 -#define swap64(x) ((((x)&0x00000000000000FFL)<<56) \ - |(((x)&0xFF00000000000000L)>>56) \ - |(((x)&0x000000000000FF00L)<<40) \ - |(((x)&0x00FF000000000000L)>>40) \ - |(((x)&0x0000000000FF0000L)<<24) \ - |(((x)&0x0000FF0000000000L)>>24) \ - |(((x)&0x00000000FF000000L)<<8) \ - |(((x)&0x000000FF00000000L)>>8)) -#elif defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8 -#define swap64(x) ((((x)&0x00000000000000FFLL)<<56) \ - |(((x)&0xFF00000000000000LL)>>56) \ - |(((x)&0x000000000000FF00LL)<<40) \ - |(((x)&0x00FF000000000000LL)>>40) \ - |(((x)&0x0000000000FF0000LL)<<24) \ - |(((x)&0x0000FF0000000000LL)>>24) \ - |(((x)&0x00000000FF000000LL)<<8) \ - |(((x)&0x000000FF00000000LL)>>8)) +# if SIZEOF_LONG == 8 +# define swap64(x) ((((x)&0x00000000000000FFL)<<56) \ + |(((x)>>56)&0xFF) \ + |(((x)&0x000000000000FF00L)<<40) \ + |(((x)&0x00FF000000000000L)>>40) \ + |(((x)&0x0000000000FF0000L)<<24) \ + |(((x)&0x0000FF0000000000L)>>24) \ + |(((x)&0x00000000FF000000L)<<8) \ + |(((x)&0x000000FF00000000L)>>8)) +# elif defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8 +# define swap64(x) ((((x)&0x00000000000000FFLL)<<56) \ + |(((x)>>56)&0xFF) \ + |(((x)&0x000000000000FF00LL)<<40) \ + |(((x)&0x00FF000000000000LL)>>40) \ + |(((x)&0x0000000000FF0000LL)<<24) \ + |(((x)&0x0000FF0000000000LL)>>24) \ + |(((x)&0x00000000FF000000LL)<<8) \ + |(((x)&0x000000FF00000000LL)>>8)) +# endif #endif -#endif #if SIZEOF_SHORT == 2 -#define swaps(x) swap16(x) +# define swaps(x) swap16(x) +#elif SIZEOF_SHORT == 4 +# define swaps(x) swap32(x) #else -#if SIZEOF_SHORT == 4 -#define swaps(x) swap32(x) -#else -define_swapx(s,short) + define_swapx(s,short) #endif -#endif #if SIZEOF_INT == 2 -#define swapi(x) swap16(x) +# define swapi(x) swap16(x) +#elif SIZEOF_INT == 4 +# define swapi(x) swap32(x) #else -#if SIZEOF_INT == 4 -#define swapi(x) swap32(x) -#else -define_swapx(i,int) + define_swapx(i,int) #endif -#endif #if SIZEOF_LONG == 4 -#define swapl(x) swap32(x) +# define swapl(x) swap32(x) +#elif SIZEOF_LONG == 8 +# define swapl(x) swap64(x) #else -#if SIZEOF_LONG == 8 -#define swapl(x) swap64(x) -#else -define_swapx(l,long) + define_swapx(l,long) #endif -#endif #ifdef HAVE_LONG_LONG -#if SIZEOF_LONG_LONG == 4 -#define swapll(x) swap32(x) -#else -#if SIZEOF_LONG_LONG == 8 -#define swapll(x) swap64(x) -#else -define_swapx(ll,LONG_LONG) +# if SIZEOF_LONG_LONG == 8 +# define swapll(x) swap64(x) +# else + define_swapx(ll,LONG_LONG) +# endif #endif -#endif -#endif #if SIZEOF_FLOAT == 4 -#if SIZEOF_LONG == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_LONG */ -#define swapf(x) swapl(x) -#define FLOAT_SWAPPER unsigned long -#else -#if SIZEOF_SHORT == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_SHORT */ -#define swapf(x) swaps(x) -#define FLOAT_SWAPPER unsigned short -#else /* SIZEOF_FLOAT == 4 but undivide by known size of int */ -define_swapx(f,float) -#endif /* #if SIZEOF_SHORT == 4 */ -#endif /* #if SIZEOF_LONG == 4 */ +# ifdef HAVE_UINT32_T +# define swapf(x) swap32(x) +# define FLOAT_SWAPPER uint32_t +# else /* SIZEOF_FLOAT == 4 but undivide by known size of int */ + define_swapx(f,float) +# endif #else /* SIZEOF_FLOAT != 4 */ -define_swapx(f,float) + define_swapx(f,float) #endif /* #if SIZEOF_FLOAT == 4 */ #if SIZEOF_DOUBLE == 8 -#if SIZEOF_LONG == 8 /* SIZEOF_DOUBLE == 8 == SIZEOF_LONG */ -#define swapd(x) swapl(x) -#define DOUBLE_SWAPPER unsigned long -#else -#if SIZEOF_LONG == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_LONG */ -static double -swapd(const double d) -{ - double dtmp = d; - unsigned long utmp[2]; - unsigned long utmp0; +# ifdef HAVE_UINT64_T /* SIZEOF_DOUBLE == 8 == SIZEOF_UINT64_T */ +# define swapd(x) swap64(x) +# define DOUBLE_SWAPPER uint64_t +# else +# if SIZEOF_LONG == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_LONG */ + static double + swapd(const double d) + { + double dtmp = d; + unsigned long utmp[2]; + unsigned long utmp0; - utmp[0] = 0; utmp[1] = 0; - memcpy(utmp,&dtmp,sizeof(double)); - utmp0 = utmp[0]; - utmp[0] = swapl(utmp[1]); - utmp[1] = swapl(utmp0); - memcpy(&dtmp,utmp,sizeof(double)); - return dtmp; -} -#else -#if SIZEOF_SHORT == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_SHORT */ -static double -swapd(const double d) -{ - double dtmp = d; - unsigned short utmp[2]; - unsigned short utmp0; + utmp[0] = 0; utmp[1] = 0; + memcpy(utmp,&dtmp,sizeof(double)); + utmp0 = utmp[0]; + utmp[0] = swapl(utmp[1]); + utmp[1] = swapl(utmp0); + memcpy(&dtmp,utmp,sizeof(double)); + return dtmp; + } +# elif SIZEOF_SHORT == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_SHORT */ + static double + swapd(const double d) + { + double dtmp = d; + unsigned short utmp[2]; + unsigned short utmp0; - utmp[0] = 0; utmp[1] = 0; - memcpy(utmp,&dtmp,sizeof(double)); - utmp0 = utmp[0]; - utmp[0] = swaps(utmp[1]); - utmp[1] = swaps(utmp0); - memcpy(&dtmp,utmp,sizeof(double)); - return dtmp; -} -#else /* SIZEOF_DOUBLE == 8 but undivide by known size of int */ -define_swapx(d, double) -#endif /* #if SIZEOF_SHORT == 4 */ -#endif /* #if SIZEOF_LONG == 4 */ -#endif /* #if SIZEOF_LONG == 8 */ + utmp[0] = 0; utmp[1] = 0; + memcpy(utmp,&dtmp,sizeof(double)); + utmp0 = utmp[0]; + utmp[0] = swaps(utmp[1]); + utmp[1] = swaps(utmp0); + memcpy(&dtmp,utmp,sizeof(double)); + return dtmp; + } +# else /* SIZEOF_DOUBLE == 8 but undivide by known size of int */ + define_swapx(d, double) +# endif +# endif /* #if SIZEOF_LONG == 8 */ #else /* SIZEOF_DOUBLE != 8 */ -define_swapx(d, double) + define_swapx(d, double) #endif /* #if SIZEOF_DOUBLE == 8 */ #undef define_swapx -#ifdef DYNAMIC_ENDIAN -#ifdef ntohs -#undef ntohs -#undef ntohl -#undef htons -#undef htonl -#endif -static int -endian(void) -{ - static int init = 0; - static int endian_value; - char *p; +#define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x)) +#define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x)) +#define rb_htonf(x) (BIGENDIAN_P()?(x):swapf(x)) +#define rb_htond(x) (BIGENDIAN_P()?(x):swapd(x)) +#define rb_htovf(x) (BIGENDIAN_P()?swapf(x):(x)) +#define rb_htovd(x) (BIGENDIAN_P()?swapd(x):(x)) +#define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x)) +#define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x)) - if (init) return endian_value; - init = 1; - p = (char*)&init; - return endian_value = p[0]?0:1; -} - -#define ntohs(x) (endian()?(x):swaps(x)) -#define ntohl(x) (endian()?(x):swapl(x)) -#define ntohf(x) (endian()?(x):swapf(x)) -#define ntohd(x) (endian()?(x):swapd(x)) -#define htons(x) (endian()?(x):swaps(x)) -#define htonl(x) (endian()?(x):swapl(x)) -#define htonf(x) (endian()?(x):swapf(x)) -#define htond(x) (endian()?(x):swapd(x)) -#define htovs(x) (endian()?swaps(x):(x)) -#define htovl(x) (endian()?swapl(x):(x)) -#define htovf(x) (endian()?swapf(x):(x)) -#define htovd(x) (endian()?swapd(x):(x)) -#define vtohs(x) (endian()?swaps(x):(x)) -#define vtohl(x) (endian()?swapl(x):(x)) -#define vtohf(x) (endian()?swapf(x):(x)) -#define vtohd(x) (endian()?swapd(x):(x)) -# ifdef NATINT_PACK -#define htov16(x) (endian()?swap16(x):(x)) -#define htov32(x) (endian()?swap32(x):(x)) -#define hton16(x) (endian()?(x):swap16(x)) -#define hton32(x) (endian()?(x):swap32(x)) -# endif -#else -#ifdef WORDS_BIGENDIAN -#ifndef ntohs -#define ntohs(x) (x) -#define ntohl(x) (x) -#define htons(x) (x) -#define htonl(x) (x) -#endif -#define ntohf(x) (x) -#define ntohd(x) (x) -#define htonf(x) (x) -#define htond(x) (x) -#define htovs(x) swaps(x) -#define htovl(x) swapl(x) -#define htovf(x) swapf(x) -#define htovd(x) swapd(x) -#define vtohs(x) swaps(x) -#define vtohl(x) swapl(x) -#define vtohf(x) swapf(x) -#define vtohd(x) swapd(x) -# ifdef NATINT_PACK -#define htov16(x) swap16(x) -#define htov32(x) swap32(x) -#define hton16(x) (x) -#define hton32(x) (x) -# endif -#else /* LITTLE ENDIAN */ -#ifdef ntohs -#undef ntohs -#undef ntohl -#undef htons -#undef htonl -#endif -#define ntohs(x) swaps(x) -#define ntohl(x) swapl(x) -#define htons(x) swaps(x) -#define htonl(x) swapl(x) -#define ntohf(x) swapf(x) -#define ntohd(x) swapd(x) -#define htonf(x) swapf(x) -#define htond(x) swapd(x) -#define htovs(x) (x) -#define htovl(x) (x) -#define htovf(x) (x) -#define htovd(x) (x) -#define vtohs(x) (x) -#define vtohl(x) (x) -#define vtohf(x) (x) -#define vtohd(x) (x) -# ifdef NATINT_PACK -#define htov16(x) (x) -#define htov32(x) (x) -#define hton16(x) swap16(x) -#define hton32(x) swap32(x) -# endif -#endif -#endif - #ifdef FLOAT_SWAPPER -#define FLOAT_CONVWITH(y) FLOAT_SWAPPER y; -#define HTONF(x,y) (memcpy(&y,&x,sizeof(float)), \ - y = htonf((FLOAT_SWAPPER)y), \ +# define FLOAT_CONVWITH(y) FLOAT_SWAPPER y; +# define HTONF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = rb_htonf((FLOAT_SWAPPER)y), \ memcpy(&x,&y,sizeof(float)), \ x) -#define HTOVF(x,y) (memcpy(&y,&x,sizeof(float)), \ - y = htovf((FLOAT_SWAPPER)y), \ +# define HTOVF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = rb_htovf((FLOAT_SWAPPER)y), \ memcpy(&x,&y,sizeof(float)), \ x) -#define NTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ - y = ntohf((FLOAT_SWAPPER)y), \ +# define NTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = rb_ntohf((FLOAT_SWAPPER)y), \ memcpy(&x,&y,sizeof(float)), \ x) -#define VTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ - y = vtohf((FLOAT_SWAPPER)y), \ +# define VTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = rb_vtohf((FLOAT_SWAPPER)y), \ memcpy(&x,&y,sizeof(float)), \ x) #else -#define FLOAT_CONVWITH(y) -#define HTONF(x,y) htonf(x) -#define HTOVF(x,y) htovf(x) -#define NTOHF(x,y) ntohf(x) -#define VTOHF(x,y) vtohf(x) +# define FLOAT_CONVWITH(y) +# define HTONF(x,y) rb_htonf(x) +# define HTOVF(x,y) rb_htovf(x) +# define NTOHF(x,y) rb_ntohf(x) +# define VTOHF(x,y) rb_vtohf(x) #endif #ifdef DOUBLE_SWAPPER -#define DOUBLE_CONVWITH(y) DOUBLE_SWAPPER y; -#define HTOND(x,y) (memcpy(&y,&x,sizeof(double)), \ - y = htond((DOUBLE_SWAPPER)y), \ +# define DOUBLE_CONVWITH(y) DOUBLE_SWAPPER y; +# define HTOND(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = rb_htond((DOUBLE_SWAPPER)y), \ memcpy(&x,&y,sizeof(double)), \ x) -#define HTOVD(x,y) (memcpy(&y,&x,sizeof(double)), \ - y = htovd((DOUBLE_SWAPPER)y), \ +# define HTOVD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = rb_htovd((DOUBLE_SWAPPER)y), \ memcpy(&x,&y,sizeof(double)), \ x) -#define NTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ - y = ntohd((DOUBLE_SWAPPER)y), \ +# define NTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = rb_ntohd((DOUBLE_SWAPPER)y), \ memcpy(&x,&y,sizeof(double)), \ x) -#define VTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ - y = vtohd((DOUBLE_SWAPPER)y), \ +# define VTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = rb_vtohd((DOUBLE_SWAPPER)y), \ memcpy(&x,&y,sizeof(double)), \ x) #else -#define DOUBLE_CONVWITH(y) -#define HTOND(x,y) htond(x) -#define HTOVD(x,y) htovd(x) -#define NTOHD(x,y) ntohd(x) -#define VTOHD(x,y) vtohd(x) +# define DOUBLE_CONVWITH(y) +# define HTOND(x,y) rb_htond(x) +# define HTOVD(x,y) rb_htovd(x) +# define NTOHD(x,y) rb_ntohd(x) +# define VTOHD(x,y) rb_vtohd(x) #endif unsigned long rb_big2ulong_pack(VALUE x); @@ -386,18 +270,6 @@ return 0; /* not reached */ } -#if SIZEOF_LONG == SIZE32 -# define EXTEND32(x) -#else -/* invariant in modulo 1<<31 */ -# define EXTEND32(x) do { if (!natint) {(x) = (((1L<<31)-1-(x))^~(~0L<<31));}} while(0) -#endif -#if SIZEOF_SHORT == SIZE16 -# define EXTEND16(x) -#else -# define EXTEND16(x) do { if (!natint) {(x) = (short)(((1<<15)-1-(x))^~(~0<<15));}} while(0) -#endif - #ifdef HAVE_LONG_LONG # define QUAD_SIZE SIZEOF_LONG_LONG #else @@ -442,8 +314,8 @@ * a | arbitrary binary string (null padded, count is width) * B | Bit string (descending bit order) * b | Bit string (ascending bit order) - * C | Unsigned byte (C unsigned char) - * c | Byte (C char) + * C | 8-bit unsigned byte (unsigned char) + * c | 8-bit signed byte (char) * D, d | Double-precision float, native format * E | Double-precision float, little-endian byte order * e | Single-precision float, little-endian byte order @@ -452,24 +324,29 @@ * g | Single-precision float, network (big-endian) byte order * H | Hex string (high nibble first) * h | Hex string (low nibble first) - * I | Unsigned integer - * i | Integer - * L | Unsigned long - * l | Long + * I | unsigned int, native endian + * i | signed int, native endian + * L | 32-bit unsigned integer (uint32_t) + * l | 32-bit signed integer (int32_t) + * L_ | unsigned long, native endian + * l_ | signed long, native endian * M | Quoted printable, MIME encoding (see RFC2045) * m | Base64 encoded string (see RFC 2045, count is width) * | (if count is 0, no line feed are added, see RFC 4648) - * N | Long, network (big-endian) byte order - * n | Short, network (big-endian) byte-order + * N | 32-bit unsigned integer, network (big-endian) byte order + * n | 16-bit unsigned integer, network (big-endian) byte order * P | Pointer to a structure (fixed-length string) * p | Pointer to a null-terminated string - * Q, q | 64-bit number - * S | Unsigned short - * s | Short + * Q | 64-bit unsigned integer (uint64_t) + * q | 64-bit signed integer (int64_t) + * S | 16-bit unsigned integer (uint16_t) + * s | 16-bit signed integer (int16_t) + * S_ | unsigned short, native endian + * s_ | signed short, native endian * U | UTF-8 * u | UU-encoded string - * V | Long, little-endian byte order - * v | Short, little-endian byte order + * V | 32-bit unsigned integer, little-endian byte order + * v | 16-bit unsigned integer, little-endian byte order * w | BER-compressed integer * X | Back up a byte * x | Null byte @@ -490,6 +367,7 @@ #ifdef NATINT_PACK int natint; /* native integer */ #endif + int signed_p, integer_size, bigendian_p; StringValue(fmt); p = RSTRING_PTR(fmt); @@ -738,90 +616,130 @@ break; case 's': /* signed short */ + signed_p = 1; + integer_size = NATINT_LEN(short, 2); + bigendian_p = BIGENDIAN_P(); + goto pack_integer; + case 'S': /* unsigned short */ - while (len-- > 0) { - short s; + signed_p = 0; + integer_size = NATINT_LEN(short, 2); + bigendian_p = BIGENDIAN_P(); + goto pack_integer; - from = NEXTFROM; - s = (short)num2i32(from); - rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); - } - break; - case 'i': /* signed int */ + signed_p = 1; + integer_size = sizeof(int); + bigendian_p = BIGENDIAN_P(); + goto pack_integer; + case 'I': /* unsigned int */ - while (len-- > 0) { - int i; + signed_p = 0; + integer_size = sizeof(int); + bigendian_p = BIGENDIAN_P(); + goto pack_integer; - from = NEXTFROM; - i = (int)num2i32(from); - rb_str_buf_cat(res, (char*)&i, sizeof(int)); - } - break; - case 'l': /* signed long */ + signed_p = 1; + integer_size = NATINT_LEN(long, 4); + bigendian_p = BIGENDIAN_P(); + goto pack_integer; + case 'L': /* unsigned long */ - while (len-- > 0) { - long l; + signed_p = 0; + integer_size = NATINT_LEN(long, 4); + bigendian_p = BIGENDIAN_P(); + goto pack_integer; - from = NEXTFROM; - l = num2i32(from); - rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); - } - break; - case 'q': /* signed quad (64bit) int */ + signed_p = 1; + integer_size = 8; + bigendian_p = BIGENDIAN_P(); + goto pack_integer; + case 'Q': /* unsigned quad (64bit) int */ - while (len-- > 0) { - char tmp[QUAD_SIZE]; + signed_p = 0; + integer_size = 8; + bigendian_p = BIGENDIAN_P(); + goto pack_integer; - from = NEXTFROM; - rb_quad_pack(tmp, from); - rb_str_buf_cat(res, (char*)&tmp, QUAD_SIZE); - } - break; - case 'n': /* unsigned short (network byte-order) */ - while (len-- > 0) { - unsigned short s; + signed_p = 0; + integer_size = 2; + bigendian_p = 1; + goto pack_integer; - from = NEXTFROM; - s = (unsigned short)num2i32(from); - s = NATINT_HTONS(s); - rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); - } - break; - case 'N': /* unsigned long (network byte-order) */ - while (len-- > 0) { - unsigned long l; + signed_p = 0; + integer_size = 4; + bigendian_p = 1; + goto pack_integer; - from = NEXTFROM; - l = num2i32(from); - l = NATINT_HTONL(l); - rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); - } - break; - case 'v': /* unsigned short (VAX byte-order) */ - while (len-- > 0) { - unsigned short s; + signed_p = 0; + integer_size = 2; + bigendian_p = 0; + goto pack_integer; - from = NEXTFROM; - s = (unsigned short)num2i32(from); - s = NATINT_HTOVS(s); - rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); - } - break; - case 'V': /* unsigned long (VAX byte-order) */ - while (len-- > 0) { - unsigned long l; + signed_p = 0; + integer_size = 4; + bigendian_p = 0; + goto pack_integer; - from = NEXTFROM; - l = num2i32(from); - l = NATINT_HTOVL(l); - rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); + pack_integer: + switch (integer_size) { + case SIZEOF_SHORT: + while (len-- > 0) { + short s; + + from = NEXTFROM; + s = (short)num2i32(from); + if (bigendian_p != BIGENDIAN_P()) s = swaps(s); + rb_str_buf_cat(res, (char *)&s, sizeof(short)); + } + break; + +#if SIZEOF_SHORT != SIZEOF_INT + case SIZEOF_INT: + while (len-- > 0) { + int i; + + from = NEXTFROM; + i = (int)num2i32(from); + if (bigendian_p != BIGENDIAN_P()) i = swapi(i); + rb_str_buf_cat(res, (char *)&i, sizeof(int)); + } + break; +#endif + +#if SIZEOF_INT != SIZEOF_LONG + case SIZEOF_LONG: + while (len-- > 0) { + long l; + + from = NEXTFROM; + l = num2i32(from); + if (bigendian_p != BIGENDIAN_P()) l = swapl(l); + rb_str_buf_cat(res, (char *)&l, sizeof(long)); + } + break; +#endif + +#if SIZEOF_LONG != QUAD_SIZE + case QUAD_SIZE: + while (len-- > 0) { + char tmp[QUAD_SIZE]; + + from = NEXTFROM; + rb_quad_pack(tmp, from); + rb_str_buf_cat(res, (char*)&tmp, QUAD_SIZE); + } + break; +#endif + + default: + rb_bug("unexpected intger size for pack"); } break; @@ -1212,16 +1130,6 @@ } \ } while (0) -#ifdef NATINT_PACK -#define PACK_LENGTH_ADJUST(type,sz) do { \ - int t__len = NATINT_LEN(type,(sz)); \ - PACK_LENGTH_ADJUST_SIZE(t__len); \ -} while (0) -#else -#define PACK_LENGTH_ADJUST(type,sz) \ - PACK_LENGTH_ADJUST_SIZE(sizeof(type)) -#endif - #define PACK_ITEM_ADJUST() while (tmp--) rb_ary_push(ary, Qnil) static VALUE @@ -1269,101 +1177,111 @@ * -------+---------+----------------------------------------- * a | String | arbitrary binary string * -------+---------+----------------------------------------- - * B | String | extract bits from each character (msb first) + * B | String | extract bits from each byte (msb first) * -------+---------+----------------------------------------- - * b | String | extract bits from each character (lsb first) + * b | String | extract bits from each byte (lsb first) * -------+---------+----------------------------------------- - * C | Fixnum | extract a byte (C char) as an unsigned integer + * C | Fixnum | extract a byte (C unsigned char) as an + * | | 8-bit unsigned integer * -------+---------+----------------------------------------- - * c | Fixnum | extract a byte (C char) as an integer + * c | Fixnum | extract a byte (C char) as an 8-bit + * | | integer * -------+---------+----------------------------------------- - * d,D | Float | treat sizeof(double) characters as + * d,D | Float | treat sizeof(double) bytes as * | | a native double * -------+---------+----------------------------------------- - * E | Float | treat sizeof(double) characters as + * E | Float | treat sizeof(double) bytes as * | | a double in little-endian byte order * -------+---------+----------------------------------------- - * e | Float | treat sizeof(float) characters as + * e | Float | treat sizeof(float) bytes as * | | a float in little-endian byte order * -------+---------+----------------------------------------- - * f,F | Float | treat sizeof(float) characters as + * f,F | Float | treat sizeof(float) bytes as * | | a native float * -------+---------+----------------------------------------- - * G | Float | treat sizeof(double) characters as + * G | Float | treat sizeof(double) bytes as * | | a double in network byte order * -------+---------+----------------------------------------- - * g | Float | treat sizeof(float) characters as a + * g | Float | treat sizeof(float) bytes as a * | | float in network byte order * -------+---------+----------------------------------------- - * H | String | extract hex nibbles from each character + * H | String | extract hex nibbles from each byte * | | (most significant first) * -------+---------+----------------------------------------- - * h | String | extract hex nibbles from each character + * h | String | extract hex nibbles from each byte * | | (least significant first) * -------+---------+----------------------------------------- - * I | Integer | treat sizeof(int) (modified by _) - * | | successive characters as an unsigned - * | | native integer + * I | Integer | treat sizeof(int) successive bytes as +* | | an unsigned native integer * -------+---------+----------------------------------------- - * i | Integer | treat sizeof(int) (modified by _) - * | | successive characters as a signed - * | | native integer + * i | Integer | treat sizeof(int) successive bytes as + * | | a signed native integer * -------+---------+----------------------------------------- - * L | Integer | treat four (modified by _) successive - * | | characters as an unsigned native - * | | long integer + * L | Integer | treat 4 successive bytes as a 32-bit + * | | unsigned native integer * -------+---------+----------------------------------------- - * l | Integer | treat four (modified by _) successive - * | | characters as a signed native - * | | long integer + * l | Integer | treat 4 successive bytes as a 32-bit + * | | signed native integer * -------+---------+----------------------------------------- + * L_ | Integer | treat sizeof(unsigned long) successive + * | | bytes as an unsigned native long integer + * -------+---------+----------------------------------------- + * l_ | Integer | treat sizeof(long) successive bytes as + * | | a signed native long integer + * -------+---------+----------------------------------------- * M | String | quoted-printable * -------+---------+----------------------------------------- * m | String | base64-encoded (RFC 2045) (default) * | | base64-encoded (RFC 4648) if followed by 0 * -------+---------+----------------------------------------- - * N | Integer | treat four characters as an unsigned - * | | long in network byte order + * N | Integer | treat 4 bytes as a 32-bit unsigned + * | | integer in network byte order (big-endian) * -------+---------+----------------------------------------- - * n | Fixnum | treat two characters as an unsigned - * | | short in network byte order + * n | Fixnum | treat 2 bytes as a 16-bit unsigned + * | | integer in network byte order (big-endian) * -------+---------+----------------------------------------- - * P | String | treat sizeof(char *) characters as a + * P | String | treat sizeof(char *) bytes as a * | | pointer, and return the length bytes * | | from the referenced location * -------+---------+----------------------------------------- - * p | String | treat sizeof(char *) characters as a + * p | String | treat sizeof(char *) bytes as a * | | pointer to a null-terminated string * -------+---------+----------------------------------------- - * Q | Integer | treat 8 characters as an unsigned - * | | quad word (64 bits) + * Q | Integer | treat 8 bytes as a 64-bit unsigned + * | | native integer * -------+---------+----------------------------------------- - * q | Integer | treat 8 characters as a signed - * | | quad word (64 bits) + * q | Integer | treat 8 bytes as a 64-bit signed + * | | native integer * -------+---------+----------------------------------------- - * S | Fixnum | treat two (different if _ used) - * | | successive characters as an unsigned - * | | short in native byte order + * S | Fixnum | treat 2 successive bytes as a 16-bit + * | | unsigned integer in native byte order * -------+---------+----------------------------------------- - * s | Fixnum | Treat two (different if _ used) - * | | successive characters as a signed short - * | | in native byte order + * s | Fixnum | treat 2 successive bytes as a 16-bit + * | | signed integer in native byte order * -------+---------+----------------------------------------- + * S_ | Fixnum | treat sizeof(unsigned short) successive + * | | bytes as an unsigned short integer in + * | | native byte order + * -------+---------+----------------------------------------- + * s_ | Fixnum | Treat sizeof(short) successive bytes as + * | | a signed short integer in native byte + * | | order + * -------+---------+----------------------------------------- * U | Integer | UTF-8 characters as unsigned integers * -------+---------+----------------------------------------- * u | String | UU-encoded * -------+---------+----------------------------------------- - * V | Fixnum | treat four characters as an unsigned - * | | long in little-endian byte order + * V | Fixnum | treat four bytes as a 32-bit unsigned + * | | integer in little-endian byte order * -------+---------+----------------------------------------- - * v | Fixnum | treat two characters as an unsigned - * | | short in little-endian byte order + * v | Fixnum | treat two bytes as a 16-bit unsigned + * | | integer in little-endian byte order * -------+---------+----------------------------------------- * w | Integer | BER-compressed integer (see Array.pack) * -------+---------+----------------------------------------- - * X | --- | skip backward one character + * X | --- | skip backward one byte * -------+---------+----------------------------------------- - * x | --- | skip forward one character + * x | --- | skip forward one byte * -------+---------+----------------------------------------- * Z | String | with trailing nulls removed * | | upto first null with * @@ -1574,7 +1492,7 @@ break; case 'c': - PACK_LENGTH_ADJUST(char,sizeof(char)); + PACK_LENGTH_ADJUST_SIZE(sizeof(char)); while (len-- > 0) { int c = *s++; if (c > (char)127) c-=256; @@ -1584,7 +1502,7 @@ break; case 'C': - PACK_LENGTH_ADJUST(unsigned char,sizeof(unsigned char)); + PACK_LENGTH_ADJUST_SIZE(sizeof(unsigned char)); while (len-- > 0) { unsigned char c = *s++; UNPACK_PUSH(INT2FIX(c)); @@ -1595,49 +1513,49 @@ case 's': signed_p = 1; integer_size = NATINT_LEN(short, 2); - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'S': signed_p = 0; integer_size = NATINT_LEN(short, 2); - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'i': signed_p = 1; integer_size = sizeof(int); - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'I': signed_p = 0; integer_size = sizeof(int); - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'l': signed_p = 1; integer_size = NATINT_LEN(long, 4); - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'L': signed_p = 0; integer_size = NATINT_LEN(long, 4); - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'q': signed_p = 1; integer_size = QUAD_SIZE; - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'Q': signed_p = 0; integer_size = QUAD_SIZE; - bigendian_p = BIGENDIAN_P; + bigendian_p = BIGENDIAN_P(); goto unpack_integer; case 'n': @@ -1668,22 +1586,22 @@ switch (integer_size) { case SIZEOF_SHORT: if (signed_p) { - PACK_LENGTH_ADJUST(short,sizeof(short)); + PACK_LENGTH_ADJUST_SIZE(sizeof(short)); while (len-- > 0) { short tmp; memcpy(&tmp, s, sizeof(short)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swaps(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swaps(tmp); s += sizeof(short); UNPACK_PUSH(INT2FIX(tmp)); } PACK_ITEM_ADJUST(); } else { - PACK_LENGTH_ADJUST(unsigned short,sizeof(unsigned short)); + PACK_LENGTH_ADJUST_SIZE(sizeof(unsigned short)); while (len-- > 0) { unsigned short tmp; memcpy(&tmp, s, sizeof(unsigned short)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swaps(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swaps(tmp); s += sizeof(unsigned short); UNPACK_PUSH(INT2FIX(tmp)); } @@ -1694,22 +1612,22 @@ #if SIZEOF_SHORT != SIZEOF_INT case SIZEOF_INT: if (signed_p) { - PACK_LENGTH_ADJUST(int,sizeof(int)); + PACK_LENGTH_ADJUST_SIZE(sizeof(int)); while (len-- > 0) { int tmp; memcpy(&tmp, s, sizeof(int)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swapi(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swapi(tmp); s += sizeof(int); UNPACK_PUSH(INT2NUM(tmp)); } PACK_ITEM_ADJUST(); } else { - PACK_LENGTH_ADJUST(unsigned int,sizeof(unsigned int)); + PACK_LENGTH_ADJUST_SIZE(sizeof(unsigned int)); while (len-- > 0) { unsigned int tmp; memcpy(&tmp, s, sizeof(unsigned int)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swapi(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swapi(tmp); s += sizeof(unsigned int); UNPACK_PUSH(UINT2NUM(tmp)); } @@ -1721,22 +1639,22 @@ #if SIZEOF_INT != SIZEOF_LONG case SIZEOF_LONG: if (signed_p) { - PACK_LENGTH_ADJUST(long,sizeof(long)); + PACK_LENGTH_ADJUST_SIZE(sizeof(long)); while (len-- > 0) { long tmp; memcpy(&tmp, s, sizeof(long)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swapl(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swapl(tmp); s += sizeof(long); UNPACK_PUSH(LONG2NUM(tmp)); } PACK_ITEM_ADJUST(); } else { - PACK_LENGTH_ADJUST(unsigned long,sizeof(unsigned long)); + PACK_LENGTH_ADJUST_SIZE(sizeof(unsigned long)); while (len-- > 0) { unsigned long tmp; memcpy(&tmp, s, sizeof(unsigned long)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swapl(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swapl(tmp); s += sizeof(unsigned long); UNPACK_PUSH(ULONG2NUM(tmp)); } @@ -1748,22 +1666,22 @@ #if defined(HAVE_LONG_LONG) && SIZEOF_LONG != SIZEOF_LONG_LONG case SIZEOF_LONG_LONG: if (signed_p) { - PACK_LENGTH_ADJUST(LONG_LONG,sizeof(LONG_LONG)); + PACK_LENGTH_ADJUST_SIZE(sizeof(LONG_LONG)); while (len-- > 0) { LONG_LONG tmp; memcpy(&tmp, s, sizeof(LONG_LONG)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swapll(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swapll(tmp); s += sizeof(LONG_LONG); UNPACK_PUSH(LL2NUM(tmp)); } PACK_ITEM_ADJUST(); } else { - PACK_LENGTH_ADJUST(unsigned LONG_LONG,sizeof(unsigned LONG_LONG)); + PACK_LENGTH_ADJUST_SIZE(sizeof(unsigned LONG_LONG)); while (len-- > 0) { unsigned LONG_LONG tmp; memcpy(&tmp, s, sizeof(unsigned LONG_LONG)); - if (bigendian_p ^ BIGENDIAN_P) tmp = swapll(tmp); + if (bigendian_p != BIGENDIAN_P()) tmp = swapll(tmp); s += sizeof(unsigned LONG_LONG); UNPACK_PUSH(ULL2NUM(tmp)); } @@ -1774,8 +1692,8 @@ #if SIZEOF_LONG != QUAD_SIZE && (!defined(HAVE_LONG_LONG) || SIZEOF_LONG_LONG != QUAD_SIZE) case QUAD_SIZE: - if (bigendian_p ^ BIGENDIAN_P) - rb_bug("unexpected endian"); + if (bigendian_p != BIGENDIAN_P()) + rb_bug("unexpected endian for unpack"); if (signed_p) { PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE); while (len-- > 0) { @@ -1798,12 +1716,12 @@ #endif default: - rb_bug("unexpected intger size"); + rb_bug("unexpected intger size for unpack"); } case 'f': case 'F': - PACK_LENGTH_ADJUST(float,sizeof(float)); + PACK_LENGTH_ADJUST_SIZE(sizeof(float)); while (len-- > 0) { float tmp; memcpy(&tmp, s, sizeof(float)); @@ -1814,7 +1732,7 @@ break; case 'e': - PACK_LENGTH_ADJUST(float,sizeof(float)); + PACK_LENGTH_ADJUST_SIZE(sizeof(float)); while (len-- > 0) { float tmp; FLOAT_CONVWITH(ftmp); @@ -1828,7 +1746,7 @@ break; case 'E': - PACK_LENGTH_ADJUST(double,sizeof(double)); + PACK_LENGTH_ADJUST_SIZE(sizeof(double)); while (len-- > 0) { double tmp; DOUBLE_CONVWITH(dtmp); @@ -1843,7 +1761,7 @@ case 'D': case 'd': - PACK_LENGTH_ADJUST(double,sizeof(double)); + PACK_LENGTH_ADJUST_SIZE(sizeof(double)); while (len-- > 0) { double tmp; memcpy(&tmp, s, sizeof(double)); @@ -1854,7 +1772,7 @@ break; case 'g': - PACK_LENGTH_ADJUST(float,sizeof(float)); + PACK_LENGTH_ADJUST_SIZE(sizeof(float)); while (len-- > 0) { float tmp; FLOAT_CONVWITH(ftmp;) @@ -1868,7 +1786,7 @@ break; case 'G': - PACK_LENGTH_ADJUST(double,sizeof(double)); + PACK_LENGTH_ADJUST_SIZE(sizeof(double)); while (len-- > 0) { double tmp; DOUBLE_CONVWITH(dtmp); Index: test/ruby/test_pack.rb =================================================================== --- test/ruby/test_pack.rb (revision 26760) +++ test/ruby/test_pack.rb (revision 26761) @@ -20,6 +20,31 @@ assert_equal($x, $x.pack("l").unpack("l")) end + def test_pack_n + assert_equal "\000\000", [0].pack('n') + assert_equal "\000\001", [1].pack('n') + assert_equal "\000\002", [2].pack('n') + assert_equal "\000\003", [3].pack('n') + assert_equal "\377\376", [65534].pack('n') + assert_equal "\377\377", [65535].pack('n') + + assert_equal "\200\000", [2**15].pack('n') + assert_equal "\177\377", [-2**15-1].pack('n') + assert_equal "\377\377", [-1].pack('n') + + assert_equal "\000\001\000\001", [1,1].pack('n*') + assert_equal "\000\001\000\001\000\001", [1,1,1].pack('n*') + end + + def test_unpack_n + assert_equal 1, "\000\001".unpack('n')[0] + assert_equal 2, "\000\002".unpack('n')[0] + assert_equal 3, "\000\003".unpack('n')[0] + assert_equal 65535, "\377\377".unpack('n')[0] + assert_equal [1,1], "\000\001\000\001".unpack('n*') + assert_equal [1,1,1], "\000\001\000\001\000\001".unpack('n*') + end + def test_pack_N assert_equal "\000\000\000\000", [0].pack('N') assert_equal "\000\000\000\001", [1].pack('N') @@ -40,12 +65,80 @@ assert_equal 1, "\000\000\000\001".unpack('N')[0] assert_equal 2, "\000\000\000\002".unpack('N')[0] assert_equal 3, "\000\000\000\003".unpack('N')[0] - assert_equal 3, "\000\000\000\003".unpack('N')[0] assert_equal 4294967295, "\377\377\377\377".unpack('N')[0] assert_equal [1,1], "\000\000\000\001\000\000\000\001".unpack('N*') assert_equal [1,1,1], "\000\000\000\001\000\000\000\001\000\000\000\001".unpack('N*') end + def test_integer_endian + s = [1].pack("s") + assert_includes(["\0\1", "\1\0"], s) + if s == "\0\1" + # big endian + assert_equal("\x01\x02", [0x0102].pack("s")) + assert_equal("\x01\x02", [0x0102].pack("S")) + assert_equal("\x01\x02\x03\x04", [0x01020304].pack("l")) + assert_equal("\x01\x02\x03\x04", [0x01020304].pack("L")) + assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("q")) + assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("Q")) + assert_match(/\A\x00*\x01\x02\z/, [0x0102].pack("s!")) + assert_match(/\A\x00*\x01\x02\z/, [0x0102].pack("S!")) + assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("i")) + assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("I")) + assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("i!")) + assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("I!")) + assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("l!")) + assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("L!")) + %w[s S l L q Q s! S! i I i! I! l! L!].each {|fmt| + nuls = [0].pack(fmt) + v = 0 + s = "".force_encoding("ascii-8bit") + nuls.bytesize.times {|i| + j = i + 40 + v = v * 256 + j + s << [j].pack("C") + } + assert_equal(s, [v].pack(fmt), "[#{v}].pack(#{fmt.dump})") + assert_equal([v], s.unpack(fmt), "#{s.dump}.unpack(#{fmt.dump})") + s2 = s+s + fmt2 = fmt+"*" + assert_equal([v,v], s2.unpack(fmt2), "#{s2.dump}.unpack(#{fmt2.dump})") + } + else + # little endian + assert_equal("\x02\x01", [0x0102].pack("s")) + assert_equal("\x02\x01", [0x0102].pack("S")) + assert_equal("\x04\x03\x02\x01", [0x01020304].pack("l")) + assert_equal("\x04\x03\x02\x01", [0x01020304].pack("L")) + assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("q")) + assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("Q")) + assert_match(/\A\x02\x01\x00*\z/, [0x0102].pack("s!")) + assert_match(/\A\x02\x01\x00*\z/, [0x0102].pack("S!")) + assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("i")) + assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("I")) + assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("i!")) + assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("I!")) + assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("l!")) + assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("L!")) + %w[s S l L q Q s! S! i I i! I! l! L!].each {|fmt| + nuls = [0].pack(fmt) + v = 0 + s = "".force_encoding("ascii-8bit") + nuls.bytesize.times {|i| + j = i+40 + v = v * 256 + j + s << [j].pack("C") + } + s.reverse! + assert_equal(s, [v].pack(fmt), "[#{v}].pack(#{fmt.dump})") + assert_equal([v], s.unpack(fmt), "#{s.dump}.unpack(#{fmt.dump})") + s2 = s+s + fmt2 = fmt+"*" + assert_equal([v,v], s2.unpack(fmt2), "#{s2.dump}.unpack(#{fmt2.dump})") + } + end + end + def test_pack_U assert_raise(RangeError) { [-0x40000001].pack("U") } assert_raise(RangeError) { [-0x40000000].pack("U") } @@ -238,6 +331,11 @@ assert_equal(s1, s2) assert_equal([513, -514], s2.unpack("s!*")) assert_equal([513, 65022], s1.unpack("S!*")) + + assert_equal(2, [1].pack("s").bytesize) + assert_equal(2, [1].pack("S").bytesize) + assert_operator(2, :<=, [1].pack("s!").bytesize) + assert_operator(2, :<=, [1].pack("S!").bytesize) end def test_pack_unpack_iI @@ -251,6 +349,11 @@ s2 = [67305985, 4244504319].pack("I!*") assert_equal([67305985, -50462977], s1.unpack("i!*")) assert_equal([67305985, 4244504319], s2.unpack("I!*")) + + assert_operator(4, :<=, [1].pack("i").bytesize) + assert_operator(4, :<=, [1].pack("I").bytesize) + assert_operator(4, :<=, [1].pack("i!").bytesize) + assert_operator(4, :<=, [1].pack("I!").bytesize) end def test_pack_unpack_lL @@ -264,6 +367,11 @@ s2 = [67305985, 4244504319].pack("L!*") assert_equal([67305985, -50462977], s1.unpack("l!*")) assert_equal([67305985, 4244504319], s2.unpack("L!*")) + + assert_equal(4, [1].pack("l").bytesize) + assert_equal(4, [1].pack("L").bytesize) + assert_operator(4, :<=, [1].pack("l!").bytesize) + assert_operator(4, :<=, [1].pack("L!").bytesize) end def test_pack_unpack_qQ @@ -272,6 +380,9 @@ assert_equal(s1, s2) 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) end def test_pack_unpack_nN @@ -280,6 +391,9 @@ assert_equal([0,1,65535,32767,32768,65535], "\000\000\000\001\377\377\177\377\200\000\377\377".unpack("n*")) assert_equal([0,1,4294967295], "\000\000\000\000\000\000\000\001\377\377\377\377".unpack("N*")) + + assert_equal(2, [1].pack("n").bytesize) + assert_equal(4, [1].pack("N").bytesize) end def test_pack_unpack_vV @@ -288,6 +402,9 @@ assert_equal([0,1,65535,32767,32768,65535], "\000\000\001\000\377\377\377\177\000\200\377\377".unpack("v*")) assert_equal([0,1,4294967295], "\000\000\000\000\001\000\000\000\377\377\377\377".unpack("V*")) + + assert_equal(2, [1].pack("v").bytesize) + assert_equal(4, [1].pack("V").bytesize) end def test_pack_unpack_fdeEgG Index: test/ruby/test_integer_comb.rb =================================================================== --- test/ruby/test_integer_comb.rb (revision 26760) +++ test/ruby/test_integer_comb.rb (revision 26761) @@ -587,6 +587,8 @@ if min <= a && a <= max assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})[0]") end + assert_operator(min, :<=, b) + assert_operator(b, :<=, max) assert_equal(a & mask, b & mask, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})[0] & #{mask}") } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/