root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / shp / LEDataInputStream.java @ 213
History | View | Annotate | Download (10.5 KB)
1 |
/*
|
---|---|
2 |
* LEDataInputStream.java
|
3 |
*
|
4 |
* Copyright (c) 1998
|
5 |
* Roedy Green
|
6 |
* Canadian Mind Products
|
7 |
* #208 - 525 Ninth Street
|
8 |
* New Westminster, BC Canada V3M 5T9
|
9 |
* tel: (604) 777-1804
|
10 |
* mailto:roedy@mindprod.com
|
11 |
* http://mindprod.com
|
12 |
*
|
13 |
*
|
14 |
* Version 1.0 1998 January 6
|
15 |
* 1.1 1998 January 7 - officially implements DataInput
|
16 |
* 1.2 1998 January 9 - add LERandomAccessFile
|
17 |
* 1.3 1998 August 27 - fix bug, readFully instead of read.
|
18 |
* 1.4 1998 November 10 - add address and phone.
|
19 |
* 1.5 1999 October 8 - use cmp.LEDataStream package name.
|
20 |
* 1.5.x 2000 Febuary 15 - Modifed by James Macgill to include LE/BE switch
|
21 |
*
|
22 |
* Very similar to DataInputStream except it reads little-endian instead of
|
23 |
* big-endian binary data.
|
24 |
* We can't extend DataInputStream directly since it has only final methods.
|
25 |
* This forces us implement LEDataInputStream with a DataInputStream object,
|
26 |
* and use wrapper methods.
|
27 |
*/
|
28 |
package com.iver.cit.gvsig.fmap.drivers.shp; |
29 |
|
30 |
import java.io.DataInput; |
31 |
import java.io.DataInputStream; |
32 |
import java.io.FileInputStream; |
33 |
import java.io.IOException; |
34 |
import java.io.InputStream; |
35 |
import java.nio.ByteOrder; |
36 |
import java.nio.MappedByteBuffer; |
37 |
import java.nio.channels.FileChannel; |
38 |
|
39 |
|
40 |
/**
|
41 |
* DOCUMENT ME!
|
42 |
*
|
43 |
* @author vcn
|
44 |
*/
|
45 |
public class LEDataInputStream implements DataInput { |
46 |
private static final String EmbeddedCopyright = "Copyright 1998 Roedy Green, Canadian Mind Products, http://mindprod.com"; |
47 |
|
48 |
// i n s t a n c e v a r i a b l e s
|
49 |
protected DataInputStream d; // to get at high level readFully methods of DataInputStream |
50 |
protected InputStream in; // to get at the low-level read methods of InputStream |
51 |
protected FileInputStream fin; |
52 |
byte[] w; // work array for buffering input |
53 |
protected MappedByteBuffer bb; |
54 |
protected boolean littleEndianMode = true; |
55 |
protected boolean m_useNIO; |
56 |
|
57 |
/**
|
58 |
* constructor
|
59 |
*
|
60 |
* @param in DOCUMENT ME!
|
61 |
*/
|
62 |
public LEDataInputStream(InputStream in) { |
63 |
this.in = in;
|
64 |
this.d = new DataInputStream(in); |
65 |
w = new byte[8]; |
66 |
m_useNIO = false;
|
67 |
} |
68 |
|
69 |
/**
|
70 |
* Creates a new LEDataInputStream object.
|
71 |
*
|
72 |
* @param fin DOCUMENT ME!
|
73 |
*/
|
74 |
public LEDataInputStream(FileInputStream fin) { |
75 |
/* this.in = fin;
|
76 |
this.d = new DataInputStream(fin);
|
77 |
w = new byte[8]; */
|
78 |
this.fin = fin;
|
79 |
|
80 |
FileChannel fc = fin.getChannel();
|
81 |
|
82 |
// Get the file's size and then map it into memory
|
83 |
try {
|
84 |
int sz = (int) fc.size(); |
85 |
bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz); |
86 |
m_useNIO = true;
|
87 |
} catch (IOException e) { |
88 |
System.out.println(e);
|
89 |
} |
90 |
} |
91 |
|
92 |
// L I T T L E E N D I A N R E A D E R S
|
93 |
// Little endian methods for multi-byte numeric types.
|
94 |
// Big-endian do fine for single-byte types and strings.
|
95 |
|
96 |
/**
|
97 |
* like DataInputStream.readShort except little endian.
|
98 |
*
|
99 |
* @return DOCUMENT ME!
|
100 |
*
|
101 |
* @throws IOException DOCUMENT ME!
|
102 |
*/
|
103 |
public final short readShort() throws IOException { |
104 |
if (m_useNIO) {
|
105 |
return bb.getShort();
|
106 |
} else {
|
107 |
if (!littleEndianMode) {
|
108 |
return d.readShort();
|
109 |
} |
110 |
|
111 |
d.readFully(w, 0, 2); |
112 |
|
113 |
return (short) (((w[1] & 0xff) << 8) | (w[0] & 0xff)); |
114 |
} |
115 |
} |
116 |
|
117 |
/**
|
118 |
* like DataInputStream.readUnsignedShort except little endian. Note,
|
119 |
* returns int even though it reads a short.
|
120 |
*
|
121 |
* @return DOCUMENT ME!
|
122 |
*
|
123 |
* @throws IOException DOCUMENT ME!
|
124 |
*/
|
125 |
public final int readUnsignedShort() throws IOException { |
126 |
if (m_useNIO) {
|
127 |
return bb.getShort();
|
128 |
} else {
|
129 |
if (!littleEndianMode) {
|
130 |
return d.readUnsignedShort();
|
131 |
} |
132 |
|
133 |
d.readFully(w, 0, 2); |
134 |
|
135 |
return (((w[1] & 0xff) << 8) | (w[0] & 0xff)); |
136 |
} |
137 |
} |
138 |
|
139 |
/**
|
140 |
* like DataInputStream.readChar except little endian.
|
141 |
*
|
142 |
* @return DOCUMENT ME!
|
143 |
*
|
144 |
* @throws IOException DOCUMENT ME!
|
145 |
*/
|
146 |
public final char readChar() throws IOException { |
147 |
if (m_useNIO) {
|
148 |
return bb.getChar();
|
149 |
} else {
|
150 |
if (!littleEndianMode) {
|
151 |
return d.readChar();
|
152 |
} |
153 |
|
154 |
d.readFully(w, 0, 2); |
155 |
|
156 |
return (char) (((w[1] & 0xff) << 8) | (w[0] & 0xff)); |
157 |
} |
158 |
} |
159 |
|
160 |
/**
|
161 |
* like DataInputStream.readInt except little endian.
|
162 |
*
|
163 |
* @return DOCUMENT ME!
|
164 |
*
|
165 |
* @throws IOException DOCUMENT ME!
|
166 |
*/
|
167 |
public final int readInt() throws IOException { |
168 |
if (m_useNIO) {
|
169 |
return bb.getInt();
|
170 |
} else {
|
171 |
if (!littleEndianMode) {
|
172 |
return d.readInt();
|
173 |
} |
174 |
|
175 |
d.readFully(w, 0, 4); |
176 |
|
177 |
return ((w[3]) << 24) | ((w[2] & 0xff) << 16) | |
178 |
((w[1] & 0xff) << 8) | (w[0] & 0xff); |
179 |
} |
180 |
} |
181 |
|
182 |
/**
|
183 |
* like DataInputStream.readLong except little endian.
|
184 |
*
|
185 |
* @return DOCUMENT ME!
|
186 |
*
|
187 |
* @throws IOException DOCUMENT ME!
|
188 |
*/
|
189 |
public final long readLong() throws IOException { |
190 |
if (m_useNIO) {
|
191 |
return bb.getLong();
|
192 |
} else {
|
193 |
if (!littleEndianMode) {
|
194 |
return d.readLong();
|
195 |
} |
196 |
|
197 |
d.readFully(w, 0, 8); |
198 |
|
199 |
return ((long) (w[7]) << 56) | /* long cast needed or shift done modulo 32 */ |
200 |
((long) (w[6] & 0xff) << 48) | ((long) (w[5] & 0xff) << 40) | |
201 |
((long) (w[4] & 0xff) << 32) | ((long) (w[3] & 0xff) << 24) | |
202 |
((long) (w[2] & 0xff) << 16) | ((long) (w[1] & 0xff) << 8) | |
203 |
(long) (w[0] & 0xff); |
204 |
} |
205 |
} |
206 |
|
207 |
/**
|
208 |
* like DataInputStream.readFloat except little endian.
|
209 |
*
|
210 |
* @return DOCUMENT ME!
|
211 |
*
|
212 |
* @throws IOException DOCUMENT ME!
|
213 |
*/
|
214 |
public final float readFloat() throws IOException { |
215 |
if (m_useNIO) {
|
216 |
return bb.getShort();
|
217 |
} else {
|
218 |
if (!littleEndianMode) {
|
219 |
return d.readFloat();
|
220 |
} |
221 |
|
222 |
return Float.intBitsToFloat(readInt()); |
223 |
} |
224 |
} |
225 |
|
226 |
/**
|
227 |
* like DataInputStream.readDouble except little endian.
|
228 |
*
|
229 |
* @return DOCUMENT ME!
|
230 |
*
|
231 |
* @throws IOException DOCUMENT ME!
|
232 |
*/
|
233 |
public final double readDouble() throws IOException { |
234 |
if (m_useNIO) {
|
235 |
return bb.getDouble();
|
236 |
} else {
|
237 |
if (!littleEndianMode) {
|
238 |
return d.readDouble();
|
239 |
} |
240 |
|
241 |
return Double.longBitsToDouble(readLong()); |
242 |
} |
243 |
} |
244 |
|
245 |
// p u r e l y w r a p p e r m e t h o d s
|
246 |
// We can't simply inherit since dataInputStream is final.
|
247 |
|
248 |
/* Watch out, may return fewer bytes than requested. */
|
249 |
public final int read(byte[] b, int off, int len) throws IOException { |
250 |
// For efficiency, we avoid one layer of wrapper
|
251 |
return in.read(b, off, len);
|
252 |
} |
253 |
|
254 |
/**
|
255 |
* DOCUMENT ME!
|
256 |
*
|
257 |
* @param b DOCUMENT ME!
|
258 |
*
|
259 |
* @throws IOException DOCUMENT ME!
|
260 |
*/
|
261 |
public final void readFully(byte[] b) throws IOException { |
262 |
d.readFully(b, 0, b.length);
|
263 |
} |
264 |
|
265 |
/**
|
266 |
* DOCUMENT ME!
|
267 |
*
|
268 |
* @param b DOCUMENT ME!
|
269 |
* @param off DOCUMENT ME!
|
270 |
* @param len DOCUMENT ME!
|
271 |
*
|
272 |
* @throws IOException DOCUMENT ME!
|
273 |
*/
|
274 |
public final void readFully(byte[] b, int off, int len) |
275 |
throws IOException { |
276 |
if (m_useNIO) {
|
277 |
bb.get(b, off, len); |
278 |
} else {
|
279 |
d.readFully(b, off, len); |
280 |
} |
281 |
} |
282 |
|
283 |
/**
|
284 |
* DOCUMENT ME!
|
285 |
*
|
286 |
* @param n DOCUMENT ME!
|
287 |
*
|
288 |
* @return DOCUMENT ME!
|
289 |
*
|
290 |
* @throws IOException DOCUMENT ME!
|
291 |
*/
|
292 |
public final int skipBytes(int n) throws IOException { |
293 |
if (m_useNIO) {
|
294 |
int pos = bb.position();
|
295 |
bb.position(pos + n); |
296 |
|
297 |
return bb.position();
|
298 |
} else {
|
299 |
return d.skipBytes(n);
|
300 |
} |
301 |
} |
302 |
|
303 |
/**
|
304 |
* DOCUMENT ME!
|
305 |
*
|
306 |
* @return DOCUMENT ME!
|
307 |
*
|
308 |
* @throws IOException DOCUMENT ME!
|
309 |
*/
|
310 |
public final int position() throws IOException { |
311 |
if (m_useNIO) {
|
312 |
return bb.position();
|
313 |
} else {
|
314 |
return 0; |
315 |
} |
316 |
} |
317 |
|
318 |
/* only reads one byte */
|
319 |
public final boolean readBoolean() throws IOException { |
320 |
return d.readBoolean();
|
321 |
} |
322 |
|
323 |
/**
|
324 |
* DOCUMENT ME!
|
325 |
*
|
326 |
* @return DOCUMENT ME!
|
327 |
*
|
328 |
* @throws IOException DOCUMENT ME!
|
329 |
*/
|
330 |
public final byte readByte() throws IOException { |
331 |
if (m_useNIO) {
|
332 |
return bb.get();
|
333 |
} else {
|
334 |
return d.readByte();
|
335 |
} |
336 |
} |
337 |
|
338 |
// note: returns an int, even though says Byte.
|
339 |
public final int readUnsignedByte() throws IOException { |
340 |
return d.readUnsignedByte();
|
341 |
} |
342 |
|
343 |
/**
|
344 |
* DOCUMENT ME!
|
345 |
*
|
346 |
* @return DOCUMENT ME!
|
347 |
*
|
348 |
* @throws IOException DOCUMENT ME!
|
349 |
*/
|
350 |
public final String readLine() throws IOException { |
351 |
return d.readLine();
|
352 |
} |
353 |
|
354 |
/**
|
355 |
* DOCUMENT ME!
|
356 |
*
|
357 |
* @return DOCUMENT ME!
|
358 |
*
|
359 |
* @throws IOException DOCUMENT ME!
|
360 |
*/
|
361 |
public final String readUTF() throws IOException { |
362 |
return d.readUTF();
|
363 |
} |
364 |
|
365 |
// Note. This is a STATIC method!
|
366 |
public final static String readUTF(DataInput in) throws IOException { |
367 |
return DataInputStream.readUTF(in); |
368 |
} |
369 |
|
370 |
/**
|
371 |
* DOCUMENT ME!
|
372 |
*
|
373 |
* @throws IOException DOCUMENT ME!
|
374 |
*/
|
375 |
public final void close() throws IOException { |
376 |
if (!m_useNIO) {
|
377 |
d.close(); |
378 |
} |
379 |
} |
380 |
|
381 |
/**
|
382 |
* DOCUMENT ME!
|
383 |
*
|
384 |
* @return DOCUMENT ME!
|
385 |
*/
|
386 |
public final int Size() { |
387 |
int x = 0; |
388 |
|
389 |
try {
|
390 |
if (m_useNIO) {
|
391 |
x = this.fin.available();
|
392 |
} else {
|
393 |
x = this.d.available();
|
394 |
} |
395 |
} catch (IOException e) { |
396 |
} |
397 |
|
398 |
return x;
|
399 |
} |
400 |
|
401 |
/**
|
402 |
* DOCUMENT ME!
|
403 |
*
|
404 |
* @param flag DOCUMENT ME!
|
405 |
*/
|
406 |
public final void setLittleEndianMode(boolean flag) { |
407 |
littleEndianMode = flag; |
408 |
|
409 |
if (m_useNIO) {
|
410 |
if (flag) {
|
411 |
bb.order(ByteOrder.LITTLE_ENDIAN);
|
412 |
} else {
|
413 |
bb.order(ByteOrder.BIG_ENDIAN);
|
414 |
} |
415 |
} |
416 |
} |
417 |
|
418 |
/**
|
419 |
* DOCUMENT ME!
|
420 |
*
|
421 |
* @return DOCUMENT ME!
|
422 |
*/
|
423 |
public final boolean getLittleEndianMode() { |
424 |
return littleEndianMode;
|
425 |
} |
426 |
|
427 |
/**
|
428 |
* DOCUMENT ME!
|
429 |
*
|
430 |
* @return DOCUMENT ME!
|
431 |
*/
|
432 |
public final boolean isLittleEndianMode() { |
433 |
return littleEndianMode;
|
434 |
} |
435 |
} |
436 |
// end class LEDataInputStream
|