char* ResultResponse::decode_metadata(char* input, ResultMetadata::Ptr* metadata, bool has_pk_indices) { int32_t flags = 0; char* buffer = decode_int32(input, flags); int32_t column_count = 0; buffer = decode_int32(buffer, column_count); if (has_pk_indices) { int32_t pk_count = 0; buffer = decode_int32(buffer, pk_count); for (int i = 0; i < pk_count; ++i) { uint16_t pk_index = 0; buffer = decode_uint16(buffer, pk_index); pk_indices_.push_back(pk_index); } } if (flags & CASS_RESULT_FLAG_HAS_MORE_PAGES) { has_more_pages_ = true; buffer = decode_bytes(buffer, &paging_state_); } else { has_more_pages_ = false; } if (!(flags & CASS_RESULT_FLAG_NO_METADATA)) { bool global_table_spec = flags & CASS_RESULT_FLAG_GLOBAL_TABLESPEC; if (global_table_spec) { buffer = decode_string(buffer, &keyspace_); buffer = decode_string(buffer, &table_); } metadata->reset(new ResultMetadata(column_count)); for (int i = 0; i < column_count; ++i) { ColumnDefinition def; def.index = i; if (!global_table_spec) { buffer = decode_string(buffer, &def.keyspace); buffer = decode_string(buffer, &def.table); } buffer = decode_string(buffer, &def.name); DataTypeDecoder type_decoder(buffer); def.data_type = DataType::ConstPtr(type_decoder.decode()); buffer = type_decoder.buffer(); (*metadata)->add(def); } } return buffer; }
bool ResultResponse::decode(int version, char* input, size_t size) { protocol_version_ = version; char* buffer = decode_int32(input, kind_); switch (kind_) { case CASS_RESULT_KIND_VOID: return true; break; case CASS_RESULT_KIND_ROWS: return decode_rows(buffer); break; case CASS_RESULT_KIND_SET_KEYSPACE: return decode_set_keyspace(buffer); break; case CASS_RESULT_KIND_PREPARED: return decode_prepared(version, buffer); break; case CASS_RESULT_KIND_SCHEMA_CHANGE: return decode_schema_change(buffer); break; default: assert(false); } return false; }
/** * inherit from {@link uv_alloc_cb} */ static void tcp_client_alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { // CL_DEBUG("read freame alloc.\n"); if (size > 0) { abstract_tcp_client_t *client = (abstract_tcp_client_t*) handle->data; client_read_tmp_buf_t *packet = &client->recv_tmp_buf; if (packet->offset < PACKET_LEN_FIELD_SIZE) { buf->base = (char*) &packet->packet_len + packet->offset; buf->len = PACKET_LEN_FIELD_SIZE - packet->offset; } else if (packet->offset == PACKET_LEN_FIELD_SIZE) { // read packet body. int32_t packet_len = decode_int32(buf->base); if (packet_len <= PACKET_LEN_FIELD_SIZE || packet_len > MAX_PACKET_LEN) { // packet invalid, close handle in read_cb. CL_ERROR("invalide packet len:%d.\n", packet_len); packet->packet_len = PACKET_INVALID; buf->base = NULL; buf->len = 0; } else { packet->packet_len = packet_len; packet->buf.base = (char*) malloc(packet->packet_len); packet->buf.len = packet_len; encode_int32(packet->buf.base, 0, packet_len); buf->base = packet->buf.base + PACKET_LEN_FIELD_SIZE; buf->len = packet_len - PACKET_LEN_FIELD_SIZE; } } else { //continue read body. buf->base = packet->buf.base + packet->offset; buf->len = packet->packet_len - packet->offset; } } }
static int mock_dvr_dispatch_packet(abstract_tcp_client_t *client, uv_buf_t *buf, int status) { int r; test_mock_dvr_t* dvr = (test_mock_dvr_t*) client; if (status == 0) { int32_t cmd = decode_int32(buf->base + 4); CL_DEBUG("mock dvr recv cmd:0x%x\n",cmd); switch (cmd) { // PROTOCOL_MAP(GEN_DISPATCH_SWTICH_CASE, GEN_SWITCH_CASE_ARGS, GEN_SWITCH_CASE_3ARGS) case 0x00018001: { mock_dvr_preview_t *t = (mock_dvr_preview_t*) malloc(sizeof(mock_dvr_preview_t)); r = mock_dvr_preview_t_init(t); r = proto_cmd_t_decode(buf, (abstract_cmd_t*) t); if (r != 0) { printf("decode packet:%s error.\n", "mock_dvr_preview"); } else { /*callback fun */ cmd_imp f = (mock_dvr_preview_impl) == ((void*) 0) ? fun_no_impl : (mock_dvr_preview_impl); f(client, (abstract_cmd_t*) t); } proto_cmd_t_destroy((abstract_cmd_t*) t); } break; default: CL_ERROR("mock dvr ignore cmd:%x.\n", cmd); FREE(buf->base); } } else { CL_ERROR("connect to dvr error:%d,%s\n", status, smts_strerror(status)); tcp_client_read_stop((abstract_tcp_client_t*) dvr); // destroy_test_mock_dvr(dvr, status); } return r; }
char* TupleIterator::decode_value(char* position) { int32_t size; char* buffer = decode_int32(position, size); value_ = Value(tuple_->protocol_version(), *current_, buffer, size); return size > 0 ? buffer + size : buffer; }
bool RecordBlock::next_record(Slice &slice) { if (offset_ + sizeof(uint32_t) < buffer_.size()) { const char *data = buffer_.data() + offset_; int dlen = decode_int32(data); Slice tmp(data + sizeof(uint32_t), dlen); slice = tmp; offset_ = offset_ + sizeof(uint32_t) + dlen; return true; } else { return false; } }
char* decode_row(char* rows, const ResultResponse* result, OutputValueVec& output) { char* buffer = rows; output.clear(); const int protocol_version = result->protocol_version(); for (int i = 0; i < result->column_count(); ++i) { int32_t size = 0; buffer = decode_int32(buffer, size); const ColumnDefinition& def = result->metadata()->get_column_definition(i); if (size >= 0) { output.push_back(Value(protocol_version, def.data_type, buffer, size)); buffer += size; } else { // null value output.push_back(Value(def.data_type)); } } return buffer; }
int32_t Value::as_int32() const { assert(!is_null() && value_type() == CASS_VALUE_TYPE_INT); int32_t value; decode_int32(data_, value); return value; }
bool ResultResponse::decode_rows(char* input) { char* buffer = decode_metadata(input, &metadata_); rows_ = decode_int32(buffer, row_count_); decode_first_row(); return true; }
bool ErrorResponse::decode(int version, char* buffer, size_t size) { char* pos = decode_int32(buffer, code_); pos = decode_string(pos, &message_); switch (code_) { case CQL_ERROR_UNAVAILABLE: pos = decode_uint16(pos, cl_); pos = decode_int32(pos, required_); decode_int32(pos, received_); break; case CQL_ERROR_READ_TIMEOUT: pos = decode_uint16(pos, cl_); pos = decode_int32(pos, received_); pos = decode_int32(pos, required_); decode_byte(pos, data_present_); break; case CQL_ERROR_WRITE_TIMEOUT: pos = decode_uint16(pos, cl_); pos = decode_int32(pos, received_); pos = decode_int32(pos, required_); decode_write_type(pos); break; case CQL_ERROR_READ_FAILURE: pos = decode_uint16(pos, cl_); pos = decode_int32(pos, received_); pos = decode_int32(pos, required_); pos = decode_int32(pos, num_failures_); decode_byte(pos, data_present_); break; case CQL_ERROR_FUNCTION_FAILURE: pos = decode_string(pos, &keyspace_); pos = decode_string(pos, &function_); decode_stringlist(pos, arg_types_); break; case CQL_ERROR_WRITE_FAILURE: pos = decode_uint16(pos, cl_); pos = decode_int32(pos, received_); pos = decode_int32(pos, required_); pos = decode_int32(pos, num_failures_); decode_write_type(pos); break; case CQL_ERROR_UNPREPARED: decode_string(pos, &prepared_id_); break; case CQL_ERROR_ALREADY_EXISTS: pos = decode_string(pos, &keyspace_); pos = decode_string(pos, &table_); break; } return true; }
char* UserTypeFieldIterator::decode_field(char* position) { int32_t size; char* buffer = decode_int32(position, size); value_ = Value(user_type_value_->protocol_version(), current_->type, buffer, size); return size > 0 ? buffer + size : buffer; }
ssize_t ResponseMessage::decode(char* input, size_t size) { char* input_pos = input; received_ += size; if (!is_header_received_) { if (version_ == 0) { version_ = input[0] & 0x7F; // "input" will always have at least 1 bytes if (version_ >= 3) { header_size_ = CASS_HEADER_SIZE_V3; } else { header_size_ = CASS_HEADER_SIZE_V1_AND_V2; } } if (received_ >= header_size_) { // We may have received more data then we need, only copy what we need size_t overage = received_ - header_size_; size_t needed = size - overage; memcpy(header_buffer_pos_, input_pos, needed); header_buffer_pos_ += needed; input_pos += needed; assert(header_buffer_pos_ == header_buffer_ + header_size_); char* buffer = header_buffer_ + 1; // Skip over "version" byte flags_ = *(buffer++); if (version_ >= 3) { buffer = decode_int16(buffer, stream_); } else { stream_ = *(buffer++); } opcode_ = *(buffer++); decode_int32(buffer, length_); is_header_received_ = true; if (!allocate_body(opcode_) || !response_body_) { return -1; } response_body_->set_buffer(length_); body_buffer_pos_ = response_body_->data(); } else { // We haven't received all the data for the header. We consume the // entire buffer. memcpy(header_buffer_pos_, input_pos, size); header_buffer_pos_ += size; return size; } } const size_t remaining = size - (input_pos - input); const size_t frame_size = header_size_ + length_; if (received_ >= frame_size) { // We may have received more data then we need, only copy what we need size_t overage = received_ - frame_size; size_t needed = remaining - overage; memcpy(body_buffer_pos_, input_pos, needed); body_buffer_pos_ += needed; input_pos += needed; assert(body_buffer_pos_ == response_body_->data() + length_); char* pos = response_body()->data(); if (flags_ & CASS_FLAG_WARNING) { pos = response_body()->decode_warnings(pos, length_); } if (flags_ & CASS_FLAG_CUSTOM_PAYLOAD) { pos = response_body()->decode_custom_payload(pos, length_); } if (!response_body_->decode(version_, pos, length_)) { is_body_error_ = true; return -1; } is_body_ready_ = true; } else { // We haven't received all the data for the frame. We consume the entire // buffer. memcpy(body_buffer_pos_, input_pos, remaining); body_buffer_pos_ += remaining; return size; } return input_pos - input; }