Projekt

Obecné

Profil

Stáhnout (4.12 KB) Statistiky
| Větev: | Tag: | Revize:
1
package jdeserialize;
2

    
3
import java.io.*;
4

    
5
/**
6
 * <p>
7
 * An InputStream designed to record data passing through the stream after a call to
8
 * record() is made.  After record() is called, the results from every read will 
9
 * be stored in an * internal buffer.  The contents of the buffer can be 
10
 * retrieved by getRecordedData(); to stop recording and clear the internal 
11
 * buffer, call stopRecording().
12
 * </p>
13
 *
14
 * <p>
15
 * <b>Note</b>: calls to mark() and reset() are merely passed through to the inner stream; if
16
 * recording is active, the buffer won't be backtracked by reset().
17
 * </p>
18
 */
19
public class LoggerInputStream extends InputStream {
20
    private ByteArrayInputStream innerStream = null;
21
    private ByteArrayOutputStream baos = null;
22
    private boolean recording = false; 
23

    
24
    public LoggerInputStream(byte[] buffer) {
25
        super();
26
        this.innerStream = new ByteArrayInputStream(buffer);
27
    }
28
    public synchronized int read() throws IOException {
29
        int i = innerStream.read();
30
        if(recording && i != -1) {
31
            if(i > 255 || i < 0) {
32
                throw new IOException("non-byte, non--1 value read from inner stream: " + i);
33
            }
34
            baos.write((byte)i);
35
        }
36
        return i;
37
    }
38
    public synchronized int read(byte[] b) throws IOException {
39
        return this.read(b, 0, b.length);
40
    }
41
    public synchronized int read(byte[] b, int off, int len) throws IOException {
42
        int retval = innerStream.read(b, off, len);
43
        if(recording && retval > 0) {
44
            if(retval > len) {
45
                throw new IOException("inner stream read(byte[], int, int) violating contract; return value > len: " + retval);
46
            }
47
            baos.write(b, off, retval);
48
        }
49
        return retval;
50
    }
51
    public synchronized long skip(long n) throws IOException {
52
        if(n < 0) {
53
            throw new IOException("can't skip negative number of bytes");
54
        }
55
        if(recording == false) {
56
            return innerStream.skip(n);
57
        }
58
        long nskipped = 0;
59
        while(n > Integer.MAX_VALUE) {
60
            long ret = skip(Integer.MAX_VALUE);
61
            nskipped += ret;
62
            if(ret < Integer.MAX_VALUE) {
63
                return nskipped;
64
            }
65
            n -= ret;
66
        }
67
        int toread = (int)n, actuallyread = 0;
68
        byte[] buf = new byte[10240];
69
        while(toread > 0) {
70
            int r = Math.min(toread, buf.length);
71
            int rret = this.read(buf, 0, r);
72
            actuallyread += rret;
73
            toread -= rret;
74
            if(rret < r) {
75
                break;
76
            }
77
        }
78
        return actuallyread;
79
    }
80
    public synchronized int available() throws IOException {
81
        return innerStream.available();
82
    }
83
    public synchronized void close() throws IOException {
84
        innerStream.close();
85
    }
86
    public synchronized void mark(int readlimit) {
87
        innerStream.mark(readlimit);
88
    }
89
    public synchronized void reset() throws IOException {
90
        innerStream.reset();
91
    }
92
    public boolean markSupported() {
93
        return innerStream.markSupported();
94
    }
95
    /**
96
     * If not currently recording, start recording.  If the stream is currently recording,
97
     * the current buffer is cleared.
98
     */
99
    public synchronized void record() {
100
        recording = true;
101
        baos = new ByteArrayOutputStream();
102
    }
103
    /**
104
     * Stops recording and clears the internal buffer.  If recording is not active, an
105
     * IOException is thrown.
106
     *
107
     * @throws IOException if recording is not currently active
108
     */
109
    public synchronized void stopRecording() throws IOException {
110
        if(recording == false) {
111
            throw new IOException("recording not active");
112
        }
113
        try {
114
            baos.close();
115
        } catch (IOException ignore) {}
116
        baos = null;
117
        recording = false;
118
    }
119
    /**
120
     * Returns the data recorded so far; if recording is not active, an empty buffer
121
     * is returned.
122
     */
123
    public synchronized byte[] getRecordedData() {
124
        if(recording == false) {
125
            return new byte[0];
126
        }
127
        return baos.toByteArray();
128
    }
129
}
(3-3/20)