* Bug #15456 fixed: Xcos 5.5.x files did not load properly
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / ScilabTypeCoder.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2015 - Scilab Enterprises - Clement DAVID
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 package org.scilab.modules.xcos.io;
16
17 import java.nio.ByteBuffer;
18 import java.nio.DoubleBuffer;
19 import java.nio.IntBuffer;
20 import java.nio.LongBuffer;
21 import java.nio.charset.Charset;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.IllegalFormatException;
26 import org.scilab.modules.types.ScilabBoolean;
27 import org.scilab.modules.types.ScilabDouble;
28 import org.scilab.modules.types.ScilabInteger;
29 import org.scilab.modules.types.ScilabIntegerTypeEnum;
30 import org.scilab.modules.types.ScilabList;
31 import org.scilab.modules.types.ScilabMList;
32 import org.scilab.modules.types.ScilabString;
33 import org.scilab.modules.types.ScilabTList;
34 import org.scilab.modules.types.ScilabType;
35 import org.scilab.modules.types.ScilabTypeEnum;
36 import org.scilab.modules.xcos.VectorOfDouble;
37 import org.scilab.modules.xcos.VectorOfInt;
38 import org.scilab.modules.xcos.VectorOfScicosID;
39
40 import java.util.logging.Level;
41 import java.util.logging.Logger;
42
43 /**
44  * Encode and decode using a var2vec / vec2var compatible encoding.
45  *
46  * <p>
47  * This encoder is used to store arbitrary data to the model. Usually some
48  * properties are hard to map to both Java and C++ STL type system, using a
49  * shared encoding let us provide an implementation whatever the language is
50  * without sharing too low-level information.
51  */
52 public class ScilabTypeCoder {
53
54     private static final Logger LOG = Logger.getLogger("org.scilab.modules.xcos.io");
55
56     class JavaScilabType {
57
58         final ScilabTypeEnum type;
59         final ScilabIntegerTypeEnum intType;
60
61         public JavaScilabType(ScilabTypeEnum type, ScilabIntegerTypeEnum intType) {
62             this.type = type;
63             this.intType = intType;
64         }
65     }
66
67     /**
68      * current position in the vec buffer
69      */
70     int position = 0;
71
72     public ScilabTypeCoder() {
73     }
74
75     /*
76      * var2vec implementation
77      */
78     /**
79      * Encode any scilab type to a buffer
80      *
81      * @param var the Scilab value to encode
82      * @return the encoded buffer
83      */
84     public VectorOfDouble var2vec(ScilabType var) {
85         final ScilabType value;
86         if (var == null) {
87             value = new ScilabDouble();
88         } else {
89             value = var;
90         }
91
92         if (LOG.isLoggable(Level.FINER)) {
93             LOG.entering(ScilabTypeCoder.class.getCanonicalName(), "var2vec");
94         }
95
96         VectorOfDouble vec = new VectorOfDouble();
97         encode(value, vec);
98
99         // System.err.println("var2vec:" + var.toString() + ":" + toString(vec));
100         if (LOG.isLoggable(Level.FINE)) {
101             LOG.log(Level.FINE, "var2vec:{0}:{1}", new Object[] {var.toString(), toString(vec)});
102         }
103
104         if (LOG.isLoggable(Level.FINER)) {
105             LOG.exiting(ScilabTypeCoder.class.getCanonicalName(), "var2vec");
106         }
107
108         return vec;
109     }
110
111     @SuppressWarnings("unchecked")
112     private VectorOfDouble encode(ScilabType var, VectorOfDouble vec) {
113         switch (var.getType()) {
114             case sci_matrix:
115                 encode((ScilabDouble) var, vec);
116                 break;
117             case sci_ints:
118                 encode((ScilabInteger) var, vec);
119                 break;
120             case sci_boolean:
121                 encode((ScilabBoolean) var, vec);
122                 break;
123             case sci_strings:
124                 encode((ScilabString) var, vec);
125                 break;
126             case sci_list:
127                 encode((ArrayList<ScilabType>) var, vec, var.getType());
128                 break;
129             case sci_mlist:
130                 encode((ArrayList<ScilabType>) var, vec, var.getType());
131                 break;
132             case sci_tlist:
133                 encode((ArrayList<ScilabType>) var, vec, var.getType());
134                 break;
135             default:
136                 break;
137         }
138
139         return vec;
140     }
141
142     /**
143      * Encode the double data
144      *
145      * @param var the data to encode
146      * @param vec the resulting buffer
147      */
148     private void encode(ScilabDouble var, VectorOfDouble vec) {
149         // Header
150         encodeHeader(var, vec, ScilabTypeEnum.sci_matrix);
151         if (var.getHeight() * var.getWidth() == 0) {
152             return;
153         }
154
155         // specific flag for managing the complex case
156         if (var.isReal()) {
157             vec.add(0f);
158         } else {
159             vec.add(1f);
160         }
161
162         // push the data
163         for (int i = 0; i < var.getHeight(); i++) {
164             for (int j = 0; j < var.getWidth(); j++) {
165                 vec.add(var.getRealElement(i, j));
166             }
167         }
168
169         // push the complex data
170         if (!var.isReal()) {
171             for (int i = 0; i < var.getHeight(); i++) {
172                 for (int j = 0; j < var.getWidth(); j++) {
173                     vec.add(var.getImaginaryElement(i, j));
174                 }
175             }
176         }
177     }
178
179     private void encode(ScilabInteger var, VectorOfDouble vec) {
180         // pre-processing: retrieve the raw data per type
181         int sizeof;
182         long[][] longData = null;
183         short[][] shortData = null;
184         int[][] intData = null;
185         byte[][] byteData = null;
186         switch (var.getPrec()) {
187             case sci_int64:
188             case sci_uint64:
189                 sizeof = Long.BYTES;
190                 longData = var.getDataAsLong();
191                 break;
192             case sci_int32:
193             case sci_uint32:
194                 sizeof = Integer.BYTES;
195                 intData = var.getDataAsInt();
196                 break;
197             case sci_int16:
198             case sci_uint16:
199                 sizeof = Short.BYTES;
200                 shortData = var.getDataAsShort();
201                 break;
202             case sci_int8:
203             case sci_uint8:
204                 sizeof = Byte.BYTES;
205                 byteData = var.getDataAsByte();
206                 break;
207             default:
208                 throw new IllegalArgumentException();
209         }
210
211         // Header
212         encodeHeader(var, vec, ScilabTypeEnum.sci_ints);
213         if (var.getHeight() * var.getWidth() == 0) {
214             return;
215         }
216
217         // push the data on a pre-allocated space
218         final int requiredBytes = sizeof * var.getHeight() * var.getWidth();
219         final int doubleLen = (requiredBytes + Double.BYTES - 1) / Double.BYTES;
220         final int index = vec.size();
221         vec.resize(index + doubleLen);
222         ByteBuffer view = vec.asByteBuffer(index, doubleLen);
223
224         for (int i = 0; i < var.getHeight(); i++) {
225             for (int j = 0; j < var.getWidth(); j++) {
226                 switch (var.getPrec()) {
227                     case sci_int64:
228                     case sci_uint64:
229                         view.putLong(longData[i][j]);
230                         break;
231                     case sci_int32:
232                     case sci_uint32:
233                         view.putInt(intData[i][j]);
234                         break;
235                     case sci_int16:
236                     case sci_uint16:
237                         view.putShort(shortData[i][j]);
238                         break;
239                     case sci_int8:
240                     case sci_uint8:
241                         view.put(byteData[i][j]);
242                         break;
243                 }
244             }
245         }
246     }
247
248     private void encode(ScilabBoolean var, VectorOfDouble vec) {
249         // header
250         encodeHeader(var, vec, ScilabTypeEnum.sci_boolean);
251         if (var.getHeight() * var.getWidth() == 0) {
252             return;
253         }
254
255         // put all the boolean as int accordingly to Scilab 6 implementation
256         final int requiredBytes = Integer.BYTES * var.getHeight() * var.getWidth();
257         final int doubleLen = (requiredBytes + Double.BYTES - 1) / Double.BYTES;
258         int index = vec.size();
259         vec.resize(index + doubleLen);
260
261         ByteBuffer buffer = vec.asByteBuffer(index, doubleLen);
262
263         for (int i = 0; i < var.getHeight(); i++) {
264             for (int j = 0; j < var.getWidth(); j++) {
265                 buffer.putInt(var.getData()[i][j] ? 1 : 0);
266             }
267         }
268     }
269
270     private void encode(ScilabString var, VectorOfDouble vec) {
271         // header
272         encodeHeader(var, vec, ScilabTypeEnum.sci_strings);
273         if (var.getHeight() * var.getWidth() == 0) {
274             return;
275         }
276
277         // add the offset table which contains the offset of each UTF-8 encoded strings
278         int offsetTableStart = vec.size();
279         vec.resize(offsetTableStart + var.getHeight() * var.getWidth());
280         int offsetTableAccumulated = 0;
281
282         // encode the strings as UTF-8 and store the associated offset
283         Charset utf8 = Charset.forName("UTF-8");
284         for (int i = 0; i < var.getHeight(); i++) {
285             for (int j = 0; j < var.getWidth(); j++) {
286                 String str = var.getData()[i][j];
287                 byte[] bytes = str.getBytes(utf8);
288                 // append the terminal '\0'
289                 final int requiredBytes = bytes.length + 1;
290                 final int doubleLen = (requiredBytes + Double.BYTES - 1) / Double.BYTES;
291
292                 // set the offset
293                 offsetTableAccumulated += doubleLen;
294                 vec.set(offsetTableStart++, offsetTableAccumulated);
295
296                 // push the data through a temporary byte buffer
297                 int index = vec.size();
298                 vec.resize(index + doubleLen);
299                 vec.asByteBuffer(index, doubleLen).put(bytes).put((byte) 0);
300
301             }
302         }
303     }
304
305     private void encode(ArrayList<ScilabType> var, VectorOfDouble vec, ScilabTypeEnum as) {
306         // header
307         encodeHeader(var, vec, as);
308
309         // encode list content
310         for (ScilabType localVar : var) {
311             encode(localVar, vec);
312         }
313     }
314
315     /**
316      * Helper method to add an header of the detected type
317      *
318      * @param var the scilab matrix type to encode
319      * @param vec the raw encoded data container
320      * @param as the type to encode
321      * @param detected the detected type
322      */
323     @SuppressWarnings({"unchecked", "fallthrough"})
324     private void encodeHeader(Object var, VectorOfDouble vec, final ScilabTypeEnum as) {
325         ScilabType matrix = null;
326         ArrayList<ScilabType> list = null;
327
328         // defensive programming
329         switch (as) {
330             case sci_boolean:
331             case sci_ints:
332             case sci_matrix:
333             case sci_strings:
334                 matrix = (ScilabType) var;
335                 break;
336             case sci_list:
337             case sci_mlist:
338             case sci_tlist:
339                 list = (ArrayList<ScilabType>) var;
340                 break;
341             default:
342                 throw new IllegalArgumentException();
343         }
344
345         // corner-case [] is a ScilabDouble
346         if (matrix != null && matrix.getHeight() * matrix.getWidth() == 0) {
347             vec.add(ScilabTypeEnum.sci_matrix.swigValue());
348             vec.add(2);
349             vec.add(0);
350             vec.add(0);
351             vec.add(0); // isComplex is part of []
352             return;
353         }
354
355         vec.add(as.swigValue());
356         if (matrix instanceof ScilabInteger) {
357             vec.add(((ScilabInteger) matrix).getPrec().swigValue());
358         }
359         if (matrix != null) {
360             vec.add(2);
361             vec.add(matrix.getHeight());
362             vec.add(matrix.getWidth());
363         } else if (list != null) {
364             vec.add(list.size());
365         } else {
366             throw new IllegalArgumentException();
367         }
368     }
369
370     /*
371      * vec2var implementation
372      */
373     /**
374      * Decode a scilab type from a buffer
375      *
376      * @param vec the buffer containing encoded scilab types
377      * @return the decoded scilab type
378      */
379     public ScilabType vec2var(VectorOfDouble vec) {
380         position = 0;
381
382         if (LOG.isLoggable(Level.FINER)) {
383             LOG.entering(ScilabTypeCoder.class.getName(), "vec2var", vec);
384         }
385
386         ScilabType var = decodeHeader(vec);
387         decode(vec, var);
388
389         // System.err.println("vec2var:" + toString(vec) + ":" + var.toString());
390         if (LOG.isLoggable(Level.FINE)) {
391             LOG.log(Level.FINE, "vec2var:{0}:{1}", new Object[] {toString(vec), var.toString()});
392         }
393
394         if (LOG.isLoggable(Level.FINER)) {
395             LOG.exiting(ScilabTypeCoder.class.getName(), "vec2var");
396         }
397
398         return var;
399     }
400
401     @FunctionalInterface
402     private static interface StoreFunction<R, C, V> {
403         public void apply(R r, C c, V v);
404     }
405
406     @SuppressWarnings("unchecked")
407     private ScilabType decode(VectorOfDouble vec, ScilabType var) {
408         switch (var.getType()) {
409             case sci_matrix:
410                 decode(vec, (ScilabDouble) var);
411                 break;
412             case sci_ints:
413                 decode(vec, (ScilabInteger) var);
414                 break;
415             case sci_boolean:
416                 decode(vec, (ScilabBoolean) var);
417                 break;
418             case sci_strings:
419                 decode(vec, (ScilabString) var);
420                 break;
421             case sci_list:
422                 decode(vec, (ArrayList<ScilabType>) var);
423                 break;
424             case sci_mlist:
425                 decode(vec, (ArrayList<ScilabType>) var);
426                 break;
427             case sci_tlist:
428                 decode(vec, (ArrayList<ScilabType>) var);
429                 break;
430             default:
431                 break;
432         }
433         return var;
434     }
435
436     private ScilabType decode(VectorOfDouble vec, ScilabDouble var) {
437         double[][] realPart = var.getRealPart();
438         for (int i = 0; i < var.getHeight(); i++) {
439             for (int j = 0; j < var.getWidth(); j++) {
440                 realPart[i][j] = vec.get(position++);
441             }
442         }
443
444         if (!var.isReal()) {
445             double[][] imaginaryPart = var.getImaginaryPart();
446
447             for (int i = 0; i < var.getHeight(); i++) {
448                 for (int j = 0; j < var.getWidth(); j++) {
449                     imaginaryPart[i][j] = vec.get(position++);
450                 }
451             }
452         }
453         return var;
454     }
455
456     private ScilabType decode(VectorOfDouble vec, ScilabInteger var) {
457         final int sizeof;
458         long[][] longData = null;
459         short[][] shortData = null;
460         int[][] intData = null;
461         byte[][] byteData = null;
462
463         switch (var.getPrec()) {
464             case sci_int64:
465             case sci_uint64:
466                 sizeof = Long.BYTES;
467                 longData = var.getDataAsLong();
468                 break;
469             case sci_int32:
470             case sci_uint32:
471                 sizeof = Integer.BYTES;
472                 intData = var.getDataAsInt();
473                 break;
474             case sci_int16:
475             case sci_uint16:
476                 sizeof = Short.BYTES;
477                 shortData = var.getDataAsShort();
478                 break;
479             case sci_int8:
480             case sci_uint8:
481                 sizeof = Byte.BYTES;
482                 byteData = var.getDataAsByte();
483                 break;
484             default:
485                 throw new IllegalArgumentException();
486         }
487
488         final int doubleLen = (sizeof * var.getHeight() * var.getWidth()) / Double.BYTES + 1;
489         ByteBuffer view = vec.asByteBuffer(position, doubleLen);
490
491         for (int i = 0; i < var.getHeight(); i++) {
492             for (int j = 0; j < var.getWidth(); j++) {
493                 switch (var.getPrec()) {
494                     case sci_int64:
495                     case sci_uint64:
496                         longData[i][j] = view.getLong();
497                         break;
498                     case sci_int32:
499                     case sci_uint32:
500                         intData[i][j] = view.getInt();
501                         break;
502                     case sci_int16:
503                     case sci_uint16:
504                         shortData[i][j] = view.getShort();
505                         break;
506                     case sci_int8:
507                     case sci_uint8:
508                         byteData[i][j] = view.get();
509                         break;
510                 }
511             }
512         }
513         position += doubleLen;
514
515         return var;
516     }
517
518     private ScilabType decode(VectorOfDouble vec, ScilabBoolean var) {
519         final boolean[][] data = var.getData();
520
521         final int doubleLen = (Integer.BYTES * var.getHeight() * var.getWidth()) / Double.BYTES + 1;
522         ByteBuffer view = vec.asByteBuffer(position, doubleLen);
523
524         for (int i = 0; i < var.getHeight(); i++) {
525             for (int j = 0; j < var.getWidth(); j++) {
526                 data[i][j] = view.getInt() != 0;
527             }
528         }
529         position += doubleLen;
530         return var;
531     }
532
533     private ScilabType decode(VectorOfDouble vec, ScilabString var) {
534         final String[][] data = var.getData();
535         decodeString(var.getHeight(), var.getWidth(), vec, (i, j, str) -> data[i][j] = str);
536         return var;
537     }
538
539     private void decodeString(int height, int width, VectorOfDouble vec, StoreFunction<Integer, Integer, String> store) {
540         // reconstruct the offset
541         int[][] offset = new int[height][width];
542         for (int i = 0; i < height; i++) {
543             for (int j = 0; j < width; j++) {
544                 offset[i][j] = (int) vec.get(position++);
545             }
546         }
547
548         Charset utf8 = Charset.forName("UTF-8");
549         int accumulatedOffset = 0;
550         // reconstruct each String object
551         for (int i = 0; i < height; i++) {
552             for (int j = 0; j < width; j++) {
553                 final int nbOfDouble = offset[i][j] - accumulatedOffset;
554                 ByteBuffer view = vec.asByteBuffer(position, nbOfDouble);
555                 byte[] bytes = new byte[nbOfDouble * Double.BYTES];
556
557                 view.get(bytes);
558
559                 // to avoid mis-decoding we have to pass the len of bytes
560                 int strlen = 0;
561                 while (bytes[strlen] != 0) {
562                     strlen++;
563                 }
564
565                 store.apply(i, j, new String(bytes, 0, strlen, utf8));
566
567                 accumulatedOffset += nbOfDouble;
568                 position += nbOfDouble;
569             }
570         }
571     }
572
573     private ScilabType decode(VectorOfDouble vec, ArrayList<ScilabType> var) {
574         for (int i = 0; i < var.size(); i++) {
575             ScilabType sub = decodeHeader(vec);
576             decode(vec, sub);
577
578             var.set(i, sub);
579         }
580         return (ScilabType) var;
581     }
582
583     @SuppressWarnings("fallthrough")
584     private ScilabType decodeHeader(VectorOfDouble vec) {
585         int nativeScilabType = (int) vec.get(position++);
586
587         // specific integer sub-type
588         int precision = 0;
589
590         // for data[][]-based type
591         int height = 0;
592         int width = 0;
593
594         // for ArrayList-based type
595         int listLen = 0;
596
597         final ScilabTypeEnum type = ScilabTypeEnum.swigToEnum(nativeScilabType);
598         switch (type) {
599             case sci_ints:
600                 // special case for integer precision
601                 precision = (int) vec.get(position++);
602             case sci_matrix:
603             case sci_boolean:
604             case sci_strings:
605                 position++; // n-Dims not managed
606                 height = (int) vec.get(position++);
607                 width = (int) vec.get(position++);
608                 break;
609             case sci_list:
610             case sci_mlist:
611             case sci_tlist:
612                 listLen = (int) vec.get(position++);
613                 break;
614             default:
615                 throw new IllegalArgumentException();
616         }
617
618         // special case for complex double matrix
619         double[][] imagData = null;
620         if (type == ScilabTypeEnum.sci_matrix) {
621             boolean isComplex = vec.get(position++) != 0;
622
623             if (isComplex) {
624                 imagData = new double[height][width];
625             }
626         }
627
628         // allocate the right type with the decoded properties
629         switch (type) {
630             case sci_matrix:
631                 if (height * width == 0) {
632                     return new ScilabDouble();
633                 } else {
634                     return new ScilabDouble(new double[height][width], imagData);
635                 }
636             case sci_boolean:
637                 if (height * width == 0) {
638                     return new ScilabDouble();
639                 } else {
640                     return new ScilabBoolean(new boolean[height][width]);
641                 }
642             case sci_ints:
643                 if (height * width == 0) {
644                     return new ScilabDouble();
645                 } else {
646                     switch (ScilabIntegerTypeEnum.swigToEnum(precision)) {
647                         case sci_int8:
648                             return new ScilabInteger(new byte[height][width], false);
649                         case sci_int16:
650                             return new ScilabInteger(new short[height][width], false);
651                         case sci_int32:
652                             return new ScilabInteger(new int[height][width], false);
653                         case sci_int64:
654                             return new ScilabInteger(new long[height][width], false);
655                         case sci_uint8:
656                             return new ScilabInteger(new byte[height][width], true);
657                         case sci_uint16:
658                             return new ScilabInteger(new short[height][width], true);
659                         case sci_uint32:
660                             return new ScilabInteger(new int[height][width], true);
661                         case sci_uint64:
662                             return new ScilabInteger(new long[height][width], true);
663
664                     }
665                 }
666             case sci_strings:
667                 if (height * width == 0) {
668                     return new ScilabDouble();
669                 } else {
670                     return new ScilabString(new String[height][width]);
671                 }
672             case sci_list:
673                 return new ScilabList(Collections.nCopies(listLen, null));
674             case sci_mlist:
675                 return new ScilabMList(new String[listLen - 1], Collections.nCopies(listLen - 1, null));
676             case sci_tlist:
677                 return new ScilabTList(new String[listLen - 1], Collections.nCopies(listLen - 1, null));
678             default:
679                 throw new IllegalArgumentException();
680
681         }
682     }
683
684     /**
685      * Format the encoded value accordingly to the Java format string
686      *
687      * @param format a
688      * {@link String#format(java.lang.String, java.lang.Object...)} compatible
689      * argument
690      * @param vec the buffer containing encoded scilab types
691      * @throws IllegalFormatException when the underlying formatting failed
692      * @throws IllegalArgumentException when the vec argument is wrongly encoded
693      * @return A formatted string
694      */
695     public String format(String format, VectorOfDouble vec) throws IllegalFormatException, IllegalArgumentException {
696         ArrayList<Object> arguments = new ArrayList<>();
697         decodeToJava(vec, arguments);
698         return String.format(format, arguments.toArray());
699     }
700
701     private void decodeToJava(VectorOfDouble vec, ArrayList<Object> arguments) {
702         int nativeScilabType = (int) vec.get(position++);
703
704         // specific integer sub-type
705         int precision = 0;
706
707         // for data[][]-based type
708         int height = 0;
709         int width = 0;
710
711         // for ArrayList-based type
712         int listLen = 0;
713
714         final ScilabTypeEnum type = ScilabTypeEnum.swigToEnum(nativeScilabType);
715         switch (type) {
716             case sci_ints:
717                 // special case for integer precision
718                 precision = (int) vec.get(position++);
719             case sci_matrix:
720             case sci_boolean:
721             case sci_strings:
722                 position++; // n-Dims not managed
723                 height = (int) vec.get(position++);
724                 width = (int) vec.get(position++);
725                 break;
726             case sci_list:
727             case sci_mlist:
728             case sci_tlist:
729                 listLen = (int) vec.get(position++);
730                 break;
731             default:
732                 throw new IllegalArgumentException();
733         }
734
735         // special case for complex double matrix
736         boolean isComplex = false;
737         if (type == ScilabTypeEnum.sci_matrix) {
738             isComplex = vec.get(position++) != 0;
739         }
740
741         // allocate the right type with the decoded properties
742         switch (type) {
743             case sci_matrix:
744                 for (int i = 0; i < height; i++) {
745                     for (int j = 0; j < width; j++) {
746                         arguments.add(vec.get(position++));
747                     }
748                 }
749
750                 if (isComplex) {
751                     for (int i = 0; i < height; i++) {
752                         for (int j = 0; j < width; j++) {
753                             arguments.add(vec.get(position++));
754                         }
755                     }
756                 }
757                 break;
758             case sci_boolean: {
759                 final int doubleLen = (Integer.BYTES * height * width) / Double.BYTES + 1;
760                 ByteBuffer view = vec.asByteBuffer(position, doubleLen);
761                 for (int i = 0; i < height; i++) {
762                     for (int j = 0; j < width; j++) {
763                         arguments.add(view.getInt() != 0);
764                     }
765                 }
766                 position += doubleLen;
767             }
768             break;
769             case sci_ints:
770                 switch (ScilabIntegerTypeEnum.swigToEnum(precision)) {
771                     case sci_int8:
772                     case sci_uint8: {
773                         final int sizeof = Byte.BYTES;
774                         final int doubleLen = (sizeof * height * width) / Double.BYTES + 1;
775                         ByteBuffer view = vec.asByteBuffer(position, doubleLen);
776                         for (int i = 0; i < height; i++) {
777                             for (int j = 0; j < width; j++) {
778                                 arguments.add(view.get());
779                             }
780                         }
781                     }
782                     break;
783                     case sci_int16:
784                     case sci_uint16: {
785                         final int sizeof = Short.BYTES;
786                         final int doubleLen = (sizeof * height * width) / Double.BYTES + 1;
787                         ByteBuffer view = vec.asByteBuffer(position, doubleLen);
788                         for (int i = 0; i < height; i++) {
789                             for (int j = 0; j < width; j++) {
790                                 arguments.add(view.getShort());
791                             }
792                         }
793                     }
794                     break;
795                     case sci_int32:
796                     case sci_uint32: {
797                         final int sizeof = Integer.BYTES;
798                         final int doubleLen = (sizeof * height * width) / Double.BYTES + 1;
799                         ByteBuffer view = vec.asByteBuffer(position, doubleLen);
800                         for (int i = 0; i < height; i++) {
801                             for (int j = 0; j < width; j++) {
802                                 arguments.add(view.getInt());
803                             }
804                         }
805                     }
806                     break;
807                     case sci_int64:
808                     case sci_uint64: {
809                         final int sizeof = Long.BYTES;
810                         final int doubleLen = (sizeof * height * width) / Double.BYTES + 1;
811                         ByteBuffer view = vec.asByteBuffer(position, doubleLen);
812                         for (int i = 0; i < height; i++) {
813                             for (int j = 0; j < width; j++) {
814                                 arguments.add(view.getLong());
815                             }
816                         }
817                     }
818                     break;
819                 }
820                 break;
821             case sci_strings:
822                 decodeString(height, width, vec, (i, j, v) -> arguments.add(v));
823                 break;
824             case sci_list:
825             case sci_mlist:
826             case sci_tlist: {
827                 for (int i = 0; i < listLen; i++) {
828                     decodeToJava(vec, arguments);
829                 }
830             }
831             break;
832             default:
833                 throw new IllegalArgumentException();
834         }
835     }
836
837     /**
838      * Utility to display a vec on debug
839      *
840      * @param vec the vector to convert
841      * @return a representative string
842      */
843     public static String toString(VectorOfDouble vec) {
844         int len = vec.size();
845         double[] copy = new double[len];
846         DoubleBuffer.wrap(copy).put(vec.asByteBuffer(0, len).asDoubleBuffer());
847         return Arrays.toString(copy);
848     }
849
850     /**
851      * Utility to display a vec on debug
852      *
853      * @param vec the vector to convert
854      * @return a representative string
855      */
856     public static String toString(VectorOfScicosID vec) {
857         int len = vec.size();
858         long[] copy = new long[len];
859         LongBuffer.wrap(copy).put(vec.asByteBuffer(0, len).asLongBuffer());
860         return Arrays.toString(copy);
861     }
862
863     /**
864      * Utility to display a vec on debug
865      *
866      * @param vec the vector to convert
867      * @return a representative string
868      */
869     public static String toString(VectorOfInt vec) {
870         int len = vec.size();
871         int[] copy = new int[len];
872         IntBuffer.wrap(copy).put(vec.asByteBuffer(0, len).asIntBuffer());
873         return Arrays.toString(copy);
874     }
875 }