static void test_pattern_unpack(struct pbc_env *env, struct pbc_slice * slice) { struct person p; int r = pbc_pattern_unpack(pat, slice, &p); if (r>=0) { printf("name = %s\n",(const char *)p.name.buffer); printf("id = %d\n",p.id); printf("email = %s\n",(const char *)p.email.buffer); int n = pbc_array_size(p.phone); int i; for (i=0;i<n;i++) { struct pbc_slice * bytes = pbc_array_slice(p.phone, i); struct person_phone pp; pbc_pattern_unpack(pat_phone , bytes , &pp); printf("\tnumber = %s\n" , (const char*)pp.number.buffer); printf("\ttype = %d\n" , pp.type); } n = pbc_array_size(p.test); for (i=0;i<n;i++) { printf("test[%d] = %d\n",i, pbc_array_integer(p.test, i , NULL)); } pbc_pattern_close_arrays(pat,&p); } }
static void set_msg_one(struct pbc_pattern * FIELD_T, struct pbc_env *p, struct file_t *file, const char *name, int start, int sz , pbc_array queue) { int i; for (i=0;i<sz;i++) { pbc_var _field; _pbcA_index(file->message_field, start+i, _field); struct field_t field; int ret = pbc_pattern_unpack(FIELD_T, _field->m.buffer, _field->m.len, &field); if (ret != 0) { continue; } struct _field f; f.id = field.id; f.name = field.name->s.str; f.type = field.type; f.label = field.label; f.type_name.n = field.type_name->s.str; set_default(&f, &field); _pbcP_push_message(p,name, &f , queue); // don't need to close pattern since no array } _pbcP_init_message(p, name); }
/* 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 = 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 = buffer_len; } else { if (!lua_isuserdata(L,4)) { return luaL_error(L, "Need a userdata"); } slice.buffer = lua_touserdata(L,4); slice.len = 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, 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 format_sz; }
static int register_internal(struct pbc_env * p, void *buffer, int size) { struct pbc_pattern * FIELD_T = _pbcP_new(8); F(0,name,string); F(1,id,int32); F(2,label,int32); F(3,type,int32); F(4,type_name,string); F(5,default_integer,int32); F(6,default_string,string); F(7,default_real,double); struct pbc_pattern * FILE_T = _pbcP_new(10); D(0,name,string); D(1,dependency,string_array); D(2,message_name,string_array); D(3,message_size,int32_array); D(4,message_field,message_array); D(5,enum_name,string_array); D(6,enum_size,int32_array); D(7,enum_string,string_array); D(8,enum_id,int32_array); int ret = 0; struct file_t file; int r = pbc_pattern_unpack(FILE_T, buffer, size, &file); if (r != 0) { ret = 1; goto _return; } _pbcM_sp_insert(p->files , file.name->s.str, NULL); pbc_array queue; _pbcA_open(queue); set_enums(p, &file); set_msgs(FIELD_T, p, &file, queue); _pbcB_register_fields(p, queue); _pbcA_close(queue); pbc_pattern_close_arrays(FILE_T, &file); _return: free(FIELD_T); free(FILE_T); return ret; }
/* 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; }