/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.vpf.io;
import org.geotools.data.vpf.exc.VPFDataFormatException;
/**
* Class TripletId.java is responsible for
*
* @author <a href="mailto:kobit@users.sourceforge.net">Artur Hefczyc</a>
* @author <a href="mailto:knuterik@onemap.org">Knut-Erik Johnsen</a>, Project
* OneMap
* @version 1.0.0
* @author <a href="mailto:jeff@ionicenterprise.com">Jeff Yutzler</a>
* @source $URL$
*/
public class TripletId extends Number {
/**
* The raw data that can be decomposed into as many as three separate
* numbers
*/
private byte[] rawData = null;
/**
* Creates a new <code>TripletId</code> instance.
*
* @param data a <code>byte[]</code> value
*/
public TripletId(byte[] data) {
rawData = data;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
String result = new String();
try {
if (getIdLength() > 0) {
result = new Integer(getId()).toString();
}
if (getTileIdLength() > 0) {
result = result.concat("%")
.concat(new Integer(getTileId()).toString())
.trim();
}
if (getNextIdLength() > 0) {
result = result.concat("%")
.concat(new Integer(getNextId()).toString())
.trim();
}
} catch (RuntimeException exp) {
throw new VPFDataFormatException("This triplet is invalid.", exp);
}
return result;
}
/**
* Returns the length in bytes of the ID
*
* @return an <code>int</code> value
*/
private int getIdLength() {
return (rawData[0] >> 6) & 3;
}
/**
* Returns the length in bytes of the Tile ID
*
* @return an <code>int</code> value
*/
private int getTileIdLength() {
return (rawData[0] >> 4) & 3;
}
/**
* Returns the length in bytes of the Next ID
*
* @return an <code>int</code> value
*/
private int getNextIdLength() {
return (rawData[0] >> 2) & 3;
}
/**
* Returns the ID value
*
* @return Returns the ID, the first number of the triplet
*/
public int getId() {
int result = 0;
int length = getIdLength();
int piece;
if (length > 0) {
try {
for (int inx = 0; inx < length; inx++) {
piece = rawData[inx + 1];
// Convert bytes from signed to unsigned
if (piece < 0) {
piece += (-2 * (Byte.MIN_VALUE));
}
result += (piece << (8 * inx));
}
} catch (RuntimeException exp) {
exp.printStackTrace();
result = 0;
}
}
return result;
}
/**
* Returns the Tile ID
* @return Returns the Tile ID, the second number of the triplet
*/
public int getTileId() {
int result = 0;
int length = getTileIdLength();
int piece;
if (length > 0) {
int rowIdLength = getIdLength();
try {
for (int inx = 0; inx < length; inx++) {
piece = rawData[inx + rowIdLength + 1];
if (piece < 0) {
piece += (2 * Byte.MAX_VALUE);
}
result += (piece << (8 * inx));
}
} catch (RuntimeException exp) {
exp.printStackTrace();
result = 0;
}
}
return result;
}
/**
* Returns the Next ID
* @return Returns the Next ID, the third number of the triplet
*/
public int getNextId() {
int result = 0;
int length = getTileIdLength();
int piece;
if (length > 0) {
int prevLength = getIdLength() + getTileIdLength();
try {
for (int inx = 0; inx < length; inx++) {
piece = rawData[inx + prevLength + 1];
if (piece < 0) {
piece += (2 * Byte.MAX_VALUE);
}
result += (piece << (8 * inx));
}
} catch (RuntimeException exp) {
exp.printStackTrace();
result = 0;
}
}
return result;
}
/**
* Describe <code>calculateDataSize</code> method here.
*
* @param definition a <code>byte</code> value indicating the details of the bytes
*
* @return an <code>int</code> value
*/
public static int calculateDataSize(byte definition) {
int[] pieces = new int[3];
pieces[0] = (definition >> 2) & 3;
pieces[1] = (definition >> 4) & 3;
pieces[2] = (definition >> 6) & 3;
int size = 0;
for (int i = 0; i < pieces.length; i++) {
switch (pieces[i]) {
case 0:
break;
case 1:
size++;
break;
case 2:
size += 2;
break;
case 3:
size += 4;
break;
default:
System.out.println("Tripled id size decoding error");
System.out.println("tripled definition: " + definition);
System.out.println("piece 0: " + pieces[0]);
System.out.println("piece 1: " + pieces[1]);
System.out.println("piece 2: " + pieces[2]);
break;
}
}
return size;
}
/* (non-Javadoc)
* @see java.lang.Number#doubleValue()
*/
public double doubleValue() {
return new Integer(getId()).doubleValue();
}
/* (non-Javadoc)
* @see java.lang.Number#floatValue()
*/
public float floatValue() {
return new Integer(getId()).floatValue();
}
/* (non-Javadoc)
* @see java.lang.Number#intValue()
*/
public int intValue() {
return getId();
}
/* (non-Javadoc)
* @see java.lang.Number#longValue()
*/
public long longValue() {
return new Integer(getId()).longValue();
}
/* (non-Javadoc)
* @see java.lang.Number#byteValue()
*/
public byte byteValue() {
return new Integer(getId()).byteValue();
}
/* (non-Javadoc)
* @see java.lang.Number#shortValue()
*/
public short shortValue() {
return new Integer(getId()).shortValue();
}
}