static inline int send_failure_str(udf_call *call, const char *err_str, size_t len) { if (! err_str) { // Better than sending an as_string with null value. return send_failure(call, NULL); } as_string stack_s; as_string_init_wlen(&stack_s, (char *)err_str, len, false); return send_failure(call, as_string_toval(&stack_s)); }
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; }
uint8_t* as_command_parse_key(uint8_t* p, uint32_t n_fields, as_key* key) { uint32_t len; uint32_t size; for (uint32_t i = 0; i < n_fields; i++) { len = cf_swap_from_be32(*(uint32_t*)p) - 1; p += 4; switch (*p++) { case AS_FIELD_DIGEST: size = (len < AS_DIGEST_VALUE_SIZE) ? len : AS_DIGEST_VALUE_SIZE; key->digest.init = true; memcpy(key->digest.value, p, size); break; case AS_FIELD_NAMESPACE: size = (len < (AS_NAMESPACE_MAX_SIZE-1)) ? len : (AS_NAMESPACE_MAX_SIZE-1); memcpy(key->ns, p, size); key->ns[size] = 0; break; case AS_FIELD_SETNAME: size = (len < (AS_SET_MAX_SIZE-1)) ? len : (AS_SET_MAX_SIZE-1); memcpy(key->set, p, size); key->set[size] = 0; break; case AS_FIELD_KEY: len--; uint8_t type = *p++; switch (type) { case AS_BYTES_INTEGER: { int64_t value; if (as_command_bytes_to_int(p, len, &value) == 0) { as_integer_init((as_integer*)&key->value, value); key->valuep = &key->value; } break; } case AS_BYTES_DOUBLE: { double value = cf_swap_from_big_float64(*(double*)p); as_double_init((as_double*)&key->value, value); key->valuep = &key->value; break; } case AS_BYTES_STRING: { char* value = malloc(len+1); memcpy(value, p, len); value[len] = 0; as_string_init_wlen((as_string*)&key->value, value, len, true); key->valuep = &key->value; break; } case AS_BYTES_BLOB: { void* value = malloc(len); memcpy(value, p, len); as_bytes_init_wrap((as_bytes*)&key->value, (uint8_t*)value, len, true); key->valuep = &key->value; break; } default: { as_log_error("Invalid key type: %d", type); break; } } break; } p += len; } return p; }