Add support of little endian float.

This commit is contained in:
take_cheeze
2014-06-13 17:56:36 +09:00
parent a0c4ca2406
commit f4f968241b
2 changed files with 34 additions and 1 deletions
+30 -1
View File
@@ -31,7 +31,7 @@ enum {
//PACK_DIR_UTF8, /* U */
//PACK_DIR_BER,
PACK_DIR_DOUBLE, /* E */
//PACK_DIR_FLOAT, /* f */
PACK_DIR_FLOAT, /* f */
PACK_DIR_STR, /* A */
PACK_DIR_HEX, /* h */
PACK_DIR_BASE64, /* m */
@@ -245,6 +245,26 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i
return 8;
}
static int
pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
{
int i;
float f;
uint8_t *buffer = (uint8_t *)&f;
str = str_len_ensure(mrb, str, sidx + 4);
f = mrb_float(o);
#ifdef MRB_ENDIAN_BIG
#error unsupported
#else
for(i = 0; i < 4; i++){
RSTRING_PTR(str)[sidx+i] = buffer[i];
}
#endif
return 4;
}
static int
pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags)
{
@@ -580,6 +600,12 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, int *dirp, int *typep, int *sizep,
size = 8;
flags |= PACK_FLAG_SIGNED;
break;
case 'e':
dir = PACK_DIR_FLOAT;
type = PACK_TYPE_FLOAT;
size = 4;
flags |= PACK_FLAG_SIGNED;
break;
case 'H':
dir = PACK_DIR_HEX;
type = PACK_TYPE_STRING;
@@ -756,6 +782,9 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
case PACK_DIR_DOUBLE:
ridx += pack_double(mrb, o, result, ridx, flags);
break;
case PACK_DIR_FLOAT:
ridx += pack_float(mrb, o, result, ridx, flags);
break;
default:
break;
}
+4
View File
@@ -88,3 +88,7 @@ end
assert('issue #1') do
[1, 2].pack("nn") == "\000\001\000\002"
end
assert 'pack float' do
assert_equal "\x00\x00@@", [3.0].pack('e')
end