New stream - don't split frames at end of buffer
authorMark Calderbank <mark@vomp.tv>
Sun, 18 Sep 2005 18:50:31 +0000 (18:50 +0000)
committerMark Calderbank <mark@vomp.tv>
Sun, 18 Sep 2005 18:50:31 +0000 (18:50 +0000)
stream.cc
stream.h

index 00665d8f89b6aaaa8968ac6bbe74eaca1ca54aef..785b11d39b7b8425e7e3bba6a265f619e48b079d 100644 (file)
--- 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;
 }
index 9abb7c373ff5b94b439df0ee777c69a8495d5066..cbe1c082840c6a8ab4fe8599b120175d83cf67a4 100644 (file)
--- 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