001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2002, Centre for Computational Geography
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.data.shapefile.prj;
018:
019: import java.io.IOException;
020: import java.nio.ByteBuffer;
021: import java.nio.ByteOrder;
022: import java.nio.CharBuffer;
023: import java.nio.MappedByteBuffer;
024: import java.nio.channels.FileChannel;
025: import java.nio.channels.ReadableByteChannel;
026: import java.nio.charset.Charset;
027: import java.nio.charset.CharsetDecoder;
028:
029: import org.geotools.data.shapefile.StreamLogging;
030: import org.geotools.referencing.ReferencingFactoryFinder;
031: import org.geotools.resources.NIOUtilities;
032: import org.opengis.referencing.FactoryException;
033:
034: /**
035: *
036: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/prj/PrjFileReader.java $
037: */
038: public class PrjFileReader {
039:
040: ByteBuffer buffer;
041: ReadableByteChannel channel;
042: CharBuffer charBuffer;
043: CharsetDecoder decoder;
044: StreamLogging streamLogger = new StreamLogging("PRJ reader");
045:
046: org.opengis.referencing.crs.CoordinateReferenceSystem cs;
047:
048: //private int[] content;
049:
050: /** Load the index file from the given channel.
051: * @param channel The channel to read from.
052: * @throws IOException If an error occurs.
053: */
054: public PrjFileReader(ReadableByteChannel channel)
055: throws IOException, FactoryException {
056: Charset chars = Charset.forName("ISO-8859-1");
057: decoder = chars.newDecoder();
058: this .channel = channel;
059: streamLogger.open();
060: init();
061:
062: //ok, everything is ready...
063: decoder.decode(buffer, charBuffer, true);
064: buffer.limit(buffer.capacity());
065: charBuffer.flip();
066:
067: String wkt = charBuffer.toString();
068:
069: cs = ReferencingFactoryFinder.getCRSFactory(null)
070: .createFromWKT(wkt);
071: }
072:
073: public org.opengis.referencing.crs.CoordinateReferenceSystem getCoodinateSystem() {
074: return cs;
075: }
076:
077: private int fill(ByteBuffer buffer, ReadableByteChannel channel)
078: throws IOException {
079: int r = buffer.remaining();
080: // channel reads return -1 when EOF or other error
081: // because they a non-blocking reads, 0 is a valid return value!!
082: while (buffer.remaining() > 0 && r != -1) {
083: r = channel.read(buffer);
084: }
085: if (r == -1) {
086: buffer.limit(buffer.position());
087: }
088: return r;
089: }
090:
091: private void init() throws IOException {
092: // create the ByteBuffer
093: // if we have a FileChannel, lets map it
094: if (channel instanceof FileChannel) {
095: FileChannel fc = (FileChannel) channel;
096: buffer = fc
097: .map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
098: buffer.position((int) fc.position());
099: } else {
100: // Some other type of channel
101: // start with a 8K buffer, should be more than adequate
102: int size = 8 * 1024;
103: // if for some reason its not, resize it
104: // size = header.getRecordLength() > size ? header.getRecordLength() : size;
105: buffer = ByteBuffer.allocateDirect(size);
106: // fill it and reset
107: fill(buffer, channel);
108: buffer.flip();
109: }
110:
111: // The entire file is in little endian
112: buffer.order(ByteOrder.LITTLE_ENDIAN);
113:
114: charBuffer = CharBuffer.allocate(8 * 1024);
115: Charset chars = Charset.forName("ISO-8859-1");
116: decoder = chars.newDecoder();
117:
118: }
119:
120: public void close() throws IOException {
121: if (buffer != null) {
122: if (buffer instanceof MappedByteBuffer) {
123: NIOUtilities.clean(buffer);
124: }
125: buffer = null;
126: }
127:
128: if (channel.isOpen()) {
129: channel.close();
130: streamLogger.close();
131: }
132: }
133:
134: }
|