summaryrefslogtreecommitdiffstats
path: root/src/lib/barrier/ClipboardChunk.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/barrier/ClipboardChunk.cpp
Import Upstream version 2.0.0+dfsgupstream/2.0.0+dfsg
Diffstat (limited to 'src/lib/barrier/ClipboardChunk.cpp')
-rw-r--r--src/lib/barrier/ClipboardChunk.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/lib/barrier/ClipboardChunk.cpp b/src/lib/barrier/ClipboardChunk.cpp
new file mode 100644
index 0000000..bc71471
--- /dev/null
+++ b/src/lib/barrier/ClipboardChunk.cpp
@@ -0,0 +1,154 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2015-2016 Symless Ltd.
+ *
+ * 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 "barrier/ClipboardChunk.h"
+
+#include "barrier/ProtocolUtil.h"
+#include "barrier/protocol_types.h"
+#include "io/IStream.h"
+#include "base/Log.h"
+#include <cstring>
+
+size_t ClipboardChunk::s_expectedSize = 0;
+
+ClipboardChunk::ClipboardChunk(size_t size) :
+ Chunk(size)
+{
+ m_dataSize = size - CLIPBOARD_CHUNK_META_SIZE;
+}
+
+ClipboardChunk*
+ClipboardChunk::start(
+ ClipboardID id,
+ UInt32 sequence,
+ const String& size)
+{
+ size_t sizeLength = size.size();
+ ClipboardChunk* start = new ClipboardChunk(sizeLength + CLIPBOARD_CHUNK_META_SIZE);
+ char* chunk = start->m_chunk;
+
+ chunk[0] = id;
+ std::memcpy (&chunk[1], &sequence, 4);
+ chunk[5] = kDataStart;
+ memcpy(&chunk[6], size.c_str(), sizeLength);
+ chunk[sizeLength + CLIPBOARD_CHUNK_META_SIZE - 1] = '\0';
+
+ return start;
+}
+
+ClipboardChunk*
+ClipboardChunk::data(
+ ClipboardID id,
+ UInt32 sequence,
+ const String& data)
+{
+ size_t dataSize = data.size();
+ ClipboardChunk* chunk = new ClipboardChunk(dataSize + CLIPBOARD_CHUNK_META_SIZE);
+ char* chunkData = chunk->m_chunk;
+
+ chunkData[0] = id;
+ std::memcpy (&chunkData[1], &sequence, 4);
+ chunkData[5] = kDataChunk;
+ memcpy(&chunkData[6], data.c_str(), dataSize);
+ chunkData[dataSize + CLIPBOARD_CHUNK_META_SIZE - 1] = '\0';
+
+ return chunk;
+}
+
+ClipboardChunk*
+ClipboardChunk::end(ClipboardID id, UInt32 sequence)
+{
+ ClipboardChunk* end = new ClipboardChunk(CLIPBOARD_CHUNK_META_SIZE);
+ char* chunk = end->m_chunk;
+
+ chunk[0] = id;
+ std::memcpy (&chunk[1], &sequence, 4);
+ chunk[5] = kDataEnd;
+ chunk[CLIPBOARD_CHUNK_META_SIZE - 1] = '\0';
+
+ return end;
+}
+
+int
+ClipboardChunk::assemble(barrier::IStream* stream,
+ String& dataCached,
+ ClipboardID& id,
+ UInt32& sequence)
+{
+ UInt8 mark;
+ String data;
+
+ if (!ProtocolUtil::readf(stream, kMsgDClipboard + 4, &id, &sequence, &mark, &data)) {
+ return kError;
+ }
+
+ if (mark == kDataStart) {
+ s_expectedSize = barrier::string::stringToSizeType(data);
+ LOG((CLOG_DEBUG "start receiving clipboard data"));
+ dataCached.clear();
+ return kStart;
+ }
+ else if (mark == kDataChunk) {
+ dataCached.append(data);
+ return kNotFinish;
+ }
+ else if (mark == kDataEnd) {
+ // validate
+ if (id >= kClipboardEnd) {
+ return kError;
+ }
+ else if (s_expectedSize != dataCached.size()) {
+ LOG((CLOG_ERR "corrupted clipboard data, expected size=%d actual size=%d", s_expectedSize, dataCached.size()));
+ return kError;
+ }
+ return kFinish;
+ }
+
+ LOG((CLOG_ERR "clipboard transmission failed: unknown error"));
+ return kError;
+}
+
+void
+ClipboardChunk::send(barrier::IStream* stream, void* data)
+{
+ ClipboardChunk* clipboardData = static_cast<ClipboardChunk*>(data);
+
+ LOG((CLOG_DEBUG1 "sending clipboard chunk"));
+
+ char* chunk = clipboardData->m_chunk;
+ ClipboardID id = chunk[0];
+ UInt32 sequence;
+ std::memcpy (&sequence, &chunk[1], 4);
+ UInt8 mark = chunk[5];
+ String dataChunk(&chunk[6], clipboardData->m_dataSize);
+
+ switch (mark) {
+ case kDataStart:
+ LOG((CLOG_DEBUG2 "sending clipboard chunk start: size=%s", dataChunk.c_str()));
+ break;
+
+ case kDataChunk:
+ LOG((CLOG_DEBUG2 "sending clipboard chunk data: size=%i", dataChunk.size()));
+ break;
+
+ case kDataEnd:
+ LOG((CLOG_DEBUG2 "sending clipboard finished"));
+ break;
+ }
+
+ ProtocolUtil::writef(stream, kMsgDClipboard, id, sequence, mark, &dataChunk);
+}