/*
 * @(#)PrintWriter.cpp
 *
 * This file is part of webCDwriter - Network CD Writing.
 *
 * Copyright (C) 2002 Jörg P. M. Haeger
 *
 * webCDwriter is free software. See CDWserver.cpp for details.
 *
 * Jörg Haeger, 22.04.2002
 */

#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include "Exception.h"
#include "Log.h"
#include "PrintWriter.h"
#include "String.h"
#include "StringBuffer.h"

PrintWriter::PrintWriter(int fd) {
	this->fd = dup(fd);
	if (this->fd == -1)
		throw new Exception("PrintWriter::PrintWriter: dup %d %s",
			errno, strerror(errno));
}

PrintWriter::PrintWriter(PrintWriter *writer) {
	fd = writer->fd;
	writer->fd = -1;
	delete writer;
}

PrintWriter::~PrintWriter() {
	if (fd == -1)
		return;
	close();
}

void PrintWriter::close() {
	if (fd == -1)
		return;
	flush();
	::close(fd);
	fd = -1;
}

void PrintWriter::flush() {
}

void PrintWriter::write(const char *str) {
	write(str, 0, strlen(str));
}

void PrintWriter::write(const char *buf, int off, int len) {
	while (len > 0) {
		fd_set fdSet;
		FD_ZERO(&fdSet);
		FD_SET(fd, &fdSet);

		struct timeval timeout;
		timeout.tv_sec = 60;
		timeout.tv_usec = 0;

		int res;
		while (1) {
			res = select(FD_SETSIZE, NULL, &fdSet, NULL, &timeout);
			if (res != -1 || errno != EINTR)
				break;
		}
		if (res == -1)
			log.debug("PrintWriter::write",
				S.e + "select: errno = " + errno
				+ " <" + strerror(errno) + ">");
		if (res == 0)
			throw new Exception("timeout");

		int n;
		while (1) {
			n = ::write(fd, &buf[off], len);
			if (n != -1 || errno != EINTR)
				break;
		}
//		log.debug("PrintWriter::write",
//			S.e + "off = " + off
//			+ ", len = " + len + ", n = " + n);
		if (n == -1) {
			log.debug("PrintWriter::write",
				S.e + "write: errno = " + errno
				+ " <" + strerror(errno) + ">");
			return;
		}
		if (n == 0)
			return;
		off += n;
		len -= n;
	}
}

void PrintWriter::write(String &s) {
	int len = s.length();
	char buf[len];
	for (int i = 0; i < len; i++)
		buf[i] = s.charAt(i);
	write(buf, 0, len);
}

void PrintWriter::write(StringBuffer &s) {
	int len = s.length();
	char buf[len];
	for (int i = 0; i < len; i++)
		buf[i] = s.charAt(i);
	write(buf, 0, len);
}
