From d1770f567321f8b01185cdf974718aea89669a37 Mon Sep 17 00:00:00 2001
From: Mike Buland <eichlan@xagasoft.com>
Date: Wed, 24 Oct 2007 00:57:18 +0000
Subject: Corrected a few issues that cropped up when using the Bu::Socket
 without a Client for buffering.  The Bu::Client has also been made a little
 more reliable.

The logger should get a few more tweaks, but it works fine for now, the hex dump
could stand another tweak or two.
---
 src/client.cpp |  4 ++--
 src/logger.cpp | 13 ++++++++++--
 src/socket.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++------------
 src/socket.h   |  2 ++
 4 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/src/client.cpp b/src/client.cpp
index b546deb..f69ea24 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -68,8 +68,8 @@ void Bu::Client::processOutput()
 	if( sWriteBuf.getSize() > 0 )
 	{
 		int nAmnt = (sWriteBuf.getSize()<2048)?(sWriteBuf.getSize()):(2048);
-		pSocket->write( sWriteBuf.getStr(), nAmnt );
-		sWriteBuf.trimFront( nAmnt );
+		int nReal = pSocket->write( sWriteBuf.getStr(), nAmnt );
+		sWriteBuf.trimFront( nReal );
 		//sWriteBuf.clear();
 	}
 }
diff --git a/src/logger.cpp b/src/logger.cpp
index fe6a916..91679ff 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -20,7 +20,11 @@ void Bu::Logger::log( uint32_t nLevel, const char *sFile, const char *sFunction,
 	va_list ap;
 	va_start( ap, sFormat );
 	char *text;
-	vasprintf( &text, sFormat, ap );
+	if( vasprintf( &text, sFormat, ap ) < 0 )
+	{
+		printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WTF?\n");
+		return;
+	}
 	va_end(ap);
 	
 	time_t t = time(NULL);
@@ -152,6 +156,11 @@ void Bu::Logger::hexDump( uint32_t nLevel, const char *sFile,
 	Bu::FString sLine;
 	for(;;)
 	{
+		{
+			char buf[15];
+			sprintf( buf, "%010d| ", j );
+			sLine += buf;
+		}
 		int kmax = 8;
 		if( nDataLen-j < 8 ) kmax = nDataLen-j;
 		for(int k = 0; k < 8; k++ )
@@ -171,7 +180,7 @@ void Bu::Logger::hexDump( uint32_t nLevel, const char *sFile,
 		for(int k = 0; k < kmax; k++ )
 		{
 			char buf[3];
-			sprintf( buf, "%c ", (pData[j+k]>32 && pData[j+k]<=128)?(pData[j+k]):('.') );
+			sprintf( buf, "%c", (pData[j+k]>32 && pData[j+k]<=128)?(pData[j+k]):('.') );
 			sLine += buf;
 		}
 		log( nLevel, sFile, sFunction, nLine, sLine.getStr() );
diff --git a/src/socket.cpp b/src/socket.cpp
index 1874fd2..73d52e4 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -179,22 +179,32 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes )
 size_t Bu::Socket::read( void *pBuf, size_t nBytes,
 		uint32_t nSec, uint32_t nUSec )
 {
+	struct timeval tv, nt, ct;
+	size_t nRead = 0;
+	
 	fd_set rfds;
 	FD_ZERO(&rfds);
 	FD_SET(nSocket, &rfds);
-	struct timeval tv = { nSec, nUSec };
-	int retval = select( nSocket+1, &rfds, NULL, NULL, &tv );
-	if( retval == -1 )
-		throw ConnectionException(
-			excodeBadReadError,
-			"Bad Read error"
-			);
-	if( !FD_ISSET( nSocket, &rfds ) )
-		throw ConnectionException(
-			excodeSocketTimeout,
-			"Socket timout on read"
-			);
-	return read( pBuf, nBytes );
+
+	gettimeofday( &nt, NULL );
+	nt.tv_sec += nSec;
+	nt.tv_usec += nUSec;
+
+	for(;;)
+	{
+		tv.tv_sec = nSec;
+		tv.tv_usec = nUSec;
+		select( nSocket+1, &rfds, NULL, NULL, &tv );
+		nRead += read( ((char *)pBuf)+nRead, nBytes-nRead );
+		if( nRead >= nBytes )
+			break;
+		gettimeofday( &ct, NULL );
+		if( (ct.tv_sec > nt.tv_sec) ||
+			(ct.tv_sec == nt.tv_sec &&
+			ct.tv_usec >= nt.tv_usec) )
+			break;
+	}
+	return nRead;
 }
 
 size_t Bu::Socket::write( const void *pBuf, size_t nBytes )
@@ -208,6 +218,36 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes )
 	return nWrote;
 }
 
+size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32_t nUSec )
+{
+	struct timeval tv, nt, ct;
+	size_t nWrote = 0;
+	
+	fd_set wfds;
+	FD_ZERO(&wfds);
+	FD_SET(nSocket, &wfds);
+
+	gettimeofday( &nt, NULL );
+	nt.tv_sec += nSec;
+	nt.tv_usec += nUSec;
+
+	for(;;)
+	{
+		tv.tv_sec = nSec;
+		tv.tv_usec = nUSec;
+		select( nSocket+1, NULL, &wfds, NULL, &tv );
+		nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote );
+		if( nWrote >= nBytes )
+			break;
+		gettimeofday( &ct, NULL );
+		if( (ct.tv_sec > nt.tv_sec) ||
+			(ct.tv_sec == nt.tv_sec &&
+			ct.tv_usec >= nt.tv_usec) )
+			break;
+	}
+	return nWrote;
+}
+
 long Bu::Socket::tell()
 {
 	throw UnsupportedException();
diff --git a/src/socket.h b/src/socket.h
index 95271f8..96cfeb9 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -25,6 +25,8 @@ namespace Bu
 		virtual size_t read( void *pBuf, size_t nBytes,
 				uint32_t nSec, uint32_t nUSec=0 );
 		virtual size_t write( const void *pBuf, size_t nBytes );
+		virtual size_t write( const void *pBuf, size_t nBytes,
+				uint32_t nSec, uint32_t nUSec=0 );
 
 		virtual long tell();
 		virtual void seek( long offset );
-- 
cgit v1.2.3