KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > jdbc > UTF8Reader


1 /*
2
3    Derby - Class org.apache.derby.impl.jdbc.UTF8Reader
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.jdbc;
23
24 import java.io.InputStream JavaDoc;
25 import java.io.Reader JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.UTFDataFormatException JavaDoc;
28 import java.io.EOFException JavaDoc;
29 import java.sql.SQLException JavaDoc;
30
31 /**
32 */

33 public final class UTF8Reader extends Reader JavaDoc
34 {
35
36     private InputStream JavaDoc in;
37     private final long utfLen; // bytes
38
private long utfCount; // bytes
39
private long readerCharCount; // characters
40
private long maxFieldSize; // characeters
41

42     private char[] buffer = new char[8 * 1024];
43     private int charactersInBuffer; // within buffer
44
private int readPositionInBuffer;
45
46     private boolean noMoreReads;
47
48     // maintain a reference to the parent object so that it can't get
49
// garbage collected until we are done with the stream.
50
private ConnectionChild parent;
51
52     public UTF8Reader(
53     InputStream JavaDoc in,
54     long maxFieldSize,
55     ConnectionChild parent,
56     Object JavaDoc synchronization)
57         throws IOException JavaDoc
58     {
59         super(synchronization);
60
61         this.in = in;
62         this.maxFieldSize = maxFieldSize;
63         this.parent = parent;
64
65         synchronized (lock) {
66             this.utfLen = readUnsignedShort();
67         }
68     }
69
70     /*
71     ** Reader implemention.
72     */

73     public int read() throws IOException JavaDoc
74     {
75         synchronized (lock) {
76
77             // check if closed..
78
if (noMoreReads)
79                 throw new IOException JavaDoc();
80
81             if (readPositionInBuffer >= charactersInBuffer) {
82                 if (fillBuffer()) {
83                     return -1;
84                 }
85                 readPositionInBuffer = 0;
86             }
87
88             return buffer[readPositionInBuffer++];
89         }
90     }
91
92     public int read(char[] cbuf, int off, int len) throws IOException JavaDoc
93     {
94         synchronized (lock) {
95             // check if closed..
96
if (noMoreReads)
97                 throw new IOException JavaDoc();
98
99             if (readPositionInBuffer >= charactersInBuffer) {
100                 if (fillBuffer()) {
101                     return -1;
102                 }
103                 readPositionInBuffer = 0;
104             }
105
106             int remainingInBuffer = charactersInBuffer - readPositionInBuffer;
107
108             if (len > remainingInBuffer)
109                 len = remainingInBuffer;
110
111             System.arraycopy(buffer, readPositionInBuffer, cbuf, off, len);
112             readPositionInBuffer += len;
113
114             return len;
115         }
116     }
117
118     public long skip(long len) throws IOException JavaDoc {
119         synchronized (lock) {
120             // check if closed..
121
if (noMoreReads)
122                 throw new IOException JavaDoc();
123
124             if (readPositionInBuffer >= charactersInBuffer) {
125                 // do somthing
126
if (fillBuffer()) {
127                     return -1;
128                 }
129                 readPositionInBuffer = 0;
130             }
131
132             int remainingInBuffer = charactersInBuffer - readPositionInBuffer;
133
134             if (len > remainingInBuffer)
135                 len = remainingInBuffer;
136
137             readPositionInBuffer += len;
138
139             return len;
140         }
141
142     }
143
144     public void close()
145     {
146         synchronized (lock) {
147             closeIn();
148             parent = null;
149             noMoreReads = true;
150         }
151     }
152
153     /*
154     ** Methods just for Cloudscape's JDBC driver
155     */

156
157     public int readInto(StringBuffer JavaDoc sb, int len) throws IOException JavaDoc {
158
159         synchronized (lock) {
160             if (readPositionInBuffer >= charactersInBuffer) {
161                 if (fillBuffer()) {
162                     return -1;
163                 }
164                 readPositionInBuffer = 0;
165             }
166
167             int remainingInBuffer = charactersInBuffer - readPositionInBuffer;
168
169             if (len > remainingInBuffer)
170                 len = remainingInBuffer;
171             sb.append(buffer, readPositionInBuffer, len);
172
173             readPositionInBuffer += len;
174
175             return len;
176         }
177     }
178     int readAsciiInto(byte[] abuf, int off, int len) throws IOException JavaDoc {
179
180         synchronized (lock) {
181             if (readPositionInBuffer >= charactersInBuffer) {
182                 if (fillBuffer()) {
183                     return -1;
184                 }
185                 readPositionInBuffer = 0;
186             }
187
188             int remainingInBuffer = charactersInBuffer - readPositionInBuffer;
189
190             if (len > remainingInBuffer)
191                 len = remainingInBuffer;
192
193             char[] lbuffer = buffer;
194             for (int i = 0; i < len; i++) {
195                 char c = lbuffer[readPositionInBuffer + i];
196                 byte cb;
197                 if (c <= 255)
198                     cb = (byte) c;
199                 else
200                     cb = (byte) '?'; // Question mark - out of range character.
201

202                 abuf[off + i] = cb;
203             }
204
205             readPositionInBuffer += len;
206
207             return len;
208         }
209     }
210
211     /*
212     ** internal implementation
213     */

214
215
216     private void closeIn() {
217         if (in != null) {
218             try {
219                 in.close();
220             } catch (IOException JavaDoc ioe) {
221             } finally {
222                 in = null;
223             }
224         }
225     }
226     private IOException JavaDoc utfFormatException(String JavaDoc s) {
227         noMoreReads = true;
228         closeIn();
229         return new UTFDataFormatException JavaDoc(s);
230     }
231
232     private IOException JavaDoc utfFormatException() {
233         noMoreReads = true;
234         closeIn();
235         return new UTFDataFormatException JavaDoc();
236     }
237
238     /**
239         Fill the buffer, return true if eof has been reached.
240     */

241     private boolean fillBuffer() throws IOException JavaDoc
242     {
243         if (in == null)
244             return true;
245
246         charactersInBuffer = 0;
247
248         try {
249         try {
250         
251             parent.setupContextStack();
252
253 readChars:
254         while (
255                 (charactersInBuffer < buffer.length) &&
256                 ((utfCount < utfLen) || (utfLen == 0)) &&
257                 ((maxFieldSize == 0) || (readerCharCount < maxFieldSize))
258               )
259         {
260             int c = in.read();
261             if (c == -1) {
262                 if (utfLen == 0) {
263                     closeIn();
264                     break readChars;
265                 }
266                 throw utfFormatException();
267             }
268
269             int finalChar;
270             switch (c >> 4) {
271                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
272                     // 0xxxxxxx
273
utfCount++;
274                     finalChar = c;
275                     break;
276
277                 case 12: case 13:
278                     {
279                     // 110x xxxx 10xx xxxx
280
utfCount += 2;
281                     int char2 = in.read();
282                     if (char2 == -1)
283                         throw utfFormatException();
284
285                     if ((char2 & 0xC0) != 0x80)
286                         throw utfFormatException();
287                     finalChar = (((c & 0x1F) << 6) | (char2 & 0x3F));
288                     break;
289                     }
290
291                 case 14:
292                     {
293                     // 1110 xxxx 10xx xxxx 10xx xxxx
294
utfCount += 3;
295                     int char2 = in.read();
296                     int char3 = in.read();
297                     if (char2 == -1 || char3 == -1)
298                         throw utfFormatException();
299
300                     if ((c == 0xE0) && (char2 == 0) && (char3 == 0))
301                     {
302                         if (utfLen == 0) {
303                             // we reached the end of a long string,
304
// that was terminated with
305
// (11100000, 00000000, 00000000)
306
closeIn();
307                             break readChars;
308                         }
309                         throw utfFormatException();
310                     }
311
312                     if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
313                         throw utfFormatException();
314
315                     finalChar = (((c & 0x0F) << 12) |
316                                ((char2 & 0x3F) << 6) |
317                                ((char3 & 0x3F) << 0));
318                     }
319                     break;
320
321                 default:
322                     // 10xx xxxx, 1111 xxxx
323
throw utfFormatException();
324             }
325
326             buffer[charactersInBuffer++] = (char) finalChar;
327             readerCharCount++;
328         }
329         if (utfLen != 0 && utfCount > utfLen)
330             throw utfFormatException("utfCount " + utfCount + " utfLen " + utfLen);
331
332         if (charactersInBuffer != 0)
333             return false;
334
335         closeIn();
336         return true;
337         } finally {
338             parent.restoreContextStack();
339         }
340         } catch (SQLException JavaDoc sqle) {
341             throw new IOException JavaDoc(sqle.getSQLState() + ":" + sqle.getMessage());
342         }
343     }
344
345
346     // this method came from java.io.DataInputStream
347
private final int readUnsignedShort() throws IOException JavaDoc {
348         int ch1 = in.read();
349         int ch2 = in.read();
350         if ((ch1 | ch2) < 0)
351             throw new EOFException JavaDoc();
352
353         return (ch1 << 8) + (ch2 << 0);
354     }
355 }
356
Popular Tags