From 7dc2b4f59f2b9019089d8a934c96148b1cdfd3b5 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Fri, 13 Jun 2014 18:22:56 +0900 Subject: Implement g/f/F/G/d/D packing. --- src/pack.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- test/pack.rb | 18 +++++++++++++++ 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/pack.c b/src/pack.c index f8cdcbaad..93fd3f16b 100644 --- a/src/pack.c +++ b/src/pack.c @@ -234,14 +234,26 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i str = str_len_ensure(mrb, str, sidx + 8); d = mrb_float(o); + if (flags & PACK_FLAG_LT) { #ifdef MRB_ENDIAN_BIG - #error unsupported + for (i = 0; i < 8; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; + } #else - for(i = 0; i < 8; i++){ - RSTRING_PTR(str)[sidx+i] = buffer[i]; - } + memcpy(RSTRING_PTR(str) + sidx, buffer, 8); +#endif + } else if (flags & PACK_FLAG_GT) { +#ifdef MRB_ENDIAN_BIG + memcpy(RSTRING_PTR(str) + sidx, buffer, 8); +#else + for (i = 0; i < 8; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; + } #endif - + } else { + memcpy(RSTRING_PTR(str) + sidx, buffer, 8); + } + return 8; } @@ -254,14 +266,26 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in str = str_len_ensure(mrb, str, sidx + 4); f = mrb_float(o); + if (flags & PACK_FLAG_LT) { #ifdef MRB_ENDIAN_BIG - #error unsupported + for (i = 0; i < 4; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; + } #else - for(i = 0; i < 4; i++){ - RSTRING_PTR(str)[sidx+i] = buffer[i]; - } + memcpy(RSTRING_PTR(str) + sidx, buffer, 4); +#endif + } else if (flags & PACK_FLAG_GT) { +#ifdef MRB_ENDIAN_BIG + memcpy(RSTRING_PTR(str) + sidx, buffer, 4); +#else + for (i = 0; i < 4; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; + } #endif - + } else { + memcpy(RSTRING_PTR(str) + sidx, buffer, 4); + } + return 4; } @@ -594,17 +618,41 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, int *dirp, int *typep, int *sizep, size = 1; flags |= PACK_FLAG_SIGNED; break; - case 'E': + case 'D': case 'd': dir = PACK_DIR_DOUBLE; type = PACK_TYPE_FLOAT; size = 8; flags |= PACK_FLAG_SIGNED; break; + case 'F': case 'f': + dir = PACK_DIR_FLOAT; + type = PACK_TYPE_FLOAT; + size = 8; + flags |= PACK_FLAG_SIGNED; + break; + case 'E': + dir = PACK_DIR_DOUBLE; + type = PACK_TYPE_FLOAT; + size = 8; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_LT; + break; case 'e': dir = PACK_DIR_FLOAT; type = PACK_TYPE_FLOAT; size = 4; - flags |= PACK_FLAG_SIGNED; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_LT; + break; + case 'G': + dir = PACK_DIR_DOUBLE; + type = PACK_TYPE_FLOAT; + size = 8; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_GT; + break; + case 'g': + dir = PACK_DIR_FLOAT; + type = PACK_TYPE_FLOAT; + size = 4; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_GT; break; case 'H': dir = PACK_DIR_HEX; diff --git a/test/pack.rb b/test/pack.rb index 2d754dfc1..02265f126 100644 --- a/test/pack.rb +++ b/test/pack.rb @@ -91,4 +91,22 @@ end assert 'pack float' do assert_equal "\x00\x00@@", [3.0].pack('e') + assert_equal "@@\x00\x00", [3.0].pack('g') + + native = [3.0].pack 'f' + assert_true native == "\x00\x00@@" or native == "@@\x00\x00" + + native = [3.0].pack 'F' + assert_true native == "\x00\x00@@" or native == "@@\x00\x00" +end + +assert 'pack double' do + assert_equal "\x00\x00\x00\x00\x00\x00\b@", [3.0].pack('E') + assert_equal "@\b\x00\x00\x00\x00\x00\x00", [3.0].pack('G') + + native = [3.0].pack 'd' + assert_true native == "\x00\x00\x00\x00\x00\x00\b@" or native == "@\b\x00\x00\x00\x00\x00\x00" + + native = [3.0].pack 'D' + assert_true native == "\x00\x00\x00\x00\x00\x00\b@" or native == "@\b\x00\x00\x00\x00\x00\x00" end -- cgit v1.2.3