All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.browsermob.vnc.SessionRecorder Maven / Gradle / Ivy

The newest version!
package com.browsermob.vnc;

//
// BrowserMob VNC Enhancements (https://browsermob.com/tools)
// Copyright (c) 2011 Neustar, Inc. - All Rights Reserved.
//
// The BrowserMob Local Script Validation Service provides validation of JavaScript files used for Server Load Testing
//
// NEUSTAR, INC. MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. NEUSTAR, INC. SHALL NOT BE LIABLE
// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
//
//  Copyright (C) 2002 Constantin Kaplinsky.  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.
//

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * SessionRecorder is a class to write FBS (FrameBuffer Stream) files.
 * FBS files are used to save RFB sessions for later playback.
 */
class SessionRecorder {

    protected FileOutputStream f;
    protected DataOutputStream df;
    protected long startTime, lastTimeOffset;

    protected byte[] buffer;
    protected int bufferSize;
    protected int bufferBytes;

    public SessionRecorder(String name, int bufsize) throws IOException {
        f = new FileOutputStream(name);
        df = new DataOutputStream(f);
        startTime = System.currentTimeMillis();
        lastTimeOffset = 0;

        bufferSize = bufsize;
        bufferBytes = 0;
        buffer = new byte[bufferSize];
    }

    public SessionRecorder(String name) throws IOException {
        this(name, 65536);
    }

    /**
     * Close the file, free resources.
     */
    public void close() throws IOException {

        if (df != null) {
            try {
                flush();
            } catch (IOException e) {
            }

            try {
                df.close();
            } finally {
                df = null;
                assert(f != null);
                f.close();
                f = null;
            }
        } else {
          assert(f == null);
        }

        buffer = null;
    }

    //
    // Write the FBS file header as defined in the rfbproxy utility.
    //

    public void writeHeader() throws IOException {
        df.write("FBS 001.000\n".getBytes());
    }

    //
    // Write one byte.
    //

    public void writeByte(int b) throws IOException {
        prepareWriting();
        buffer[bufferBytes++] = (byte) b;
    }

    //
    // Write 16-bit value, big-endian.
    //

    public void writeShortBE(int v) throws IOException {
        prepareWriting();
        buffer[bufferBytes++] = (byte) (v >> 8);
        buffer[bufferBytes++] = (byte) v;
    }

    //
    // Write 32-bit value, big-endian.
    //

    public void writeIntBE(int v) throws IOException {
        prepareWriting();
        buffer[bufferBytes] = (byte) (v >> 24);
        buffer[bufferBytes + 1] = (byte) (v >> 16);
        buffer[bufferBytes + 2] = (byte) (v >> 8);
        buffer[bufferBytes + 3] = (byte) v;
        bufferBytes += 4;
    }

    //
    // Write 16-bit value, little-endian.
    //

    public void writeShortLE(int v) throws IOException {
        prepareWriting();
        buffer[bufferBytes++] = (byte) v;
        buffer[bufferBytes++] = (byte) (v >> 8);
    }

    //
    // Write 32-bit value, little-endian.
    //

    public void writeIntLE(int v) throws IOException {
        prepareWriting();
        buffer[bufferBytes] = (byte) v;
        buffer[bufferBytes + 1] = (byte) (v >> 8);
        buffer[bufferBytes + 2] = (byte) (v >> 16);
        buffer[bufferBytes + 3] = (byte) (v >> 24);
        bufferBytes += 4;
    }

    //
    // Write byte arrays.
    //

    public void write(byte b[], int off, int len) throws IOException {
        prepareWriting();
        while (len > 0) {
            if (bufferBytes > bufferSize - 4)
                flush(false);

            int partLen;
            if (bufferBytes + len > bufferSize) {
                partLen = bufferSize - bufferBytes;
            } else {
                partLen = len;
            }
            System.arraycopy(b, off, buffer, bufferBytes, partLen);
            bufferBytes += partLen;
            off += partLen;
            len -= partLen;
        }
    }

    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    //
    // Flush the output. This method saves buffered data in the
    // underlying file object adding data sizes and timestamps. If the
    // updateTimeOffset is set to false, then the current time offset
    // will not be changed for next write operation.
    //

    public void flush(boolean updateTimeOffset) throws IOException {
        if (bufferBytes > 0) {
            df.writeInt(bufferBytes);
            df.write(buffer, 0, (bufferBytes + 3) & 0x7FFFFFFC);
            df.writeInt((int) lastTimeOffset);
            bufferBytes = 0;
            if (updateTimeOffset)
                lastTimeOffset = -1;
        }
    }

    public void flush() throws IOException {
        flush(true);
    }

    //
    // Before writing any data, remember time offset and flush the
    // buffer before it becomes full.
    //

    protected void prepareWriting() throws IOException {
        if (lastTimeOffset == -1)
            lastTimeOffset = System.currentTimeMillis() - startTime;
        if (bufferBytes > bufferSize - 4)
            flush(false);
    }

    /**
     * finalize() implemented to assure proper cleanup
     * @exception Throwable under some unforseeable circumstance
     */
    @Override
    protected void finalize() throws Throwable {
        try {
            close();
        } catch (Throwable t) {
        } finally {
          try {
              super.finalize();
          } catch (Throwable t2) {}
        }
    }

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy