amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t state, amqp_channel_t channel) { amqp_pool_table_entry_t *entry; size_t index = channel % POOL_TABLE_SIZE; entry = state->pool_table[index]; for ( ; NULL != entry; entry = entry->next) { if (channel == entry->channel) { return &entry->pool; } } entry = malloc(sizeof(amqp_pool_table_entry_t)); if (NULL == entry) { return NULL; } entry->channel = channel; entry->next = state->pool_table[index]; state->pool_table[index] = entry; init_amqp_pool(&entry->pool, state->frame_max); return &entry->pool; }
int amqp_tune_connection(amqp_connection_state_t state, int channel_max, int frame_max, int heartbeat) { void *newbuf; ENFORCE_STATE(state, CONNECTION_STATE_IDLE); state->channel_max = channel_max; state->frame_max = frame_max; state->heartbeat = heartbeat; empty_amqp_pool(&state->frame_pool); init_amqp_pool(&state->frame_pool, frame_max); state->inbound_buffer.len = frame_max; state->outbound_buffer.len = frame_max; newbuf = realloc(state->outbound_buffer.bytes, frame_max); if (newbuf == NULL) { amqp_destroy_connection(state); return -ENOMEM; } state->outbound_buffer.bytes = newbuf; return 0; }
amqp_connection_state_t amqp_new_connection(void) { amqp_connection_state_t state = (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_)); if (state == NULL) { return NULL; } init_amqp_pool(&state->frame_pool, INITIAL_FRAME_POOL_PAGE_SIZE); init_amqp_pool(&state->decoding_pool, INITIAL_DECODING_POOL_PAGE_SIZE); state->state = CONNECTION_STATE_IDLE; state->inbound_buffer.bytes = NULL; state->outbound_buffer.bytes = NULL; if (amqp_tune_connection(state, 0, INITIAL_FRAME_POOL_PAGE_SIZE, 0) != 0) { empty_amqp_pool(&state->frame_pool); empty_amqp_pool(&state->decoding_pool); free(state); return NULL; } state->inbound_offset = 0; state->target_size = HEADER_SIZE; state->sockfd = -1; state->sock_inbound_buffer.len = INITIAL_INBOUND_SOCK_BUFFER_SIZE; state->sock_inbound_buffer.bytes = malloc(INITIAL_INBOUND_SOCK_BUFFER_SIZE); if (state->sock_inbound_buffer.bytes == NULL) { amqp_destroy_connection(state); return NULL; } state->sock_inbound_offset = 0; state->sock_inbound_limit = 0; state->first_queued_frame = NULL; state->last_queued_frame = NULL; return state; }
amqp_table_t TableValueImpl::CopyTable(const amqp_table_t &table, amqp_pool_ptr_t &pool) { if (0 == table.num_entries) { return AMQP_EMPTY_TABLE; } pool = boost::shared_ptr<amqp_pool_t>(new amqp_pool_t, free_pool); init_amqp_pool(pool.get(), 1024); return CopyTableInner(table, *pool.get()); }
amqp_table_t TableValueImpl::CreateAmqpTable(const Table &table, amqp_pool_ptr_t &pool) { if (0 == table.size()) { return AMQP_EMPTY_TABLE; } pool = boost::shared_ptr<amqp_pool_t>(new amqp_pool_t, free_pool); init_amqp_pool(pool.get(), 1024); return CreateAmqpTableInner(table, *pool.get()); }
amqp_connection_state_t amqp_new_connection(void) { amqp_connection_state_t state = (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_)); if (state == NULL) return NULL; init_amqp_pool(&state->frame_pool, INITIAL_FRAME_POOL_PAGE_SIZE); init_amqp_pool(&state->decoding_pool, INITIAL_DECODING_POOL_PAGE_SIZE); if (amqp_tune_connection(state, 0, INITIAL_FRAME_POOL_PAGE_SIZE, 0) != 0) goto out_nomem; state->inbound_buffer.bytes = amqp_pool_alloc(&state->frame_pool, state->inbound_buffer.len); if (state->inbound_buffer.bytes == NULL) goto out_nomem; state->state = CONNECTION_STATE_INITIAL; /* the server protocol version response is 8 bytes, which conveniently is also the minimum frame size */ state->target_size = 8; state->sockfd = -1; state->sock_inbound_buffer.len = INITIAL_INBOUND_SOCK_BUFFER_SIZE; state->sock_inbound_buffer.bytes = malloc(INITIAL_INBOUND_SOCK_BUFFER_SIZE); if (state->sock_inbound_buffer.bytes == NULL) goto out_nomem; return state; out_nomem: free(state->sock_inbound_buffer.bytes); empty_amqp_pool(&state->frame_pool); empty_amqp_pool(&state->decoding_pool); free(state); return NULL; }
amqp_connection_state_t amqp_new_connection(void) { int res; amqp_connection_state_t state = (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_)); if (state == NULL) { return NULL; } res = amqp_tune_connection(state, 0, AMQP_INITIAL_FRAME_POOL_PAGE_SIZE, 0); if (0 != res) { goto out_nomem; } state->inbound_buffer.bytes = state->header_buffer; state->inbound_buffer.len = sizeof(state->header_buffer); state->state = CONNECTION_STATE_INITIAL; /* the server protocol version response is 8 bytes, which conveniently is also the minimum frame size */ state->target_size = 8; state->sock_inbound_buffer.len = AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE; state->sock_inbound_buffer.bytes = malloc(AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE); if (state->sock_inbound_buffer.bytes == NULL) { goto out_nomem; } init_amqp_pool(&state->properties_pool, 512); return state; out_nomem: free(state->sock_inbound_buffer.bytes); free(state); return NULL; }
static void test_table_codec(FILE *out) { amqp_pool_t pool; int result; amqp_table_entry_t inner_entries[2]; amqp_table_t inner_table; amqp_field_value_t inner_values[2]; amqp_array_t inner_array; amqp_table_entry_t entries[14]; amqp_table_t table; inner_entries[0].key = amqp_cstring_bytes("one"); inner_entries[0].value.kind = AMQP_FIELD_KIND_I32; inner_entries[0].value.value.i32 = 54321; inner_entries[1].key = amqp_cstring_bytes("two"); inner_entries[1].value.kind = AMQP_FIELD_KIND_UTF8; inner_entries[1].value.value.bytes = amqp_cstring_bytes("A long string"); inner_table.num_entries = 2; inner_table.entries = inner_entries; inner_values[0].kind = AMQP_FIELD_KIND_I32; inner_values[0].value.i32 = 54321; inner_values[1].kind = AMQP_FIELD_KIND_UTF8; inner_values[1].value.bytes = amqp_cstring_bytes("A long string"); inner_array.num_entries = 2; inner_array.entries = inner_values; entries[0].key = amqp_cstring_bytes("longstr"); entries[0].value.kind = AMQP_FIELD_KIND_UTF8; entries[0].value.value.bytes = amqp_cstring_bytes("Here is a long string"); entries[1].key = amqp_cstring_bytes("signedint"); entries[1].value.kind = AMQP_FIELD_KIND_I32; entries[1].value.value.i32 = 12345; entries[2].key = amqp_cstring_bytes("decimal"); entries[2].value.kind = AMQP_FIELD_KIND_DECIMAL; entries[2].value.value.decimal.decimals = 3; entries[2].value.value.decimal.value = 123456; entries[3].key = amqp_cstring_bytes("timestamp"); entries[3].value.kind = AMQP_FIELD_KIND_TIMESTAMP; entries[3].value.value.u64 = 109876543209876; entries[4].key = amqp_cstring_bytes("table"); entries[4].value.kind = AMQP_FIELD_KIND_TABLE; entries[4].value.value.table = inner_table; entries[5].key = amqp_cstring_bytes("byte"); entries[5].value.kind = AMQP_FIELD_KIND_I8; entries[5].value.value.i8 = (int8_t)255; entries[6].key = amqp_cstring_bytes("long"); entries[6].value.kind = AMQP_FIELD_KIND_I64; entries[6].value.value.i64 = 1234567890; entries[7].key = amqp_cstring_bytes("short"); entries[7].value.kind = AMQP_FIELD_KIND_I16; entries[7].value.value.i16 = 655; entries[8].key = amqp_cstring_bytes("bool"); entries[8].value.kind = AMQP_FIELD_KIND_BOOLEAN; entries[8].value.value.boolean = 1; entries[9].key = amqp_cstring_bytes("binary"); entries[9].value.kind = AMQP_FIELD_KIND_BYTES; entries[9].value.value.bytes = amqp_cstring_bytes("a binary string"); entries[10].key = amqp_cstring_bytes("void"); entries[10].value.kind = AMQP_FIELD_KIND_VOID; entries[11].key = amqp_cstring_bytes("array"); entries[11].value.kind = AMQP_FIELD_KIND_ARRAY; entries[11].value.value.array = inner_array; entries[12].key = amqp_cstring_bytes("float"); entries[12].value.kind = AMQP_FIELD_KIND_F32; entries[12].value.value.f32 = M_PI; entries[13].key = amqp_cstring_bytes("double"); entries[13].value.kind = AMQP_FIELD_KIND_F64; entries[13].value.value.f64 = M_PI; table.num_entries = 14; table.entries = entries; fprintf(out, "AAAAAAAAAA\n"); { amqp_field_value_t val; val.kind = AMQP_FIELD_KIND_TABLE; val.value.table = table; dump_value(0, val, out); } init_amqp_pool(&pool, 4096); { amqp_table_t decoded; size_t decoding_offset = 0; amqp_bytes_t decoding_bytes; decoding_bytes.len = sizeof(pre_encoded_table); decoding_bytes.bytes = pre_encoded_table; result = amqp_decode_table(decoding_bytes, &pool, &decoded, &decoding_offset); if (result < 0) die("Table decoding failed: %s", amqp_error_string(-result)); fprintf(out, "BBBBBBBBBB\n"); { amqp_field_value_t val; val.kind = AMQP_FIELD_KIND_TABLE; val.value.table = decoded; dump_value(0, val, out); } } { uint8_t encoding_buffer[4096]; amqp_bytes_t encoding_result; size_t offset = 0; memset(&encoding_buffer[0], 0, sizeof(encoding_buffer)); encoding_result.len = sizeof(encoding_buffer); encoding_result.bytes = &encoding_buffer[0]; result = amqp_encode_table(encoding_result, &table, &offset); if (result < 0) die("Table encoding failed: %s", amqp_error_string(-result)); if (offset != sizeof(pre_encoded_table)) die("Offset should be %ld, was %ld", (long)sizeof(pre_encoded_table), (long)offset); result = memcmp(pre_encoded_table, encoding_buffer, offset); if (result != 0) die("Table encoding differed", result); } empty_amqp_pool(&pool); }
amqp_rpc_reply_t amqp_read_message_noblock(amqp_connection_state_t state, amqp_channel_t channel, amqp_message_t *message, AMQP_UNUSED int flags, struct timeval *timeout) { amqp_frame_t frame; amqp_rpc_reply_t ret; size_t body_read; char *body_read_ptr; int res; memset(&ret, 0, sizeof(amqp_rpc_reply_t)); memset(message, 0, sizeof(amqp_message_t)); res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out1; } if (AMQP_FRAME_HEADER != frame.frame_type) { if (AMQP_FRAME_METHOD == frame.frame_type && (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id || AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) { ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; ret.reply = frame.payload.method; } else { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_UNEXPECTED_STATE; amqp_put_back_frame(state, &frame); } goto error_out1; } init_amqp_pool(&message->pool, 4096); res = amqp_basic_properties_clone(frame.payload.properties.decoded, &message->properties, &message->pool); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out3; } if (0 == frame.payload.properties.body_size) { message->body = amqp_empty_bytes; } else { message->body = amqp_bytes_malloc(frame.payload.properties.body_size); if (NULL == message->body.bytes) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_NO_MEMORY; goto error_out1; } } body_read = 0; body_read_ptr = message->body.bytes; while (body_read < message->body.len) { res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out2; } if (AMQP_FRAME_BODY != frame.frame_type) { if (AMQP_FRAME_METHOD == frame.frame_type && (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id || AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) { ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; ret.reply = frame.payload.method; } else { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_BAD_AMQP_DATA; } goto error_out2; } if (body_read + frame.payload.body_fragment.len > message->body.len) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_BAD_AMQP_DATA; goto error_out2; } memcpy(body_read_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); body_read += frame.payload.body_fragment.len; body_read_ptr += frame.payload.body_fragment.len; } ret.reply_type = AMQP_RESPONSE_NORMAL; return ret; error_out2: amqp_bytes_free(message->body); error_out3: empty_amqp_pool(&message->pool); error_out1: return ret; }