[Box Backup-commit] COMMIT r2935 - box/trunk/lib/common

subversion at boxbackup.org subversion at boxbackup.org
Fri Apr 22 14:41:08 BST 2011


Author: chris
Date: 2011-04-22 14:41:07 +0100 (Fri, 22 Apr 2011)
New Revision: 2935

Added:
   box/trunk/lib/common/GetLine.cpp
   box/trunk/lib/common/GetLine.h
Modified:
   box/trunk/lib/common/FdGetLine.cpp
   box/trunk/lib/common/FdGetLine.h
   box/trunk/lib/common/IOStreamGetLine.cpp
   box/trunk/lib/common/IOStreamGetLine.h
Log:
Refactor GetLines to share common code, fix whitespace removal at end of line.


Modified: box/trunk/lib/common/FdGetLine.cpp
===================================================================
--- box/trunk/lib/common/FdGetLine.cpp	2011-04-22 13:37:45 UTC (rev 2934)
+++ box/trunk/lib/common/FdGetLine.cpp	2011-04-22 13:41:07 UTC (rev 2935)
@@ -20,13 +20,6 @@
 
 #include "MemLeakFindOn.h"
 
-// utility whitespace function
-inline bool iw(int c)
-{
-	return (c == ' ' || c == '\t' || c == '\v' || c == '\f'); // \r, \n are already excluded
-}
-
-
 // --------------------------------------------------------------------------
 //
 // Function
@@ -36,12 +29,7 @@
 //
 // --------------------------------------------------------------------------
 FdGetLine::FdGetLine(int fd)
-	: mFileHandle(fd),
-	  mLineNumber(0),
-	  mBufferBegin(0),
-	  mBytesInBuffer(0),
-	  mPendingEOF(false),
-	  mEOF(false)
+: mFileHandle(fd)
 {
 	if(mFileHandle < 0) {THROW_EXCEPTION(CommonException, BadArguments)}
 	//printf("FdGetLine buffer size = %d\n", sizeof(mBuffer));
@@ -74,130 +62,50 @@
 std::string FdGetLine::GetLine(bool Preprocess)
 {
 	if(mFileHandle == -1) {THROW_EXCEPTION(CommonException, GetLineNoHandle)}
-
-	// EOF?
-	if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}
 	
 	std::string r;
+	bool result = GetLineInternal(r, Preprocess);
 
-	bool foundLineEnd = false;
-
-	while(!foundLineEnd && !mEOF)
+	if(!result)
 	{
-		// Use any bytes left in the buffer
-		while(mBufferBegin < mBytesInBuffer)
-		{
-			int c = mBuffer[mBufferBegin++];
-			if(c == '\r')
-			{
-				// Ignore nasty Windows line ending extra chars
-			}
-			else if(c == '\n')
-			{
-				// Line end!
-				foundLineEnd = true;
-				break;
-			}
-			else
-			{
-				// Add to string
-				r += c;
-			}
-			
-			// Implicit line ending at EOF
-			if(mBufferBegin >= mBytesInBuffer && mPendingEOF)
-			{
-				foundLineEnd = true;
-			}
-		}
-		
-		// Check size
-		if(r.size() > FDGETLINE_MAX_LINE_SIZE)
-		{
-			THROW_EXCEPTION(CommonException, GetLineTooLarge)
-		}
-		
-		// Read more in?
-		if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF)
-		{
-#ifdef WIN32
-			int bytes;
-
-			if (mFileHandle == _fileno(stdin))
-			{
-				bytes = console_read(mBuffer, sizeof(mBuffer));
-			}
-			else
-			{
-				bytes = ::read(mFileHandle, mBuffer, 
-					sizeof(mBuffer));
-			}
-#else // !WIN32
-			int bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer));
-#endif // WIN32
-			
-			// Error?
-			if(bytes == -1)
-			{
-				THROW_EXCEPTION(CommonException, OSFileError)
-			}
-			
-			// Adjust buffer info
-			mBytesInBuffer = bytes;
-			mBufferBegin = 0;
-			
-			// EOF / closed?
-			if(bytes == 0)
-			{
-				mPendingEOF = true;
-			}
-		}
-		
-		// EOF?
-		if(mPendingEOF && mBufferBegin >= mBytesInBuffer)
-		{
-			// File is EOF, and now we've depleted the buffer completely, so tell caller as well.
-			mEOF = true;
-		}
+		// should never fail for FdGetLine
+		THROW_EXCEPTION(CommonException, Internal);
 	}
+	
+	return r;
+}
 
-	if(!Preprocess)
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    FdGetLine::ReadMore()
+//		Purpose: Read more bytes from the handle, possible the
+//			 console, into mBuffer and return the number of
+//			 bytes read, 0 on EOF or -1 on error.
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+int FdGetLine::ReadMore(int Timeout)
+{
+	int bytes;
+	
+#ifdef WIN32
+	if (mFileHandle == _fileno(stdin))
 	{
-		return r;
+		bytes = console_read(mBuffer, sizeof(mBuffer));
 	}
 	else
 	{
-		// Check for comment char, but char before must be whitespace
-		int end = 0;
-		int size = r.size();
-		while(end < size)
-		{
-			if(r[end] == '#' && (end == 0 || (iw(r[end-1]))))
-			{
-				break;
-			}
-			end++;
-		}
-		
-		// Remove whitespace
-		int begin = 0;
-		while(begin < size && iw(r[begin]))
-		{
-			begin++;
-		}
+		bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer));
+	}
+#else // !WIN32
+	bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer));
+#endif // WIN32
 
-		if(end < size && !iw(r[end]))
-		{
-			end--;
-		}
-
-		while(end > begin && end < size && iw(r[end]))
-		{
-			end--;
-		}
-		
-		// Return a sub string
-		return r.substr(begin, end - begin + 1);
+	if(bytes == 0)
+	{
+		mPendingEOF = true;
 	}
 }
 
@@ -207,7 +115,7 @@
 // Function
 //		Name:    FdGetLine::DetachFile()
 //		Purpose: Detaches the file handle, setting the file pointer correctly.
-//				 Probably not good for sockets...
+//			 Probably not good for sockets...
 //		Created: 2003/07/24
 //
 // --------------------------------------------------------------------------
@@ -230,4 +138,3 @@
 	mFileHandle = -1;
 }
 
-

Modified: box/trunk/lib/common/FdGetLine.h
===================================================================
--- box/trunk/lib/common/FdGetLine.h	2011-04-22 13:37:45 UTC (rev 2934)
+++ box/trunk/lib/common/FdGetLine.h	2011-04-22 13:41:07 UTC (rev 2935)
@@ -12,20 +12,8 @@
 
 #include <string>
 
-#ifdef BOX_RELEASE_BUILD
-	#define FDGETLINE_BUFFER_SIZE		1024
-#elif defined WIN32
-	// need enough space for at least one unicode character 
-	// in UTF-8 when calling console_read() from bbackupquery
-	#define FDGETLINE_BUFFER_SIZE		5
-#else
-	#define FDGETLINE_BUFFER_SIZE		4
-#endif
+#include "GetLine.h"
 
-// Just a very large upper bound for line size to avoid
-// people sending lots of data over sockets and causing memory problems.
-#define FDGETLINE_MAX_LINE_SIZE			(1024*256)
-
 // --------------------------------------------------------------------------
 //
 // Class
@@ -34,7 +22,7 @@
 //		Created: 2003/07/24
 //
 // --------------------------------------------------------------------------
-class FdGetLine
+class FdGetLine : public GetLine
 {
 public:
 	FdGetLine(int fd);
@@ -43,22 +31,19 @@
 	FdGetLine(const FdGetLine &rToCopy);
 
 public:
-	std::string GetLine(bool Preprocess = false);
-	bool IsEOF() {return mEOF;}
-	int GetLineNumber() {return mLineNumber;}
-	
+	virtual std::string GetLine(bool Preprocess = false);
 	// Call to detach, setting file pointer correctly to last bit read.
 	// Only works for lseek-able file descriptors.
 	void DetachFile();
-	
+	// if we read 0 bytes from an fd, it must be end of stream,
+	// because we don't support timeouts
+	virtual bool IsStreamDataLeft() { return false; }
+
+protected:
+	int ReadMore(int Timeout = IOStream::TimeOutInfinite);
+
 private:
-	char mBuffer[FDGETLINE_BUFFER_SIZE];
 	int mFileHandle;
-	int mLineNumber;
-	int mBufferBegin;
-	int mBytesInBuffer;
-	bool mPendingEOF;
-	bool mEOF;
 };
 
 #endif // FDGETLINE__H

