Compare View

switch
from
...
to
 
Commits (2)
src/main/java/eu/omp/irap/vespa/votable/votabledata/BinaryStreamParser.java
... ... @@ -39,9 +39,6 @@ public final class BinaryStreamParser implements DataParser {
39 39 /** The logger for the class BinaryStreamParser. */
40 40 private static final Logger LOGGER = Logger.getLogger(BinaryStreamParser.class.getName());
41 41  
42   - /** The index of the current position in the bytes array. */
43   - private int cursor;
44   -
45 42 /** The XML nodes of VOTable document, containing the column names. */
46 43 private List<Field> fieldsNodes;
47 44  
... ... @@ -61,7 +58,6 @@ public final class BinaryStreamParser implements DataParser {
61 58 * Binary serialization in the VOTable REC.</a>
62 59 */
63 60 public BinaryStreamParser(Stream voStream, List<Field> fieldsNodes) {
64   - cursor = 0;
65 61 this.fieldsNodes = fieldsNodes;
66 62 String strStream = voStream.getValue().replaceAll("(\\r|\\n)", "");
67 63 stream = ByteBuffer.wrap(DatatypeConverter.parseBase64Binary(strStream));
... ... @@ -118,7 +114,7 @@ public final class BinaryStreamParser implements DataParser {
118 114 int colId = nValue % nbColumns;
119 115 Field column = fieldsNodes.get(colId);
120 116  
121   - rowSize = getRowSize(column);
  117 + rowSize = getRowSize(column, stream);
122 118  
123 119 // May be useful: if arraySize == 0, continue
124 120  
... ... @@ -126,7 +122,7 @@ public final class BinaryStreamParser implements DataParser {
126 122 row = new Object[nbColumns];
127 123 }
128 124  
129   - row[colId] = processDataBlock(column.getDatatype());
  125 + row[colId] = processDataBlock(column.getDatatype(), rowSize, stream);
130 126  
131 127 if (colId == nbColumns - 1) {
132 128 data.add(row);
... ... @@ -139,11 +135,12 @@ public final class BinaryStreamParser implements DataParser {
139 135 /**
140 136 * @param column The XML node of the VOTable data, containing informations about the column,
141 137 * like the data primitive type.
  138 + * @param byteBuffer The stream.
142 139 * @return The size of the row, in bytes.
143 140 * @throws BufferUnderflowException Can not get the array size because there is no bytes to read
144 141 * in the stream.
145 142 */
146   - private int getRowSize(Field column) {
  143 + private static int getRowSize(Field column, ByteBuffer byteBuffer) {
147 144 DataType dataType = column.getDatatype();
148 145 int blockSize = getBlockSize(dataType);
149 146 int arraySize;
... ... @@ -151,7 +148,7 @@ public final class BinaryStreamParser implements DataParser {
151 148 arraySize = blockSize;
152 149 } else if ("*".equals(column.getArraysize())) {
153 150 try {
154   - arraySize = stream.getInt() * blockSize;
  151 + arraySize = byteBuffer.getInt() * blockSize;
155 152 } catch (BufferUnderflowException e) {
156 153 LOGGER.log(Level.SEVERE, "No space left on stream, can not get array size", e);
157 154 throw new BufferUnderflowException();
... ... @@ -167,160 +164,286 @@ public final class BinaryStreamParser implements DataParser {
167 164 * @return An object representing the data. It can be any of the primitive type defined in the
168 165 * VOtableREC. See http://www.ivoa.net/documents/REC/VOTable/VOTable-20040811.html#ToC11
169 166 */
170   - private Object processDataBlock(DataType dataType) {
  167 + private static Object processDataBlock(DataType dataType, int rowSize, ByteBuffer stream) {
171 168 Object dataBlock;
172 169 int blockSize = getBlockSize(dataType);
  170 + int nbElement = blockSize == 0 ? 0 : rowSize / blockSize;
  171 + if (nbElement == 0) {
  172 + return "";
  173 + }
173 174 if (dataType.equals(DataType.BOOLEAN)) {
174   - if (rowSize != blockSize) {
175   - int nb = rowSize / blockSize;
176   - if (nb == 0) { dataBlock = ""; }
177   - else {
178   - StringJoiner sj = new StringJoiner(" ", "", "");
179   - for (int i = 0; i < nb; i++) {
180   - sj.add(String.valueOf(new Boolean(stream.getInt() == 0 ? false : true)));
181   - }
182   - dataBlock = sj.toString();
183   - }
184   - } else {
185   - dataBlock = new Boolean(stream.getInt() == 0 ? false : true);
186   - }
  175 + dataBlock = processBoolean(nbElement, stream);
187 176 } else if (dataType.equals(DataType.UNSIGNED_BYTE)) {
188   - if (rowSize != blockSize) {
189   - int nb = rowSize / blockSize;
190   - if (nb == 0) { dataBlock = ""; }
191   - else {
192   - StringJoiner sj = new StringJoiner(" ", "", "");
193   - for (int i = 0; i < nb; i++) {
194   - sj.add(String.valueOf(stream.get()));
195   - }
196   - dataBlock = sj.toString();
197   - }
198   - } else {
199   - dataBlock = stream.get();
200   - }
  177 + dataBlock = processUnsignedByte(nbElement, stream);
201 178 } else if (dataType.equals(DataType.SHORT)) {
202   - if (rowSize != blockSize) {
203   - int nb = rowSize / blockSize;
204   - if (nb == 0) { dataBlock = ""; }
205   - else {
206   - StringJoiner sj = new StringJoiner(" ", "", "");
207   - for (int i = 0; i < nb; i++) {
208   - sj.add(String.valueOf(stream.getShort()));
209   - }
210   - dataBlock = sj.toString();
211   - }
212   - } else {
213   - dataBlock = stream.getShort();
214   - }
  179 + dataBlock = processShort(nbElement, stream);
215 180 } else if (dataType.equals(DataType.INT)) {
216   - if (rowSize != blockSize) {
217   - int nb = rowSize / blockSize;
218   - if (nb == 0) { dataBlock = ""; }
219   - else {
220   - StringJoiner sj = new StringJoiner(" ", "", "");
221   - for (int i = 0; i < nb; i++) {
222   - sj.add(String.valueOf(stream.getInt()));
223   - }
224   - dataBlock = sj.toString();
225   - }
226   - } else {
227   - dataBlock = stream.getInt();
228   - }
  181 + dataBlock = processInt(nbElement, stream);
229 182 } else if (dataType.equals(DataType.LONG)) {
230   - if (rowSize != blockSize) {
231   - int nb = rowSize / blockSize;
232   - if (nb == 0) { dataBlock = ""; }
233   - else {
234   - StringJoiner sj = new StringJoiner(" ", "", "");
235   - for (int i = 0; i < nb; i++) {
236   - sj.add(String.valueOf(stream.getLong()));
237   - }
238   - dataBlock = sj.toString();
239   - }
240   - } else {
241   - dataBlock = stream.getLong();
242   - }
  183 + dataBlock = processLong(nbElement, stream);
243 184 } else if (dataType.equals(DataType.CHAR)) {
244   - String value = new String();
245   - for (int i = 0; i < rowSize && cursor < stream.capacity()
246   - && stream.position() < stream.limit(); i++) {
247   - value += (char) stream.get();
248   - }
249   - dataBlock = value.trim();
  185 + dataBlock = processChar(nbElement, stream);
250 186 } else if (dataType.equals(DataType.UNICODE_CHAR)) {
251   - String value = new String();
252   - for (int i = 0; i < rowSize && cursor < stream.capacity(); i += 2) {
253   - value += stream.getChar();
254   - }
255   - dataBlock = value.trim();
  187 + dataBlock = processUnicodeChar(nbElement, stream);
256 188 } else if (dataType.equals(DataType.FLOAT)) {
257   - if (rowSize != blockSize) {
258   - int nb = rowSize / blockSize;
259   - if (nb == 0) { dataBlock = ""; }
260   - else {
261   - StringJoiner sj = new StringJoiner(" ", "", "");
262   - for (int i = 0; i < nb; i++) {
263   - sj.add(String.valueOf(stream.getFloat()));
264   - }
265   - dataBlock = sj.toString();
266   - }
267   - } else {
268   - dataBlock = stream.getFloat();
269   - }
  189 + dataBlock = processFloat(nbElement, stream);
270 190 } else if (dataType.equals(DataType.DOUBLE)) {
271   - if (rowSize != blockSize) {
272   - int nb = rowSize / blockSize;
273   - if (nb == 0) { dataBlock = ""; }
274   - else {
275   - StringJoiner sj = new StringJoiner(" ", "", "");
276   - for (int i = 0; i < nb; i++) {
277   - sj.add(String.valueOf(stream.getDouble()));
278   - }
279   - dataBlock = sj.toString();
280   - }
281   - } else {
282   - dataBlock = stream.getDouble();
283   - }
  191 + dataBlock = processDouble(nbElement, stream);
284 192 } else if (dataType.equals(DataType.FLOAT_COMPLEX)) {
285   - if (rowSize != blockSize) {
286   - int nb = rowSize / blockSize;
287   - if (nb == 0) { dataBlock = ""; }
288   - else {
289   - StringJoiner sj = new StringJoiner(" ", "", "");
290   - for (int i = 0; i < nb; i++) {
291   - sj.add(String.valueOf(stream.getFloat()));
292   - sj.add(String.valueOf(stream.getFloat()));
293   - }
294   - dataBlock = sj.toString();
295   - }
296   - } else {
297   - StringJoiner sj = new StringJoiner(" ", "", "");
298   - sj.add(String.valueOf(stream.getFloat()));
299   - sj.add(String.valueOf(stream.getFloat()));
300   - dataBlock = sj.toString();
301   - }
  193 + dataBlock = processFloatComplex(nbElement, stream);
302 194 } else if (dataType.equals(DataType.DOUBLE_COMPLEX)) {
303   - if (rowSize != blockSize) {
304   - int nb = rowSize / blockSize;
305   - if (nb == 0) { dataBlock = ""; }
306   - else {
307   - StringJoiner sj = new StringJoiner(" ", "", "");
308   - for (int i = 0; i < nb; i++) {
309   - sj.add(String.valueOf(stream.getDouble()));
310   - sj.add(String.valueOf(stream.getDouble()));
311   - }
312   - dataBlock = sj.toString();
313   - }
314   - } else {
315   - StringJoiner sj = new StringJoiner(" ", "", "");
316   - sj.add(String.valueOf(stream.getDouble()));
317   - sj.add(String.valueOf(stream.getDouble()));
318   - dataBlock = sj.toString();
319   - }
  195 + dataBlock = processDoubleComplex(nbElement, stream);
320 196 } else {
321 197 BinaryStreamParser.LOGGER.warning("Data type " + dataType + " is not supported.");
322 198 dataBlock = null;
323 199 }
324 200 return dataBlock;
325 201 }
  202 +
  203 + /**
  204 + * Process a double complex data type and return the result.
  205 + *
  206 + * @param nbElement The number of element inside the byte buffer.
  207 + * @param byteBuffer The Byte Buffer used.
  208 + * @return The processed data.
  209 + */
  210 + private static Object processDoubleComplex(int nbElement, ByteBuffer byteBuffer) {
  211 + Object dataBlock;
  212 + if (nbElement != 1) {
  213 + StringJoiner sj = new StringJoiner(" ", "", "");
  214 + for (int i = 0; i < nbElement; i++) {
  215 + sj.add(String.valueOf(byteBuffer.getDouble()));
  216 + sj.add(String.valueOf(byteBuffer.getDouble()));
  217 + }
  218 + dataBlock = sj.toString();
  219 + } else {
  220 + StringJoiner sj = new StringJoiner(" ", "", "");
  221 + sj.add(String.valueOf(byteBuffer.getDouble()));
  222 + sj.add(String.valueOf(byteBuffer.getDouble()));
  223 + dataBlock = sj.toString();
  224 + }
  225 + return dataBlock;
  226 + }
  227 +
  228 + /**
  229 + * Process a float complex data type and return the result.
  230 + *
  231 + * @param nbElement The number of element inside the byte buffer.
  232 + * @param byteBuffer The Byte Buffer used.
  233 + * @return The processed data.
  234 + */
  235 + private static Object processFloatComplex(int nbElement, ByteBuffer byteBuffer) {
  236 + Object dataBlock;
  237 + if (nbElement != 1) {
  238 + StringJoiner sj = new StringJoiner(" ", "", "");
  239 + for (int i = 0; i < nbElement; i++) {
  240 + sj.add(String.valueOf(byteBuffer.getFloat()));
  241 + sj.add(String.valueOf(byteBuffer.getFloat()));
  242 + }
  243 + dataBlock = sj.toString();
  244 + } else {
  245 + StringJoiner sj = new StringJoiner(" ", "", "");
  246 + sj.add(String.valueOf(byteBuffer.getFloat()));
  247 + sj.add(String.valueOf(byteBuffer.getFloat()));
  248 + dataBlock = sj.toString();
  249 + }
  250 + return dataBlock;
  251 + }
  252 +
  253 + /**
  254 + * Process a double data type and return the result.
  255 + *
  256 + * @param nbElement The number of element inside the byte buffer.
  257 + * @param byteBuffer The Byte Buffer used.
  258 + * @return The processed data.
  259 + */
  260 + private static Object processDouble(int nbElement, ByteBuffer byteBuffer) {
  261 + Object dataBlock;
  262 + if (nbElement != 1) {
  263 + StringJoiner sj = new StringJoiner(" ", "", "");
  264 + for (int i = 0; i < nbElement; i++) {
  265 + sj.add(String.valueOf(byteBuffer.getDouble()));
  266 + }
  267 + dataBlock = sj.toString();
  268 + } else {
  269 + dataBlock = byteBuffer.getDouble();
  270 + }
  271 + return dataBlock;
  272 + }
  273 +
  274 + /**
  275 + * Process a float data type and return the result.
  276 + *
  277 + * @param nbElement The number of element inside the byte buffer.
  278 + * @param byteBuffer The Byte Buffer used.
  279 + * @return The processed data.
  280 + */
  281 + private static Object processFloat(int nbElement, ByteBuffer byteBuffer) {
  282 + Object dataBlock;
  283 + if (nbElement != 1) {
  284 + StringJoiner sj = new StringJoiner(" ", "", "");
  285 + for (int i = 0; i < nbElement; i++) {
  286 + sj.add(String.valueOf(byteBuffer.getFloat()));
  287 + }
  288 + dataBlock = sj.toString();
  289 + } else {
  290 + dataBlock = byteBuffer.getFloat();
  291 + }
  292 + return dataBlock;
  293 + }
  294 +
  295 + /**
  296 + * Process a unicode char data type and return the result.
  297 + *
  298 + * @param nbElement The number of element inside the byte buffer.
  299 + * @param byteBuffer The Byte Buffer used.
  300 + * @return The processed data.
  301 + */
  302 + private static Object processUnicodeChar(int nbElement, ByteBuffer byteBuffer) {
  303 + Object dataBlock;
  304 + String value = new String();
  305 + for (int i = 0; i < nbElement; i += 2) {
  306 + value += byteBuffer.getChar();
  307 + }
  308 + dataBlock = value.trim();
  309 + return dataBlock;
  310 + }
  311 +
  312 + /**
  313 + * Process a char data type and return the result.
  314 + *
  315 + * @param nbElement The number of element inside the byte buffer.
  316 + * @param byteBuffer The Byte Buffer used.
  317 + * @return The processed data.
  318 + */
  319 + private static Object processChar(int nbElement, ByteBuffer byteBuffer) {
  320 + Object dataBlock;
  321 + String value = new String();
  322 + for (int i = 0; i < nbElement && byteBuffer.position() < byteBuffer.limit(); i++) {
  323 + value += (char) byteBuffer.get();
  324 + }
  325 + dataBlock = value.trim();
  326 + return dataBlock;
  327 + }
  328 +
  329 + /**
  330 + * Process a long data type and return the result.
  331 + *
  332 + * @param nbElement The number of element inside the byte buffer.
  333 + * @param byteBuffer The Byte Buffer used.
  334 + * @return The processed data.
  335 + */
  336 + private static Object processLong(int nbElement, ByteBuffer byteBuffer) {
  337 + Object dataBlock;
  338 + if (nbElement != 1) {
  339 + StringJoiner sj = new StringJoiner(" ", "", "");
  340 + for (int i = 0; i < nbElement; i++) {
  341 + sj.add(String.valueOf(byteBuffer.getLong()));
  342 + }
  343 + dataBlock = sj.toString();
  344 + } else {
  345 + dataBlock = byteBuffer.getLong();
  346 + }
  347 + return dataBlock;
  348 + }
  349 +
  350 + /**
  351 + * Process a int data type and return the result.
  352 + *
  353 + * @param nbElement The number of element inside the byte buffer.
  354 + * @param byteBuffer The Byte Buffer used.
  355 + * @return The processed data.
  356 + */
  357 + private static Object processInt(int nbElement, ByteBuffer byteBuffer) {
  358 + Object dataBlock;
  359 + if (nbElement != 1) {
  360 + StringJoiner sj = new StringJoiner(" ", "", "");
  361 + for (int i = 0; i < nbElement; i++) {
  362 + sj.add(String.valueOf(byteBuffer.getInt()));
  363 + }
  364 + dataBlock = sj.toString();
  365 + } else {
  366 + dataBlock = byteBuffer.getInt();
  367 + }
  368 + return dataBlock;
  369 + }
  370 +
  371 + /**
  372 + * Process a short data type and return the result.
  373 + *
  374 + * @param nbElement The number of element inside the byte buffer.
  375 + * @param byteBuffer The Byte Buffer used.
  376 + * @return The processed data.
  377 + */
  378 + private static Object processShort(int nbElement, ByteBuffer byteBuffer) {
  379 + Object dataBlock;
  380 + if (nbElement != 1) {
  381 + StringJoiner sj = new StringJoiner(" ", "", "");
  382 + for (int i = 0; i < nbElement; i++) {
  383 + sj.add(String.valueOf(byteBuffer.getShort()));
  384 + }
  385 + dataBlock = sj.toString();
  386 + } else {
  387 + dataBlock = byteBuffer.getShort();
  388 + }
  389 + return dataBlock;
  390 + }
  391 +
  392 + /**
  393 + * Process a unsigned byte data type and return the result.
  394 + *
  395 + * @param nbElement The number of element inside the byte buffer.
  396 + * @param byteBuffer The Byte Buffer used.
  397 + * @return The processed data.
  398 + */
  399 + private static Object processUnsignedByte(int nbElement, ByteBuffer byteBuffer) {
  400 + Object dataBlock;
  401 + if (nbElement != 1) {
  402 + StringJoiner sj = new StringJoiner(" ", "", "");
  403 + for (int i = 0; i < nbElement; i++) {
  404 + sj.add(String.valueOf(byteBuffer.get()));
  405 + }
  406 + dataBlock = sj.toString();
  407 + } else {
  408 + dataBlock = byteBuffer.get();
  409 + }
  410 + return dataBlock;
  411 + }
  412 +
  413 + /**
  414 + * Process a boolean data type and return the result.
  415 + *
  416 + * @param nbElement The number of element inside the byte buffer.
  417 + * @param byteBuffer The Byte Buffer used.
  418 + * @return The processed data.
  419 + */
  420 + private static Object processBoolean(int nbElement, ByteBuffer byteBuffer) {
  421 + Object dataBlock;
  422 + if (nbElement != 1) {
  423 + StringJoiner sj = new StringJoiner(" ", "", "");
  424 + for (int i = 0; i < nbElement; i++) {
  425 + sj.add(String.valueOf(new Boolean(byteBuffer.getInt() == 0 ? false : true)));
  426 + }
  427 + dataBlock = sj.toString();
  428 + } else {
  429 + dataBlock = new Boolean(byteBuffer.getInt() == 0 ? false : true);
  430 + }
  431 + return dataBlock;
  432 + }
  433 +
  434 + /**
  435 + * Decode then return the value of a TD element base64 encoded.
  436 + *
  437 + * @param content The content.
  438 + * @param field The field.
  439 + * @return The decoded value.
  440 + */
  441 + public static Object readTdValue(String content, Field field) {
  442 + String strStream = content.replaceAll("(\\r|\\n)", "");
  443 + ByteBuffer stream = ByteBuffer.wrap(
  444 + DatatypeConverter.parseBase64Binary(strStream));
  445 + int rowSize = getRowSize(field, stream);
  446 + return processDataBlock(field.getDatatype(), rowSize, stream);
  447 + }
  448 +
326 449 }
... ...
src/main/java/eu/omp/irap/vespa/votable/votabledata/TableDataParser.java
... ... @@ -20,6 +20,7 @@ import java.util.ArrayList;
20 20 import java.util.List;
21 21 import java.util.logging.Logger;
22 22  
  23 +import eu.omp.irap.vespa.epntapclient.votable.model.EncodingType;
23 24 import eu.omp.irap.vespa.epntapclient.votable.model.Field;
24 25 import eu.omp.irap.vespa.epntapclient.votable.model.TableData;
25 26 import eu.omp.irap.vespa.epntapclient.votable.model.Td;
... ... @@ -58,7 +59,13 @@ public class TableDataParser implements DataParser {
58 59 Object[] rowRes = new Object[fieldsNodes.size()];
59 60 List<Td> tds = row.getTD();
60 61 for (int i = 0; i < fieldsNodes.size(); i++) {
61   - rowRes[i] = tds.get(i).getValue().isEmpty() ? "": tds.get(i).getValue();
  62 + Td td = tds.get(i);
  63 + if (EncodingType.BASE_64 == td.getEncoding()) {
  64 + Field field = fieldsNodes.get(i);
  65 + rowRes[i] = BinaryStreamParser.readTdValue(td.getValue(), field);
  66 + } else {
  67 + rowRes[i] = td.getValue().isEmpty() ? "": td.getValue();
  68 + }
62 69 }
63 70 res.add(rowRes);
64 71 }
... ...