void amqp_destroy_connection(amqp_connection_state_t state) { empty_amqp_pool(&state->frame_pool); empty_amqp_pool(&state->decoding_pool); free(state->outbound_buffer.bytes); free(state->sock_inbound_buffer.bytes); free(state); }
int amqp_destroy_connection(amqp_connection_state_t state) { int s = state->sockfd; empty_amqp_pool(&state->frame_pool); empty_amqp_pool(&state->decoding_pool); free(state->outbound_buffer.bytes); free(state->sock_inbound_buffer.bytes); free(state); if (s >= 0 && amqp_socket_close(s) < 0) return -amqp_socket_error(); else return 0; }
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; }
int amqp_destroy_connection(amqp_connection_state_t state) { int status = AMQP_STATUS_OK; if (state) { int i; for (i = 0; i < POOL_TABLE_SIZE; ++i) { amqp_pool_table_entry_t *entry = state->pool_table[i]; while (NULL != entry) { amqp_pool_table_entry_t *todelete = entry; empty_amqp_pool(&entry->pool); entry = entry->next; free(todelete); } } free(state->outbound_buffer.bytes); free(state->sock_inbound_buffer.bytes); amqp_socket_delete(state->socket); empty_amqp_pool(&state->properties_pool); free(state); } return status; }
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; }
void free_pool(amqp_pool_t *pool) { empty_amqp_pool(pool); delete pool; }
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; }
void amqp_destroy_message(amqp_message_t *message) { empty_amqp_pool(&message->pool); amqp_bytes_free(message->body); }