/*
* 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.util;
import org.geotools.data.vpf.ifc.DataTypesDefinition;
import org.geotools.data.vpf.io.VPFDate;
/**
* Class DataUtils.java is responsible for a bunch of
* miscellaneous operations for reading and converting
* data
*
* <p>
* Created: Wed Jan 29 10:06:37 2003
* </p>
*
* @author <a href="mailto:kobit@users.sourceforge.net">Artur Hefczyc</a>
*
*
* @source $URL$
* @version $Id$
*/
public class DataUtils implements DataTypesDefinition {
/**
* Describe <code>toBigEndian</code> method here.
*
* @param source a <code>byte[]</code> value
* @return a <code>byte[]</code> value
*/
public static byte[] toBigEndian(byte[] source) {
byte[] result = new byte[source.length];
for (int i = 0; i < source.length; i++) {
result[i] = source[source.length - (i + 1)];
}
return result;
}
/**
* Describe <code>decodeData</code> method here.
*
* @param bytes a <code>byte[]</code> value
* @param type a <code>char</code> value
* @return an <code>Object</code> value
*/
public static Object decodeData(byte[] bytes, char type) {
Object result = null;
switch (type) {
case DATA_TEXT:
case DATA_LEVEL1_TEXT:
case DATA_LEVEL2_TEXT:
case DATA_LEVEL3_TEXT:
StringBuffer sb = new StringBuffer(bytes.length);
for (int i = 0; i < bytes.length; i++) {
sb.append((char) bytes[i]);
}
boolean isNull = false;
for (int i = 0; i < STRING_NULL_VALUES.length; i++) {
isNull |= sb.toString().trim()
.equalsIgnoreCase(STRING_NULL_VALUES[i]);
}
if (isNull) {
result = null;
} else {
result = sb.toString().trim();
}
break;
case DATA_SHORT_FLOAT:
result = new Float(decodeFloat(bytes));
break;
case DATA_LONG_FLOAT:
result = new Double(decodeDouble(bytes));
break;
case DATA_SHORT_INTEGER:
result = new Short(decodeShort(bytes));
break;
case DATA_LONG_INTEGER:
result = new Integer(decodeInt(bytes));
break;
case DATA_2_COORD_F:
// {
// // I doubt this is being used
// float[][] coords = new float[bytes.length / DATA_2_COORD_F_LEN][2];
// byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(floatData, bytes, i * DATA_2_COORD_F_LEN);
// coords[i][0] = decodeFloat(floatData);
// copyArrays(floatData, bytes, i * (DATA_2_COORD_F_LEN + 1));
// coords[i][1] = decodeFloat(floatData);
// }
// DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_F_LEN];
// double xval, yval;
// byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(floatData, bytes, i * DATA_2_COORD_F_LEN);
// xval = decodeFloat(floatData);
// copyArrays(floatData, bytes, i * (DATA_2_COORD_F_LEN + 1));
// yval = decodeFloat(floatData);
// coords[i] = new DirectPosition2D(xval, yval);
// }
// result = coords;
// result = new Coordinate2DFloat(coords);
// }
//
// break;
case DATA_2_COORD_R:
// {
// I doubt this is being used
// DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_R_LEN];
// double xval, yval;
// byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(doubleData, bytes, i * DATA_2_COORD_R_LEN);
// xval = decodeDouble(doubleData);
// copyArrays(doubleData, bytes, i * (DATA_2_COORD_R_LEN + 1));
// yval = decodeDouble(doubleData);
// coords[i] = new DirectPosition2D(xval, yval);
// }
//
// result = coords;
// double[][] coords = new double[bytes.length / DATA_2_COORD_R_LEN][2];
// byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(doubleData, bytes, i * DATA_2_COORD_R_LEN);
// coords[i][0] = decodeDouble(doubleData);
// copyArrays(doubleData, bytes, i * (DATA_2_COORD_R_LEN + 1));
// coords[i][1] = decodeDouble(doubleData);
// }
//
// result = new Coordinate2DDouble(coords);
// }
//
// break;
//
case DATA_3_COORD_F:
// {
// I doubt this is being used
// DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_R_LEN];
// double xval, yval, zval;
// byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(floatData, bytes, i * DATA_3_COORD_F_LEN);
// xval = decodeFloat(floatData);
// copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 1));
// yval = decodeFloat(floatData);
// copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 2));
// zval = decodeFloat(floatData);
// coords[i] = new GeneralDirectPosition(xval, yval, zval);
// }
//
// result = coords;
// float[][] coords = new float[bytes.length / DATA_3_COORD_F_LEN][3];
// byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(floatData, bytes, i * DATA_3_COORD_F_LEN);
// coords[i][0] = decodeFloat(floatData);
// copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 1));
// coords[i][1] = decodeFloat(floatData);
// copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 2));
// coords[i][2] = decodeFloat(floatData);
// }
//
// result = new Coordinate3DFloat(coords);
// }
//
// break;
//
case DATA_3_COORD_R:
// {
// I doubt this is being used
// DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_R_LEN];
// double xval, yval, zval;
// byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(doubleData, bytes, i * DATA_3_COORD_R_LEN);
// xval = decodeDouble(doubleData);
// copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 1));
// yval = decodeDouble(doubleData);
// copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 2));
// zval = decodeDouble(doubleData);
// coords[i] = new GeneralDirectPosition(xval, yval, zval);
// }
//
// result = coords;
// double[][] coords = new double[bytes.length / DATA_3_COORD_R_LEN][3];
// byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
//
// for (int i = 0; i < coords.length; i++) {
// copyArrays(doubleData, bytes, i * DATA_3_COORD_R_LEN);
// coords[i][0] = decodeDouble(doubleData);
// copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 1));
// coords[i][1] = decodeDouble(doubleData);
// copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 2));
// coords[i][2] = decodeDouble(doubleData);
// }
//
// result = new Coordinate3DDouble(coords);
// }
{
throw new RuntimeException("If this code is actually being used, replace it with equivalent code from VPFFile.");
}
case DATA_DATE_TIME:
result = new VPFDate(bytes);
break;
case DATA_NULL_FIELD:
break;
case DATA_TRIPLET_ID:
default:
break;
}
return result;
}
/**
* Describe <code>copyArrays</code> method here.
*
* @param dest a <code>byte[]</code> value
* @param source a <code>byte[]</code> value
* @param fromIdx an <code>int</code> value
*/
public static void copyArrays(byte[] dest, byte[] source, int fromIdx) {
for (int i = 0; i < dest.length; i++) {
dest[i] = source[i + fromIdx];
}
}
/**
* Describe <code>decodeShort</code> method here.
*
* @param bytes a <code>byte[]</code> value
* @return a <code>short</code> value
*/
public static short decodeShort(byte[] bytes) {
short res = 0;
int shift = 8;
for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
res |= ((short) (bytes[i] & 0xff) << shift);
shift -= 8;
}
return res;
}
// public static int littleEndianToInt(byte[] fourBytes)
// {
// int res = 0;
// int limit = Math.min(fourBytes.length, 4);
// for (int i = 0; i < limit; i++)
// {
// res |= (fourBytes[i] & 0xFF) << (i*8);
// } // end of for (int i = 0; i < limit-1; i++)
// return res;
// }
/**
* Describe <code>decodeInt</code> method here.
*
* @param bytes a <code>byte[]</code> value
* @return an <code>int</code> value
*/
public static int decodeInt(byte[] bytes) {
int res = 0;
int shift = 24;
for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
res |= ((bytes[i] & 0xff) << shift);
shift -= 8;
}
return res;
}
/**
* Describe <code>decodeFloat</code> method here.
*
* @param bytes a <code>byte[]</code> value
* @return a <code>float</code> value
*/
public static float decodeFloat(byte[] bytes) {
int res = 0;
int shift = 24;
for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
res |= ((bytes[i] & 0xff) << shift);
shift -= 8;
}
return Float.intBitsToFloat(res);
}
/**
* Describe <code>decodeDouble</code> method here.
*
* @param bytes a <code>byte[]</code> value
* @return a <code>double</code> value
*/
public static double decodeDouble(byte[] bytes) {
long res = 0;
int shift = 56;
for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
res |= ((long) (bytes[i] & 0xff) << shift);
shift -= 8;
}
return Double.longBitsToDouble(res);
}
/**
* Describe <code>unsigByteToInt</code> method here.
*
* @param b a <code>byte</code> value
* @return an <code>int</code> value
*/
public static int unsigByteToInt(byte b) {
return (int) b & 0xFF;
}
/**
* Describe <code>getDataTypeSize</code> method here.
*
* @param type a <code>char</code> value
* @return an <code>int</code> value
*/
public static int getDataTypeSize(char type) {
int size = -1;
switch (type) {
case DATA_TEXT:
case DATA_LEVEL1_TEXT:
case DATA_LEVEL2_TEXT:
case DATA_LEVEL3_TEXT:
size = 1;
break;
case DATA_SHORT_FLOAT:
size = DATA_SHORT_FLOAT_LEN;
break;
case DATA_LONG_FLOAT:
size = DATA_LONG_FLOAT_LEN;
break;
case DATA_SHORT_INTEGER:
size = DATA_SHORT_INTEGER_LEN;
break;
case DATA_LONG_INTEGER:
size = DATA_LONG_INTEGER_LEN;
break;
case DATA_2_COORD_F:
size = DATA_2_COORD_F_LEN;
break;
case DATA_2_COORD_R:
size = DATA_2_COORD_R_LEN;
break;
case DATA_3_COORD_F:
size = DATA_3_COORD_F_LEN;
break;
case DATA_3_COORD_R:
size = DATA_3_COORD_R_LEN;
break;
case DATA_DATE_TIME:
size = DATA_DATE_TIME_LEN;
break;
case DATA_NULL_FIELD:
size = DATA_NULL_FIELD_LEN;
break;
case DATA_TRIPLET_ID:
size = DATA_TRIPLET_ID_LEN;
default:
break;
}
return size;
}
/**
* Describe <code>isNumeric</code> method here.
*
* @param type a <code>char</code> value
* @return a <code>boolean</code> value
*/
public static boolean isNumeric(char type) {
switch (type) {
case DATA_TEXT:
case DATA_LEVEL1_TEXT:
case DATA_LEVEL2_TEXT:
case DATA_LEVEL3_TEXT:
case DATA_DATE_TIME:
case DATA_NULL_FIELD:
return false;
case DATA_SHORT_FLOAT:
case DATA_LONG_FLOAT:
case DATA_SHORT_INTEGER:
case DATA_LONG_INTEGER:
return true;
case DATA_2_COORD_F:
case DATA_2_COORD_R:
case DATA_3_COORD_F:
case DATA_3_COORD_R:
case DATA_TRIPLET_ID:
return true;
default:
return false;
}
}
}
// DataUtils