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,9 +39,6 @@ public final class BinaryStreamParser implements DataParser {
39 /** The logger for the class BinaryStreamParser. */ 39 /** The logger for the class BinaryStreamParser. */
40 private static final Logger LOGGER = Logger.getLogger(BinaryStreamParser.class.getName()); 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 /** The XML nodes of VOTable document, containing the column names. */ 42 /** The XML nodes of VOTable document, containing the column names. */
46 private List<Field> fieldsNodes; 43 private List<Field> fieldsNodes;
47 44
@@ -61,7 +58,6 @@ public final class BinaryStreamParser implements DataParser { @@ -61,7 +58,6 @@ public final class BinaryStreamParser implements DataParser {
61 * Binary serialization in the VOTable REC.</a> 58 * Binary serialization in the VOTable REC.</a>
62 */ 59 */
63 public BinaryStreamParser(Stream voStream, List<Field> fieldsNodes) { 60 public BinaryStreamParser(Stream voStream, List<Field> fieldsNodes) {
64 - cursor = 0;  
65 this.fieldsNodes = fieldsNodes; 61 this.fieldsNodes = fieldsNodes;
66 String strStream = voStream.getValue().replaceAll("(\\r|\\n)", ""); 62 String strStream = voStream.getValue().replaceAll("(\\r|\\n)", "");
67 stream = ByteBuffer.wrap(DatatypeConverter.parseBase64Binary(strStream)); 63 stream = ByteBuffer.wrap(DatatypeConverter.parseBase64Binary(strStream));
@@ -118,7 +114,7 @@ public final class BinaryStreamParser implements DataParser { @@ -118,7 +114,7 @@ public final class BinaryStreamParser implements DataParser {
118 int colId = nValue % nbColumns; 114 int colId = nValue % nbColumns;
119 Field column = fieldsNodes.get(colId); 115 Field column = fieldsNodes.get(colId);
120 116
121 - rowSize = getRowSize(column); 117 + rowSize = getRowSize(column, stream);
122 118
123 // May be useful: if arraySize == 0, continue 119 // May be useful: if arraySize == 0, continue
124 120
@@ -126,7 +122,7 @@ public final class BinaryStreamParser implements DataParser { @@ -126,7 +122,7 @@ public final class BinaryStreamParser implements DataParser {
126 row = new Object[nbColumns]; 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 if (colId == nbColumns - 1) { 127 if (colId == nbColumns - 1) {
132 data.add(row); 128 data.add(row);
@@ -139,11 +135,12 @@ public final class BinaryStreamParser implements DataParser { @@ -139,11 +135,12 @@ public final class BinaryStreamParser implements DataParser {
139 /** 135 /**
140 * @param column The XML node of the VOTable data, containing informations about the column, 136 * @param column The XML node of the VOTable data, containing informations about the column,
141 * like the data primitive type. 137 * like the data primitive type.
  138 + * @param byteBuffer The stream.
142 * @return The size of the row, in bytes. 139 * @return The size of the row, in bytes.
143 * @throws BufferUnderflowException Can not get the array size because there is no bytes to read 140 * @throws BufferUnderflowException Can not get the array size because there is no bytes to read
144 * in the stream. 141 * in the stream.
145 */ 142 */
146 - private int getRowSize(Field column) { 143 + private static int getRowSize(Field column, ByteBuffer byteBuffer) {
147 DataType dataType = column.getDatatype(); 144 DataType dataType = column.getDatatype();
148 int blockSize = getBlockSize(dataType); 145 int blockSize = getBlockSize(dataType);
149 int arraySize; 146 int arraySize;
@@ -151,7 +148,7 @@ public final class BinaryStreamParser implements DataParser { @@ -151,7 +148,7 @@ public final class BinaryStreamParser implements DataParser {
151 arraySize = blockSize; 148 arraySize = blockSize;
152 } else if ("*".equals(column.getArraysize())) { 149 } else if ("*".equals(column.getArraysize())) {
153 try { 150 try {
154 - arraySize = stream.getInt() * blockSize; 151 + arraySize = byteBuffer.getInt() * blockSize;
155 } catch (BufferUnderflowException e) { 152 } catch (BufferUnderflowException e) {
156 LOGGER.log(Level.SEVERE, "No space left on stream, can not get array size", e); 153 LOGGER.log(Level.SEVERE, "No space left on stream, can not get array size", e);
157 throw new BufferUnderflowException(); 154 throw new BufferUnderflowException();
@@ -167,160 +164,286 @@ public final class BinaryStreamParser implements DataParser { @@ -167,160 +164,286 @@ public final class BinaryStreamParser implements DataParser {
167 * @return An object representing the data. It can be any of the primitive type defined in the 164 * @return An object representing the data. It can be any of the primitive type defined in the
168 * VOtableREC. See http://www.ivoa.net/documents/REC/VOTable/VOTable-20040811.html#ToC11 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 Object dataBlock; 168 Object dataBlock;
172 int blockSize = getBlockSize(dataType); 169 int blockSize = getBlockSize(dataType);
  170 + int nbElement = blockSize == 0 ? 0 : rowSize / blockSize;
  171 + if (nbElement == 0) {
  172 + return "";
  173 + }
173 if (dataType.equals(DataType.BOOLEAN)) { 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 } else if (dataType.equals(DataType.UNSIGNED_BYTE)) { 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 } else if (dataType.equals(DataType.SHORT)) { 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 } else if (dataType.equals(DataType.INT)) { 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 } else if (dataType.equals(DataType.LONG)) { 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 } else if (dataType.equals(DataType.CHAR)) { 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 } else if (dataType.equals(DataType.UNICODE_CHAR)) { 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 } else if (dataType.equals(DataType.FLOAT)) { 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 } else if (dataType.equals(DataType.DOUBLE)) { 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 } else if (dataType.equals(DataType.FLOAT_COMPLEX)) { 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 } else if (dataType.equals(DataType.DOUBLE_COMPLEX)) { 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 } else { 196 } else {
321 BinaryStreamParser.LOGGER.warning("Data type " + dataType + " is not supported."); 197 BinaryStreamParser.LOGGER.warning("Data type " + dataType + " is not supported.");
322 dataBlock = null; 198 dataBlock = null;
323 } 199 }
324 return dataBlock; 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,6 +20,7 @@ import java.util.ArrayList;
20 import java.util.List; 20 import java.util.List;
21 import java.util.logging.Logger; 21 import java.util.logging.Logger;
22 22
  23 +import eu.omp.irap.vespa.epntapclient.votable.model.EncodingType;
23 import eu.omp.irap.vespa.epntapclient.votable.model.Field; 24 import eu.omp.irap.vespa.epntapclient.votable.model.Field;
24 import eu.omp.irap.vespa.epntapclient.votable.model.TableData; 25 import eu.omp.irap.vespa.epntapclient.votable.model.TableData;
25 import eu.omp.irap.vespa.epntapclient.votable.model.Td; 26 import eu.omp.irap.vespa.epntapclient.votable.model.Td;
@@ -58,7 +59,13 @@ public class TableDataParser implements DataParser { @@ -58,7 +59,13 @@ public class TableDataParser implements DataParser {
58 Object[] rowRes = new Object[fieldsNodes.size()]; 59 Object[] rowRes = new Object[fieldsNodes.size()];
59 List<Td> tds = row.getTD(); 60 List<Td> tds = row.getTD();
60 for (int i = 0; i < fieldsNodes.size(); i++) { 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 res.add(rowRes); 70 res.add(rowRes);
64 } 71 }