int pbc_pattern_unpack(struct pbc_pattern *pat, struct pbc_slice *s, void * output) { pbc_ctx _ctx; int r = _pbcC_open(_ctx, s->buffer, s->len); if (r <= 0) { _pbcC_close(_ctx); return r+1; } set_default(pat, output); struct context * ctx = (struct context *)_ctx; int i; for (i=0;i<ctx->number;i++) { struct _pattern_field * f = bsearch_pattern(pat, ctx->a[i].id); if (f) { char * out = (char *)output + f->offset; if (unpack_field(f->ctype , f->ptype , ctx->buffer , &ctx->a[i], out) != 0) { pbc_pattern_close_arrays(pat, output); _pbcC_close(_ctx); return -i-1; } } } _pbcC_close(_ctx); return 0; }
static void _pbc_rmessage_new(struct pbc_rmessage * ret , struct _message * type , void *buffer, int size) { pbc_ctx _ctx; if (_pbcC_open(_ctx,buffer,size) <=0) { memset(ret , 0, sizeof(*ret)); return; } struct context * ctx = (struct context *)_ctx; ret->msg = type; ret->index = _pbcM_sp_new(); int i; for (i=0;i<ctx->number;i++) { int id = ctx->a[i].id; 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 = malloc(SIZE_ARRAY); v->type = f; _pbcA_open(v->v.array); *vv = v; } else { v= *vv; } if (f->label == LABEL_PACKED) { push_value_packed(v->v.array , f , &(ctx->a[i]), buffer); } else { push_value_array(v->v.array , f, &(ctx->a[i]), buffer); } } else { struct value * v = read_value(f, &(ctx->a[i]), buffer); if (v) { _pbcM_sp_insert(ret->index, f->name, v); } } } } _pbcC_close(_ctx); }
static void set_default(struct pbc_pattern *pat, uint8_t * output) { int i; for (i=0;i<pat->count;i++) { if (pat->f[i].ctype == CTYPE_ARRAY || pat->f[i].ctype == CTYPE_PACKED) { struct _pbc_array *array = (struct _pbc_array *)(output + pat->f[i].offset); _pbcA_open(array); continue; } else if (pat->f[i].ptype == PTYPE_MESSAGE) { struct _pbc_ctx *ctx = (struct _pbc_ctx *)(output + pat->f[i].offset); _pbcC_open(ctx , NULL , 0); continue; } else if (pat->f[i].ptype == PTYPE_ENUM) { pbc_var defv; defv->integer.low = pat->f[i].defv->e.id; defv->integer.hi = 0; set_default_v(output + pat->f[i].offset, pat->f[i].ctype, defv); continue; } set_default_v(output + pat->f[i].offset, pat->f[i].ctype, pat->f[i].defv); } }
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); }