mirror of https://github.com/Icinga/icinga2.git
stream/livestatus: refactor ReadLine with context saving
This commit is contained in:
parent
90275774f9
commit
80c91aa91e
|
@ -84,13 +84,11 @@ void LivestatusComponent::ClientThreadProc(const Socket::Ptr& client)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
String line;
|
String line;
|
||||||
bool read_line = false;
|
ReadLineContext context;
|
||||||
|
|
||||||
std::vector<String> lines;
|
std::vector<String> lines;
|
||||||
|
|
||||||
while (stream->ReadLine(&line)) {
|
while (stream->ReadLine(&line, context)) {
|
||||||
read_line = true;
|
|
||||||
|
|
||||||
if (line.GetLength() > 0)
|
if (line.GetLength() > 0)
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
else
|
else
|
||||||
|
|
|
@ -24,42 +24,54 @@
|
||||||
|
|
||||||
using namespace icinga;
|
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."));
|
if (context.Eof)
|
||||||
/*
|
|
||||||
char *buffer = new char[maxLength];
|
|
||||||
|
|
||||||
size_t rc = Peek(buffer, maxLength);
|
|
||||||
|
|
||||||
if (rc == 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (size_t i = 0; i < rc; i++) {
|
for (;;) {
|
||||||
if (buffer[i] == '\n') {
|
if (context.MustRead) {
|
||||||
*line = String(buffer, &(buffer[i]));
|
context.Buffer = (char *)realloc(context.Buffer, context.Size + maxLength);
|
||||||
|
|
||||||
|
if (!context.Buffer)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
|
||||||
|
size_t rc = Read(context.Buffer + context.Size, maxLength);
|
||||||
|
|
||||||
|
if (rc == 0) {
|
||||||
|
*line = String(context.Buffer, &(context.Buffer[context.Size]));
|
||||||
|
boost::algorithm::trim_right(*line);
|
||||||
|
|
||||||
|
context.Eof = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Size += rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
size_t first_newline;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < context.Size; i++) {
|
||||||
|
if (context.Buffer[i] == '\n') {
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (count == 1)
|
||||||
|
first_newline = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.MustRead = (count <= 1);
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
*line = String(context.Buffer, &(context.Buffer[first_newline]));
|
||||||
boost::algorithm::trim_right(*line);
|
boost::algorithm::trim_right(*line);
|
||||||
|
|
||||||
Read(NULL, i + 1);
|
memmove(context.Buffer, context.Buffer + first_newline + 1, context.Size - first_newline - 1);
|
||||||
|
context.Size -= first_newline + 1;
|
||||||
delete buffer;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsReadEOF()) {
|
|
||||||
*line = String(buffer, buffer + rc);
|
|
||||||
boost::algorithm::trim_right(*line);
|
|
||||||
|
|
||||||
Read(NULL, rc);
|
|
||||||
|
|
||||||
delete buffer;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete buffer;*/
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,17 @@
|
||||||
namespace icinga
|
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.
|
* A stream.
|
||||||
*
|
*
|
||||||
|
@ -64,7 +75,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void Close(void) = 0;
|
virtual void Close(void) = 0;
|
||||||
|
|
||||||
bool ReadLine(String *line, size_t maxLength = 4096);
|
bool ReadLine(String *line, ReadLineContext& context, size_t maxLength = 4096);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue