mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Support float/double unpacking.
This commit is contained in:
+65
-1
@@ -255,6 +255,35 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i
|
||||
return 8;
|
||||
}
|
||||
|
||||
static int
|
||||
unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary, unsigned int flags)
|
||||
{
|
||||
int i;
|
||||
double d;
|
||||
uint8_t *buffer = (uint8_t *)&d;
|
||||
|
||||
if (flags & PACK_FLAG_LITTLEENDIAN) {
|
||||
#ifdef MRB_ENDIAN_BIG
|
||||
for (i = 0; i < 8; ++i) {
|
||||
buffer[8 - i - 1] = src[i];
|
||||
}
|
||||
#else
|
||||
memcpy(buffer, src, 8);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef MRB_ENDIAN_BIG
|
||||
memcpy(buffer, src, 8);
|
||||
#else
|
||||
for (i = 0; i < 8; ++i) {
|
||||
buffer[8 - i - 1] = src[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
mrb_ary_push(mrb, ary, mrb_float_value(mrb, d));
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
static int
|
||||
pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
|
||||
{
|
||||
@@ -285,6 +314,35 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int
|
||||
unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary, unsigned int flags)
|
||||
{
|
||||
int i;
|
||||
float f;
|
||||
uint8_t *buffer = (uint8_t *)&f;
|
||||
|
||||
if (flags & PACK_FLAG_LITTLEENDIAN) {
|
||||
#ifdef MRB_ENDIAN_BIG
|
||||
for (i = 0; i < 4; ++i) {
|
||||
buffer[4 - i - 1] = src[i];
|
||||
}
|
||||
#else
|
||||
memcpy(buffer, src, 4);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef MRB_ENDIAN_BIG
|
||||
memcpy(buffer, src, 4);
|
||||
#else
|
||||
for (i = 0; i < 4; ++i) {
|
||||
buffer[4 - i - 1] = src[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
mrb_ary_push(mrb, ary, mrb_float_value(mrb, f));
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int
|
||||
pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags)
|
||||
{
|
||||
@@ -623,7 +681,7 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, int *dirp, int *typep, int *sizep,
|
||||
case 'F': case 'f':
|
||||
dir = PACK_DIR_FLOAT;
|
||||
type = PACK_TYPE_FLOAT;
|
||||
size = 8;
|
||||
size = 4;
|
||||
flags |= PACK_FLAG_SIGNED;
|
||||
break;
|
||||
case 'E':
|
||||
@@ -899,6 +957,12 @@ mrb_pack_unpack(mrb_state *mrb, mrb_value str)
|
||||
case PACK_DIR_BASE64:
|
||||
srcidx += unpack_m(mrb, sptr, srclen - srcidx, result, flags);
|
||||
break;
|
||||
case PACK_DIR_FLOAT:
|
||||
srcidx += unpack_float(mrb, sptr, srclen - srcidx, result, flags);
|
||||
break;
|
||||
case PACK_DIR_DOUBLE:
|
||||
srcidx += unpack_double(mrb, sptr, srclen - srcidx, result, flags);
|
||||
break;
|
||||
}
|
||||
if (count > 0) {
|
||||
count--;
|
||||
|
||||
+25
-14
@@ -89,24 +89,35 @@ assert('issue #1') do
|
||||
[1, 2].pack("nn") == "\000\001\000\002"
|
||||
end
|
||||
|
||||
def assert_pack tmpl, packed, unpacked
|
||||
assert_equal packed, unpacked.pack(tmpl)
|
||||
assert_equal unpacked, packed.unpack(tmpl)
|
||||
end
|
||||
|
||||
PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01
|
||||
|
||||
assert 'pack float' do
|
||||
assert_equal "\x00\x00@@", [3.0].pack('e')
|
||||
assert_equal "@@\x00\x00", [3.0].pack('g')
|
||||
assert_pack 'e', "\x00\x00@@", [3.0]
|
||||
assert_pack 'g', "@@\x00\x00", [3.0]
|
||||
|
||||
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"
|
||||
if PACK_IS_LITTLE_ENDIAN
|
||||
assert_pack 'f', "\x00\x00@@", [3.0]
|
||||
assert_pack 'F', "\x00\x00@@", [3.0]
|
||||
else
|
||||
assert_pack 'f', "@@\x00\x00", [3.0]
|
||||
assert_pack 'F', "@@\x00\x00", [3.0]
|
||||
end
|
||||
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')
|
||||
assert_pack 'E', "\x00\x00\x00\x00\x00\x00\b@", [3.0]
|
||||
assert_pack 'G', "@\b\x00\x00\x00\x00\x00\x00", [3.0]
|
||||
|
||||
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"
|
||||
if PACK_IS_LITTLE_ENDIAN
|
||||
assert_pack 'd', "\x00\x00\x00\x00\x00\x00\b@", [3.0]
|
||||
assert_pack 'D', "\x00\x00\x00\x00\x00\x00\b@", [3.0]
|
||||
else
|
||||
assert_pack 'd', "@\b\x00\x00\x00\x00\x00\x00", [3.0]
|
||||
assert_pack 'D', "@\b\x00\x00\x00\x00\x00\x00", [3.0]
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user