Commit 2c530b054c2b0d4eb9845d294c646bd6840de082

Authored by Nathanael Jourdane
1 parent 1bc7a17a
Exists in master

bugFix: Parse numeric data correctly.

src/main/java/eu/omp/irap/vespa/epntapclient/votable/controller/VOTableDataParser.java
... ... @@ -17,6 +17,7 @@
17 17 package eu.omp.irap.vespa.epntapclient.votable.controller;
18 18  
19 19 import java.io.IOException;
  20 +import java.nio.ByteBuffer;
20 21 import java.util.ArrayList;
21 22 import java.util.Base64;
22 23 import java.util.HashMap;
... ... @@ -53,7 +54,7 @@ public class VOTableDataParser {
53 54 private String[] columnsName;
54 55  
55 56 /** The byte array stored in the VOTable Table stream (if any). */
56   - private byte[] bytes;
  57 + private ByteBuffer stream;
57 58  
58 59 /** The index of the current position in the bytes array. */
59 60 private int cursor;
... ... @@ -178,19 +179,19 @@ public class VOTableDataParser {
178 179 /**
179 180 * get the data on its BINARY form.
180 181 *
181   - * @param stream the data Stream in the VOTable Table.
  182 + * @param voStream the data Stream in the VOTable Table.
182 183 * @param fields The Fields corresponding to the Table.
183 184 * @throws UnsupportedOperationException Data as arrays are not supported yet.
184 185 */
185   - private void parseBinaryStream(Stream stream, List<Field> fields) {
  186 + private void parseBinaryStream(Stream voStream, List<Field> fields) {
186 187 logger.info("Parsing data in BINARY stream...");
187   - String strStream = stream.getValue().replaceAll("(\r|\n)", "");
  188 + String strStream = voStream.getValue().replaceAll("(\r|\n)", "");
188 189  
189   - bytes = Base64.getDecoder().decode(strStream);
  190 + stream = ByteBuffer.wrap(Base64.getDecoder().decode(strStream));
190 191 Object[] row = new Object[columnsName.length];
191 192  
192 193 int nValue = 0;
193   - while (cursor < bytes.length) {
  194 + while (stream.hasRemaining()) {
194 195 int nColumn = nValue % columnsName.length;
195 196 Field column = fields.get(nColumn);
196 197 DataType dataType = column.getDatatype();
... ... @@ -214,39 +215,50 @@ public class VOTableDataParser {
214 215 if (column.getArraysize() == null) {
215 216 arraySize = blockSize;
216 217 } else if ("*".equals(column.getArraysize())) {
217   - arraySize = getValue(4) * blockSize;
  218 + arraySize = stream.getInt() * blockSize;
218 219 } else {
219 220 arraySize = Integer.parseInt(column.getArraysize()) * blockSize;
220 221 }
221   -
222 222 if ((arraySize != blockSize) && !(dataType.equals(DataType.CHAR)
223 223 || dataType.equals(DataType.UNICODE_CHAR))) {
224   - throw new UnsupportedOperationException("Data as arrays are not supported yet.");
  224 + throw new UnsupportedOperationException("Numeric data as array are not supported.");
225 225 }
226 226  
227 227 if (nColumn == 0) {
228 228 row = new Object[columnsName.length];
229 229 }
230 230  
231   - if (dataType.equals(DataType.CHAR) || dataType.equals(DataType.UNICODE_CHAR)) {
  231 + if (dataType.equals(DataType.BOOLEAN)) {
  232 + row[nColumn] = new Boolean(stream.getInt() == 0 ? false : true);
  233 + } else if (dataType.equals(DataType.UNSIGNED_BYTE)) {
  234 + row[nColumn] = stream.get();
  235 + } else if (dataType.equals(DataType.SHORT)) {
  236 + row[nColumn] = stream.getShort();
  237 + } else if (dataType.equals(DataType.INT)) {
  238 + row[nColumn] = stream.getInt();
  239 + } else if (dataType.equals(DataType.LONG)) {
  240 + row[nColumn] = stream.getLong();
  241 + } else if (dataType.equals(DataType.CHAR)) {
232 242 String value = new String();
233   - for (int i = 0; i < arraySize && cursor < bytes.length; i += blockSize) {
234   - value += (char) getValue(blockSize);
  243 + for (int i = 0; i < arraySize && cursor < stream.capacity(); i++) {
  244 + value += (char) stream.get();
235 245 }
236 246 row[nColumn] = value.trim();
237   - } else if (dataType.equals(DataType.BOOLEAN) || dataType.equals(DataType.BIT)) {
238   - row[nColumn] = new Boolean(getValue(blockSize) == 0 ? false : true);
239   - } else if (dataType.equals(DataType.UNSIGNED_BYTE) || dataType.equals(DataType.SHORT)) {
240   - row[nColumn] = new Short((short) getValue(blockSize));
241   - } else if (dataType.equals(DataType.INT)) {
242   - row[nColumn] = new Integer(getValue(blockSize));
243   - } else if (dataType.equals(DataType.LONG)) {
244   - row[nColumn] = new Long(getValue(blockSize));
245   - } else { // float
246   - row[nColumn] = new Float(getValue(blockSize));
  247 + } else if (dataType.equals(DataType.UNICODE_CHAR)) {
  248 + String value = new String();
  249 + for (int i = 0; i < arraySize && cursor < stream.capacity(); i += 2) {
  250 + value += stream.getChar();
  251 + }
  252 + row[nColumn] = value.trim();
  253 + } else if (dataType.equals(DataType.FLOAT)) {
  254 + row[nColumn] = stream.getFloat();
  255 + } else if (dataType.equals(DataType.DOUBLE)) {
  256 + row[nColumn] = stream.getDouble();
  257 + } else {
  258 + logger.warn("Data type " + dataType + " is not supprted.");
247 259 }
248 260  
249   - // logger.debug("**" + columnsName[nColumn] + "**: " + row[nColumn])
  261 + // logger.debug(columnsName[nColumn] + ": " + row[nColumn])
250 262  
251 263 row[nColumn] = row[nColumn];
252 264 if (nColumn == columnsName.length - 1) {
... ... @@ -283,20 +295,4 @@ public class VOTableDataParser {
283 295 logger.info("Parsing data in FITS stream...");
284 296 // TODO Implement parseFITSStream()
285 297 }
286   -
287   - /**
288   - * Get the integer value of a bytes block. For example, [0x01, 0x05] returns 230, and increment
289   - * the cursor.
290   - *
291   - * @param blockSize The size of the bytes block to get
292   - * @return The integer value of the bytes block.
293   - */
294   - private int getValue(int blockSize) {
295   - int intVal = 0;
296   - for (int i = 0; i < blockSize; i++) {
297   - intVal += 0xFF & (bytes[cursor + i] << ((blockSize - 1 - i) * 8));
298   - }
299   - cursor += blockSize;
300   - return intVal;
301   - }
302 298 }
... ...