Statistics
| Revision:

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