int amqp_send_frame_to(amqp_connection_state_t state,
		       amqp_frame_t const *frame,
		       amqp_output_fn_t fn,
		       void *context)
{
  amqp_bytes_t encoded;
  int payload_len;
  int separate_body;

  separate_body = inner_send_frame(state, frame, &encoded, &payload_len);
  switch (separate_body) {
    case 0:
      AMQP_CHECK_RESULT(fn(context,
			   state->outbound_buffer.bytes,
			   payload_len + (HEADER_SIZE + FOOTER_SIZE)));
      return 0;

    case 1:
      AMQP_CHECK_RESULT(fn(context, state->outbound_buffer.bytes, HEADER_SIZE));
      AMQP_CHECK_RESULT(fn(context, encoded.bytes, payload_len));
      {
	assert(FOOTER_SIZE == 1);
	char frame_end_byte = AMQP_FRAME_END;
	AMQP_CHECK_RESULT(fn(context, &frame_end_byte, FOOTER_SIZE));
      }
      return 0;

    default:
      return separate_body;
  }
}
int amqp_send_frame(amqp_connection_state_t state,
		    amqp_frame_t const *frame)
{
  amqp_bytes_t encoded;
  int payload_len;
  int separate_body;

  separate_body = inner_send_frame(state, frame, &encoded, &payload_len);
  switch (separate_body) {
    case 0:
      AMQP_CHECK_RESULT(write(state->sockfd,
			      state->outbound_buffer.bytes,
			      payload_len + (HEADER_SIZE + FOOTER_SIZE)));
      return 0;

    case 1: {
      struct iovec iov[3];
      char frame_end_byte = AMQP_FRAME_END;
      iov[0].iov_base = state->outbound_buffer.bytes;
      iov[0].iov_len = HEADER_SIZE;
      iov[1].iov_base = encoded.bytes;
      iov[1].iov_len = payload_len;
      iov[2].iov_base = &frame_end_byte;
      assert(FOOTER_SIZE == 1);
      iov[2].iov_len = FOOTER_SIZE;
      AMQP_CHECK_RESULT(writev(state->sockfd, &iov[0], 3));
      return 0;
    }

    default:
      return separate_body;
  }
}
int amqp_send_frame(amqp_connection_state_t state,
		    amqp_frame_t const *frame)
{
  amqp_bytes_t encoded;
  int payload_len;
  int separate_body;

  separate_body = inner_send_frame(state, frame, &encoded, &payload_len);
  switch (separate_body) {
    case 0:
      AMQP_CHECK_RESULT(write_ignore_pipe_signal(state->sockfd,
			                         state->outbound_buffer.bytes,
			                         payload_len + (HEADER_SIZE + FOOTER_SIZE)));
      return 0;

    case 1:
      AMQP_CHECK_RESULT(write_ignore_pipe_signal(state->sockfd, state->outbound_buffer.bytes, HEADER_SIZE));
      AMQP_CHECK_RESULT(write_ignore_pipe_signal(state->sockfd, encoded.bytes, payload_len));
      {
	unsigned char frame_end_byte = AMQP_FRAME_END;
	assert(FOOTER_SIZE == 1);
	AMQP_CHECK_RESULT(write_ignore_pipe_signal(state->sockfd, &frame_end_byte, FOOTER_SIZE));
      }
      return 0;

    default:
      return separate_body;
  }
}
int amqp_send_frame(amqp_connection_state_t state,
		    amqp_frame_t const *frame)
{
  amqp_bytes_t encoded;
  int payload_len;
  int separate_body;

  separate_body = inner_send_frame(state, frame, &encoded, &payload_len);
  switch (separate_body) {
    case 0:

#ifdef __GNUC__ /* frgo, 2010-06-11 */
      AMQP_CHECK_RESULT(write(state->sockfd,
			      state->outbound_buffer.bytes,
			      payload_len + (HEADER_SIZE + FOOTER_SIZE)));
#else
	  {
		int nRC = RABBITMQ_C_NO_ERROR;

		nRC = write(state->sockfd,
			      state->outbound_buffer.bytes,
			      payload_len + (HEADER_SIZE + FOOTER_SIZE));
		if( nRC < 0 )
		  return nRC;
	  }
#endif
      return 0;

    case 1: {
      struct iovec iov[3];
      char frame_end_byte = AMQP_FRAME_END;
      iov[0].iov_base = state->outbound_buffer.bytes;
      iov[0].iov_len = HEADER_SIZE;
      iov[1].iov_base = encoded.bytes;
      iov[1].iov_len = payload_len;
      iov[2].iov_base = &frame_end_byte;
      assert(FOOTER_SIZE == 1);
      iov[2].iov_len = FOOTER_SIZE;

#ifdef __GNUC__ /* frgo, 2010-06-11 */
      AMQP_CHECK_RESULT(writev(state->sockfd, &iov[0], 3));
#else
	  {
		int nRC = RABBITMQ_C_NO_ERROR;

		nRC = writev(state->sockfd, &iov[0], 3);
		if( nRC < 0 )
		  return nRC;
	  }
#endif

	  return 0;
    }

    default:
      return separate_body;
  }
}
int amqp_send_frame_to(amqp_connection_state_t state,
		       amqp_frame_t const *frame,
		       amqp_output_fn_t fn,
		       void *context)
{
  amqp_bytes_t encoded;
  int payload_len;
  int separate_body;

  separate_body = inner_send_frame(state, frame, &encoded, &payload_len);
  switch (separate_body) {
    case 0:

#ifdef __GNUC__ /* frgo, 2010-06-11 */
      AMQP_CHECK_RESULT(fn(context,
			   state->outbound_buffer.bytes,
			   payload_len + (HEADER_SIZE + FOOTER_SIZE)));
#else
	  {
		int nRC = RABBITMQ_C_NO_ERROR;

		nRC = fn(context,
			   state->outbound_buffer.bytes,
			   payload_len + (HEADER_SIZE + FOOTER_SIZE));
		if( nRC < 0 )
		  return nRC;
	  }
#endif

      return 0;

    case 1:
#ifdef __GNUC__ /* frgo, 2010-06-11 */
      AMQP_CHECK_RESULT(fn(context, state->outbound_buffer.bytes, HEADER_SIZE));
#else
	  {
		int nRC = RABBITMQ_C_NO_ERROR;

		nRC = fn(context, state->outbound_buffer.bytes, HEADER_SIZE);
		if( nRC < 0 )
		  return nRC;
	  }
#endif

#ifdef __GNUC__ /* frgo, 2010-06-11 */
       AMQP_CHECK_RESULT(fn(context, encoded.bytes, payload_len));
#else
	  {
		int nRC = RABBITMQ_C_NO_ERROR;

		nRC = fn(context, encoded.bytes, payload_len);
		if( nRC < 0 )
		  return nRC;
	  }
#endif
	  {
		assert(FOOTER_SIZE == 1);
		char frame_end_byte = AMQP_FRAME_END;

#ifdef __GNUC__ /* frgo, 2010-06-11 */
		AMQP_CHECK_RESULT(fn(context, &frame_end_byte, FOOTER_SIZE));
#else
	    {
		  int nRC = RABBITMQ_C_NO_ERROR;

	  	  nRC = fn(context, &frame_end_byte, FOOTER_SIZE);
		  if( nRC < 0 )
		    return nRC;
	    }
#endif
      }
      return 0;

    default:
      return separate_body;
  }
}