From 2c530b054c2b0d4eb9845d294c646bd6840de082 Mon Sep 17 00:00:00 2001 From: Nathanael Jourdane Date: Wed, 9 Mar 2016 14:38:16 +0100 Subject: [PATCH] bugFix: Parse numeric data correctly. --- src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java | 74 +++++++++++++++++++++++++++++++++++--------------------------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java b/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java index 6b688a7..81963c6 100644 --- a/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java +++ b/src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java @@ -17,6 +17,7 @@ package eu.omp.irap.vespa.epntapclient.votable.controller; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Base64; import java.util.HashMap; @@ -53,7 +54,7 @@ public class VOTableDataParser { private String[] columnsName; /** The byte array stored in the VOTable Table stream (if any). */ - private byte[] bytes; + private ByteBuffer stream; /** The index of the current position in the bytes array. */ private int cursor; @@ -178,19 +179,19 @@ public class VOTableDataParser { /** * get the data on its BINARY form. * - * @param stream the data Stream in the VOTable Table. + * @param voStream the data Stream in the VOTable Table. * @param fields The Fields corresponding to the Table. * @throws UnsupportedOperationException Data as arrays are not supported yet. */ - private void parseBinaryStream(Stream stream, List fields) { + private void parseBinaryStream(Stream voStream, List fields) { logger.info("Parsing data in BINARY stream..."); - String strStream = stream.getValue().replaceAll("(\\r|\\n)", ""); + String strStream = voStream.getValue().replaceAll("(\\r|\\n)", ""); - bytes = Base64.getDecoder().decode(strStream); + stream = ByteBuffer.wrap(Base64.getDecoder().decode(strStream)); Object[] row = new Object[columnsName.length]; int nValue = 0; - while (cursor < bytes.length) { + while (stream.hasRemaining()) { int nColumn = nValue % columnsName.length; Field column = fields.get(nColumn); DataType dataType = column.getDatatype(); @@ -214,39 +215,50 @@ public class VOTableDataParser { if (column.getArraysize() == null) { arraySize = blockSize; } else if ("*".equals(column.getArraysize())) { - arraySize = getValue(4) * blockSize; + arraySize = stream.getInt() * blockSize; } else { arraySize = Integer.parseInt(column.getArraysize()) * blockSize; } - if ((arraySize != blockSize) && !(dataType.equals(DataType.CHAR) || dataType.equals(DataType.UNICODE_CHAR))) { - throw new UnsupportedOperationException("Data as arrays are not supported yet."); + throw new UnsupportedOperationException("Numeric data as array are not supported."); } if (nColumn == 0) { row = new Object[columnsName.length]; } - if (dataType.equals(DataType.CHAR) || dataType.equals(DataType.UNICODE_CHAR)) { + if (dataType.equals(DataType.BOOLEAN)) { + row[nColumn] = new Boolean(stream.getInt() == 0 ? false : true); + } else if (dataType.equals(DataType.UNSIGNED_BYTE)) { + row[nColumn] = stream.get(); + } else if (dataType.equals(DataType.SHORT)) { + row[nColumn] = stream.getShort(); + } else if (dataType.equals(DataType.INT)) { + row[nColumn] = stream.getInt(); + } else if (dataType.equals(DataType.LONG)) { + row[nColumn] = stream.getLong(); + } else if (dataType.equals(DataType.CHAR)) { String value = new String(); - for (int i = 0; i < arraySize && cursor < bytes.length; i += blockSize) { - value += (char) getValue(blockSize); + for (int i = 0; i < arraySize && cursor < stream.capacity(); i++) { + value += (char) stream.get(); } row[nColumn] = value.trim(); - } else if (dataType.equals(DataType.BOOLEAN) || dataType.equals(DataType.BIT)) { - row[nColumn] = new Boolean(getValue(blockSize) == 0 ? false : true); - } else if (dataType.equals(DataType.UNSIGNED_BYTE) || dataType.equals(DataType.SHORT)) { - row[nColumn] = new Short((short) getValue(blockSize)); - } else if (dataType.equals(DataType.INT)) { - row[nColumn] = new Integer(getValue(blockSize)); - } else if (dataType.equals(DataType.LONG)) { - row[nColumn] = new Long(getValue(blockSize)); - } else { // float - row[nColumn] = new Float(getValue(blockSize)); + } else if (dataType.equals(DataType.UNICODE_CHAR)) { + String value = new String(); + for (int i = 0; i < arraySize && cursor < stream.capacity(); i += 2) { + value += stream.getChar(); + } + row[nColumn] = value.trim(); + } else if (dataType.equals(DataType.FLOAT)) { + row[nColumn] = stream.getFloat(); + } else if (dataType.equals(DataType.DOUBLE)) { + row[nColumn] = stream.getDouble(); + } else { + logger.warn("Data type " + dataType + " is not supprted."); } - // logger.debug("**" + columnsName[nColumn] + "**: " + row[nColumn]) + // logger.debug(columnsName[nColumn] + ": " + row[nColumn]) row[nColumn] = row[nColumn]; if (nColumn == columnsName.length - 1) { @@ -283,20 +295,4 @@ public class VOTableDataParser { logger.info("Parsing data in FITS stream..."); // TODO Implement parseFITSStream() } - - /** - * Get the integer value of a bytes block. For example, [0x01, 0x05] returns 230, and increment - * the cursor. - * - * @param blockSize The size of the bytes block to get - * @return The integer value of the bytes block. - */ - private int getValue(int blockSize) { - int intVal = 0; - for (int i = 0; i < blockSize; i++) { - intVal += 0xFF & (bytes[cursor + i] << ((blockSize - 1 - i) * 8)); - } - cursor += blockSize; - return intVal; - } } -- libgit2 0.21.2