/* lightuserdata pattern string format "ixrsmb" integer size lightuserdata buffer integer buffer_len */ static int _pattern_unpack(lua_State *L) { struct pbc_pattern * pat = (struct pbc_pattern *)checkuserdata(L, 1); if (pat == NULL) { return luaL_error(L, "unpack pattern is NULL"); } size_t format_sz = 0; const char * format = lua_tolstring(L,2,&format_sz); int size = (int)lua_tointeger(L,3); struct pbc_slice slice; if (lua_isstring(L,4)) { size_t buffer_len = 0; const char *buffer = luaL_checklstring(L,4,&buffer_len); slice.buffer = (void *)buffer; slice.len = (int)buffer_len; } else { if (!lua_isuserdata(L,4)) { return luaL_error(L, "Need a userdata"); } slice.buffer = lua_touserdata(L,4); slice.len = (int)luaL_checkinteger(L,5); } char * temp = (char *)alloca(size); int ret = pbc_pattern_unpack(pat, &slice, temp); if (ret < 0) { return 0; } lua_checkstack(L, (int)format_sz + 3); int i; char * ptr = temp; bool array = false; for (i=0;i<format_sz;i++) { char type = format[i]; if (type >= 'a' && type <='z') { ptr = (char *)_push_value(L,ptr,type); } else { array = true; int n = pbc_array_size((struct _pbc_array *)ptr); lua_createtable(L,n,0); int j; for (j=0;j<n;j++) { _push_array(L,(struct _pbc_array *)ptr, type, j); } ptr += sizeof(pbc_array); } } if (array) { pbc_pattern_close_arrays(pat, temp); } return (int)format_sz; }
/* lightuserdata pattern string format "ixrsmb" integer size lightuserdata buffer integer buffer_len */ static int _pattern_unpack(lua_State *L) { struct pbc_pattern * pat = lua_touserdata(L, 1); size_t format_sz = 0; const char * format = lua_tolstring(L,2,&format_sz); int size = lua_tointeger(L,3); struct pbc_slice slice; if (lua_isstring(L,4)) { size_t buffer_len = 0; const char *buffer = lua_tolstring(L,4,&buffer_len); slice.buffer = (void *)buffer; slice.len = buffer_len; } else { slice.buffer = lua_touserdata(L,4); slice.len = lua_tointeger(L,5); } char temp[size]; int ret = pbc_pattern_unpack(pat, &slice, temp); if (ret < 0) return 0; lua_checkstack(L, format_sz + 3); int i; char * ptr = temp; bool array = false; for (i=0;i<format_sz;i++) { char type = format[i]; if (type >= 'a' && type <='z') { ptr = _push_value(L,ptr,type); } else { array = true; int n = pbc_array_size((void *)ptr); lua_createtable(L,n,0); int j; for (j=0;j<n;j++) { _push_array(L,(void *)ptr, type, j); } } } if (array) { pbc_pattern_close_arrays(pat, temp); } return format_sz; }