From 94ae08701bbd7585a0b7e5a92d1975965a503c03 Mon Sep 17 00:00:00 2001 From: Dennis Kao <ulysseskao@gmail.com> Date: Wed, 15 Jan 2014 11:28:52 +0800 Subject: [PATCH] Merge branch 'origin/2.1.x' --- xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java | 330 ++++++++++++++---------------------------------------- 1 files changed, 89 insertions(+), 241 deletions(-) diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java index 35a3156..4dabae4 100644 --- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java +++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java @@ -2,6 +2,8 @@ //~--- JDK imports ------------------------------------------------------------ +import javax.swing.JFileChooser; +import javax.swing.JFrame; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; @@ -11,8 +13,6 @@ import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; -import javax.swing.JFileChooser; -import javax.swing.JFrame; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; @@ -27,10 +27,9 @@ * * @author Ulysses * @version 0.1 - * @since 2006/5/17 �U�� 01:24:10 + * @since 2006/5/17 */ -public class Dgn7fileReader -{ +public class Dgn7fileReader { private static final Logger logger = LogManager.getLogger(Dgn7fileReader.class); private Dgn7fileHeader header; @@ -38,17 +37,16 @@ ByteBuffer buffer; private ElementType fileElementType = ElementType.UNDEFINED; private ByteBuffer headerTransfer; - private final Record record = new Record(); + private final Element.FileRecord record = new Element.FileRecord(); private final boolean randomAccessEnabled; private Lock lock; private boolean useMemoryMappedBuffer; private long currentOffset = 0L; - private StreamLogging streamLogger = new StreamLogging("Shapefile Reader"); + private StreamLogging streamLogger = new StreamLogging("Dgn7 Reader"); private int maxElementId = 0; - public Dgn7fileReader(ReadableByteChannel channel, boolean strict, boolean useMemoryMapped, Lock lock) - throws IOException, Dgn7fileException - { + public Dgn7fileReader(FileChannel channel, boolean strict, boolean useMemoryMapped, Lock lock) + throws IOException, Dgn7fileException { this.channel = channel; this.useMemoryMappedBuffer = useMemoryMapped; streamLogger.open(); @@ -58,34 +56,29 @@ init(strict); } - public Dgn7fileReader(ReadableByteChannel channel, Lock lock) throws IOException, Dgn7fileException - { + public Dgn7fileReader(FileChannel channel, Lock lock) throws IOException, Dgn7fileException { this(channel, true, true, lock); } // ensure the capacity of the buffer is of size by doubling the original // capacity until it is big enough // this may be naiive and result in out of MemoryError as implemented... - public static ByteBuffer ensureCapacity(ByteBuffer buffer, int size, boolean useMemoryMappedBuffer) - { + public static ByteBuffer ensureCapacity(ByteBuffer buffer, int size, boolean useMemoryMappedBuffer) { // This sucks if you accidentally pass is a MemoryMappedBuffer of size // 80M // like I did while messing around, within moments I had 1 gig of // swap... - if (buffer.isReadOnly() || useMemoryMappedBuffer) - { + if (buffer.isReadOnly() || useMemoryMappedBuffer) { return buffer; } int limit = buffer.limit(); - while (limit < size) - { + while (limit < size) { limit *= 2; } - if (limit != buffer.limit()) - { + if (limit != buffer.limit()) { // if (record.ready) { buffer = ByteBuffer.allocateDirect(limit); @@ -99,31 +92,26 @@ } // for filling a ReadableByteChannel - public static int fill(ByteBuffer buffer, ReadableByteChannel channel) throws IOException - { + public static int fill(ByteBuffer buffer, ReadableByteChannel channel) throws IOException { int r = buffer.remaining(); // channel reads return -1 when EOF or other error // because they a non-blocking reads, 0 is a valid return value!! - while ((buffer.remaining() > 0) && (r != -1)) - { + while ((buffer.remaining() > 0) && (r != -1)) { r = channel.read(buffer); } - if (r == -1) - { + if (r == -1) { buffer.limit(buffer.position()); } return r; } - public static Dgn7fileHeader readHeader(ReadableByteChannel channel, boolean strict) throws IOException - { + public static Dgn7fileHeader readHeader(ReadableByteChannel channel, boolean strict) throws IOException { ByteBuffer buffer = ByteBuffer.allocateDirect(4); - if (fill(buffer, channel) == -1) - { + if (fill(buffer, channel) == -1) { throw new EOFException("Premature end of header"); } @@ -138,8 +126,7 @@ buffer = ByteBuffer.allocateDirect(length + 4); buffer.put(old); - if (fill(buffer, channel) == -1) - { + if (fill(buffer, channel) == -1) { throw new EOFException("Premature end of header"); } @@ -152,23 +139,19 @@ return header; } - public Dgn7fileHeader getHeader() - { + public Dgn7fileHeader getHeader() { return header; } - public void close() throws IOException - { + public void close() throws IOException { lock.unlockRead(); - if (channel.isOpen()) - { + if (channel.isOpen()) { channel.close(); streamLogger.close(); } - if (buffer instanceof MappedByteBuffer) - { + if (buffer instanceof MappedByteBuffer) { NIOUtilities.clean(buffer); } @@ -176,13 +159,11 @@ header = null; } - public boolean supportsRandomAccess() - { + public boolean supportsRandomAccess() { return randomAccessEnabled; } - public Record nextElement() throws IOException, Dgn7fileException - { + public Element.FileRecord nextElement() throws IOException, Dgn7fileException { // need to update position buffer.position(this.toBufferOffset(record.end)); @@ -201,12 +182,10 @@ // track the record location int elementLength = (buffer.getShort() * 2) + 4; - if (!buffer.isReadOnly() && !useMemoryMappedBuffer) - { + if (!buffer.isReadOnly() && !useMemoryMappedBuffer) { // capacity is less than required for the record // copy the old into the newly allocated - if (buffer.capacity() < elementLength) - { + if (buffer.capacity() < elementLength) { this.currentOffset += buffer.position(); ByteBuffer old = buffer; @@ -221,8 +200,7 @@ // remaining is less than record length // compact the remaining data and read again, // allowing enough room for one more record header - if (buffer.remaining() < elementLength) - { + if (buffer.remaining() < elementLength) { this.currentOffset += buffer.position(); buffer.compact(); fill(buffer, channel); @@ -252,8 +230,7 @@ // second guess them... buffer.mark(); - if (recordType.isMultiPoint()) - { + if (recordType.isMultiPoint()) { int lowCoorX = buffer.getInt(); lowCoorX = DgnUtility.convertFromDGN(lowCoorX); @@ -292,6 +269,7 @@ record.length = elementLength; record.signature = signature; record.number = recordNumber; + record.buffer = buffer; // remember, we read one int already... record.end = this.toFileOffset(buffer.position()) + elementLength - 4; @@ -307,24 +285,18 @@ return record; } - public void goTo(int offset) throws IOException, UnsupportedOperationException - { - if (randomAccessEnabled) - { - if (this.useMemoryMappedBuffer) - { + public void goTo(int offset) throws IOException, UnsupportedOperationException { + if (randomAccessEnabled) { + if (this.useMemoryMappedBuffer) { buffer.position(offset); - } else - { + } else { /* * Check to see if requested offset is already loaded; ensure * that record header is in the buffer */ - if ((this.currentOffset <= offset) && (this.currentOffset + buffer.limit() >= offset + 4)) - { + if ((this.currentOffset <= offset) && (this.currentOffset + buffer.limit() >= offset + 4)) { buffer.position(this.toBufferOffset(offset)); - } else - { + } else { FileChannel fc = (FileChannel) this.channel; fc.position(offset); @@ -339,25 +311,20 @@ record.end = offset; - try - { + try { hasNext(); - } catch (IOException ioe) - { + } catch (IOException ioe) { record.end = oldRecordOffset; throw ioe; } - } else - { + } else { throw new UnsupportedOperationException("Random Access not enabled"); } } - public Record elementAt(int offset) throws IOException, UnsupportedOperationException, Dgn7fileException - { - if (randomAccessEnabled) - { + public Element.FileRecord elementAt(int offset) throws IOException, UnsupportedOperationException, Dgn7fileException { + if (randomAccessEnabled) { this.goTo(offset); return nextElement(); @@ -366,25 +333,21 @@ throw new UnsupportedOperationException("Random Access not enabled"); } - public boolean hasNext() throws IOException - { + public boolean hasNext() throws IOException { // mark current position int position = buffer.position(); // ensure the proper position, regardless of read or handler behavior - try - { + try { buffer.position(this.toBufferOffset(record.end)); - } catch (IllegalArgumentException e) - { + } catch (IllegalArgumentException e) { logger.warn("position=" + this.toBufferOffset(record.end), e); return false; } // no more data left - if (buffer.remaining() < 4) - { + if (buffer.remaining() < 4) { return false; } @@ -392,8 +355,7 @@ boolean hasNext = true; short type = buffer.getShort(); - if (type == -1) - { + if (type == -1) { hasNext = false; } @@ -403,8 +365,7 @@ return hasNext; } - private void init(boolean strict) throws IOException, Dgn7fileException - { + private void init(boolean strict) throws IOException, Dgn7fileException { header = readHeader(channel, strict); // fileElementType = header.getElementType(); @@ -416,8 +377,7 @@ // { // throw new IOException("Unsuported shape type:" + fileElementType); // } - if ((channel instanceof FileChannel) && useMemoryMappedBuffer) - { + if ((channel instanceof FileChannel) && useMemoryMappedBuffer) { FileChannel fc = (FileChannel) channel; buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); @@ -425,8 +385,7 @@ // buffer.position(100); buffer.position(header.size()); this.currentOffset = 0; - } else - { + } else { // force useMemoryMappedBuffer to false this.useMemoryMappedBuffer = false; @@ -444,33 +403,26 @@ record.end = toFileOffset(buffer.position()); } - private int toBufferOffset(int offset) - { + private int toBufferOffset(int offset) { return (int) (offset - currentOffset); } - private int toFileOffset(int offset) - { + private int toFileOffset(int offset) { return (int) (currentOffset + offset); } - public int getCount(int count) throws Dgn7fileException - { - try - { - if (channel == null) - { + public int getCount(int count) throws Dgn7fileException { + try { + if (channel == null) { return -1; } count = 0; - for (int tmp = readElement(); tmp != -1; tmp = readElement()) - { + for (int tmp = readElement(); tmp != -1; tmp = readElement()) { count += tmp; } - } catch (IOException ioe) - { + } catch (IOException ioe) { count = -1; // What now? This seems arbitrarily appropriate ! @@ -480,23 +432,19 @@ return count; } - public int getCount() throws Dgn7fileException - { + public int getCount() throws Dgn7fileException { return getCount(0); } - private int readElement() throws IOException - { - if (!fillBuffer()) - { + private int readElement() throws IOException { + if (!fillBuffer()) { return -1; } // burn the record number buffer.getInt(); - if (!fillBuffer()) - { + if (!fillBuffer()) { return -1; } @@ -506,8 +454,7 @@ // subtract that from the record length recordlength -= 4; - if (!fillBuffer()) - { + if (!fillBuffer()) { return -1; } @@ -515,13 +462,11 @@ int type = buffer.getInt(); // go to end of record - while (buffer.limit() < buffer.position() + recordlength) - { + while (buffer.limit() < buffer.position() + recordlength) { recordlength -= buffer.limit() - buffer.position(); buffer.clear(); - if (channel.read(buffer) < 1) - { + if (channel.read(buffer) < 1) { return -1; } } @@ -529,8 +474,7 @@ buffer.position(buffer.position() + recordlength); // return 0 if record is null. Null records should be counted. - if (type == 0) - { + if (type == 0) { // this is a null feature return 0; } @@ -538,28 +482,23 @@ return 1; } - private boolean fillBuffer() throws IOException - { + private boolean fillBuffer() throws IOException { int result = 1; - if (buffer.limit() <= buffer.position() + 4) - { + if (buffer.limit() <= buffer.position() + 4) { result = fill(buffer, channel); } return result > 0; } - public static void main(String[] args) - { + public static void main(String[] args) { JFileChooser jfc = new JFileChooser("D:/TEMP"); File f = null; int r = jfc.showOpenDialog(new JFrame()); - if (r == JFileChooser.APPROVE_OPTION) - { - try - { + if (r == JFileChooser.APPROVE_OPTION) { + try { f = jfc.getSelectedFile(); FileChannel channel = new FileInputStream(f).getChannel(); @@ -573,25 +512,20 @@ count = 0; size = 0; - try - { + try { Element lastComplex = null; - while (reader.hasNext()) - { + while (reader.hasNext()) { size++; - Dgn7fileReader.Record record = reader.nextElement(); + Element.FileRecord record = reader.nextElement(); - if (record.element() != null) - { + if (record.element() != null) { Element element = (Element) record.element(); ElementType type = element.getElementType(); - if ((!type.isComplexElement()) && (!element.isComponentElement())) - { - if (lastComplex != null) - { + if ((!type.isComplexElement()) && (!element.isComponentElement())) { + if (lastComplex != null) { // @todo add process in here count++; lastComplex = null; @@ -599,19 +533,14 @@ // @todo add process in here count++; - } else if (element.isComponentElement()) - { - if (lastComplex != null) - { + } else if (element.isComponentElement()) { + if (lastComplex != null) { ((ComplexElement) lastComplex).add(element); } - } else if (type.isComplexElement()) - { - if (lastComplex == null) - { + } else if (type.isComplexElement()) { + if (lastComplex == null) { lastComplex = element; - } else - { + } else { // @todo add process in here count++; lastComplex = element; @@ -619,104 +548,23 @@ } } } - } catch (IOException e) - { + } catch (IOException e) { logger.warn("Stop read dgn file", e); - } catch (Dgn7fileException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } finally - { + } catch (Dgn7fileException e) { + logger.warn(e.getMessage(), e); + } finally { reader.close(); } - System.out.println("count=" + count + " size=" + size); + logger.debug("count=" + count + " size=" + size); // reader.close(); - } catch (IOException ioe) - { - System.out.println(ioe); - ioe.printStackTrace(); - } catch (Dgn7fileException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (IOException ioe) { + logger.warn(ioe.getMessage(), ioe); + } catch (Dgn7fileException e) { + logger.warn(e.getMessage(), e); } } System.exit(0); - } - - public final class Record - { - int length; - int number = 0; - int offset; // Relative to the whole file - int start = 0; // Relative to the current loaded buffer - short signature = 0; - - /** - * The minimum X value. - */ - public double minX; - - /** - * The minimum Y value. - */ - public double minY; - - /** - * The minimum Z value. - */ - public double minZ; - - /** - * The maximum X value. - */ - public double maxX; - - /** - * The maximum Y value. - */ - public double maxY; - - /** - * The maximum Z value. - */ - public double maxZ; - - // ElementType type; - int end = 0; // Relative to the whole file - Object element = null; - IElementHandler handler; - - public Object element() - { - if (element == null) - { - buffer.position(start); - buffer.order(ByteOrder.LITTLE_ENDIAN); - - if (handler == null) - { - return null; - } - - element = handler.read(buffer, signature, length); - } - - return element; - } - - public int offset() - { - return offset; - } - - /** - * A summary of the record. - */ - public String toString() - { - return "Record " + number + " length " + length + " bounds " + minX + "," + minY + " " + maxX + "," + maxY; - } } } -- Gitblit v0.0.0-SNAPSHOT