From 8debabc6b968e5c152c93068c445835e0d6926d6 Mon Sep 17 00:00:00 2001 From: Mark Calderbank Date: Sun, 18 Sep 2005 18:50:31 +0000 Subject: [PATCH] New stream - don't split frames at end of buffer --- stream.cc | 97 ++++++++++++++++++++++++++----------------------------- stream.h | 5 +-- 2 files changed, 49 insertions(+), 53 deletions(-) diff --git a/stream.cc b/stream.cc index 00665d8..785b11d 100644 --- a/stream.cc +++ b/stream.cc @@ -43,83 +43,78 @@ int Stream::init(int bufsize) outbuf = (UCHAR*) malloc(bufsize); if (!outbuf) return 0; bufferSize = bufsize; - bufferHead = bufferTail = 0; + bufferHead = 0; + bufferTail = 0; + bufferMark = -1; initted = 1; return 1; } void Stream::flush() { - bufferHead = bufferTail = 0; + bufferHead = 0; + bufferTail = 0; + bufferMark = -1; } int Stream::put(UCHAR* inbuf, int len) { int ret = 0; - int freespace; - int localTail = bufferTail; - if (localTail == 0) localTail = bufferSize; - if (len == 0) return ret; + int tail = bufferTail; + int head = bufferHead; + if (tail == 0) tail = bufferSize; - freespace = localTail - bufferHead - 1; - if (freespace < 0) freespace += bufferSize; - if (len > freespace) return ret; - - if (bufferHead >= localTail) + if (head < tail) { - // We have free rein to the end of the buffer - if (len < (bufferSize - bufferHead)) + // The free space is in one continuous chunk. + if (len < tail - head) { - // We won't reach the end of the buffer. - memcpy(outbuf + bufferHead, inbuf, len); + memcpy(outbuf + head, inbuf, len); bufferHead += len; - ret += len; return ret; - } else - { - // We'll reach the end of the buffer and loop round. - memcpy(outbuf + bufferHead, inbuf, (bufferSize - bufferHead)); - inbuf += (bufferSize - bufferHead); - ret += (bufferSize - bufferHead); - len -= (bufferSize - bufferHead); - bufferHead = 0; - if (len == 0) return ret; + ret = len; } } - - if (localTail - bufferHead == 1) return ret; // Full - - // We can advance the head up to the tail - // If we reach it, we are full. - if (len < (localTail - bufferHead - 1)) + else if (len <= bufferSize - head) { - // We'll fall short of the tail. - memcpy(outbuf + bufferHead, inbuf, len); - bufferHead += len; - ret += len; return ret; - } else + // There is enough space above the Head. + memcpy(outbuf + head, inbuf, len); + if (head + len == bufferSize) + bufferHead = 0; + else + bufferHead += len; + ret = len; + } + else if (len < tail) { - // We'll hit the tail. - memcpy(outbuf + bufferHead, inbuf, (localTail - bufferHead - 1)); - ret += (localTail - bufferHead - 1); - bufferHead = localTail - 1; - return ret; + bufferMark = head; + memcpy(outbuf, inbuf, len); + bufferHead = len; + ret = len; } + return ret; } - + int Stream::drain(int fd) { int ret = 0; - int localHead = bufferHead; + int head = bufferHead; + int tail = bufferTail; + int mark = bufferMark; int written; - if (localHead < bufferTail) + if (mark == -1 && tail > head) mark = bufferSize; + + if (mark >= 0) { - // Drain to the end of the buffer - written = write(fd, outbuf + bufferTail, (bufferSize - bufferTail)); + // Drain up to the marker. + written = write(fd, outbuf + tail, (mark - tail)); if (written < 0) return ret; ret += written; - if (written == (bufferSize - bufferTail)) - bufferTail = 0; + if (written == (mark - tail)) + { + bufferMark = -1; + bufferTail = tail = 0; + } else { bufferTail += written; @@ -127,11 +122,11 @@ int Stream::drain(int fd) } } - if (localHead == bufferTail) return ret; // Empty + if (tail == head) return ret; // Empty - written = write(fd, outbuf + bufferTail, (localHead - bufferTail)); + written = write(fd, outbuf + tail, (head - tail)); if (written < 0) return ret; ret += written; - bufferTail += written; + bufferTail = tail + written; return ret; } diff --git a/stream.h b/stream.h index 9abb7c3..cbe1c08 100644 --- a/stream.h +++ b/stream.h @@ -42,8 +42,9 @@ class Stream int initted; UCHAR* outbuf; int bufferSize; - int bufferHead; - int bufferTail; + volatile int bufferHead; + volatile int bufferTail; + volatile int bufferMark; }; #endif -- 2.39.2