Copied: box/trunk/lib/common/GetLine.cpp (from rev 2927, box/trunk/lib/common/FdGetLine.cpp)
===================================================================
--- box/trunk/lib/common/GetLine.cpp	                        (rev 0)
+++ box/trunk/lib/common/GetLine.cpp	2011-04-22 13:41:07 UTC (rev 2935)
@@ -0,0 +1,176 @@
+// --------------------------------------------------------------------------
+//
+// File
+//		Name:    GetLine.cpp
+//		Purpose: Common base class for line based file descriptor reading
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+	#include <unistd.h>
+#endif
+
+#include "GetLine.h"
+#include "CommonException.h"
+
+#include "MemLeakFindOn.h"
+
+// utility whitespace function
+inline bool iw(int c)
+{
+	return (c == ' ' || c == '\t' || c == '\v' || c == '\f'); // \r, \n are already excluded
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    GetLine::GetLine(int)
+//		Purpose: Constructor, taking file descriptor
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+GetLine::GetLine()
+: mLineNumber(0),
+  mBufferBegin(0),
+  mBytesInBuffer(0),
+  mPendingEOF(false),
+  mEOF(false)
+{ }
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    GetLine::GetLineInternal(std::string &, bool, int)
+//		Purpose: Gets a line from the file, returning it in rOutput.
+//			 If Preprocess is true, leading and trailing
+//			 whitespace is removed, and comments (after #)  are
+//			 deleted. Returns true if a line is available now,
+//			 false if retrying may get a line (eg timeout,
+//			 signal), and exceptions if it's EOF.
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+bool GetLine::GetLineInternal(std::string &rOutput, bool Preprocess,
+	int Timeout)
+{
+	// EOF?
+	if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}
+	
+	// Initialise string to stored into
+	rOutput = mPendingString;
+	mPendingString.erase();
+
+	bool foundLineEnd = false;
+
+	while(!foundLineEnd && !mEOF)
+	{
+		// Use any bytes left in the buffer
+		while(mBufferBegin < mBytesInBuffer)
+		{
+			int c = mBuffer[mBufferBegin++];
+			if(c == '\r')
+			{
+				// Ignore nasty Windows line ending extra chars
+			}
+			else if(c == '\n')
+			{
+				// Line end!
+				foundLineEnd = true;
+				break;
+			}
+			else
+			{
+				// Add to string
+				rOutput += c;
+			}
+			
+			// Implicit line ending at EOF
+			if(mBufferBegin >= mBytesInBuffer && mPendingEOF)
+			{
+				foundLineEnd = true;
+			}
+		}
+		
+		// Check size
+		if(rOutput.size() > GETLINE_MAX_LINE_SIZE)
+		{
+			THROW_EXCEPTION(CommonException, GetLineTooLarge)
+		}
+		
+		// Read more in?
+		if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF)
+		{
+			int bytes = ReadMore(Timeout);
+			
+			// Error?
+			if(bytes == -1)
+			{
+				THROW_EXCEPTION(CommonException, OSFileError)
+			}
+			
+			// Adjust buffer info
+			mBytesInBuffer = bytes;
+			mBufferBegin = 0;
+			
+			// No data returned?
+			if(bytes == 0 && IsStreamDataLeft())
+			{
+			       // store string away
+			       mPendingString = rOutput;
+			       // Return false;
+			       return false;
+			}
+		}
+		
+		// EOF?
+		if(mPendingEOF && mBufferBegin >= mBytesInBuffer)
+		{
+			// File is EOF, and now we've depleted the buffer completely, so tell caller as well.
+			mEOF = true;
+		}
+	}
+
+	if(Preprocess)
+	{
+		// Check for comment char, but char before must be whitespace
+		// end points to a gap between characters, may equal start if
+		// the string to be extracted has zero length, and indexes the
+		// first character not in the string (== length, or a # mark
+		// or whitespace)
+		int end = 0;
+		int size = rOutput.size();
+		while(end < size)
+		{
+			if(rOutput[end] == '#' && (end == 0 || (iw(rOutput[end-1]))))
+			{
+				break;
+			}
+			end++;
+		}
+		
+		// Remove whitespace
+		int begin = 0;
+		while(begin < size && iw(rOutput[begin]))
+		{
+			begin++;
+		}
+
+		while(end > begin && end <= size && iw(rOutput[end-1]))
+		{
+			end--;
+		}
+		
+		// Return a sub string
+		rOutput = rOutput.substr(begin, end - begin);
+	}
+
+	return true;
+}
+
+

