cep_write_buffered.c 1.83 KB
/**
 * \file
 *
 * \author	Georg Hopp
 *
 * \copyright
 * Copyright © 2014 Georg Hopp
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "trbase.h"
#include "trio.h"

#include "tr/comm_end_point.h"

int
TR_cepWriteBuffered(TR_CommEndPoint this, size_t * size)
{
	TR_RemoteData data;
	int           send;

	*size = 0;

	data = TR_cepNextWriteData(this);

	while(data) {
		send = TR_socketSend(this->transport, data);

		switch (send) {
			case FALSE: // EAGAIN
			case -3:    // remote not ready
				TR_queuePutFirst(this->write_buffer, data);
				break;

			case -1:    // FAILURE
			case -2:    // remote close
				TR_delete(data);
				TR_queueDestroy(this->write_buffer);
				*size = this->write_buffer_size;
				break;

			default:
				{
					TR_RemoteData new_data = NULL;

					if (send != ((TR_SizedData)data)->size) {
						new_data = TR_new(
								TR_RemoteData,
								((TR_SizedData)data)->data + send,
								((TR_SizedData)data)->size - send,
								data->remote);
					} else {
						new_data = TR_cepNextWriteData(this);
					}

					*size += send;
					TR_delete(data);
					data = new_data;
				}
				break;
		}
		
		if (send <= 0) break;
	}

	if (! data) {
		return -4; // no more data to send
	}

	return send;
}

// vim: set ts=4 sw=4: