1 /************************************************************
2 * Copyright *
3 * Portions of this software are Copyright (c) 1993 - 2002, *
4 * Chad Z. Hower (Kudzu) and the Indy Pit Crew *
5 * - http://www.nevrona.com/Indy/ *
6 ************************************************************/
7 package org.indy.util;
8
9 import java.io.ByteArrayInputStream;
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12
13
14 /***
15 * A light weight read-write buffer used by Indy.
16 *
17 * NOTE: This class is not thread-safe; if you wish to use
18 * this IdBuffer in a multi-threaded environment you must
19 * provide your own synchronization.
20 *
21 *@author OTG
22 *@version 1.0
23 */
24 public class IndyBuffer extends ByteArrayOutputStream {
25 private OpenByteArrayInputStream reader = new OpenByteArrayInputStream(buf, 0,
26 buf.length);
27
28 /***
29 * Checks whether reader's buffer is in sync with writer's,
30 * and refreshes if neccessary.
31 */
32 protected void readerIsDirty() {
33 //could be that the whole buffer reference has changed,
34 //or just that the count needs updating
35 if (reader.getBufLength() != buf.length) {
36 //something of a hack
37 reader = new OpenByteArrayInputStream(buf, reader.getPos(),
38 count - reader.getPos());
39 }
40 else if (count != reader.getCount()) {
41 reader.setCount(count);
42 }
43 }
44
45 /***
46 * Clears the buffer
47 */
48 public void clear() {
49 reset();
50 reader.reset();
51 }
52
53 /***
54 * Returns some data from the buffer non-destructively
55 * (i.e. doesn't remove it).
56 *
57 *@param b An array of bytes to read into
58 *@param off The offset to start filling <code>b</code> at
59 *@param len The number of bytes to read
60 *@throws IndexOutOfBoundsException If off or len are invalid
61 *@see #read(byte[],int,int)
62 */
63 public void peek(byte[] b, int off, int len) {
64 if ((off < 0) || (off > count) || (len < 0) || ((off + len) > count) ||
65 ((off + len) < 0)) {
66 throw new IndexOutOfBoundsException();
67 }
68
69 System.arraycopy(buf, off, b, 0, len);
70 }
71
72 /***
73 * Reads some bytes from the buffer.
74 *
75 *@param b An array of bytes to read into.
76 *@param off The offset to start filling <code>b</code> at
77 *@param len The number of bytes to read
78 *@see #peek(byte[],int,int)
79 */
80 public void read(byte[] b, int off, int len) {
81 readerIsDirty();
82
83
84 /*** @todo Bounds checking here */
85 reader.read(b, off, len);
86 }
87
88 /***
89 * Attempts to read a line of text from the buffer. See
90 * the general contract of {@Link OpenByteArryInputStream#readLine()}.
91 *
92 *@return A line of text from the buffer, or null if no line is found.
93 *@throws IOException If an IO error occurrs.
94 */
95 public String readLine() throws IOException {
96 readerIsDirty();
97
98 return reader.readLine();
99 }
100
101 /***
102 * Returns the current number of bytes in the buffer.
103 *
104 * @return The current size of the buffer in bytes.
105 */
106 public int size() {
107 readerIsDirty();
108
109 return count - reader.getPos();
110 }
111
112 /***
113 * A ByteArrayInputStream that exposes it's current
114 * position so it can be synced with the overall buffer.
115 *
116 *@author OTG
117 */
118 private class OpenByteArrayInputStream extends ByteArrayInputStream {
119 /***
120 * Constructs a new instance.
121 *
122 *@param b The buffer to use.
123 *@param offset The offset at which to start reads.
124 *@param len The length of the buffer.
125 */
126 public OpenByteArrayInputStream(byte[] b, int offset, int len) {
127 super(b, offset, len);
128 }
129
130 private void setCount(int newCount) {
131 super.count = newCount;
132 }
133
134 /***
135 * Gets the current read position
136 *
137 *@return The read position of the buffer.
138 */
139 public int getPos() {
140 return this.pos;
141 }
142
143 /***
144 * Gets the current length of the buffer array.
145 *
146 *@return The length of the buffer array.
147 */
148 public int getBufLength() {
149 return super.buf.length;
150
151 //make *positive* we're getting the right one!
152 }
153
154 /***
155 * Gets the current amount of buffered data.
156 *
157 *@return The amount of buffered data in bytes.
158 */
159 public int getCount() {
160 return super.count;
161 }
162
163 byte[] peek() {
164 byte[] res = new byte[this.count];
165
166 System.arraycopy(super.buf, 0, res, 0, this.count);
167
168 return res;
169 }
170
171 /***
172 * Reads a line of character data from the buffer.
173 * This, unlike java.io.BufferedReader will return
174 * null if there is data, but no EOL.
175 *
176 * It allows any combination of LF and CR.
177 *
178 *@return A line of text, or NULL if no EOL is present.
179 *@throws IOException If an IO error occurs.
180 */
181 public String readLine() throws IOException {
182 byte[] b = new byte[count - pos];
183
184 System.arraycopy(buf, pos, b, 0, count - pos);
185
186 String s = new String(b);
187 char[] c = s.toCharArray();
188
189 boolean pairedBreak = false;
190 int cpos = 0;
191
192 for (int i = 0; i < c.length; i++) {
193 if ((c[i] == '\n') || (c[i] == '\r')) {
194 cpos = i;
195
196 if ((i + 1) < c.length) {
197 if ((c[i + 1] == '\n') || (c[i + 1] == '\r')) {
198 pairedBreak = true;
199 }
200 }
201
202 break;
203 }
204 }
205
206 String res = null;
207
208 if (cpos > 0) {
209 pos += (s.substring(0, cpos).getBytes().length + 1);
210 res = s.substring(0, cpos);
211 }
212
213 //get rid of the feed chars
214 if (pairedBreak) {
215 pos++;
216 }
217
218 return res;
219 }
220 }
221 }
This page was automatically generated by Maven