/*
* noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin
- * Copyright (C) 2017 Samuel Mannehed for Cendio AB
+ * Copyright (C) 2018 Samuel Mannehed for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
buff[offset + 2] = 0; // padding
buff[offset + 3] = 0; // padding
- var n = text.length;
+ let length = text.length;
- buff[offset + 4] = n >> 24;
- buff[offset + 5] = n >> 16;
- buff[offset + 6] = n >> 8;
- buff[offset + 7] = n;
+ buff[offset + 4] = length >> 24;
+ buff[offset + 5] = length >> 16;
+ buff[offset + 6] = length >> 8;
+ buff[offset + 7] = length;
- for (var i = 0; i < n; i++) {
- buff[offset + 8 + i] = text.charCodeAt(i);
- }
+ sock._sQlen += 8;
- sock._sQlen += 8 + n;
- sock.flush();
+ // We have to keep track of from where in the text we begin creating the
+ // buffer for the flush in the next iteration.
+ let textOffset = 0;
+
+ let remaining = length;
+ while (remaining > 0) {
+
+ let flushSize = Math.min(remaining, (sock._sQbufferSize - sock._sQlen));
+ if (flushSize <= 0) {
+ this._fail("Clipboard contents could not be sent");
+ break;
+ }
+
+ offset = sock._sQlen;
+
+ for (let i = 0; i < flushSize; i++) {
+ buff[offset + i] = text.charCodeAt(textOffset + i);
+ }
+
+ sock._sQlen += flushSize;
+ sock.flush();
+
+ remaining -= flushSize;
+ textOffset += flushSize;
+ }
},
setDesktopSize: function (sock, width, height, id, flags) {
describe('#clipboardPasteFrom', function () {
it('should send the given text in a paste event', function () {
- var expected = {_sQ: new Uint8Array(11), _sQlen: 0, flush: function () {}};
+ var expected = {_sQ: new Uint8Array(11), _sQlen: 0,
+ _sQbufferSize: 11, flush: function () {}};
RFB.messages.clientCutText(expected, 'abc');
client.clipboardPasteFrom('abc');
expect(client._sock).to.have.sent(expected._sQ);
});
+ it('should flush multiple times for large clipboards', function () {
+ sinon.spy(client._sock, 'flush');
+ let long_text = "";
+ for (let i = 0; i < client._sock._sQbufferSize + 100; i++) {
+ long_text += 'a';
+ }
+ client.clipboardPasteFrom(long_text);
+ expect(client._sock.flush).to.have.been.calledTwice;
+ });
+
it('should not send the text if we are not in a normal state', function () {
sinon.spy(client._sock, 'flush');
client._rfb_connection_state = "connecting";