Preliminary version of RFB Session Player converted from TightVNC Java
viewer sources.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2500 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/src/com/tightvnc/rfbplayer/FbsInputStream.java b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
new file mode 100644
index 0000000..fab854b
--- /dev/null
+++ b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
@@ -0,0 +1,174 @@
+//
+// Copyright (C) 2002 HorizonLive.com, Inc. All Rights Reserved.
+//
+// This is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This software 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 software; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+//
+
+//
+// FbsInputStream.java
+//
+
+import java.io.*;
+
+class FbsInputStream extends InputStream {
+
+ protected InputStream in;
+ protected long startTime;
+ protected long timeOffset;
+
+ protected byte[] buffer;
+ protected int bufferSize;
+ protected int bufferPos;
+
+ //
+ // Constructors.
+ //
+
+ FbsInputStream() throws IOException {
+ throw new IOException("FbsInputStream: no such constructor");
+ }
+
+ FbsInputStream(InputStream in) throws IOException
+ {
+ this.in = in;
+ startTime = System.currentTimeMillis();
+ timeOffset = 0;
+
+ byte[] b = new byte[12];
+ readFully(b);
+
+ if (b[0] != 'F' || b[1] != 'B' || b[2] != 'S' || b[3] != ' ' ||
+ b[4] != '0' || b[5] != '0' || b[6] != '1' || b[7] != '.' ||
+ b[8] < '0' || b[8] > '9' || b[9] < '0' || b[9] > '9' ||
+ b[10] < '0' || b[10] > '9' || b[11] != '\n') {
+ throw new IOException("Incorrect protocol version");
+ }
+
+ buffer = null;
+ bufferSize = 0;
+ bufferPos = 0;
+ }
+
+ //
+ // Basic methods overriding InputStream's methods.
+ //
+
+ public int read() throws IOException
+ {
+ while (bufferSize == 0) {
+ if (!fillBuffer())
+ return -1;
+ }
+ bufferSize--;
+ return buffer[bufferPos++] & 0xFF;
+ }
+
+ public int available() throws IOException
+ {
+ // FIXME: This will work incorrectly if our caller will wait until
+ // some amount of data is available when the buffer contains less
+ // data than then that. Current implementation never reads more
+ // data until the buffer is fully exhausted.
+ return bufferSize;
+ }
+
+ public void close() throws IOException
+ {
+ in.close();
+ in = null;
+ startTime = 0;
+ timeOffset = 0;
+
+ buffer = null;
+ bufferSize = 0;
+ bufferPos = 0;
+ }
+
+ //
+ // Methods providing additional functionality.
+ //
+
+ public void resumeReading()
+ {
+ startTime = System.currentTimeMillis() - timeOffset;
+ }
+
+ //
+ // Methods for internal use.
+ //
+
+ private boolean fillBuffer() throws IOException
+ {
+ bufferSize = (int)readUnsigned32();
+ if (bufferSize >= 0) {
+ int realSize = (bufferSize + 3) & 0xFFFFFFFC;
+ buffer = new byte[realSize];
+ readFully(buffer);
+ bufferPos = 0;
+
+ timeOffset = readUnsigned32();
+ }
+
+ if (bufferSize < 0 || timeOffset < 0) {
+ buffer = null;
+ bufferSize = 0;
+ bufferPos = 0;
+ return false;
+ }
+
+ while (true) {
+ long timeDiff = startTime + timeOffset - System.currentTimeMillis();
+ if (timeDiff <= 0) {
+ break;
+ }
+ try {
+ Thread.currentThread().sleep(timeDiff);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ return true;
+ }
+
+ private long readUnsigned32() throws IOException
+ {
+ byte[] buf = new byte[4];
+ if (!readFully(buf))
+ return -1;
+
+ return ((long)(buf[0] & 0xFF) << 24 |
+ (buf[1] & 0xFF) << 16 |
+ (buf[2] & 0xFF) << 8 |
+ (buf[3] & 0xFF));
+ }
+
+ private boolean readFully(byte[] b) throws IOException
+ {
+ int off = 0;
+ int len = b.length;
+
+ while (off != len) {
+ int count = in.read(b, off, len - off);
+ if (count < 0) {
+ return false;
+ }
+ off += count;
+ }
+
+ return true;
+ }
+}
+