Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/util/DataPipe.java @ 8451

Last change on this file since 8451 was 6152, checked in by bfarka, 14 years ago

added ecj and custom statistics to communicate with the okb services #1441

File size: 5.6 KB
Line 
1/*
2  Copyright 2009 by Sean Luke
3  Licensed under the Academic Free License version 3.0
4  See the file "LICENSE" for more information
5*/
6
7
8package ec.util;
9import java.io.*;
10
11/*
12  DataPipe is a mechanism which allows you to pipe data from an OutputStream to an InputStream within a single thread.
13  This differs from a PipedInputStream/PipedOutputSteam pair in that it permits a single thread (in fact requires it
14  due to lack of synchronization for speed).  To do this, the DataPipe maintains an extensible buffer which gets as large
15  as necessary when filled with data from the InputStream, then expels it out the OutputStream when called.  The
16  default Input and Output streams of a DataPipe are DataInputStream and DataOutputStream, since reading and writing
17  binary objects is its primary function.
18
19  <p>The procedure is as follows: create the DataPipe, then start writing to its DataInputStream.  When you are done,
20  start reading from its DataOutputStream. DataPipe is meant to be one-shot: write a bunch of stuff, then read <i>all</i> of it.
21  You shouldn't read and write piecemeal as the DataPipe is not a true circular buffer and will grow without bound with wasted
22  space equal to the amount you've read so far.
23
24  <p>You <i>can</i>, however, reuse the DataPipe by calling reset() on it. 
25  Note that this retains the current buffer however large it has grown to.
26*/
27
28public class DataPipe
29    {
30    // an extensible array which can be pushed into, then pulled out of
31    byte[] buffer = new byte[8192];
32
33    // the number of bytes in the array -- in reality this is the number of bytes written to the array so far
34    int size = 0;
35   
36    // the number of bytes read from the array.  pull will always trail size
37    int pull = 0;
38   
39    // Double the size of the buffer
40    void resize()
41        {
42        byte[] newbuffer = new byte[buffer.length * 2];
43        System.arraycopy(buffer, 0, newbuffer, 0, buffer.length);
44        buffer = newbuffer;
45        }
46   
47    // Add a byte to the buffer
48    void push(byte b)
49        {
50        if (size >= buffer.length) resize();
51        buffer[size++] = b;
52        }
53   
54    // Add bytes to the buffer, read from b[offset]... b[offset+length-1]
55    void push(byte[] b, int offset, int length)
56        {
57        if (size + length > buffer.length) resize();
58        System.arraycopy(b, offset, buffer, size, length);
59        size += length;
60        }
61       
62    // Return an unsigned byte read from the buffer.
63    // If there are no bytes left to read, -1 is returned.
64    int pull()
65        {
66        if (pull==size) return -1;  // EOF
67        byte b = buffer[pull++];
68        if (b < 0) return b + 256;
69        return b;
70        }
71   
72    // Provide up to *length* bytes from the buffer.  They are
73    // placed into b[offset] ... b[offset + length - 1].
74    // If there aren't *length* bytes in the buffer, some number
75    // less than that is actually provided.  The actual number
76    // of bytes provided is returned.
77    // If there are no bytes left to read at all, -1 is returned.
78    int pull(byte[] b, int offset, int length)
79        {
80        if (pull==size) return -1;
81        if (length > size-pull) length = size-pull;
82        System.arraycopy(buffer, pull, b, offset, length);
83        pull += length;
84        return length;
85        }
86   
87    /** The input stream */
88    public DataInputStream input;
89    /** The output stream */
90    public DataOutputStream output;
91   
92    public DataPipe()
93        {
94        OutputStream outStream = new OutputStream()
95            {
96            public void write(int b) throws IOException { push((byte)b); }
97            public void write(byte[] b, int off, int len) throws IOException { push(b, off, len); }
98            public void write(byte[] b) throws IOException { push(b, 0, b.length); }
99            };
100        output = new DataOutputStream(outStream);
101       
102        InputStream inStream = new InputStream()
103            {
104            public int read() throws IOException { return pull(); }
105            public int read(byte[] b, int off, int len) throws IOException { return pull(b, off, len); }
106            public int read(byte[] b) throws IOException { return pull(b, 0, b.length); }
107            };
108       
109        input = new DataInputStream(inStream);
110        }
111   
112    /** Reset the buffer.  Does not resize it back to a smaller size -- if it has ballooned it will
113        stay large, though it will no longer have wasted space in it.  If you wish to make the buffer
114        a more manageable size, create a new DataPipe instead. */
115    public void reset()
116        {
117        pull = size = 0;
118        }
119       
120    /** Returns the total size of the buffer. */
121    public int size()
122        {
123        return buffer.length;
124        }
125   
126    /** Returns the number of elements written to the buffer so far (after the last reset()). */
127    public int numWritten()
128        {
129        return size;
130        }
131       
132    /** Returns the number of elements read from the buffer so far (after the last reset()). */
133    public int numRead()
134        {
135        return pull;
136        }
137       
138    /** A poor-man's clone for serializable but not cloneable objects:
139        serializes an object to the pipe, then deserializes it. */
140    public static Object copy(Serializable obj) throws IOException, ClassNotFoundException
141        {
142        DataPipe pipe = new DataPipe();
143        ObjectOutputStream s = new ObjectOutputStream(pipe.output);
144        ObjectInputStream u = new ObjectInputStream(pipe.input);
145        s.writeObject(obj);
146        return u.readObject();
147        }
148
149    public String toString() { return "DataPipe(" + numWritten() + ", " + numRead() + ", " + size() + ")"; }
150    }
Note: See TracBrowser for help on using the repository browser.