static int _register_no_dependency(struct pbc_env * p,struct pbc_rmessage ** files , int n ) { int r = 0; int i; for (i=0;i<n;i++) { if (files[i] == NULL) continue; const char *filename = NULL; int err = _check_file_name(p, files[i], &filename); switch(err) { case CHECK_FILE_EXIST: break; case CHECK_FILE_DEPENDENCY: ++r; break; case CHECK_FILE_OK: { struct _stringpool *pool = _pbcS_new(); filename = _pbcS_build(pool, filename , strlen(filename)); _pbcM_sp_insert(p->files , filename, pool); _register(p,files[i],pool); files[i] = NULL; } break; } } return r; }
struct _message * _pbcP_init_message(struct pbc_env * p, const char *name) { struct _message * m = _pbcM_sp_query(p->msgs, name); if (m == NULL) { m = malloc(sizeof(*m)); m->def = NULL; m->key = name; m->id = NULL; m->name = _pbcM_sp_new(); m->env = p; _pbcM_sp_insert(p->msgs, name, m); return m; } if (m->id) { // extend message, delete old id map. _pbcM_ip_delete(m->id); } struct _iter iter = { 0, NULL }; _pbcM_sp_foreach_ud(m->name, _count, &iter); iter.table = malloc(iter.count * sizeof(struct map_kv)); iter.count = 0; _pbcM_sp_foreach_ud(m->name, _set_table, &iter); m->id = _pbcM_ip_new(iter.table , iter.count); free(iter.table); return m; }
void _pbcP_push_message(struct pbc_env * p, const char *name, struct _field *f , pbc_array queue) { struct _message * m = _pbcM_sp_query(p->msgs, name); if (m==NULL) { m = malloc(sizeof(*m)); m->def = NULL; m->key = name; m->id = NULL; m->name = _pbcM_sp_new(); _pbcM_sp_insert(p->msgs, name, m); } struct _field * field = malloc(sizeof(*field)); memcpy(field,f,sizeof(*f)); _pbcM_sp_insert(m->name, field->name, field); pbc_var atom; atom->m.buffer = field; if (f->type == PTYPE_MESSAGE || f->type == PTYPE_ENUM) { _pbcA_push(queue, atom); } }
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; }
struct _enum * _pbcP_push_enum(struct pbc_env * p, const char *name, struct map_kv *table, int sz) { void * check = _pbcM_sp_query(p->enums, name); if (check) return NULL; struct _enum * v = malloc(sizeof(*v)); v->key = name; v->id = _pbcM_ip_new(table,sz); v->name = _pbcM_si_new(table,sz); v->default_v->e.id = table[0].id; v->default_v->e.name = table[0].pointer; _pbcM_sp_insert(p->enums, name , v); return v; }
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 _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); }