001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.vpf.util;
017:
018: import org.geotools.data.vpf.ifc.DataTypesDefinition;
019: import org.geotools.data.vpf.io.VPFDate;
020:
021: /**
022: * Class DataUtils.java is responsible for a bunch of
023: * miscellaneous operations for reading and converting
024: * data
025: *
026: * <p>
027: * Created: Wed Jan 29 10:06:37 2003
028: * </p>
029: *
030: * @author <a href="mailto:kobit@users.sourceforge.net">Artur Hefczyc</a>
031: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/vpf/src/main/java/org/geotools/data/vpf/util/DataUtils.java $
032: * @version $Id: DataUtils.java 22482 2006-10-31 02:58:00Z desruisseaux $
033: */
034: public class DataUtils implements DataTypesDefinition {
035: /**
036: * Describe <code>toBigEndian</code> method here.
037: *
038: * @param source a <code>byte[]</code> value
039: * @return a <code>byte[]</code> value
040: */
041: public static byte[] toBigEndian(byte[] source) {
042: byte[] result = new byte[source.length];
043:
044: for (int i = 0; i < source.length; i++) {
045: result[i] = source[source.length - (i + 1)];
046: }
047:
048: return result;
049: }
050:
051: /**
052: * Describe <code>decodeData</code> method here.
053: *
054: * @param bytes a <code>byte[]</code> value
055: * @param type a <code>char</code> value
056: * @return an <code>Object</code> value
057: */
058: public static Object decodeData(byte[] bytes, char type) {
059: Object result = null;
060:
061: switch (type) {
062: case DATA_TEXT:
063: case DATA_LEVEL1_TEXT:
064: case DATA_LEVEL2_TEXT:
065: case DATA_LEVEL3_TEXT:
066:
067: StringBuffer sb = new StringBuffer(bytes.length);
068:
069: for (int i = 0; i < bytes.length; i++) {
070: sb.append((char) bytes[i]);
071: }
072:
073: boolean isNull = false;
074:
075: for (int i = 0; i < STRING_NULL_VALUES.length; i++) {
076: isNull |= sb.toString().trim().equalsIgnoreCase(
077: STRING_NULL_VALUES[i]);
078: }
079:
080: if (isNull) {
081: result = null;
082: } else {
083: result = sb.toString().trim();
084: }
085:
086: break;
087:
088: case DATA_SHORT_FLOAT:
089: result = new Float(decodeFloat(bytes));
090:
091: break;
092:
093: case DATA_LONG_FLOAT:
094: result = new Double(decodeDouble(bytes));
095:
096: break;
097:
098: case DATA_SHORT_INTEGER:
099: result = new Short(decodeShort(bytes));
100:
101: break;
102:
103: case DATA_LONG_INTEGER:
104: result = new Integer(decodeInt(bytes));
105:
106: break;
107:
108: case DATA_2_COORD_F:
109: // {
110: // // I doubt this is being used
111: // float[][] coords = new float[bytes.length / DATA_2_COORD_F_LEN][2];
112: // byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
113: //
114: // for (int i = 0; i < coords.length; i++) {
115: // copyArrays(floatData, bytes, i * DATA_2_COORD_F_LEN);
116: // coords[i][0] = decodeFloat(floatData);
117: // copyArrays(floatData, bytes, i * (DATA_2_COORD_F_LEN + 1));
118: // coords[i][1] = decodeFloat(floatData);
119: // }
120: // DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_F_LEN];
121: // double xval, yval;
122: // byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
123: //
124: // for (int i = 0; i < coords.length; i++) {
125: // copyArrays(floatData, bytes, i * DATA_2_COORD_F_LEN);
126: // xval = decodeFloat(floatData);
127: // copyArrays(floatData, bytes, i * (DATA_2_COORD_F_LEN + 1));
128: // yval = decodeFloat(floatData);
129: // coords[i] = new DirectPosition2D(xval, yval);
130: // }
131:
132: // result = coords;
133: // result = new Coordinate2DFloat(coords);
134: // }
135: //
136: // break;
137:
138: case DATA_2_COORD_R:
139: // {
140: // I doubt this is being used
141: // DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_R_LEN];
142: // double xval, yval;
143: // byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
144: //
145: // for (int i = 0; i < coords.length; i++) {
146: // copyArrays(doubleData, bytes, i * DATA_2_COORD_R_LEN);
147: // xval = decodeDouble(doubleData);
148: // copyArrays(doubleData, bytes, i * (DATA_2_COORD_R_LEN + 1));
149: // yval = decodeDouble(doubleData);
150: // coords[i] = new DirectPosition2D(xval, yval);
151: // }
152: //
153: // result = coords;
154: // double[][] coords = new double[bytes.length / DATA_2_COORD_R_LEN][2];
155: // byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
156: //
157: // for (int i = 0; i < coords.length; i++) {
158: // copyArrays(doubleData, bytes, i * DATA_2_COORD_R_LEN);
159: // coords[i][0] = decodeDouble(doubleData);
160: // copyArrays(doubleData, bytes, i * (DATA_2_COORD_R_LEN + 1));
161: // coords[i][1] = decodeDouble(doubleData);
162: // }
163: //
164: // result = new Coordinate2DDouble(coords);
165: // }
166: //
167: // break;
168: //
169: case DATA_3_COORD_F:
170: // {
171: // I doubt this is being used
172: // DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_R_LEN];
173: // double xval, yval, zval;
174: // byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
175: //
176: // for (int i = 0; i < coords.length; i++) {
177: // copyArrays(floatData, bytes, i * DATA_3_COORD_F_LEN);
178: // xval = decodeFloat(floatData);
179: // copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 1));
180: // yval = decodeFloat(floatData);
181: // copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 2));
182: // zval = decodeFloat(floatData);
183: // coords[i] = new GeneralDirectPosition(xval, yval, zval);
184: // }
185: //
186: // result = coords;
187: // float[][] coords = new float[bytes.length / DATA_3_COORD_F_LEN][3];
188: // byte[] floatData = new byte[DATA_SHORT_FLOAT_LEN];
189: //
190: // for (int i = 0; i < coords.length; i++) {
191: // copyArrays(floatData, bytes, i * DATA_3_COORD_F_LEN);
192: // coords[i][0] = decodeFloat(floatData);
193: // copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 1));
194: // coords[i][1] = decodeFloat(floatData);
195: // copyArrays(floatData, bytes, i * (DATA_3_COORD_F_LEN + 2));
196: // coords[i][2] = decodeFloat(floatData);
197: // }
198: //
199: // result = new Coordinate3DFloat(coords);
200: // }
201: //
202: // break;
203: //
204: case DATA_3_COORD_R:
205: // {
206: // I doubt this is being used
207: // DirectPosition[] coords = new DirectPosition2D[bytes.length / DATA_2_COORD_R_LEN];
208: // double xval, yval, zval;
209: // byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
210: //
211: // for (int i = 0; i < coords.length; i++) {
212: // copyArrays(doubleData, bytes, i * DATA_3_COORD_R_LEN);
213: // xval = decodeDouble(doubleData);
214: // copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 1));
215: // yval = decodeDouble(doubleData);
216: // copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 2));
217: // zval = decodeDouble(doubleData);
218: // coords[i] = new GeneralDirectPosition(xval, yval, zval);
219: // }
220: //
221: // result = coords;
222: // double[][] coords = new double[bytes.length / DATA_3_COORD_R_LEN][3];
223: // byte[] doubleData = new byte[DATA_LONG_FLOAT_LEN];
224: //
225: // for (int i = 0; i < coords.length; i++) {
226: // copyArrays(doubleData, bytes, i * DATA_3_COORD_R_LEN);
227: // coords[i][0] = decodeDouble(doubleData);
228: // copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 1));
229: // coords[i][1] = decodeDouble(doubleData);
230: // copyArrays(doubleData, bytes, i * (DATA_3_COORD_R_LEN + 2));
231: // coords[i][2] = decodeDouble(doubleData);
232: // }
233: //
234: // result = new Coordinate3DDouble(coords);
235: // }
236: {
237: throw new RuntimeException(
238: "If this code is actually being used, replace it with equivalent code from VPFFile.");
239: }
240: case DATA_DATE_TIME:
241: result = new VPFDate(bytes);
242:
243: break;
244:
245: case DATA_NULL_FIELD:
246: break;
247:
248: case DATA_TRIPLET_ID:
249: default:
250: break;
251: }
252:
253: return result;
254: }
255:
256: /**
257: * Describe <code>copyArrays</code> method here.
258: *
259: * @param dest a <code>byte[]</code> value
260: * @param source a <code>byte[]</code> value
261: * @param fromIdx an <code>int</code> value
262: */
263: public static void copyArrays(byte[] dest, byte[] source,
264: int fromIdx) {
265: for (int i = 0; i < dest.length; i++) {
266: dest[i] = source[i + fromIdx];
267: }
268: }
269:
270: /**
271: * Describe <code>decodeShort</code> method here.
272: *
273: * @param bytes a <code>byte[]</code> value
274: * @return a <code>short</code> value
275: */
276: public static short decodeShort(byte[] bytes) {
277: short res = 0;
278: int shift = 8;
279:
280: for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
281: res |= ((short) (bytes[i] & 0xff) << shift);
282: shift -= 8;
283: }
284:
285: return res;
286: }
287:
288: // public static int littleEndianToInt(byte[] fourBytes)
289: // {
290: // int res = 0;
291: // int limit = Math.min(fourBytes.length, 4);
292: // for (int i = 0; i < limit; i++)
293: // {
294: // res |= (fourBytes[i] & 0xFF) << (i*8);
295: // } // end of for (int i = 0; i < limit-1; i++)
296: // return res;
297: // }
298:
299: /**
300: * Describe <code>decodeInt</code> method here.
301: *
302: * @param bytes a <code>byte[]</code> value
303: * @return an <code>int</code> value
304: */
305: public static int decodeInt(byte[] bytes) {
306: int res = 0;
307: int shift = 24;
308:
309: for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
310: res |= ((bytes[i] & 0xff) << shift);
311: shift -= 8;
312: }
313:
314: return res;
315: }
316:
317: /**
318: * Describe <code>decodeFloat</code> method here.
319: *
320: * @param bytes a <code>byte[]</code> value
321: * @return a <code>float</code> value
322: */
323: public static float decodeFloat(byte[] bytes) {
324: int res = 0;
325: int shift = 24;
326:
327: for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
328: res |= ((bytes[i] & 0xff) << shift);
329: shift -= 8;
330: }
331:
332: return Float.intBitsToFloat(res);
333: }
334:
335: /**
336: * Describe <code>decodeDouble</code> method here.
337: *
338: * @param bytes a <code>byte[]</code> value
339: * @return a <code>double</code> value
340: */
341: public static double decodeDouble(byte[] bytes) {
342: long res = 0;
343: int shift = 56;
344:
345: for (int i = 0; (i < bytes.length) && (shift >= 0); i++) {
346: res |= ((long) (bytes[i] & 0xff) << shift);
347: shift -= 8;
348: }
349:
350: return Double.longBitsToDouble(res);
351: }
352:
353: /**
354: * Describe <code>unsigByteToInt</code> method here.
355: *
356: * @param b a <code>byte</code> value
357: * @return an <code>int</code> value
358: */
359: public static int unsigByteToInt(byte b) {
360: return (int) b & 0xFF;
361: }
362:
363: /**
364: * Describe <code>getDataTypeSize</code> method here.
365: *
366: * @param type a <code>char</code> value
367: * @return an <code>int</code> value
368: */
369: public static int getDataTypeSize(char type) {
370: int size = -1;
371:
372: switch (type) {
373: case DATA_TEXT:
374: case DATA_LEVEL1_TEXT:
375: case DATA_LEVEL2_TEXT:
376: case DATA_LEVEL3_TEXT:
377: size = 1;
378:
379: break;
380:
381: case DATA_SHORT_FLOAT:
382: size = DATA_SHORT_FLOAT_LEN;
383:
384: break;
385:
386: case DATA_LONG_FLOAT:
387: size = DATA_LONG_FLOAT_LEN;
388:
389: break;
390:
391: case DATA_SHORT_INTEGER:
392: size = DATA_SHORT_INTEGER_LEN;
393:
394: break;
395:
396: case DATA_LONG_INTEGER:
397: size = DATA_LONG_INTEGER_LEN;
398:
399: break;
400:
401: case DATA_2_COORD_F:
402: size = DATA_2_COORD_F_LEN;
403:
404: break;
405:
406: case DATA_2_COORD_R:
407: size = DATA_2_COORD_R_LEN;
408:
409: break;
410:
411: case DATA_3_COORD_F:
412: size = DATA_3_COORD_F_LEN;
413:
414: break;
415:
416: case DATA_3_COORD_R:
417: size = DATA_3_COORD_R_LEN;
418:
419: break;
420:
421: case DATA_DATE_TIME:
422: size = DATA_DATE_TIME_LEN;
423:
424: break;
425:
426: case DATA_NULL_FIELD:
427: size = DATA_NULL_FIELD_LEN;
428:
429: break;
430:
431: case DATA_TRIPLET_ID:
432: size = DATA_TRIPLET_ID_LEN;
433:
434: default:
435: break;
436: }
437:
438: return size;
439: }
440:
441: /**
442: * Describe <code>isNumeric</code> method here.
443: *
444: * @param type a <code>char</code> value
445: * @return a <code>boolean</code> value
446: */
447: public static boolean isNumeric(char type) {
448: switch (type) {
449: case DATA_TEXT:
450: case DATA_LEVEL1_TEXT:
451: case DATA_LEVEL2_TEXT:
452: case DATA_LEVEL3_TEXT:
453: case DATA_DATE_TIME:
454: case DATA_NULL_FIELD:
455: return false;
456:
457: case DATA_SHORT_FLOAT:
458: case DATA_LONG_FLOAT:
459: case DATA_SHORT_INTEGER:
460: case DATA_LONG_INTEGER:
461: return true;
462:
463: case DATA_2_COORD_F:
464: case DATA_2_COORD_R:
465: case DATA_3_COORD_F:
466: case DATA_3_COORD_R:
467: case DATA_TRIPLET_ID:
468: return true;
469:
470: default:
471: return false;
472: }
473: }
474: }
475:
476: // DataUtils
|