Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@591 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/win/rfbplayer/FbsInputStream.cxx b/win/rfbplayer/FbsInputStream.cxx
new file mode 100644
index 0000000..6381a16
--- /dev/null
+++ b/win/rfbplayer/FbsInputStream.cxx
@@ -0,0 +1,251 @@
+/* Copyright (C) 2004 TightVNC Team. 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 class
+
+#include <windows.h>
+
+#include <rfb/Exception.h>
+
+#include <rfbplayer/FbsInputStream.h>
+
+FbsInputStream::FbsInputStream(char* FileName) {
+ bufferSize = 0;
+ ptr = end = start = NULL;
+
+ timeOffset = 0;
+ seekOffset = -1;
+ startTime = GetTickCount();
+
+ playbackSpeed = 1.0;
+ seekBackwards = false;
+ paused = false;
+
+ interruptDelay = false;
+
+ fbsFile = fopen(FileName, "rb");
+ if (fbsFile == NULL) {
+ char *msg = new char[12 + sizeof(FileName)];
+ strcpy(msg, "Can't open ");
+ strcat(msg, FileName);
+ throw rfb::Exception(msg);
+ }
+
+ U8 b[12];
+ readNByte(b, 12);
+
+ 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 rfb::Exception("Incorrect protocol version");
+ }
+}
+
+FbsInputStream::~FbsInputStream() {
+ if (start != NULL)
+ delete [] start;
+ ptr = end = start = NULL;
+ fclose(fbsFile);
+}
+
+int FbsInputStream::pos() {
+ return ptr - start;
+}
+
+//
+// Close FbsInputStream and free data buffer
+//
+
+void FbsInputStream::close() {
+ fclose(fbsFile);
+
+ startTime = -1;
+ timeOffset = 0;
+ seekOffset = -1;
+ seekBackwards = false;
+ paused = false;
+ playbackSpeed = 1.0;
+
+ if (start != NULL)
+ delete [] start;
+ ptr = end = start = NULL;
+ bufferSize = 0;
+}
+
+//
+// Fill data buffer from the session file (InStream::overrun() override)
+//
+
+int FbsInputStream::overrun(int itemSize, int nItems, bool wait=true) {
+ // Just wait unless we are performing playback OR seeking.
+ waitWhilePaused();
+
+ // Perform backwardSeek (throws the special exception)
+ if (seekBackwards) {
+ throw rfb::Exception("[REWIND]");
+ }
+
+ // Save a tail of data
+ U8 *tmp;
+ int n = end - ptr;
+ if (n) {
+ tmp = new U8[n];
+ memmove(tmp, ptr, n);
+ }
+
+ bufferSize = (int)readUnsigned32();
+ if (bufferSize >= 0) {
+ if (start != NULL)
+ delete [] start;
+ int realSize = (bufferSize + 3) & 0xFFFFFFFC; // padding to multiple of 32-bits
+ ptr = start = new U8[realSize + n];
+ end = ptr + bufferSize + n;
+ if (n) {
+ memmove(start, tmp, n);
+ delete [] tmp;
+ }
+ readNByte(start + n, realSize);
+ timeOffset = (long)(readUnsigned32() / playbackSpeed);
+
+ if (itemSize * nItems > bufferSize)
+ nItems = bufferSize / itemSize;
+ }
+
+ if (bufferSize < 0 || timeOffset < 0) {
+ if (start != NULL)
+ delete [] start;
+ ptr = end = start = NULL;
+ bufferSize = 0;
+ return 0;
+ }
+
+ if (seekOffset >= 0) {
+ if (timeOffset >= seekOffset) {
+ startTime = GetTickCount() - seekOffset;
+ seekOffset = -1;
+ } else {
+ return nItems;
+ }
+ }
+
+ while (!interruptDelay) {
+ long timeDiff = startTime + timeOffset - GetTickCount();
+ if (timeDiff <= 0) {
+ break;
+ }
+ Sleep(min(20, timeDiff));
+ waitWhilePaused();
+ }
+ interruptDelay = false;
+
+ return nItems;
+}
+
+int FbsInputStream::readUnsigned32() {
+ U8 buf[4];
+ if (!readNByte(buf, 4))
+ return -1;
+
+ return ((long)(buf[0] & 0xFF) << 24 |
+ (buf[1] & 0xFF) << 16 |
+ (buf[2] & 0xFF) << 8 |
+ (buf[3] & 0xFF));
+}
+
+//
+// Read n-bytes from the session file
+//
+
+bool FbsInputStream::readNByte(U8 b[], int n) {
+ int off = 0;
+
+ while (off != n) {
+ int count = fread(b, 1, n - off, fbsFile);
+ if (count < n) {
+ if (ferror(fbsFile))
+ throw rfb::Exception("Read error from session file");
+ if (feof(fbsFile))
+ throw rfb::Exception("[End Of File]");
+ }
+ off += count;
+ }
+ return true;
+}
+
+void FbsInputStream::waitWhilePaused() {
+ while (paused && !isSeeking()) {
+ // A small delay helps to decrease the cpu usage
+ Sleep(20);
+ }
+}
+
+void FbsInputStream::interruptFrameDelay() {
+ interruptDelay = true;
+}
+
+//
+// Methods providing additional functionality.
+//
+
+long FbsInputStream::getTimeOffset() {
+ //long off = max(seekOffset, timeOffset);
+ return (long)(timeOffset * playbackSpeed);
+}
+
+void FbsInputStream::setTimeOffset(long pos) {
+ seekOffset = (long)(pos / playbackSpeed);
+ if (seekOffset < timeOffset) {
+ seekBackwards = true;
+ }
+}
+
+void FbsInputStream::setSpeed(double newSpeed) {
+ long newOffset = (long)(timeOffset * playbackSpeed / newSpeed);
+ startTime += timeOffset - newOffset;
+ timeOffset = newOffset;
+ if (isSeeking()) {
+ seekOffset = (long)(seekOffset * playbackSpeed / newSpeed);
+ }
+ playbackSpeed = newSpeed;
+}
+
+double FbsInputStream::getSpeed() {
+ return playbackSpeed;
+}
+
+bool FbsInputStream::isSeeking() {
+ return (seekOffset >= 0);
+}
+
+long FbsInputStream::getSeekOffset() {
+ return (long)(seekOffset * playbackSpeed);
+}
+
+bool FbsInputStream::isPaused() {
+ return paused;
+}
+
+void FbsInputStream::pausePlayback() {
+ paused = true;
+}
+
+void FbsInputStream::resumePlayback() {
+ paused = false;
+ startTime = GetTickCount() - timeOffset;
+}