static void as_command_parse_value(uint8_t* p, uint8_t type, uint32_t value_size, as_val** value) { // Allocate values on heap. switch (type) { case AS_BYTES_UNDEF: { *value = (as_val*)&as_nil; break; } case AS_BYTES_INTEGER: { int64_t v = 0; as_command_bytes_to_int(p, value_size, &v); *value = (as_val*)as_integer_new(v); break; } case AS_BYTES_DOUBLE: { double v = cf_swap_from_big_float64(*(double*)p); *value = (as_val*)as_double_new(v); break; } case AS_BYTES_STRING: { char* v = malloc(value_size + 1); memcpy(v, p, value_size); v[value_size] = 0; *value = (as_val*)as_string_new_wlen(v, value_size, true); break; } case AS_BYTES_LIST: case AS_BYTES_MAP: { as_buffer buffer; buffer.data = p; buffer.size = value_size; as_serializer ser; as_msgpack_init(&ser); as_serializer_deserialize(&ser, &buffer, value); as_serializer_destroy(&ser); break; } default: { void* v = malloc(value_size); memcpy(v, p, value_size); *value = (as_val*)as_bytes_new_wrap(v, value_size, true); break; } } }
as_val * map_to_asval(const as_particle *p) { map_mem *p_map_mem = (map_mem *)p; as_buffer buf; as_buffer_init(&buf); buf.data = p_map_mem->data; buf.capacity = p_map_mem->sz; buf.size = p_map_mem->sz; as_serializer s; as_msgpack_init(&s); as_val *val; as_serializer_deserialize(&s, &buf, &val); as_serializer_destroy(&s); return val; }
uint8_t* as_command_parse_bins(as_record* rec, uint8_t* p, uint32_t n_bins, bool deserialize) { as_bin* bin = rec->bins.entries; // Parse bins for (uint32_t i = 0; i < n_bins; i++, bin++) { uint32_t op_size = cf_swap_from_be32(*(uint32_t*)p); p += 5; uint8_t type = *p; p += 2; uint8_t name_size = *p++; uint8_t name_len = (name_size <= AS_BIN_NAME_MAX_LEN)? name_size : AS_BIN_NAME_MAX_LEN; memcpy(bin->name, p, name_len); bin->name[name_len] = 0; p += name_size; uint32_t value_size = (op_size - (name_size + 4)); switch (type) { case AS_BYTES_UNDEF: { bin->valuep = (as_bin_value*)&as_nil; break; } case AS_BYTES_INTEGER: { int64_t value; if (as_command_bytes_to_int(p, value_size, &value) == 0) { as_integer_init((as_integer*)&bin->value, value); bin->valuep = &bin->value; } break; } case AS_BYTES_DOUBLE: { double value = cf_swap_from_big_float64(*(double*)p); as_double_init((as_double*)&bin->value, value); bin->valuep = &bin->value; break; } case AS_BYTES_STRING: { char* value = malloc(value_size + 1); memcpy(value, p, value_size); value[value_size] = 0; as_string_init_wlen((as_string*)&bin->value, (char*)value, value_size, true); bin->valuep = &bin->value; break; } case AS_BYTES_LIST: case AS_BYTES_MAP: { if (deserialize) { as_val* value = 0; as_buffer buffer; buffer.data = p; buffer.size = value_size; as_serializer ser; as_msgpack_init(&ser); as_serializer_deserialize(&ser, &buffer, &value); as_serializer_destroy(&ser); bin->valuep = (as_bin_value*)value; } else { void* value = malloc(value_size); memcpy(value, p, value_size); as_bytes_init_wrap((as_bytes*)&bin->value, value, value_size, true); bin->value.bytes.type = (as_bytes_type)type; bin->valuep = &bin->value; } break; } default: { void* value = malloc(value_size); memcpy(value, p, value_size); as_bytes_init_wrap((as_bytes*)&bin->value, value, value_size, true); bin->value.bytes.type = (as_bytes_type)type; bin->valuep = &bin->value; break; } } rec->bins.size++; p += value_size; } return p; }
static void as_command_parse_value(uint8_t* p, uint8_t type, uint32_t value_size, as_val** value) { // Allocate values on heap. switch (type) { case AS_BYTES_UNDEF: { *value = (as_val*)&as_nil; break; } case AS_BYTES_INTEGER: { int64_t v = 0; as_command_bytes_to_int(p, value_size, &v); *value = (as_val*)as_integer_new(v); break; } case AS_BYTES_DOUBLE: { double v = cf_swap_from_big_float64(*(double*)p); *value = (as_val*)as_double_new(v); break; } case AS_BYTES_STRING: { char* v = cf_malloc(value_size + 1); memcpy(v, p, value_size); v[value_size] = 0; *value = (as_val*)as_string_new_wlen(v, value_size, true); break; } case AS_BYTES_GEOJSON: { uint8_t * ptr = p; // skip flags ptr++; // ncells uint16_t ncells = cf_swap_from_be16(* (uint16_t *) ptr); ptr += sizeof(uint16_t); // skip any cells ptr += sizeof(uint64_t) * ncells; // Use the json bytes. size_t jsonsz = value_size - 1 - 2 - (ncells * sizeof(uint64_t)); char* v = cf_malloc(jsonsz + 1); memcpy(v, ptr, jsonsz); v[jsonsz] = 0; *value = (as_val*) as_geojson_new_wlen(v, jsonsz, true); break; } case AS_BYTES_LIST: case AS_BYTES_MAP: { as_buffer buffer; buffer.data = p; buffer.size = value_size; as_serializer ser; as_msgpack_init(&ser); as_serializer_deserialize(&ser, &buffer, value); as_serializer_destroy(&ser); break; } default: { void* v = cf_malloc(value_size); memcpy(v, p, value_size); *value = (as_val*)as_bytes_new_wrap(v, value_size, true); break; } } }
void clbin_to_asval(cl_bin * bin, as_serializer * ser, as_val ** val) { if ( val == NULL ) return; switch( bin->object.type ) { case CL_NULL :{ *val = (as_val *) &as_nil; break; } case CL_INT : { *val = (as_val *) as_integer_new(bin->object.u.i64); break; } case CL_STR : { // steal the pointer from the object into the val *val = (as_val *) as_string_new(strdup(bin->object.u.str), true /*ismalloc*/); // TODO: re-evaluate the follow zero-copy for strings from cl_bins // *val = (as_val *) as_string_new(bin->object.u.str, true /*ismalloc*/); // bin->object.free = NULL; break; } case CL_LIST : case CL_MAP : { // use a temporary buffer, which doesn't need to be destroyed as_buffer buf = { .capacity = (uint32_t) bin->object.sz, .size = (uint32_t) bin->object.sz, .data = (uint8_t *) bin->object.u.blob }; // print_buffer(&buf); as_serializer_deserialize(ser, &buf, val); break; } case CL_BLOB: case CL_JAVA_BLOB: case CL_CSHARP_BLOB: case CL_PYTHON_BLOB: case CL_RUBY_BLOB: case CL_ERLANG_BLOB: default : { *val = NULL; uint8_t * raw = malloc(sizeof(bin->object.sz)); memcpy(raw, bin->object.u.blob, bin->object.sz); as_bytes * b = as_bytes_new_wrap(raw, (uint32_t)bin->object.sz, true /*ismalloc*/); b->type = (as_bytes_type)bin->object.type; *val = (as_val *) b; break; } } } void clbin_to_asrecord(cl_bin * bin, as_record * r) { switch(bin->object.type) { case CL_NULL: { as_record_set_nil(r, bin->bin_name); break; } case CL_INT: { as_record_set_int64(r, bin->bin_name, bin->object.u.i64); break; } case CL_STR: { as_record_set_strp(r, bin->bin_name, bin->object.u.str, true); // the following completes the handoff of the value. bin->object.free = NULL; break; } case CL_LIST: case CL_MAP: { as_val * val = NULL; as_buffer buffer; buffer.data = (uint8_t *) bin->object.u.blob; buffer.size = (uint32_t)bin->object.sz; as_serializer ser; as_msgpack_init(&ser); as_serializer_deserialize(&ser, &buffer, &val); as_serializer_destroy(&ser); as_record_set(r, bin->bin_name, (as_bin_value *) val); break; } default: { as_record_set_rawp(r, bin->bin_name, bin->object.u.blob, (uint32_t)bin->object.sz, true); // the following completes the handoff of the value. bin->object.free = NULL; break; } } } void clbins_to_asrecord(cl_bin * bins, uint32_t nbins, as_record * r) { uint32_t n = nbins < r->bins.capacity ? nbins : r->bins.capacity; for ( int i = 0; i < n; i++ ) { clbin_to_asrecord(&bins[i], r); } }