aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/io/StreamBuffer.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
commit9b1b081cfdb1c0fb6457278775e0823f8bc10f62 (patch)
treece8840148d8445055ba9e4f12263b2208f234c16 /src/lib/io/StreamBuffer.cpp
Import Upstream version 2.0.0+dfsgupstream/2.0.0+dfsg
Diffstat (limited to 'src/lib/io/StreamBuffer.cpp')
-rw-r--r--src/lib/io/StreamBuffer.cpp146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/lib/io/StreamBuffer.cpp b/src/lib/io/StreamBuffer.cpp
new file mode 100644
index 0000000..61f05ba
--- /dev/null
+++ b/src/lib/io/StreamBuffer.cpp
@@ -0,0 +1,146 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2012-2016 Symless Ltd.
+ * Copyright (C) 2002 Chris Schoeneman
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "io/StreamBuffer.h"
+
+//
+// StreamBuffer
+//
+
+const UInt32 StreamBuffer::kChunkSize = 4096;
+
+StreamBuffer::StreamBuffer() :
+ m_size(0),
+ m_headUsed(0)
+{
+ // do nothing
+}
+
+StreamBuffer::~StreamBuffer()
+{
+ // do nothing
+}
+
+const void*
+StreamBuffer::peek(UInt32 n)
+{
+ assert(n <= m_size);
+
+ // if requesting no data then return NULL so we don't try to access
+ // an empty list.
+ if (n == 0) {
+ return NULL;
+ }
+
+ // reserve space in first chunk
+ ChunkList::iterator head = m_chunks.begin();
+ head->reserve(n + m_headUsed);
+
+ // consolidate chunks into the first chunk until it has n bytes
+ ChunkList::iterator scan = head;
+ ++scan;
+ while (head->size() - m_headUsed < n && scan != m_chunks.end()) {
+ head->insert(head->end(), scan->begin(), scan->end());
+ scan = m_chunks.erase(scan);
+ }
+
+ return static_cast<const void*>(&(head->begin()[m_headUsed]));
+}
+
+void
+StreamBuffer::pop(UInt32 n)
+{
+ // discard all chunks if n is greater than or equal to m_size
+ if (n >= m_size) {
+ m_size = 0;
+ m_headUsed = 0;
+ m_chunks.clear();
+ return;
+ }
+
+ // update size
+ m_size -= n;
+
+ // discard chunks until more than n bytes would've been discarded
+ ChunkList::iterator scan = m_chunks.begin();
+ assert(scan != m_chunks.end());
+ while (scan->size() - m_headUsed <= n) {
+ n -= (UInt32)scan->size() - m_headUsed;
+ m_headUsed = 0;
+ scan = m_chunks.erase(scan);
+ assert(scan != m_chunks.end());
+ }
+
+ // remove left over bytes from the head chunk
+ if (n > 0) {
+ m_headUsed += n;
+ }
+}
+
+void
+StreamBuffer::write(const void* vdata, UInt32 n)
+{
+ assert(vdata != NULL);
+
+ // ignore if no data, otherwise update size
+ if (n == 0) {
+ return;
+ }
+ m_size += n;
+
+ // cast data to bytes
+ const UInt8* data = static_cast<const UInt8*>(vdata);
+
+ // point to last chunk if it has space, otherwise append an empty chunk
+ ChunkList::iterator scan = m_chunks.end();
+ if (scan != m_chunks.begin()) {
+ --scan;
+ if (scan->size() >= kChunkSize) {
+ ++scan;
+ }
+ }
+ if (scan == m_chunks.end()) {
+ scan = m_chunks.insert(scan, Chunk());
+ }
+
+ // append data in chunks
+ while (n > 0) {
+ // choose number of bytes for next chunk
+ assert(scan->size() <= kChunkSize);
+ UInt32 count = kChunkSize - (UInt32)scan->size();
+ if (count > n)
+ count = n;
+
+ // transfer data
+ scan->insert(scan->end(), data, data + count);
+ n -= count;
+ data += count;
+
+ // append another empty chunk if we're not done yet
+ if (n > 0) {
+ ++scan;
+ scan = m_chunks.insert(scan, Chunk());
+ }
+ }
+}
+
+UInt32
+StreamBuffer::getSize() const
+{
+ return m_size;
+}