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); } }
void _pbcB_register_fields(struct pbc_env *p, pbc_array queue) { int sz = pbc_array_size(queue); int i; for (i=0;i<sz;i++) { pbc_var atom; _pbcA_index(queue,i,atom); struct _field * f = atom->m.buffer; set_field_one(p, f); } }
/* 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 void set_enums(struct pbc_env *p, struct file_t *file) { int n = pbc_array_size(file->enum_size); int i; int start = 0; for (i=0;i<n;i++) { pbc_var name; _pbcA_index(file->enum_name,i,name); pbc_var var; _pbcA_index(file->enum_size,i,var); set_enum_one(p, file, name->s.str, start , (int)var->integer.low); start += var->integer.low; } }
static void set_msgs(struct pbc_pattern * FIELD_T, struct pbc_env *p, struct file_t *file , pbc_array queue) { int n = pbc_array_size(file->message_size); int i; int start = 0; for (i=0;i<n;i++) { pbc_var name; _pbcA_index(file->message_name,i,name); pbc_var sz; _pbcA_index(file->message_size,i,sz); set_msg_one(FIELD_T, p, file, name->s.str, start , (int)sz->integer.low , queue); start += sz->integer.low; } }
/* 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; }
static void _pbc_rmessage_new(struct pbc_rmessage * ret , struct _message * type , void *buffer, int size , struct heap *h) { if (size == 0) { ret->msg = type; ret->index = _pbcM_sp_new(0 , h); ret->heap = h; return; } pbc_ctx _ctx; int count = _pbcC_open(_ctx,buffer,size); if (count <= 0) { type->env->lasterror = "rmessage decode context error"; memset(ret , 0, sizeof(*ret)); return; } struct context * ctx = (struct context *)_ctx; ret->msg = type; ret->index = _pbcM_sp_new(count, h); ret->heap = h; int i; for (i=0;i<ctx->number;i++) { int id = ctx->a[i].wire_id >> 3; struct _field * f = _pbcM_ip_query(type->id , id); if (f) { if (f->label == LABEL_REPEATED || f->label == LABEL_PACKED) { struct value * v; void ** vv = _pbcM_sp_query_insert(ret->index, f->name); if (*vv == NULL) { v = _pbcH_alloc(h, SIZE_ARRAY); v->type = f; _pbcA_open_heap(v->v.array,ret->heap); *vv = v; } else { v= *vv; } if (f->label == LABEL_PACKED) { push_value_packed(type, v->v.array , f , &(ctx->a[i]), buffer); if (pbc_array_size(v->v.array) == 0) { type->env->lasterror = "rmessage decode packed data error"; *vv = NULL; } } else { push_value_array(h,v->v.array , f, &(ctx->a[i]), buffer); if (pbc_array_size(v->v.array) == 0) { type->env->lasterror = "rmessage decode repeated data error"; *vv = NULL; } } } else { struct value * v = read_value(h, f, &(ctx->a[i]), buffer); if (v) { _pbcM_sp_insert(ret->index, f->name, v); } else { type->env->lasterror = "rmessage decode data error"; } } } } _pbcC_close(_ctx); }