Beispiel #1
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));
}
Beispiel #2
0
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.");
}
Beispiel #3
0
bool
as_event_command_parse_result(as_event_command* cmd)
{
    as_msg* msg = (as_msg*)cmd->buf;
    as_msg_swap_header_from_be(msg);
    uint8_t* p = cmd->buf + sizeof(as_msg);
    as_status status = msg->result_code;

    switch (status) {
    case AEROSPIKE_OK: {
        as_record rec;

        if (msg->n_ops < 1000) {
            as_record_inita(&rec, msg->n_ops);
        }
        else {
            as_record_init(&rec, msg->n_ops);
        }

        rec.gen = msg->generation;
        rec.ttl = cf_server_void_time_to_ttl(msg->record_ttl);

        p = as_command_ignore_fields(p, msg->n_fields);
        as_command_parse_bins(&rec, p, msg->n_ops, cmd->deserialize);

        as_event_response_complete(cmd);
        ((as_async_record_command*)cmd)->listener(0, &rec, cmd->udata, cmd->event_loop);
        as_event_command_release(cmd);
        as_record_destroy(&rec);
        break;
    }

    case AEROSPIKE_ERR_UDF: {
        as_error err;
        as_command_parse_udf_failure(p, &err, msg, status);
        as_event_response_error(cmd, &err);
        break;
    }

    default: {
        as_error err;
        as_error_set_message(&err, status, as_error_string(status));
        as_event_response_error(cmd, &err);
        break;
    }
    }
    return true;
}
Beispiel #4
0
as_status
as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data)
{
    // Read header
    as_proto_msg msg;
    as_status status = as_socket_read_deadline(err, fd, (uint8_t*)&msg, sizeof(as_proto_msg), deadline_ms);

    if (status) {
        return status;
    }

    as_proto_swap_from_be(&msg.proto);
    as_msg_swap_header_from_be(&msg.m);
    size_t size = msg.proto.sz  - msg.m.header_sz;
    uint8_t* buf = 0;

    if (size > 0) {
        // Read remaining message bytes.
        buf = as_command_init(size);
        status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);

        if (status) {
            as_command_free(buf, size);
            return status;
        }
    }

    // Parse result code and record.
    status = msg.m.result_code;
    as_command_parse_result_data* data = user_data;

    switch (status) {
    case AEROSPIKE_OK: {
        if (data->record) {
            as_record* rec = *data->record;

            if (rec) {
                if (msg.m.n_ops > rec->bins.capacity) {
                    if (rec->bins._free) {
                        free(rec->bins.entries);
                    }
                    rec->bins.capacity = msg.m.n_ops;
                    rec->bins.size = 0;
                    rec->bins.entries = malloc(sizeof(as_bin) * msg.m.n_ops);
                    rec->bins._free = true;
                }
            }
            else {
                rec = as_record_new(msg.m.n_ops);
                *data->record = rec;
            }
            rec->gen = msg.m.generation;
            rec->ttl = cf_server_void_time_to_ttl(msg.m.record_ttl);

            uint8_t* p = as_command_ignore_fields(buf, msg.m.n_fields);
            as_command_parse_bins(rec, p, msg.m.n_ops, data->deserialize);
        }
        break;
    }

    case AEROSPIKE_ERR_UDF: {
        status = as_command_parse_udf_failure(buf, err, &msg.m, status);
        break;
    }

    default:
        as_error_set_message(err, status, as_error_string(status));
        break;
    }
    as_command_free(buf, size);
    return status;
}