这里是编码相关的函数,有很多magic number, 一般看函数的功能和用途即可:
/* we assume IEEE 754 internal format for single and double precision floats. */
void mp_encode_double(lua_State *L, mp_buf *buf, double d) {
unsigned char b[9];
float f = d;
assert(sizeof(f) == 4 && sizeof(d) == 8);
if (d == (double)f) {
b[0] = 0xca; /* float IEEE 754 */
memcpy(b+1,&f,4);
memrevifle(b+1,4);
mp_buf_append(L,buf,b,5);
} else if (sizeof(d) == 8) {
b[0] = 0xcb; /* double IEEE 754 */
memcpy(b+1,&d,8);
memrevifle(b+1,8);
mp_buf_append(L,buf,b,9);
}
}
void mp_encode_int(lua_State *L, mp_buf *buf, int64_t n) {
unsigned char b[9];
int enclen;
if (n >= 0) {
if (n <= 127) {
b[0] = n & 0x7f; /* positive fixnum */
enclen = 1;
} else if (n <= 0xff) {
b[0] = 0xcc; /* uint 8 */
b[1] = n & 0xff;
enclen = 2;
} else if (n <= 0xffff) {
b[0] = 0xcd; /* uint 16 */
b[1] = (n & 0xff00) >> 8;
b[2] = n & 0xff;
enclen = 3;
} else if (n <= 0xffffffffLL) {
b[0] = 0xce; /* uint 32 */
b[1] = (n & 0xff000000) >> 24;
b[2] = (n & 0xff0000) >> 16;
b[3] = (n & 0xff00) >> 8;
b[4] = n & 0xff;
enclen = 5;
} else {
b[0] = 0xcf; /* uint 64 */
b[1] = (n & 0xff00000000000000LL) >> 56;
b[2] = (n & 0xff000000000000LL) >> 48;
b[3] = (n & 0xff0000000000LL) >> 40;
b[4] = (n & 0xff00000000LL) >> 32;
b[5] = (n & 0xff000000) >> 24;
b[6] = (n & 0xff0000) >> 16;
b[7] = (n & 0xff00) >> 8;
b[8] = n & 0xff;
enclen = 9;
}
} else {
if (n >= -32) {
b[0] = ((signed char)n); /* negative fixnum */
enclen = 1;
} else if (n >= -128) {
b[0] = 0xd0; /* int 8 */
b[1] = n & 0xff;
enclen = 2;
} else if (n >= -32768) {
b[0] = 0xd1; /* int 16 */
b[1] = (n & 0xff00) >> 8;
b[2] = n & 0xff;
enclen = 3;
} else if (n >= -2147483648LL) {
b[0] = 0xd2; /* int 32 */
b[1] = (n & 0xff000000) >> 24;
b[2] = (n & 0xff0000) >> 16;
b[3] = (n & 0xff00) >> 8;
b[4] = n & 0xff;
enclen = 5;
} else {
b[0] = 0xd3; /* int 64 */
b[1] = (n & 0xff00000000000000LL) >> 56;
b[2] = (n & 0xff000000000000LL) >> 48;
b[3] = (n & 0xff0000000000LL) >> 40;
b[4] = (n & 0xff00000000LL) >> 32;
b[5] = (n & 0xff000000) >> 24;
b[6] = (n & 0xff0000) >> 16;
b[7] = (n & 0xff00) >> 8;
b[8] = n & 0xff;
enclen = 9;
}
}
mp_buf_append(L,buf,b,enclen);
}
void mp_encode_array(lua_State *L, mp_buf *buf, int64_t n) {
unsigned char b[5];
int enclen;
if (n <= 15) {
b[0] = 0x90 | (n & 0xf); /* fix array */
enclen = 1;
} else if (n <= 65535) {
b[0] = 0xdc; /* array 16 */
b[1] = (n & 0xff00) >> 8;
b[2] = n & 0xff;
enclen = 3;
} else {
b[0] = 0xdd; /* array 32 */
b[1] = (n & 0xff000000) >> 24;
b[2] = (n & 0xff0000) >> 16;
b[3] = (n & 0xff00) >> 8;
b[4] = n & 0xff;
enclen = 5;
}
mp_buf_append(L,buf,b,enclen);
}
void mp_encode_map(lua_State *L, mp_buf *buf, int64_t n) {
unsigned char b[5];
int enclen;
if (n <= 15) {
b[0] = 0x80 | (n & 0xf); /* fix map */
enclen = 1;
} else if (n <= 65535) {
b[0] = 0xde; /* map 16 */
b[1] = (n & 0xff00) >> 8;
b[2] = n & 0xff;
enclen = 3;
} else {
b[0] = 0xdf; /* map 32 */
b[1] = (n & 0xff000000) >> 24;
b[2] = (n & 0xff0000) >> 16;
b[3] = (n & 0xff00) >> 8;
b[4] = n & 0xff;
enclen = 5;
}
mp_buf_append(L,buf,b,enclen);
}
/* --------------------------- Lua types encoding --------------------------- */
void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
size_t len;
const char *s;
s = lua_tolstring(L,-1,&len);
mp_encode_bytes(L,buf,(const unsigned char*)s,len);
}
void mp_encode_lua_bool(lua_State *L, mp_buf *buf) {
unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2;
mp_buf_append(L,buf,&b,1);
}
/* Lua 5.3 has a built in 64-bit integer type */
void mp_encode_lua_integer(lua_State *L, mp_buf *buf) {
#if (LUA_VERSION_NUM < 503) && BITS_32
lua_Number i = lua_tonumber(L,-1);
#else
lua_Integer i = lua_tointeger(L,-1);
#endif
mp_encode_int(L, buf, (int64_t)i);
}
/* Lua 5.2 and lower only has 64-bit doubles, so we need to
* detect if the double may be representable as an int
* for Lua < 5.3 */
void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
lua_Number n = lua_tonumber(L,-1);
if (IS_INT64_EQUIVALENT(n)) {
mp_encode_lua_integer(L, buf);
} else {
mp_encode_double(L,buf,(double)n);
}
}
void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level);
/* Convert a lua table into a message pack list. */
void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
#if LUA_VERSION_NUM < 502
size_t len = lua_objlen(L,-1), j;
#else
size_t len = lua_rawlen(L,-1), j;
#endif
mp_encode_array(L,buf,len);
luaL_checkstack(L, 1, "in function mp_encode_lua_table_as_array");
for (j = 1; j <= len; j++) {
lua_pushnumber(L,j);
lua_gettable(L,-2);
mp_encode_lua_type(L,buf,level+1);
}
}