Copied: box/trunk/lib/common/GetLine.h (from rev 2927, box/trunk/lib/common/FdGetLine.h)
===================================================================
--- box/trunk/lib/common/GetLine.h	                        (rev 0)
+++ box/trunk/lib/common/GetLine.h	2011-04-22 13:41:07 UTC (rev 2935)
@@ -0,0 +1,66 @@
+// --------------------------------------------------------------------------
+//
+// File
+//		Name:    GetLine.h
+//		Purpose: Common base class for line based file descriptor reading
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+
+#ifndef GETLINE__H
+#define GETLINE__H
+
+#include <string>
+
+#ifdef BOX_RELEASE_BUILD
+	#define GETLINE_BUFFER_SIZE		1024
+#elif defined WIN32
+	// need enough space for at least one unicode character 
+	// in UTF-8 when calling console_read() from bbackupquery
+	#define GETLINE_BUFFER_SIZE		5
+#else
+	#define GETLINE_BUFFER_SIZE		4
+#endif
+
+// Just a very large upper bound for line size to avoid
+// people sending lots of data over sockets and causing memory problems.
+#define GETLINE_MAX_LINE_SIZE			(1024*256)
+
+// --------------------------------------------------------------------------
+//
+// Class
+//		Name:    GetLine
+//		Purpose: Common base class for line based file descriptor reading
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+class GetLine
+{
+protected:
+	GetLine();
+
+private:
+	GetLine(const GetLine &rToCopy);
+
+public:
+	virtual bool IsEOF() {return mEOF;}
+	int GetLineNumber() {return mLineNumber;}
+	
+protected:
+	bool GetLineInternal(std::string &rOutput,
+		bool Preprocess = false,
+		int Timeout = IOStream::TimeOutInfinite);
+	virtual int ReadMore(int Timeout = IOStream::TimeOutInfinite) = 0;
+	virtual bool IsStreamDataLeft() = 0;
+
+	char mBuffer[GETLINE_BUFFER_SIZE];
+	int mLineNumber;
+	int mBufferBegin;
+	int mBytesInBuffer;
+	bool mPendingEOF;
+	std::string mPendingString;
+	bool mEOF;
+};
+
+#endif // GETLINE__H
+

Modified: box/trunk/lib/common/IOStreamGetLine.cpp
===================================================================
--- box/trunk/lib/common/IOStreamGetLine.cpp	2011-04-22 13:37:45 UTC (rev 2934)
+++ box/trunk/lib/common/IOStreamGetLine.cpp	2011-04-22 13:41:07 UTC (rev 2935)
@@ -13,13 +13,6 @@
 
 #include "MemLeakFindOn.h"
 
-// utility whitespace function
-inline bool iw(int c)
-{
-	return (c == ' ' || c == '\t' || c == '\v' || c == '\f'); // \r, \n are already excluded
-}
-
-
 // --------------------------------------------------------------------------
 //
 // Function
@@ -29,12 +22,7 @@
 //
 // --------------------------------------------------------------------------
 IOStreamGetLine::IOStreamGetLine(IOStream &Stream)
-	: mrStream(Stream),
-	  mLineNumber(0),
-	  mBufferBegin(0),
-	  mBytesInBuffer(0),
-	  mPendingEOF(false),
-	  mEOF(false)
+: mrStream(Stream)
 {
 }
 
@@ -66,123 +54,30 @@
 // --------------------------------------------------------------------------
 bool IOStreamGetLine::GetLine(std::string &rOutput, bool Preprocess, int Timeout)
 {
-	// EOF?
-	if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}
-	
-	// Initialise string to stored into
-	std::string r(mPendingString);
-	mPendingString.erase();
+	return GetLineInternal(rOutput, Preprocess, Timeout);
+}
 
-	bool foundLineEnd = false;
 
-	while(!foundLineEnd && !mEOF)
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    IOStreamGetLine::ReadMore()
+//		Purpose: Read more bytes from the handle, possible the
+//			 console, into mBuffer and return the number of
+//			 bytes read, 0 on EOF or -1 on error.
+//		Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+int IOStreamGetLine::ReadMore(int Timeout)
+{
+	int bytes = mrStream.Read(mBuffer, sizeof(mBuffer), Timeout);
+	
+	if(!mrStream.StreamDataLeft())
 	{
-		// Use any bytes left in the buffer
-		while(mBufferBegin < mBytesInBuffer)
-		{
-			int c = mBuffer[mBufferBegin++];
-			if(c == '\r')
-			{
-				// Ignore nasty Windows line ending extra chars
-			}
-			else if(c == '\n')
-			{
-				// Line end!
-				foundLineEnd = true;
-				break;
-			}
-			else
-			{
-				// Add to string
-				r += c;
-			}
-			
-			// Implicit line ending at EOF
-			if(mBufferBegin >= mBytesInBuffer && mPendingEOF)
-			{
-				foundLineEnd = true;
-			}
-		}
-		
-		// Check size
-		if(r.size() > IOSTREAMGETLINE_MAX_LINE_SIZE)
-		{
-			THROW_EXCEPTION(CommonException, GetLineTooLarge)
-		}
-		
-		// Read more in?
-		if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF)
-		{
-			int bytes = mrStream.Read(mBuffer, sizeof(mBuffer), Timeout);
-			
-			// Adjust buffer info
-			mBytesInBuffer = bytes;
-			mBufferBegin = 0;
-			
-			// EOF / closed?
-			if(!mrStream.StreamDataLeft())
-			{
-				mPendingEOF = true;
-			}
-			
-			// No data returned?
-			if(bytes == 0 && mrStream.StreamDataLeft())
-			{
-				// store string away
-				mPendingString = r;
-				// Return false;
-				return false;
-			}
-		}
-		
-		// EOF?
-		if(mPendingEOF && mBufferBegin >= mBytesInBuffer)
-		{
-			// File is EOF, and now we've depleted the buffer completely, so tell caller as well.
-			mEOF = true;
-		}
+		mPendingEOF = true;
 	}
 
