[icinga-checkins] icinga.org: icinga2/master: stream/livestatus: refactor ReadLine with context saving

git at icinga.org git at icinga.org
Wed Jul 3 16:17:44 CEST 2013


Module: icinga2
Branch: master
Commit: 80c91aa91e18f94e3bcaefb15a26a9f55875024c
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=80c91aa91e18f94e3bcaefb15a26a9f55875024c

Author: Michael Friedrich <michael.friedrich at netways.de>
Date:   Wed Jul  3 16:16:38 2013 +0200

stream/livestatus: refactor ReadLine with context saving

---

 components/livestatus/component.cpp |    6 +--
 lib/base/stream.cpp                 |   60 +++++++++++++++++++++--------------
 lib/base/stream.h                   |   13 +++++++-
 3 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/components/livestatus/component.cpp b/components/livestatus/component.cpp
index fe30e16..7ef3138 100644
--- a/components/livestatus/component.cpp
+++ b/components/livestatus/component.cpp
@@ -84,13 +84,11 @@ void LivestatusComponent::ClientThreadProc(const Socket::Ptr& client)
 
 	for (;;) {
 		String line;
-		bool read_line = false;
+		ReadLineContext context;
 
 		std::vector<String> lines;
 
-		while (stream->ReadLine(&line)) {
-			read_line = true;
-
+		while (stream->ReadLine(&line, context)) {
 			if (line.GetLength() > 0)
 				lines.push_back(line);
 			else
diff --git a/lib/base/stream.cpp b/lib/base/stream.cpp
index 1405194..0ef9571 100644
--- a/lib/base/stream.cpp
+++ b/lib/base/stream.cpp
@@ -24,42 +24,54 @@
 
 using namespace icinga;
 
-bool Stream::ReadLine(String *line, size_t maxLength)
+bool Stream::ReadLine(String *line, ReadLineContext& context, size_t maxLength)
 {
-	BOOST_THROW_EXCEPTION(std::runtime_error("Not implemented."));
-	/*
-	char *buffer = new char[maxLength];
+	if (context.Eof)
+		return false;
 
-	size_t rc = Peek(buffer, maxLength);
+	for (;;) {
+		if (context.MustRead) {
+			context.Buffer = (char *)realloc(context.Buffer, context.Size + maxLength);
 
-	if (rc == 0)
-		return false;
+			if (!context.Buffer)
+				throw std::bad_alloc();
 
-	for (size_t i = 0; i < rc; i++) {
-		if (buffer[i] == '\n') {
-			*line = String(buffer, &(buffer[i]));
-			boost::algorithm::trim_right(*line);
+			size_t rc = Read(context.Buffer + context.Size, maxLength);
 
-			Read(NULL, i + 1);
+			if (rc == 0) {
+				*line = String(context.Buffer, &(context.Buffer[context.Size]));
+				boost::algorithm::trim_right(*line);
 
-			delete buffer;
+				context.Eof = true;
 
-			return true;
+				return true;
+			}
+
+			context.Size += rc;
 		}
-	}
 
-	if (IsReadEOF()) {
-		*line = String(buffer, buffer + rc);
-		boost::algorithm::trim_right(*line);
+		int count = 0;
+		size_t first_newline;
 
-		Read(NULL, rc);
+		for (size_t i = 0; i < context.Size; i++) {
+			if (context.Buffer[i] == '\n') {
+				count++;
 
-		delete buffer;
+				if (count == 1)
+					first_newline = i;
+			}
+		}
 
-		return true;
-	}
+		context.MustRead = (count <= 1);
+
+		if (count > 0) {
+			*line = String(context.Buffer, &(context.Buffer[first_newline]));
+			boost::algorithm::trim_right(*line);
 
-	delete buffer;*/
+			memmove(context.Buffer, context.Buffer + first_newline + 1, context.Size - first_newline - 1);
+			context.Size -= first_newline + 1;
 
-	return false;
+			return true;
+		}
+	}
 }
diff --git a/lib/base/stream.h b/lib/base/stream.h
index 510cbb0..b51eb59 100644
--- a/lib/base/stream.h
+++ b/lib/base/stream.h
@@ -29,6 +29,17 @@
 namespace icinga
 {
 
+struct ReadLineContext
+{
+	ReadLineContext(void) : Buffer(NULL), Size(0), Eof(false), MustRead(true)
+	{ }
+
+	char *Buffer;
+	size_t Size;
+	bool Eof;
+	bool MustRead;
+};
+
 /**
  * A stream.
  *
@@ -64,7 +75,7 @@ public:
 	 */
 	virtual void Close(void) = 0;
 
-	bool ReadLine(String *line, size_t maxLength = 4096);
+	bool ReadLine(String *line, ReadLineContext& context, size_t maxLength = 4096);
 };
 
 }





More information about the icinga-checkins mailing list