#include "acl_stdafx.hpp"
#ifndef ACL_PREPARE_COMPILE
#include "acl_cpp/stream/ostream.hpp"
#endif

namespace acl {

int ostream::write(const void* data, size_t size, bool loop /* = true */)
{
	int   ret;
	if (loop)
		ret = acl_vstream_writen(stream_, data, size);
	else
		ret = acl_vstream_write(stream_, data, (int) size);
	if (ret == ACL_VSTREAM_EOF)
		eof_ = true;
	return ret;
}

int ostream::writev(const struct iovec *v, int count, bool loop)
{
	int   ret;
	if (loop)
		ret = acl_vstream_writevn(stream_, v, count);
	else
		ret = acl_vstream_writev(stream_, v, count);
	if (ret == ACL_VSTREAM_EOF)
		eof_ = true;
	return ret;
}

int ostream::vformat(const char* fmt, va_list ap)
{
	int   ret = acl_vstream_vfprintf(stream_, fmt, ap);
	if (ret == ACL_VSTREAM_EOF)
		eof_ = true;
	return ret;
}

int ostream::write(acl_int64 n)
{
	return write(&n, sizeof(n), true);
}

int ostream::write(int n)
{
	return write(&n, sizeof(n), true);
}

int ostream::write(short n)
{
	return write(&n, sizeof(n), true);
}

int ostream::write(char ch)
{
	return write(&ch, sizeof(ch), false);
}

int ostream::write(const acl::string& s, bool loop)
{
	return write(s.c_str(), s.length(), loop);
}

int ostream::format(const char* fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	int ret = vformat(fmt, ap);
	va_end(ap);
	return ret;
}

int ostream::puts(const char* s)
{
	return format("%s\r\n", s);
}

ostream& ostream::operator<<(const acl::string& s)
{
	(void) write(s.c_str(), s.length(), true);
	return *this;
}

ostream& ostream::operator<<(const char* s)
{
	(void) write(s, strlen(s), true);
	return *this;
}

ostream& ostream::operator<<(acl_int64 n)
{
	(void) write(&n, sizeof(n), true);
	return *this;
}

ostream& ostream::operator<<(int n)
{
	(void) write(&n, sizeof(n), true);
	return *this;
}

ostream& ostream::operator<<(short n)
{
	(void) write(&n, sizeof(n), true);
	return *this;
}

ostream& ostream::operator<<(char ch)
{
	(void) write(&ch, sizeof(ch), false);
	return *this;
}

int ostream::push_pop(const char* in, size_t len,
	string* out /* = NULL */ acl_unused,
	size_t max /* = 0 */ acl_unused)
{
	if (in == NULL || len == 0)
		return 0;
	if ((size_t) write(in, len) != len)
		return -1;
	if (out == NULL)
		return 0;
	if (max > 0 && len > max)
		len = max;
	out->append(in, len);
	return (int) len;
}


} // namespace acl
