Compare View
Commits (2)
Showing
2 changed files
Show diff stats
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 | } | ... | ... |