mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
added LHF's lpack module
This commit is contained in:
parent
3ce5487a73
commit
3379b15660
@ -71,7 +71,7 @@ newlib_files = " src/newlib/devman.c src/newlib/stubs.c src/newlib/genstd.c"
|
||||
|
||||
# Lua module files
|
||||
module_files = """ src/modules/pio.c src/modules/spi.c src/modules/tmr.c src/modules/pd.c src/modules/uart.c
|
||||
src/modules/term.c src/modules/pwm.c"""
|
||||
src/modules/term.c src/modules/pwm.c src/modules/lpack.c"""
|
||||
|
||||
# Optimizer flags (speed or size)
|
||||
#opt = "-O3"
|
||||
|
@ -27,6 +27,9 @@ LUALIB_API int ( luaopen_term )( lua_State* L );
|
||||
#define AUXLIB_PWM "pwm"
|
||||
LUALIB_API int ( luaopen_pwm )( lua_State* L );
|
||||
|
||||
#define AUXLIB_PACK "pack"
|
||||
LUALIB_API int ( luaopen_pack )( lua_State* L );
|
||||
|
||||
#ifdef ELUA_MOD_CHECK_PARS
|
||||
|
||||
// Helper macros
|
||||
|
268
src/modules/lpack.c
Normal file
268
src/modules/lpack.c
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* lpack.c
|
||||
* a Lua library for packing and unpacking binary data
|
||||
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
|
||||
* 29 Jun 2007 19:27:20
|
||||
* This code is hereby placed in the public domain.
|
||||
* with contributions from Ignacio Castano <castanyo@yahoo.es> and
|
||||
* Roberto Ierusalimschy <roberto@inf.puc-rio.br>.
|
||||
*
|
||||
* Modified by BogdanM for eLua
|
||||
*/
|
||||
|
||||
#define OP_ZSTRING 'z' /* zero-terminated string */
|
||||
#define OP_BSTRING 'p' /* string preceded by length byte */
|
||||
#define OP_WSTRING 'P' /* string preceded by length word */
|
||||
#define OP_SSTRING 'a' /* string preceded by length size_t */
|
||||
#define OP_STRING 'A' /* string */
|
||||
#define OP_FLOAT 'f' /* float */
|
||||
#define OP_DOUBLE 'd' /* double */
|
||||
#define OP_NUMBER 'n' /* Lua number */
|
||||
#define OP_CHAR 'c' /* char */
|
||||
#define OP_BYTE 'b' /* byte = unsigned char */
|
||||
#define OP_SHORT 'h' /* short */
|
||||
#define OP_USHORT 'H' /* unsigned short */
|
||||
#define OP_INT 'i' /* int */
|
||||
#define OP_UINT 'I' /* unsigned int */
|
||||
#define OP_LONG 'l' /* long */
|
||||
#define OP_ULONG 'L' /* unsigned long */
|
||||
#define OP_LITTLEENDIAN '<' /* little endian */
|
||||
#define OP_BIGENDIAN '>' /* big endian */
|
||||
#define OP_NATIVE '=' /* native endian */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "auxmods.h"
|
||||
|
||||
static void badcode(lua_State *L, int c)
|
||||
{
|
||||
char s[]="bad code `?'";
|
||||
s[sizeof(s)-3]=c;
|
||||
luaL_argerror(L,1,s);
|
||||
}
|
||||
|
||||
static int doendian(int c)
|
||||
{
|
||||
int x=1;
|
||||
int e=*(char*)&x;
|
||||
if (c==OP_LITTLEENDIAN) return !e;
|
||||
if (c==OP_BIGENDIAN) return e;
|
||||
if (c==OP_NATIVE) return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void doswap(int swap, void *p, size_t n)
|
||||
{
|
||||
if (swap)
|
||||
{
|
||||
char *a=p;
|
||||
int i,j;
|
||||
for (i=0, j=n-1, n=n/2; n--; i++, j--)
|
||||
{
|
||||
char t=a[i]; a[i]=a[j]; a[j]=t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define UNPACKNUMBER(OP,T) \
|
||||
case OP: \
|
||||
{ \
|
||||
T a; \
|
||||
int m=sizeof(a); \
|
||||
if (i+m>len) goto done; \
|
||||
memcpy(&a,s+i,m); \
|
||||
i+=m; \
|
||||
doswap(swap,&a,m); \
|
||||
lua_pushnumber(L,(lua_Number)a); \
|
||||
++n; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define UNPACKSTRING(OP,T) \
|
||||
case OP: \
|
||||
{ \
|
||||
T l; \
|
||||
int m=sizeof(l); \
|
||||
if (i+m>len) goto done; \
|
||||
memcpy(&l,s+i,m); \
|
||||
doswap(swap,&l,m); \
|
||||
if (i+m+l>len) goto done; \
|
||||
i+=m; \
|
||||
lua_pushlstring(L,s+i,l); \
|
||||
i+=l; \
|
||||
++n; \
|
||||
break; \
|
||||
}
|
||||
|
||||
static int l_unpack(lua_State *L) /** unpack(s,f,[init]) */
|
||||
{
|
||||
size_t len;
|
||||
const char *s=luaL_checklstring(L,1,&len);
|
||||
const char *f=luaL_checkstring(L,2);
|
||||
int i=luaL_optnumber(L,3,1)-1;
|
||||
int n=0;
|
||||
int swap=0;
|
||||
lua_pushnil(L);
|
||||
while (*f)
|
||||
{
|
||||
int c=*f++;
|
||||
int N=1;
|
||||
if (isdigit(*f))
|
||||
{
|
||||
N=0;
|
||||
while (isdigit(*f)) N=10*N+(*f++)-'0';
|
||||
if (N==0 && c==OP_STRING) { lua_pushliteral(L,""); ++n; }
|
||||
}
|
||||
while (N--) switch (c)
|
||||
{
|
||||
case OP_LITTLEENDIAN:
|
||||
case OP_BIGENDIAN:
|
||||
case OP_NATIVE:
|
||||
{
|
||||
swap=doendian(c);
|
||||
N=0;
|
||||
break;
|
||||
}
|
||||
case OP_STRING:
|
||||
{
|
||||
++N;
|
||||
if (i+N>len) goto done;
|
||||
lua_pushlstring(L,s+i,N);
|
||||
i+=N;
|
||||
++n;
|
||||
N=0;
|
||||
break;
|
||||
}
|
||||
case OP_ZSTRING:
|
||||
{
|
||||
size_t l;
|
||||
if (i>=len) goto done;
|
||||
l=strlen(s+i);
|
||||
lua_pushlstring(L,s+i,l);
|
||||
i+=l+1;
|
||||
++n;
|
||||
break;
|
||||
}
|
||||
UNPACKSTRING(OP_BSTRING, unsigned char)
|
||||
UNPACKSTRING(OP_WSTRING, unsigned short)
|
||||
UNPACKSTRING(OP_SSTRING, size_t)
|
||||
UNPACKNUMBER(OP_NUMBER, lua_Number)
|
||||
UNPACKNUMBER(OP_DOUBLE, double)
|
||||
UNPACKNUMBER(OP_FLOAT, float)
|
||||
UNPACKNUMBER(OP_CHAR, char)
|
||||
UNPACKNUMBER(OP_BYTE, unsigned char)
|
||||
UNPACKNUMBER(OP_SHORT, short)
|
||||
UNPACKNUMBER(OP_USHORT, unsigned short)
|
||||
UNPACKNUMBER(OP_INT, int)
|
||||
UNPACKNUMBER(OP_UINT, unsigned int)
|
||||
UNPACKNUMBER(OP_LONG, long)
|
||||
UNPACKNUMBER(OP_ULONG, unsigned long)
|
||||
case ' ': case ',':
|
||||
break;
|
||||
default:
|
||||
badcode(L,c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
lua_pushnumber(L,i+1);
|
||||
lua_replace(L,-n-2);
|
||||
return n+1;
|
||||
}
|
||||
|
||||
#define PACKNUMBER(OP,T) \
|
||||
case OP: \
|
||||
{ \
|
||||
T a=(T)luaL_checknumber(L,i++); \
|
||||
doswap(swap,&a,sizeof(a)); \
|
||||
luaL_addlstring(&b,(void*)&a,sizeof(a)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define PACKSTRING(OP,T) \
|
||||
case OP: \
|
||||
{ \
|
||||
size_t l; \
|
||||
const char *a=luaL_checklstring(L,i++,&l); \
|
||||
T ll=(T)l; \
|
||||
doswap(swap,&ll,sizeof(ll)); \
|
||||
luaL_addlstring(&b,(void*)&ll,sizeof(ll)); \
|
||||
luaL_addlstring(&b,a,l); \
|
||||
break; \
|
||||
}
|
||||
|
||||
static int l_pack(lua_State *L) /** pack(f,...) */
|
||||
{
|
||||
int i=2;
|
||||
const char *f=luaL_checkstring(L,1);
|
||||
int swap=0;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L,&b);
|
||||
while (*f)
|
||||
{
|
||||
int c=*f++;
|
||||
int N=1;
|
||||
if (isdigit(*f))
|
||||
{
|
||||
N=0;
|
||||
while (isdigit(*f)) N=10*N+(*f++)-'0';
|
||||
}
|
||||
while (N--) switch (c)
|
||||
{
|
||||
case OP_LITTLEENDIAN:
|
||||
case OP_BIGENDIAN:
|
||||
case OP_NATIVE:
|
||||
{
|
||||
swap=doendian(c);
|
||||
N=0;
|
||||
break;
|
||||
}
|
||||
case OP_STRING:
|
||||
case OP_ZSTRING:
|
||||
{
|
||||
size_t l;
|
||||
const char *a=luaL_checklstring(L,i++,&l);
|
||||
luaL_addlstring(&b,a,l+(c==OP_ZSTRING));
|
||||
break;
|
||||
}
|
||||
PACKSTRING(OP_BSTRING, unsigned char)
|
||||
PACKSTRING(OP_WSTRING, unsigned short)
|
||||
PACKSTRING(OP_SSTRING, size_t)
|
||||
PACKNUMBER(OP_NUMBER, lua_Number)
|
||||
PACKNUMBER(OP_DOUBLE, double)
|
||||
PACKNUMBER(OP_FLOAT, float)
|
||||
PACKNUMBER(OP_CHAR, char)
|
||||
PACKNUMBER(OP_BYTE, unsigned char)
|
||||
PACKNUMBER(OP_SHORT, short)
|
||||
PACKNUMBER(OP_USHORT, unsigned short)
|
||||
PACKNUMBER(OP_INT, int)
|
||||
PACKNUMBER(OP_UINT, unsigned int)
|
||||
PACKNUMBER(OP_LONG, long)
|
||||
PACKNUMBER(OP_ULONG, unsigned long)
|
||||
case ' ': case ',':
|
||||
break;
|
||||
default:
|
||||
badcode(L,c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_reg pack_map[] =
|
||||
{
|
||||
{"pack", l_pack},
|
||||
{"unpack", l_unpack},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int luaopen_pack( lua_State *L )
|
||||
{
|
||||
luaL_register( L, AUXLIB_PACK, pack_map );
|
||||
return 1;
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
{ AUXLIB_PD, luaopen_pd },\
|
||||
{ AUXLIB_UART, luaopen_uart },\
|
||||
{ AUXLIB_TERM, luaopen_term },\
|
||||
{ AUXLIB_PWM, luaopen_pwm }
|
||||
{ AUXLIB_PWM, luaopen_pwm },\
|
||||
{ AUXLIB_PACK, luaopen_pack }
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user