int lset_generate_value( as_val ** return_valpp, int seed, int val_type ){ static char * meth = "generate_value()"; int rc = 0; *return_valpp = NULL; // Start with nothing. char * mallocd_buf = NULL; char sourceChars[26] = "abcdefghijklmnopqrstuvwxyz"; switch( val_type ){ case LIST_FORMAT: *return_valpp = lset_gen_list_val( seed ); break; case NUMBER_FORMAT: // We have to malloc an int here because someone else will have // to reclaim (destroy) it. srand( seed ); as_integer * intp = as_integer_new( rand() % lset_g_config->key_max); *return_valpp = (as_val *) intp; break; case STRING_FORMAT: // Malloc a string buffer, write in it, and then create a // as_string object for it. // NOTE: RIght now, this is just a simple, variable size string // based on the value_len parameter in the config structure. mallocd_buf = (char *) malloc( lset_g_config->value_len+1); srand( seed ); //generate random string length from the given value_len int new_val = rand() % lset_g_config->value_len; int i; for (i=0; i<new_val; ++i) { mallocd_buf[i] = sourceChars[rand()%26]; } mallocd_buf[new_val] = '\0'; as_string * str_val = as_string_new( mallocd_buf, true ); *return_valpp = (as_val *) str_val; break; // case COMPLEX_1_FORMAT: // case COMPLEX_2_FORMAT: // case COMPLEX_3_FORMAT: // printf("[ERROR]<%s:%s>WE ARE NOT YET HANDLING COMPLEX FORMATS\n", // MOD, meth ); // break; case NO_FORMAT: default: printf("[ERROR]<%s:%s>UNKNOWN FORMAT: %d \n", MOD, meth, val_type ); } // end switch object type return rc; } // end generate_value()
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; } } }
static inline bool unpack_integer(serial_context *ser_cont, int64_t in, as_val **out) { if (VERBOSE) { ver("%sInteger %" PRId64, indent(ser_cont), in); } as_val *tmp = (as_val *)as_integer_new(in); if (tmp == NULL) { err("Error while allocating integer"); return false; } *out = tmp; return true; }
// Local utility. static as_val * as_val_from_flat_key(uint8_t * flat_key, uint32_t size) { uint8_t type = *flat_key; uint8_t * key = flat_key + 1; switch ( type ) { case AS_PARTICLE_TYPE_INTEGER: // TODO - verify size is (1 + 8) ??? // Flat integer keys are in big-endian order. return (as_val *) as_integer_new(cf_swap_from_be64(*(int64_t *)key)); case AS_PARTICLE_TYPE_STRING: { // Key length is size - 1, then +1 for null-termination. char * buf = cf_malloc(size); if (! buf) { return NULL; } uint32_t len = size - 1; memcpy(buf, key, len); buf[len] = '\0'; return (as_val *) as_string_new(buf, true); } case AS_PARTICLE_TYPE_BLOB: { uint32_t blob_size = size - 1; uint8_t *buf = cf_malloc(blob_size); if (! buf) { return NULL; } memcpy(buf, key, blob_size); return (as_val *) as_bytes_new_wrap(buf, blob_size, true); } default: return NULL; } }
as_arraylist_init(&list, 3, 0); as_arraylist_append_int64(&list, 1); as_arraylist_append_int64(&list, 2); as_arraylist_append_int64(&list, 3); as_hashmap map; as_hashmap_init(&map, 32); as_stringmap_set_int64((as_map *) &map, "x", 7); as_stringmap_set_int64((as_map *) &map, "y", 8); as_stringmap_set_int64((as_map *) &map, "z", 9); as_record r, * rec = &r; as_record_init(rec, 10); as_record_set_int64(rec, "a", 123); as_record_set_str(rec, "b", "abc"); as_record_set_integer(rec, "c", as_integer_new(456)); as_record_set_string(rec, "d", as_string_new("def",false)); as_record_set_list(rec, "e", (as_list *) &list); as_record_set_map(rec, "f", (as_map *) &map); as_key key; as_key_init(&key, "test", "test", "foo"); as_status rc = aerospike_key_put(as, &err, NULL, &key, rec); as_key_destroy(&key); info("bins: "); as_record_foreach(&r, key_basics_print_bins, NULL); as_record_destroy(rec);
#include "../util/map_rec.h" /****************************************************************************** * VARIABLES *****************************************************************************/ static as_aerospike as; /****************************************************************************** * TEST CASES *****************************************************************************/ TEST( record_udf_1, "echo bin a of {a = 123, b = 456 }" ) { as_rec * rec = map_rec_new(); as_rec_set(rec, "a", (as_val *) as_integer_new(123)); as_list * arglist = (as_list *) as_arraylist_new(1,0); as_list_append_str(arglist, "a"); as_result * res = as_success_new(NULL); int rc = as_module_apply_record(&mod_lua, &as, "records", "getbin", rec, arglist, res); assert_int_eq( rc, 0 ); assert_true( res->is_success ); assert_not_null( res->value ); assert_int_eq( as_integer_toint((as_integer *) res->value), 123 ); as_rec_destroy(rec); as_list_destroy(arglist);
as_val * produce() { if ( produced >= limit ) return AS_STREAM_END; produced++; return (as_val *) as_integer_new(produced); }
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; } } }
/** * Call with AS_OPERATIONS_CDT_OP only. */ static bool as_operations_cdt_op(as_operations *ops, const as_bin_name name, as_cdt_optype op, size_t n, ...) { if (op >= cdt_op_table_size) { return false; } const cdt_op_table_entry *entry = &cdt_op_table[op]; if (n < entry->count - entry->opt_args || n > entry->count) { return false; } va_list vl; if (n > 0) { va_start(vl, n); } as_arraylist list; as_arraylist_inita(&list, (uint32_t)n + 1); // +1 to avoid alloca(0) undefined behavior for (size_t i = 0; i < n; i++) { as_cdt_paramtype type = entry->args[i]; switch (type) { case AS_CDT_PARAM_PAYLOAD: { as_val *arg = va_arg(vl, as_val *); if (as_arraylist_append(&list, arg) != AS_ARRAYLIST_OK) { va_end(vl); as_arraylist_destroy(&list); return false; } break; } case AS_CDT_PARAM_COUNT: { uint64_t arg = va_arg(vl, uint64_t); if (as_arraylist_append(&list, (as_val *)as_integer_new(arg)) != AS_ARRAYLIST_OK) { va_end(vl); as_arraylist_destroy(&list); return false; } break; } case AS_CDT_PARAM_INDEX: { int64_t arg = va_arg(vl, int64_t); if (as_arraylist_append(&list, (as_val *)as_integer_new(arg)) != AS_ARRAYLIST_OK) { va_end(vl); as_arraylist_destroy(&list); return false; } break; } default: break; } } if (n > 0) { va_end(vl); } as_serializer ser; as_msgpack_init(&ser); uint32_t list_size = as_serializer_serialize_getsize(&ser, (as_val *) &list); as_bytes *bytes = as_bytes_new(sizeof(uint16_t) + list_size); uint8_t *list_write = as_bytes_get(bytes); uint16_t *list_write_op = (uint16_t *)list_write; *list_write_op = cf_swap_to_be16(op); list_write += sizeof(uint16_t); as_serializer_serialize_presized(&ser, (const as_val *) &list, list_write); as_serializer_destroy(&ser); as_arraylist_destroy(&list); bytes->size = bytes->capacity; // as_bytes->type default to AS_BYTES_BLOB if (entry->rw_type == CDT_RW_TYPE_MODIFY) { return as_operations_add_cdt_modify(ops, name, (as_bin_value *) bytes); } return as_operations_add_cdt_read(ops, name, (as_bin_value *) bytes); }
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); } }