2 // Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved.
4 // This is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This software is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this software; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // SessionRecorder is a class to write FBS (FrameBuffer Stream) files.
22 // FBS files are used to save RFB sessions for later playback.
27 class SessionRecorder {
29 protected FileOutputStream f;
30 protected DataOutputStream df;
31 protected long startTime, lastTimeOffset;
33 protected byte[] buffer;
34 protected int bufferSize;
35 protected int bufferBytes;
37 public SessionRecorder(String name, int bufsize) throws IOException {
38 f = new FileOutputStream(name);
39 df = new DataOutputStream(f);
40 startTime = System.currentTimeMillis();
45 buffer = new byte[bufferSize];
48 public SessionRecorder(String name) throws IOException {
53 // Close the file, free resources.
56 public void close() throws IOException {
59 } catch (IOException e) {
69 // Write the FBS file header as defined in the rfbproxy utility.
72 public void writeHeader() throws IOException {
73 df.write("FBS 001.000\n".getBytes());
80 public void writeByte(int b) throws IOException {
82 buffer[bufferBytes++] = (byte)b;
86 // Write 16-bit value, big-endian.
89 public void writeShortBE(int v) throws IOException {
91 buffer[bufferBytes++] = (byte)(v >> 8);
92 buffer[bufferBytes++] = (byte)v;
96 // Write 32-bit value, big-endian.
99 public void writeIntBE(int v) throws IOException {
101 buffer[bufferBytes] = (byte)(v >> 24);
102 buffer[bufferBytes + 1] = (byte)(v >> 16);
103 buffer[bufferBytes + 2] = (byte)(v >> 8);
104 buffer[bufferBytes + 3] = (byte)v;
109 // Write 16-bit value, little-endian.
112 public void writeShortLE(int v) throws IOException {
114 buffer[bufferBytes++] = (byte)v;
115 buffer[bufferBytes++] = (byte)(v >> 8);
119 // Write 32-bit value, little-endian.
122 public void writeIntLE(int v) throws IOException {
124 buffer[bufferBytes] = (byte)v;
125 buffer[bufferBytes + 1] = (byte)(v >> 8);
126 buffer[bufferBytes + 2] = (byte)(v >> 16);
127 buffer[bufferBytes + 3] = (byte)(v >> 24);
132 // Write byte arrays.
135 public void write(byte b[], int off, int len) throws IOException {
138 if (bufferBytes > bufferSize - 4)
142 if (bufferBytes + len > bufferSize) {
143 partLen = bufferSize - bufferBytes;
147 System.arraycopy(b, off, buffer, bufferBytes, partLen);
148 bufferBytes += partLen;
154 public void write(byte b[]) throws IOException {
155 write(b, 0, b.length);
159 // Flush the output. This method saves buffered data in the
160 // underlying file object adding data sizes and timestamps. If the
161 // updateTimeOffset is set to false, then the current time offset
162 // will not be changed for next write operation.
165 public void flush(boolean updateTimeOffset) throws IOException {
166 if (bufferBytes > 0) {
167 df.writeInt(bufferBytes);
168 df.write(buffer, 0, (bufferBytes + 3) & 0x7FFFFFFC);
169 df.writeInt((int)lastTimeOffset);
171 if (updateTimeOffset)
176 public void flush() throws IOException {
181 // Before writing any data, remember time offset and flush the
182 // buffer before it becomes full.
185 protected void prepareWriting() throws IOException {
186 if (lastTimeOffset == -1)
187 lastTimeOffset = System.currentTimeMillis() - startTime;
188 if (bufferBytes > bufferSize - 4)