source: trunk/packages/sipb-xen-vnc-client/code/SessionRecorder.java @ 968

Last change on this file since 968 was 66, checked in by quentin, 17 years ago

Initial checkin of modified Java VNC viewer for use as remote console

File size: 4.6 KB
Line 
1//
2//  Copyright (C) 2002 Constantin Kaplinsky.  All Rights Reserved.
3//
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.
8//
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.
13//
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,
17//  USA.
18//
19
20//
21// SessionRecorder is a class to write FBS (FrameBuffer Stream) files.
22// FBS files are used to save RFB sessions for later playback.
23//
24
25import java.io.*;
26
27class SessionRecorder {
28
29  protected FileOutputStream f;
30  protected DataOutputStream df;
31  protected long startTime, lastTimeOffset;
32
33  protected byte[] buffer;
34  protected int bufferSize;
35  protected int bufferBytes;
36
37  public SessionRecorder(String name, int bufsize) throws IOException {
38    f = new FileOutputStream(name);
39    df = new DataOutputStream(f);
40    startTime = System.currentTimeMillis();
41    lastTimeOffset = 0;
42   
43    bufferSize = bufsize;
44    bufferBytes = 0;
45    buffer = new byte[bufferSize];
46  }
47
48  public SessionRecorder(String name) throws IOException {
49    this(name, 65536);
50  }
51
52  //
53  // Close the file, free resources.
54  //
55
56  public void close() throws IOException {
57    try {
58      flush();
59    } catch (IOException e) {
60    }
61
62    df = null;
63    f.close();
64    f = null;
65    buffer = null;
66  }
67
68  //
69  // Write the FBS file header as defined in the rfbproxy utility.
70  //
71
72  public void writeHeader() throws IOException {
73    df.write("FBS 001.000\n".getBytes());
74  }
75
76  //
77  // Write one byte.
78  //
79
80  public void writeByte(int b) throws IOException {
81    prepareWriting();
82    buffer[bufferBytes++] = (byte)b;
83  }
84
85  //
86  // Write 16-bit value, big-endian.
87  //
88
89  public void writeShortBE(int v) throws IOException {
90    prepareWriting();
91    buffer[bufferBytes++] = (byte)(v >> 8);
92    buffer[bufferBytes++] = (byte)v;
93  }
94
95  //
96  // Write 32-bit value, big-endian.
97  //
98
99  public void writeIntBE(int v) throws IOException {
100    prepareWriting();
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;
105    bufferBytes += 4;
106  }
107
108  //
109  // Write 16-bit value, little-endian.
110  //
111
112  public void writeShortLE(int v) throws IOException {
113    prepareWriting();
114    buffer[bufferBytes++] = (byte)v;
115    buffer[bufferBytes++] = (byte)(v >> 8);
116  }
117
118  //
119  // Write 32-bit value, little-endian.
120  //
121
122  public void writeIntLE(int v) throws IOException {
123    prepareWriting();
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);
128    bufferBytes += 4;
129  }
130
131  //
132  // Write byte arrays.
133  //
134
135  public void write(byte b[], int off, int len) throws IOException {
136    prepareWriting();
137    while (len > 0) {
138      if (bufferBytes > bufferSize - 4)
139        flush(false);
140
141      int partLen;
142      if (bufferBytes + len > bufferSize) {
143        partLen = bufferSize - bufferBytes;
144      } else {
145        partLen = len;
146      }
147      System.arraycopy(b, off, buffer, bufferBytes, partLen);
148      bufferBytes += partLen;
149      off += partLen;
150      len -= partLen;
151    }
152  }
153
154  public void write(byte b[]) throws IOException {
155    write(b, 0, b.length);
156  }
157
158  //
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.
163  //
164
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);
170      bufferBytes = 0;
171      if (updateTimeOffset)
172        lastTimeOffset = -1;
173    }
174  }
175
176  public void flush() throws IOException {
177    flush(true);
178  }
179
180  //
181  // Before writing any data, remember time offset and flush the
182  // buffer before it becomes full.
183  //
184
185  protected void prepareWriting() throws IOException {
186    if (lastTimeOffset == -1)
187      lastTimeOffset = System.currentTimeMillis() - startTime;
188    if (bufferBytes > bufferSize - 4)
189      flush(false);
190  }
191
192}
193
Note: See TracBrowser for help on using the repository browser.