Projekt

Obecné

Profil

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

    
3
import java.io.*;
4
import java.util.*;
5

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

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