static const char * _concat_name(struct _stringpool *p , const char *prefix , int prefix_sz , const char *name , int name_sz) { if (prefix_sz == 0) { return _pbcS_build(p , name, name_sz); } char temp[name_sz + prefix_sz + 2]; memcpy(temp,prefix,prefix_sz); temp[prefix_sz] = '.'; memcpy(temp+prefix_sz+1,name,name_sz); temp[name_sz + prefix_sz + 1] = '\0'; return _pbcS_build(p , temp, name_sz + prefix_sz + 1); }
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; }
static const char * _concat_name(struct _stringpool *p , const char *prefix , int prefix_sz , const char *name , int name_sz, int *sz) { if (prefix_sz == 0) { if (sz) { *sz = name_sz; } return _pbcS_build(p , name, name_sz); } char * temp = (char *)alloca(name_sz + prefix_sz + 2); memcpy(temp,prefix,prefix_sz); temp[prefix_sz] = '.'; memcpy(temp+prefix_sz+1,name,name_sz); temp[name_sz + prefix_sz + 1] = '\0'; if (sz) { *sz = name_sz + prefix_sz + 1; } const char * ret = _pbcS_build(p , temp, name_sz + prefix_sz + 1); return ret; }
static void _set_default(struct _stringpool *pool, struct _field *f , int ptype, const char *value, int sz) { if (value == NULL || sz == 0) { if (f->type == PTYPE_STRING || f->type == PTYPE_BYTES) { f->default_v->s.str = ""; f->default_v->s.len = 0; } else { f->default_v->integer.low = 0; f->default_v->integer.hi = 0; } return; } switch (f->type) { case PTYPE_DOUBLE: case PTYPE_FLOAT: f->default_v->real = strtod(value,NULL); break; case PTYPE_STRING: f->default_v->s.str = _pbcS_build(pool, value , sz); f->default_v->s.len = sz; break; case PTYPE_ENUM: f->default_v->s.str = value; f->default_v->s.len = sz; break; case PTYPE_BOOL: if (strcmp(value,"true") == 0) { f->default_v->integer.low = 1; } else { f->default_v->integer.low = 0; } f->default_v->integer.hi = 0; break; case PTYPE_INT64: case PTYPE_UINT64: case PTYPE_SFIXED64: case PTYPE_SINT64: // todo string to int64 case PTYPE_INT32: case PTYPE_FIXED32: case PTYPE_UINT32: case PTYPE_SFIXED32: case PTYPE_SINT32: f->default_v->integer.low = atol(value); f->default_v->integer.hi = 0; break; default: f->default_v->integer.low = 0; f->default_v->integer.hi = 0; break; } }
static const char * _concat_name(struct _stringpool *p , const char *prefix , int prefix_sz , const char *name , int name_sz, int *sz) { char temp[1024]; if (prefix_sz == 0) { if (sz) { *sz = name_sz; } return _pbcS_build(p , name, name_sz); } const int len = name_sz + prefix_sz; //char *temp =(char *) _pbcM_malloc(len + 2); memcpy(temp,prefix,prefix_sz); temp[prefix_sz] = '.'; memcpy(temp+prefix_sz+1,name,name_sz); temp[name_sz + prefix_sz + 1] = '\0'; if (sz) { *sz = name_sz + prefix_sz + 1; } //free(temp); return _pbcS_build(p , temp, name_sz + prefix_sz + 1); }
static void _register_enum(struct pbc_env *p, struct _stringpool *pool, struct pbc_rmessage * enum_type, const char *prefix, int prefix_sz) { int field_count = pbc_rmessage_size(enum_type, "value"); struct map_kv *table = malloc(field_count * sizeof(struct map_kv)); int i; for (i=0;i<field_count;i++) { struct pbc_rmessage * value = pbc_rmessage_message(enum_type, "value", i); int enum_name_sz; const char *enum_name = pbc_rmessage_string(value , "name" , 0 , &enum_name_sz); table[i].pointer = (void *)_pbcS_build(pool, enum_name , enum_name_sz); table[i].id = pbc_rmessage_integer(value , "number", 0 , 0); } int name_sz; const char * name = pbc_rmessage_string(enum_type, "name", 0 , &name_sz); const char *temp = _concat_name(pool, prefix , prefix_sz , name , name_sz, NULL); _pbcP_push_enum(p,temp,table,field_count); free(table); }
static void _register_message(struct pbc_env *p, struct _stringpool *pool, struct pbc_rmessage * message_type, const char *prefix, int prefix_sz, pbc_array queue) { int name_sz; const char * name = pbc_rmessage_string(message_type, "name", 0 , &name_sz); int sz = 0; const char *temp = _concat_name(pool, prefix , prefix_sz , name , name_sz, &sz); int field_count = pbc_rmessage_size(message_type, "field"); int i; for (i=0;i<field_count;i++) { struct pbc_rmessage * field = pbc_rmessage_message(message_type, "field" , i); struct _field f; int field_name_sz; const char * field_name = pbc_rmessage_string(field, "name", 0 , &field_name_sz); f.name = _pbcS_build(pool,field_name,field_name_sz); _register_field(field, &f , pool); _pbcP_push_message(p, temp , &f , queue); } _pbcP_init_message(p, temp); _register_extension(p, pool, temp, sz,message_type, queue); // nested enum int enum_count = pbc_rmessage_size(message_type, "enum_type"); for (i=0;i<enum_count;i++) { struct pbc_rmessage * enum_type = pbc_rmessage_message(message_type, "enum_type", i); _register_enum(p, pool, enum_type, temp, sz); } // nested type int message_count = pbc_rmessage_size(message_type, "nested_type"); for (i=0;i<message_count;i++) { struct pbc_rmessage * nested_type = pbc_rmessage_message(message_type, "nested_type", i); _register_message(p, pool, nested_type, temp, sz, queue); } }
static void _set_default(struct _stringpool *pool, struct _field *f , int ptype, const char *value, int sz) { if (value == NULL || sz == 0) { if (f->type == PTYPE_STRING || f->type == PTYPE_BYTES) { f->default_v->s.str = ""; f->default_v->s.len = 0; } else { f->default_v->integer.low = 0; f->default_v->integer.hi = 0; } return; } switch (f->type) { case PTYPE_DOUBLE: case PTYPE_FLOAT: f->default_v->real = strtod(value,NULL); break; case PTYPE_STRING: f->default_v->s.str = _pbcS_build(pool, value , sz); f->default_v->s.len = sz; break; case PTYPE_ENUM: // enum default value will be converted to f->default_v->e in bootstrap.c : set_field_one() f->default_v->s.str = value; f->default_v->s.len = sz; break; case PTYPE_BOOL: if (strcmp(value,"true") == 0) { f->default_v->integer.low = 1; } else { f->default_v->integer.low = 0; } f->default_v->integer.hi = 0; break; case PTYPE_UINT64: case PTYPE_INT64: case PTYPE_SFIXED64: case PTYPE_SINT64: { long long v = strtoll(value, NULL, 10); f->default_v->integer.low = (long) v; f->default_v->integer.hi = (long)(v >> 32); break; } case PTYPE_INT32: case PTYPE_FIXED32: case PTYPE_SFIXED32: case PTYPE_SINT32: { int low = strtol(value, NULL, 10); f->default_v->integer.low = low; if (low < 0) { f->default_v->integer.hi = -1; } else { f->default_v->integer.hi = 0; } break; } case PTYPE_UINT32: f->default_v->integer.low = strtoul(value, NULL, 10); f->default_v->integer.hi = 0; break; case PTYPE_BYTES: case PTYPE_MESSAGE: // bytes and message types have no default value f->default_v->m.buffer = 0; f->default_v->m.len = 0; break; default: f->default_v->integer.low = 0; f->default_v->integer.hi = 0; break; } }