-	if(!Preprocess)
-	{
-		rOutput = r;
-		return true;
-	}
-	else
-	{
-		// Check for comment char, but char before must be whitespace
-		int end = 0;
-		int size = r.size();
-		while(end < size)
-		{
-			if(r[end] == '#' && (end == 0 || (iw(r[end-1]))))
-			{
-				break;
-			}
-			end++;
-		}
-		
-		// Remove whitespace
-		int begin = 0;
-		while(begin < size && iw(r[begin]))
-		{
-			begin++;
-		}
-
-		if(end < size && !iw(r[end]))
-		{
-			end--;
-		}
-
-		while(end > begin && end < size && iw(r[end]))
-		{
-			end--;
-		}
-		
-		// Return a sub string
-		rOutput = r.substr(begin, end - begin + 1);
-		return true;
-	}
+	return bytes;	
 }
 
 

Modified: box/trunk/lib/common/IOStreamGetLine.h
===================================================================
--- box/trunk/lib/common/IOStreamGetLine.h	2011-04-22 13:37:45 UTC (rev 2934)
+++ box/trunk/lib/common/IOStreamGetLine.h	2011-04-22 13:41:07 UTC (rev 2935)
@@ -12,18 +12,9 @@
 
 #include <string>
 
+#include "GetLine.h"
 #include "IOStream.h"
 
-#ifdef BOX_RELEASE_BUILD
-	#define IOSTREAMGETLINE_BUFFER_SIZE		1024
-#else
-	#define IOSTREAMGETLINE_BUFFER_SIZE		4
-#endif
-
-// Just a very large upper bound for line size to avoid
-// people sending lots of data over sockets and causing memory problems.
-#define IOSTREAMGETLINE_MAX_LINE_SIZE			(1024*256)
-
 // --------------------------------------------------------------------------
 //
 // Class
@@ -32,7 +23,7 @@
 //		Created: 2003/07/24
 //
 // --------------------------------------------------------------------------
-class IOStreamGetLine
+class IOStreamGetLine : public GetLine
 {
 public:
 	IOStreamGetLine(IOStream &Stream);
@@ -42,29 +33,28 @@
 
 public:
 	bool GetLine(std::string &rOutput, bool Preprocess = false, int Timeout = IOStream::TimeOutInfinite);
-	bool IsEOF() {return mEOF;}
-	int GetLineNumber() {return mLineNumber;}
 	
 	// Call to detach, setting file pointer correctly to last bit read.
 	// Only works for lseek-able file descriptors.
 	void DetachFile();
 	
+	virtual bool IsStreamDataLeft()
+	{
+		return mrStream.StreamDataLeft();
+	}
+	
 	// For doing interesting stuff with the remaining data...
 	// Be careful with this!
 	const void *GetBufferedData() const {return mBuffer + mBufferBegin;}
 	int GetSizeOfBufferedData() const {return mBytesInBuffer - mBufferBegin;}
 	void IgnoreBufferedData(int BytesToIgnore);
 	IOStream &GetUnderlyingStream() {return mrStream;}
+
+protected:
+	int ReadMore(int Timeout = IOStream::TimeOutInfinite);
 	
 private:
-	char mBuffer[IOSTREAMGETLINE_BUFFER_SIZE];
 	IOStream &mrStream;
-	int mLineNumber;
-	int mBufferBegin;
-	int mBytesInBuffer;
-	bool mPendingEOF;
-	bool mEOF;
-	std::string mPendingString;
 };
 
 #endif // IOSTREAMGETLINE__H




More information about the Boxbackup-commit mailing list