Improved type ScilabInteger (avoid the Long conversion)
[scilab.git] / scilab / modules / types / src / java / org / scilab / modules / types / scilabTypes / ScilabInteger.java
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2009-2009 - DIGITEO - Antoine ELIAS
4  * 
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  * 
11  */
12
13 package org.scilab.modules.types.scilabTypes;
14
15 import java.util.Arrays;
16
17 /**
18  * This class provides a wrapping on the Scilab Integer datatype
19  */
20 public class ScilabInteger implements ScilabType {
21
22         private long[][] longData = null;
23         private short[][] shortData = null;
24         private int[][] intData = null;
25         private byte[][] byteData = null;
26         private IntegerType prec;
27         private boolean bUnsigned;
28
29         /**
30          * The different size of the integer type.
31          */
32         public enum IntegerType {
33                 /** Integer of size 8 */
34                 TYPE8,
35                 /** Integer of size 16 */
36                 TYPE16,
37                 /** Integer of size 32 */
38                 TYPE32,
39                 /** Integer of size 64 */
40                 TYPE64
41         }
42         
43         /**
44          * Default constructor
45          */
46         public ScilabInteger() {
47
48         }
49
50         /**
51          * Constructor with values
52          * 
53          * @param data the values
54          * @param bUnsigned true, if the values are unsigned; false if they are signed.
55          */
56         public ScilabInteger(byte[][] data, boolean bUnsigned) {
57                 this.setData(data, bUnsigned);
58         }
59
60         /**
61          * Constructor with values
62          * 
63          * @param data the values
64          * @param bUnsigned true, if the values are unsigned; false if they are signed.
65          */
66         public ScilabInteger(short[][] data, boolean bUnsigned) {
67                 this.setData(data, bUnsigned);
68         }
69
70         /**
71          * Constructor with values
72          * 
73          * @param data the values
74          * @param bUnsigned true, if the values are unsigned; false if they are signed.
75          */
76         public ScilabInteger(int[][] data, boolean bUnsigned) {
77                 this.setData(data, bUnsigned);
78         }
79
80         /**
81          * Constructor with values
82          * 
83          * @param data the values
84          * @param bUnsigned true, if the values are unsigned; false if they are signed.
85          */
86         public ScilabInteger(long[][] data, boolean bUnsigned) {
87                 this.setData(data, bUnsigned);
88         }
89
90         /**
91          * Constructor with single signed value
92          * 
93          * @param value the unique value
94          */
95         public ScilabInteger(byte value) {
96                 this.byteData = new byte[1][1];
97                 this.byteData[0][0] = value;
98                 this.prec = IntegerType.TYPE8;
99         }
100
101         /**
102          * Constructor with single signed value
103          * 
104          * @param value the unique value
105          */
106         public ScilabInteger(short value) {
107                 this.shortData = new short[1][1];
108                 this.shortData[0][0] = value;
109                 this.prec = IntegerType.TYPE16;
110         }
111
112         /**
113          * Constructor with single signed value
114          * 
115          * @param value the unique value
116          */
117         public ScilabInteger(int value) {
118                 this.intData = new int[1][1];
119                 this.intData[0][0] = value;
120                 this.prec = IntegerType.TYPE32;
121         }
122
123         /**
124          * Constructor with single signed value
125          * 
126          * @param value the unique value
127          */
128         public ScilabInteger(long value) {
129                 this.longData = new long[1][1];
130                 this.longData[0][0] = value;
131                 this.prec = IntegerType.TYPE64;
132         }
133
134         /**
135          * Set the current values 
136          * 
137          * @param data the values to set
138          * @param bUnsigned true, if these values are unsigned; false otherwise.
139          */
140         public void setData(byte[][] data, boolean bUnsigned) {
141                 this.byteData = data;
142                 prec = IntegerType.TYPE8;
143                 this.bUnsigned = bUnsigned; 
144         }
145
146         /**
147          * Set the current values 
148          * 
149          * @param data the values to set
150          * @param bUnsigned true, if these values are unsigned; false otherwise.
151          */
152         public void setData(short[][] data, boolean bUnsigned) {
153                 this.shortData = data;
154                 prec = IntegerType.TYPE16;
155                 this.bUnsigned = bUnsigned; 
156         }
157
158         /**
159          * Set the current values 
160          * 
161          * @param data the values to set
162          * @param bUnsigned true, if these values are unsigned; false otherwise.
163          */
164         public void setData(int[][] data, boolean bUnsigned) {
165                 this.intData = data;
166                 prec = IntegerType.TYPE32;
167                 this.bUnsigned = bUnsigned; 
168         }
169
170         /**
171          * Set the current values 
172          * 
173          * @param data the values to set
174          * @param bUnsigned true, if these values are unsigned; false otherwise.
175          */
176         public void setData(long[][] data, boolean bUnsigned) {
177                 this.longData = data;
178                 prec = IntegerType.TYPE64;
179                 this.bUnsigned = bUnsigned; 
180         }
181
182         /**
183          * If the precision is not 64, all values will be converted to long 
184          * (attention, the convertion can be long)
185          * if precision is 64, just return the data
186          * @return the values
187          */
188         public long[][] getData() {
189                 long[][] convertedMatrix = new long[this.getHeight()][this.getWidth()];
190                 switch (this.getPrec()) {
191
192                         case TYPE8:
193                                 for (int i = 0; i < this.getHeight(); i++) {
194                                         for (int j = 0; j < this.getWidth(); j++) {
195                                                 convertedMatrix[i][j] = Long.valueOf(byteData[i][j]);
196                                         }
197                                 }
198                                 return convertedMatrix;
199                         case TYPE16:
200                                 for (int i = 0; i < this.getHeight(); i++) {
201                                         for (int j = 0; j < this.getWidth(); j++) {
202                                                 convertedMatrix[i][j] = Long.valueOf(shortData[i][j]);
203                                         }
204                                 }
205                                 return convertedMatrix;
206                         case TYPE32:
207                                 for (int i = 0; i < this.getHeight(); i++) {
208                                         for (int j = 0; j < this.getWidth(); j++) {
209                                                 convertedMatrix[i][j] = Long.valueOf(intData[i][j]);
210                                         }
211                                 }
212                                 return convertedMatrix;
213                         case TYPE64:
214                                 return longData;
215                 }
216                 return null;
217         }
218         
219
220         /**
221          * Returns the value as the form of short
222          * @return the values as short
223          */
224         public short[][] getDataAsShort() {
225                 return shortData;
226         }
227
228         /**
229          * Returns the value as the form of byte
230          * @return the values as byte
231          */
232         public byte[][] getDataAsByte() {
233                 return byteData;
234         }
235
236         /**
237          * Returns the value as the form of int
238          * @return the values as int
239          */
240         public int[][] getDataAsInt() {
241                 return intData;
242         }
243
244         /**
245          * Returns the value as the form of long
246          * Only for Scilab 6.X
247          * @return the values as long
248          */
249         public long[][] getDataAsLong() {
250                 return longData;
251         }
252
253         /**
254          * @return the precision of the values
255          */
256         public IntegerType getPrec() {
257                 return prec;
258         }
259
260         /**
261          * @return true, if the values are signed, false otherwise.
262          */
263         public boolean isUnsigned() {
264                 return bUnsigned;
265         }
266
267         /**
268          * @return the height of the value matrix
269          * @see org.scilab.modules.types.scilabTypes.ScilabType#getHeight()
270          */
271         @Override
272                 public int getHeight() {
273                 switch (this.getPrec()) {
274                         case TYPE8:
275                                 if (byteData == null) {
276                                         return 0;
277                                 }
278                                 return byteData.length;
279                         case TYPE16:
280                                 if (shortData == null) {
281                                         return 0;
282                                 }
283                                 return shortData.length;
284                         case TYPE32:
285                                 if (intData == null) {
286                                         return 0;
287                                 }
288                                 return intData.length;
289                         case TYPE64:
290                                 if (longData == null) {
291                                         return 0;
292                                 }
293                                 return longData.length;
294                         default:
295                                 return 0;
296                 }
297         }
298
299         /**
300          * @return the width of the value matrix
301          * @see org.scilab.modules.types.scilabTypes.ScilabType#getWidth()
302          */
303         @Override
304         public int getWidth() {
305                 switch (this.getPrec()) {
306                         case TYPE8:
307                                 if (byteData == null) {
308                                         return 0;
309                                 }
310                                 return byteData[0].length;
311                         case TYPE16:
312                                 if (shortData == null) {
313                                         return 0;
314                                 }
315                                 return shortData[0].length;
316                         case TYPE32:
317                                 if (intData == null) {
318                                         return 0;
319                                 }
320                                 return intData[0].length;
321                         case TYPE64:
322                                 if (longData == null) {
323                                         return 0;
324                                 }
325                                 return longData[0].length;
326                         default:
327                                 return 0;
328                 }
329         }
330
331         // int32(X), int8(x) , int16([x,x,x;x,x,x])
332         //       uint32(X), uint8(x) , uint16([x,x,x;x,x,x])
333         
334         /**
335          * @return true, if there is no values; false otherwise.
336          */
337     public boolean isEmpty() {
338                 switch (this.getPrec()) {
339                         case TYPE8:
340                                 return byteData == null;
341                         case TYPE16:
342                                 return shortData == null;
343                         case TYPE32:
344                                 return intData == null;
345                         case TYPE64:
346                                 return longData == null;
347                         default:
348                                 return true;
349                 }
350     }
351         
352     /**
353          * @see org.scilab.modules.types.scilabTypes.ScilabType#equals(Object)
354      */
355     public boolean equals(Object obj) {
356         if (obj instanceof ScilabInteger) {
357             return Arrays.deepEquals(this.getData(), ((ScilabInteger)obj).getData());
358         } else {
359             return false;
360         }
361     }
362
363     /**
364      * @return the pretty-printed values 
365      * @see java.lang.Object#toString()
366      */
367     @Override
368         public String toString() {
369         StringBuilder result = new StringBuilder();
370                 
371                 
372                 if (isEmpty()) {
373                         result.append("int([])");
374                         return result.toString();
375                 }
376                 
377                 if (isUnsigned()) {
378                         result.append("u");
379                 }
380                 result.append("int");
381                 
382                 switch (this.getPrec()) {
383                 case TYPE8:
384                         result.append("8");
385                         break;
386
387                 case TYPE16:
388                         result.append("16");
389                         break;
390                         
391                 case TYPE32:
392                         result.append("32");
393                         break;
394                         
395                 case TYPE64:
396                         result.append("64");
397                         break;
398                         
399                 default:
400                         break;
401                 }
402
403                 result.append("([");
404                 appendData(result);
405                 result.append("])");
406         
407                 return result.toString();
408         }
409
410         /**
411          * Put each value on the buffer.
412          * 
413          * @param result the current buffer
414          */
415         private void appendData(StringBuilder result) {
416                 for (int i = 0; i < getHeight(); ++i) {
417                         for (int j = 0; j < getWidth(); ++j) {
418
419                                 result.append(getData()[i][j]);
420                                 
421                                 
422                                 if (j != getWidth() - 1) {
423                                         result.append(", ");
424                                 }
425                         }
426                         if (i != getHeight() - 1) {
427                                 result.append(" ; ");
428                         }
429                 }
430         }
431         
432 }