// Byte swap header from network byte order (big endian) to current machine byte order. void as_msg_swap_header_from_be(as_msg *m) { m->generation = cf_swap_from_be32(m->generation); m->record_ttl = cf_swap_from_be32(m->record_ttl); m->transaction_ttl = cf_swap_from_be32(m->transaction_ttl); m->n_fields = cf_swap_from_be16(m->n_fields); m->n_ops= cf_swap_from_be16(m->n_ops); }
static as_status as_parse_roles(as_error* err, uint8_t* buffer, size_t size, as_vector* /*<as_role*>*/ roles) { uint8_t* p = buffer; uint8_t* end = buffer + size; as_role* role; char role_name[AS_ROLE_SIZE]; int len; int sz; uint8_t id; uint8_t field_count; uint8_t result; while (p < end) { result = p[1]; if (result != 0) { return result; } field_count = p[3]; p += HEADER_REMAINING; role_name[0] = 0; role = 0; for (uint8_t b = 0; b < field_count; b++) { len = cf_swap_from_be32(*(int*)p); p += 4; id = *p++; len--; if (id == ROLE) { sz = (len <= (AS_ROLE_SIZE-1))? len : (AS_ROLE_SIZE-1); memcpy(role_name, p, sz); role_name[sz] = 0; p += len; } else if (id == PRIVILEGES) { p = as_parse_privileges(p, &role); } else { p += len; } } if (role_name[0] == 0 && role == 0) { continue; } if (! role) { role = cf_malloc(sizeof(as_role)); role->privileges_size = 0; } strcpy(role->name, role_name); as_vector_append(roles, &role); } return AEROSPIKE_OK; }
static as_status as_parse_users(as_error* err, uint8_t* buffer, size_t size, as_vector* /*<as_user*>*/ users) { uint8_t* p = buffer; uint8_t* end = buffer + size; as_user* user; char user_name[AS_USER_SIZE]; int len; int sz; uint8_t id; uint8_t field_count; uint8_t result; while (p < end) { result = p[1]; if (result != 0) { return result; } field_count = p[3]; p += HEADER_REMAINING; user_name[0] = 0; user = 0; for (uint8_t b = 0; b < field_count; b++) { len = cf_swap_from_be32(*(int*)p); p += 4; id = *p++; len--; if (id == USER) { sz = (len <= (AS_USER_SIZE-1))? len : (AS_USER_SIZE-1); memcpy(user_name, p, sz); user_name[sz] = 0; p += len; } else if (id == ROLES) { p = as_parse_users_roles(p, &user); } else { p += len; } } if (user_name[0] == 0 && user == 0) { continue; } if (! user) { user = cf_malloc(sizeof(as_user)); user->roles_size = 0; } strcpy(user->name, user_name); as_vector_append(users, &user); } return 0; }
static as_status as_command_parse_udf_failure(uint8_t* p, as_error* err, as_msg* msg, as_status status) { p = as_command_ignore_fields(p, msg->n_fields); as_bin_name name; for (uint32_t i = 0; i < msg->n_ops; i++) { 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(name, p, name_len); name[name_len] = 0; p += name_size; uint32_t value_size = (op_size - (name_size + 4)); if (strcmp(name, "FAILURE") == 0) { as_val* val = 0; as_command_parse_value(p, type, value_size, &val); status = as_command_parse_udf_error(err, status, val); as_val_destroy(val); return status; } p += value_size; } return as_error_set_message(err, status, as_error_string(status)); }
uint8_t* as_command_ignore_bins(uint8_t* p, uint32_t n_bins) { for (uint32_t i = 0; i < n_bins; i++) { p += cf_swap_from_be32(*(uint32_t*)p) + 4; } return p; }
uint8_t* as_command_ignore_fields(uint8_t* p, uint32_t n_fields) { if (n_fields > 0) { for (uint32_t i = 0; i < n_fields; i++) { p += cf_swap_from_be32(*(uint32_t*)p) + 4; } } return p; }
as_status as_command_parse_success_failure_bins(uint8_t** pp, as_error* err, as_msg* msg, as_val** value) { uint8_t* p = *pp; p = as_command_ignore_fields(p, msg->n_fields); as_bin_name name; for (uint32_t i = 0; i < msg->n_ops; i++) { 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(name, p, name_len); name[name_len] = 0; p += name_size; uint32_t value_size = (op_size - (name_size + 4)); if (strcmp(name, "SUCCESS") == 0) { if (value) { as_command_parse_value(p, type, value_size, value); } *pp = p + value_size; return AEROSPIKE_OK; } if (strcmp(name, "FAILURE") == 0) { as_val* val = 0; as_command_parse_value(p, type, value_size, &val); if (val == 0) { as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Received null FAILURE bin."); } else if (val->type == AS_STRING) { as_error_set_message(err, AEROSPIKE_ERR_CLIENT, ((as_string*)val)->value); } else { as_error_update(err, AEROSPIKE_ERR_CLIENT, "Expected string for FAILURE bin. Received %d", val->type); } as_val_destroy(val); return err->code; } p += value_size; } return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to find SUCCESS or FAILURE bin."); }
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; }
// Byte swap field from network byte order (big endian) to current machine byte order. void cl_msg_swap_field_from_be(cl_msg_field *mf) { mf->field_sz = cf_swap_from_be32(mf->field_sz); }