package com.ximple.io.dgn7;
|
|
//~--- JDK imports ------------------------------------------------------------
|
|
import java.nio.BufferUnderflowException;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
import com.vividsolutions.jts.geom.Envelope;
|
|
import com.ximple.util.DgnUtility;
|
|
/**
|
* FileRecord
|
*
|
* @author Ulysses
|
* @version 0.1
|
*/
|
public class Element {
|
public static final int CONSTRUCTION_CLASS = 0;
|
public static final int CONSTRUCTION_RULE_CLASS = 0;
|
public static final int DIMENSION_CLASS = 0;
|
public static final int LINEAR_PATTERNED_CLASS = 0;
|
public static final int MAX_ELEMENT_SIZE = 0;
|
public static final int MAX_VERTICES = 100;
|
public static final int PATTERN_AREA = 0;
|
public static final int PATTERN_COMPONENT_CLASS = 0;
|
public static final int PATTERN_CROSSHATCH = 0;
|
public static final int PATTERN_HATCH = 0;
|
public static final int PRIMARY_CLASS = 0;
|
public static final int PRIMARY_RULE_CLASS = 0;
|
|
protected short[] raw;
|
protected byte attrOffset = 0;
|
protected ByteBuffer rawBuffer;
|
protected boolean newElement = false;
|
|
Element(byte[] raw) {
|
// this.raw = raw;
|
this.raw = new short[raw.length / 2];
|
rawBuffer = ByteBuffer.wrap(raw);
|
rawBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
rawBuffer.asShortBuffer().get(this.raw);
|
}
|
|
public int getLineStyle() {
|
return (raw[17] & 0x0007);
|
}
|
|
protected void setLineStyle(int value) {
|
if (value > -1 && value < 8)
|
raw[17] = (short) ((raw[17] & 0xfff8) | (value & 0x0007));
|
else
|
new IllegalArgumentException("Out of Range!");
|
}
|
|
public Envelope getRange() {
|
int lowCoorX = ((raw[3] << 16) & 0xffff0000) + (raw[2] & 0x0000ffff);
|
lowCoorX = DgnUtility.convertFromDGN(lowCoorX);
|
|
int lowCoorY = ((raw[5] << 16) & 0xffff0000) + (raw[4] & 0x0000ffff);
|
lowCoorY = DgnUtility.convertFromDGN(lowCoorY);
|
|
int highCoorX = ((raw[9] << 16) & 0xffff0000) + (raw[8] & 0x0000ffff);
|
highCoorX = DgnUtility.convertFromDGN(highCoorX);
|
|
int highCoorY = ((raw[11] << 16) & 0xffff0000) + (raw[10] & 0x0000ffff);
|
highCoorY = DgnUtility.convertFromDGN(highCoorY);
|
|
return new Envelope(DgnUtility.converUnitToCoord(lowCoorX), DgnUtility.converUnitToCoord(highCoorX),
|
DgnUtility.converUnitToCoord(lowCoorY), DgnUtility.converUnitToCoord(highCoorY));
|
}
|
|
public void setRange(Envelope bbox) {
|
int lowCoordX = DgnUtility.converCoordToUnit(bbox.getMinX());
|
int temp = DgnUtility.converToDGN(lowCoordX);
|
raw[3] = (short) (temp >> 16 & 0x0000ffff);
|
raw[2] = (short) (temp & 0x0000ffff);
|
|
int lowCoordY = DgnUtility.converCoordToUnit(bbox.getMinY());
|
temp = DgnUtility.converToDGN(lowCoordY);
|
raw[5] = (short) (temp >> 16 & 0x0000ffff);
|
raw[4] = (short) (temp & 0x0000ffff);
|
|
// lowZ
|
raw[7] = 0;
|
raw[8] = 0;
|
|
int highCoorX = DgnUtility.converCoordToUnit(bbox.getMaxX());
|
temp = DgnUtility.converToDGN(highCoorX);
|
raw[9] = (short) (temp >> 16 & 0x0000ffff);
|
raw[8] = (short) (temp & 0x0000ffff);
|
|
int highCoorY = DgnUtility.converCoordToUnit(bbox.getMaxY());
|
temp = DgnUtility.converToDGN(highCoorY);
|
raw[11] = (short) (temp >> 16 & 0x0000ffff);
|
raw[10] = (short) (temp & 0x0000ffff);
|
|
// highZ
|
raw[13] = (short) 0xffff;
|
raw[12] = (short) 0xffff;
|
|
}
|
|
public boolean isComponentElement() {
|
return (short) ((raw[0] >>> 7) & 0x0001) == 1;
|
}
|
|
protected void setComponentElement(boolean value) {
|
raw[0] = (short) ((raw[0] & 0xff7f) | (value ? 0x0080 : 0x0));
|
}
|
|
public boolean removeUserAttributeData(int iLinkageId) {
|
return true;
|
}
|
|
public boolean removeUserAttributeData(int iLinkageId, int iLinkageIndex) {
|
return true;
|
}
|
|
public boolean isDeleted() {
|
return (short) ((raw[0] >>> 15) & 0x0001) == 1;
|
}
|
|
protected void setDeleted(boolean value) {
|
raw[0] = (short) ((raw[0] & 0x7fff) | ((((value) ? 1 : 0) << 15) & 0x8000));
|
}
|
|
public int getColorIndex() {
|
return ((raw[17] >>> 8) & 0x00ff);
|
}
|
|
protected void setColorIndex(int value) {
|
if (value > -1 && value < 256)
|
{
|
raw[17] = (short) ((raw[17] & 0x00ff) | (value << 8 & 0xff00));
|
} else new IllegalArgumentException("Out of Range!");
|
}
|
|
public int getType() {
|
return ((raw[0] >>> 8) & 0x007f);
|
}
|
|
protected void setType(int value) {
|
raw[0] = (short) ((raw[0] & 0x80ff) | (value << 8) & 0x3f00);
|
}
|
|
public ElementType getElementType() {
|
return ElementType.forID(getType());
|
}
|
|
public int getLevelIndex() {
|
return (raw[0] & 0x003f);
|
}
|
|
public void setLevelIndex(int value) {
|
raw[0] = (short) ((raw[0] & 0xffc0) | (value & 0x003f));
|
}
|
|
public int getWeight() {
|
return ((raw[17] >>> 3) & 0x001f);
|
}
|
|
public void setWeight(int value) {
|
if (value > -1 && value < 31) {
|
raw[17] = (short) ((raw[17] & 0xff07) | (value << 3 & 0x00f8));
|
} else {
|
throw new RuntimeException("Out of Range!");
|
}
|
}
|
|
public short getFollowLength() {
|
return raw[1];
|
}
|
|
protected void setFollowLength(short value) {
|
assert (raw.length >= value + 2);
|
raw[1] = value;
|
}
|
|
public void addUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId) throws Element.Exception {
|
}
|
|
public void addUserAttributeData(byte[] pDataBlock, int iLinkageId, Object oDataDef) throws Element.Exception {
|
}
|
|
public boolean hasUserAttributeData() {
|
if (raw[15] <= 0) {
|
return false;
|
}
|
|
short index = (short) (raw[15] + 16);
|
|
if (index == -1) {
|
return false;
|
}
|
|
return true;
|
}
|
|
public int getUserAttributeDataOffset() {
|
return (raw[15] + 16);
|
}
|
|
public List<UserAttributeData> getUserAttributeData() {
|
short[] data;
|
short length, nextAttribute;
|
|
if (raw[15] <= 0) {
|
return new ArrayList<UserAttributeData>();
|
}
|
|
short index = (short) (raw[15] + 16 + attrOffset);
|
|
if (index == -1) {
|
return null;
|
}
|
|
ArrayList<UserAttributeData> aLinkageSet = new ArrayList<UserAttributeData>();
|
|
while (index < raw.length) {
|
|
|
if (raw[index] == 0 || ((short) raw[index]) == 0x8000)
|
{
|
index += 4;
|
aLinkageSet.add(null);
|
continue;
|
}
|
|
length = (short) (raw[index] & (short) 0x00ff);
|
|
if (length == 0) {
|
break;
|
}
|
|
if (length > raw.length - index - 1)
|
{
|
return null;
|
}
|
|
nextAttribute = (short) (index + length + 1);
|
data = new short[length];
|
System.arraycopy(raw, index + 1, data, 0, length);
|
|
if (data[0] == (short) 0x0020) {
|
aLinkageSet.add(new FrammeAttributeData(data));
|
} else {
|
aLinkageSet.add(new UserAttributeData(data));
|
}
|
|
index = nextAttribute;
|
}
|
|
return aLinkageSet;
|
}
|
|
public void getUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId, int iLinkageIndex) {
|
}
|
|
public void getUserAttributeData(byte[] pDataBlock, int iLinkageId, Object oDataDef) {
|
}
|
|
|
public ByteBuffer getRawBuffer() {
|
return rawBuffer.asReadOnlyBuffer();
|
}
|
|
public short[] getRawArray() {
|
if (raw == null) return null;
|
short[] result = new short[raw.length];
|
System.arraycopy(raw, 0, result, 0, raw.length);
|
return result;
|
}
|
|
public static class Exception extends java.lang.Exception {
|
public Exception() {
|
}
|
|
// Constructs an ElementRecord.Exception with no detail message.
|
public Exception(String oStrMessage) {
|
super(oStrMessage);
|
}
|
}
|
|
protected static int getOffsetPosition(int offset) {
|
return offset * 2;
|
}
|
|
public void resyncBuffer() {
|
byte[] tempRaw = new byte[this.raw.length * 2];
|
ByteBuffer tempBuffer = ByteBuffer.wrap(tempRaw);
|
tempBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
tempBuffer.asShortBuffer().put(this.raw);
|
|
int pos = rawBuffer.position();
|
rawBuffer = tempBuffer;
|
rawBuffer.position(pos);
|
}
|
|
public static class ElementHandler implements IElementHandler {
|
ElementType elementType;
|
|
public ElementHandler(ElementType elementType) {
|
this.elementType = elementType;
|
}
|
|
public ElementType getElementType() {
|
return elementType;
|
}
|
|
public Element read(ByteBuffer buffer, short signature, int length) {
|
byte[] dst = new byte[length];
|
try {
|
buffer.get(dst, 4, dst.length - 4);
|
} catch (BufferUnderflowException exception) {
|
throw exception;
|
}
|
|
ByteBuffer tmpBuffer = ByteBuffer.wrap(dst);
|
tmpBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
tmpBuffer.position(0);
|
tmpBuffer.putShort(signature);
|
tmpBuffer.putShort((short) ((length / 2) - 2));
|
|
/*
|
ShortBuffer sbuffer = tmpBuffer.asShortBuffer();
|
|
short[] rawMem = new short[(length / 2)];
|
sbuffer.get(rawMem, 2, rawMem.length - 2);
|
rawMem[0] = signature;
|
rawMem[1] = (short) ((length / 2) - 2);
|
*/
|
Element elm = createElement(dst);
|
|
return elm;
|
}
|
|
public void write(ByteBuffer buffer, Object element) {
|
buffer.put(((Element) element).rawBuffer);
|
}
|
|
public int getLength(Object element) {
|
return ((Element) element).raw.length;
|
}
|
|
public int getBufferLength(Object element) {
|
return ((Element) element).rawBuffer.limit();
|
}
|
|
protected Element createElement(byte[] raw) {
|
return new Element(raw);
|
}
|
}
|
|
public static final class FileRecord {
|
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;
|
ByteBuffer buffer;
|
|
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 "FileRecord " + number + " length " + length + " bounds " + minX + "," + minY + " " + maxX + "," + maxY;
|
}
|
}
|
}
|