Cleaner handling of floats in pack/unpack
This commit is contained in:
70
lstrlib.c
70
lstrlib.c
@@ -1358,16 +1358,6 @@ struct cD {
|
|||||||
#define MAXALIGN (offsetof(struct cD, u))
|
#define MAXALIGN (offsetof(struct cD, u))
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Union for serializing floats
|
|
||||||
*/
|
|
||||||
typedef union Ftypes {
|
|
||||||
float f;
|
|
||||||
double d;
|
|
||||||
lua_Number n;
|
|
||||||
} Ftypes;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** information to pack/unpack stuff
|
** information to pack/unpack stuff
|
||||||
*/
|
*/
|
||||||
@@ -1384,7 +1374,9 @@ typedef struct Header {
|
|||||||
typedef enum KOption {
|
typedef enum KOption {
|
||||||
Kint, /* signed integers */
|
Kint, /* signed integers */
|
||||||
Kuint, /* unsigned integers */
|
Kuint, /* unsigned integers */
|
||||||
Kfloat, /* floating-point numbers */
|
Kfloat, /* single-precision floating-point numbers */
|
||||||
|
Knumber, /* Lua "native" floating-point numbers */
|
||||||
|
Kdouble, /* double-precision floating-point numbers */
|
||||||
Kchar, /* fixed-length strings */
|
Kchar, /* fixed-length strings */
|
||||||
Kstring, /* strings with prefixed length */
|
Kstring, /* strings with prefixed length */
|
||||||
Kzstr, /* zero-terminated strings */
|
Kzstr, /* zero-terminated strings */
|
||||||
@@ -1453,8 +1445,8 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
|
|||||||
case 'J': *size = sizeof(lua_Integer); return Kuint;
|
case 'J': *size = sizeof(lua_Integer); return Kuint;
|
||||||
case 'T': *size = sizeof(size_t); return Kuint;
|
case 'T': *size = sizeof(size_t); return Kuint;
|
||||||
case 'f': *size = sizeof(float); return Kfloat;
|
case 'f': *size = sizeof(float); return Kfloat;
|
||||||
case 'd': *size = sizeof(double); return Kfloat;
|
case 'n': *size = sizeof(lua_Number); return Knumber;
|
||||||
case 'n': *size = sizeof(lua_Number); return Kfloat;
|
case 'd': *size = sizeof(double); return Kdouble;
|
||||||
case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
|
case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
|
||||||
case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
|
case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
|
||||||
case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
|
case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
|
||||||
@@ -1580,15 +1572,27 @@ static int str_pack (lua_State *L) {
|
|||||||
packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
|
packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Kfloat: { /* floating-point options */
|
case Kfloat: { /* C float */
|
||||||
Ftypes u;
|
float f = (float)luaL_checknumber(L, arg); /* get argument */
|
||||||
char *buff = luaL_prepbuffsize(&b, size);
|
char *buff = luaL_prepbuffsize(&b, sizeof(f));
|
||||||
lua_Number n = luaL_checknumber(L, arg); /* get argument */
|
/* move 'f' to final result, correcting endianness if needed */
|
||||||
if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */
|
copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
|
||||||
else if (size == sizeof(u.d)) u.d = (double)n;
|
luaL_addsize(&b, size);
|
||||||
else u.n = n;
|
break;
|
||||||
/* move 'u' to final result, correcting endianness if needed */
|
}
|
||||||
copywithendian(buff, (char *)&u, size, h.islittle);
|
case Knumber: { /* Lua float */
|
||||||
|
lua_Number f = luaL_checknumber(L, arg); /* get argument */
|
||||||
|
char *buff = luaL_prepbuffsize(&b, sizeof(f));
|
||||||
|
/* move 'f' to final result, correcting endianness if needed */
|
||||||
|
copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
|
||||||
|
luaL_addsize(&b, size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Kdouble: { /* C double */
|
||||||
|
double f = (double)luaL_checknumber(L, arg); /* get argument */
|
||||||
|
char *buff = luaL_prepbuffsize(&b, sizeof(f));
|
||||||
|
/* move 'f' to final result, correcting endianness if needed */
|
||||||
|
copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
|
||||||
luaL_addsize(&b, size);
|
luaL_addsize(&b, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1714,13 +1718,21 @@ static int str_unpack (lua_State *L) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Kfloat: {
|
case Kfloat: {
|
||||||
Ftypes u;
|
float f;
|
||||||
lua_Number num;
|
copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
|
||||||
copywithendian((char *)&u, data + pos, size, h.islittle);
|
lua_pushnumber(L, (lua_Number)f);
|
||||||
if (size == sizeof(u.f)) num = (lua_Number)u.f;
|
break;
|
||||||
else if (size == sizeof(u.d)) num = (lua_Number)u.d;
|
}
|
||||||
else num = u.n;
|
case Knumber: {
|
||||||
lua_pushnumber(L, num);
|
lua_Number f;
|
||||||
|
copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
|
||||||
|
lua_pushnumber(L, f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Kdouble: {
|
||||||
|
double f;
|
||||||
|
copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
|
||||||
|
lua_pushnumber(L, (lua_Number)f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Kchar: {
|
case Kchar: {
|
||||||
|
|||||||
Reference in New Issue
Block a user