Javasci: fix java build, javadoc warnings
[scilab.git] / scilab / modules / types / src / java / org / scilab / modules / types / ScilabInteger.java
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2009-2009 - DIGITEO - Antoine ELIAS
4  *  Copyright (C) 2011-2011 - DIGITEO - Calixte DENIZET
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.types;
18
19 import java.io.IOException;
20 import java.io.ObjectInput;
21 import java.io.ObjectOutput;
22 import java.util.Arrays;
23
24 /**
25  * This class provides a representation on the Scilab Integer datatype<br>
26  * <br>
27  * This class is {@link java.io.Serializable} and any modification could impact
28  * load and store of data (Xcos files, Javasci saved data, etc...).<br>
29  * <br>
30  * Example:<BR>
31  * <code>
32  * byte [][]a={{32,42,41}, {12,13,32}};<BR>
33  * ScilabInteger aMatrix = new ScilabInteger(a, true); // true = unsigned
34  * </code>
35  *
36  * @see org.scilab.modules.javasci.Scilab
37  */
38 public class ScilabInteger implements ScilabType {
39
40     private static final long serialVersionUID = 1759633801332932450L;
41
42     private static final int VERSION = 0;
43
44     protected long[][] longData;
45     protected short[][] shortData;
46     protected int[][] intData;
47     protected byte[][] byteData;
48     protected ScilabIntegerTypeEnum precision;
49     protected String varName;
50     protected boolean swaped;
51     transient protected boolean byref;
52
53     /**
54      * Default constructor
55      */
56     public ScilabInteger() { }
57
58     /**
59      * Constructor with values
60      *
61      * @param data
62      *            the values
63      * @param bUnsigned
64      *            true, if the values are unsigned; false if they are signed.
65      */
66     public ScilabInteger(byte[][] data, boolean bUnsigned) {
67         this.setData(data, bUnsigned);
68     }
69
70     /**
71      * Constructor with values
72      *
73      * @param data
74      *            the values
75      * @param bUnsigned
76      *            true, if the values are unsigned; false if they are signed.
77      */
78     public ScilabInteger(short[][] data, boolean bUnsigned) {
79         this.setData(data, bUnsigned);
80     }
81
82     /**
83      * Constructor with values
84      *
85      * @param data
86      *            the values
87      * @param bUnsigned
88      *            true, if the values are unsigned; false if they are signed.
89      */
90     public ScilabInteger(int[][] data, boolean bUnsigned) {
91         this.setData(data, bUnsigned);
92     }
93
94     /**
95      * Constructor with values
96      *
97      * @param data
98      *            the values
99      * @param bUnsigned
100      *            true, if the values are unsigned; false if they are signed.
101      */
102     public ScilabInteger(long[][] data, boolean bUnsigned) {
103         this.setData(data, bUnsigned);
104     }
105
106     /**
107      * Constructor with values
108      *
109      * @param varName the variable name
110      * @param data
111      *            the values
112      * @param bUnsigned
113      *            true, if the values are unsigned; false if they are signed.
114      * @param swaped true if the matrices are stored row by row
115      */
116     public ScilabInteger(String varName, byte[][] data, boolean bUnsigned, boolean swaped) {
117         this.setData(data, bUnsigned);
118         this.varName = varName;
119         this.swaped = swaped;
120     }
121
122     /**
123      * Constructor with values
124      *
125      * @param varName the variable name
126      * @param data
127      *            the values
128      * @param bUnsigned
129      *            true, if the values are unsigned; false if they are signed.
130      * @param swaped true if the matrices are stored row by row
131      */
132     public ScilabInteger(String varName, short[][] data, boolean bUnsigned, boolean swaped) {
133         this.setData(data, bUnsigned);
134         this.varName = varName;
135         this.swaped = swaped;
136     }
137
138     /**
139      * Constructor with values
140      *
141      * @param varName the variable name
142      * @param data
143      *            the values
144      * @param bUnsigned
145      *            true, if the values are unsigned; false if they are signed.
146      * @param swaped true if the matrices are stored row by row
147      */
148     public ScilabInteger(String varName, int[][] data, boolean bUnsigned, boolean swaped) {
149         this.setData(data, bUnsigned);
150         this.varName = varName;
151         this.swaped = swaped;
152     }
153
154     /**
155      * Constructor with values
156      *
157      * @param varName the variable name
158      * @param data
159      *            the values
160      * @param bUnsigned
161      *            true, if the values are unsigned; false if they are signed.
162      * @param swaped true if the matrices are stored row by row
163      */
164     public ScilabInteger(String varName, long[][] data, boolean bUnsigned, boolean swaped) {
165         this.setData(data, bUnsigned);
166         this.varName = varName;
167         this.swaped = swaped;
168     }
169
170     /**
171      * Constructor with single signed value
172      *
173      * @param value
174      *            the unique value
175      */
176     public ScilabInteger(byte value) {
177         this.byteData = new byte[1][1];
178         this.byteData[0][0] = value;
179         this.precision = ScilabIntegerTypeEnum.sci_int8;
180     }
181
182     /**
183      * Constructor with single signed value
184      *
185      * @param value
186      *            the unique value
187      */
188     public ScilabInteger(short value) {
189         this.shortData = new short[1][1];
190         this.shortData[0][0] = value;
191         this.precision = ScilabIntegerTypeEnum.sci_int16;
192     }
193
194     /**
195      * Constructor with single signed value
196      *
197      * @param value
198      *            the unique value
199      */
200     public ScilabInteger(int value) {
201         this.intData = new int[1][1];
202         this.intData[0][0] = value;
203         this.precision = ScilabIntegerTypeEnum.sci_int32;
204     }
205
206     /**
207      * Constructor with single signed value
208      *
209      * @param value
210      *            the unique value
211      */
212     public ScilabInteger(long value) {
213         this.longData = new long[1][1];
214         this.longData[0][0] = value;
215         this.precision = ScilabIntegerTypeEnum.sci_int64;
216     }
217
218     /**
219      * Constructor with single signed value
220      *
221      * @param value
222      *            the unique value
223      * @param bUnsigned
224      *            true, if these values are unsigned; false otherwise.
225      */
226     public ScilabInteger(byte value, boolean bUnsigned) {
227         this(value);
228         this.precision = bUnsigned ? ScilabIntegerTypeEnum.sci_uint8 : ScilabIntegerTypeEnum.sci_int8;
229     }
230
231     /**
232      * Constructor with single signed value
233      *
234      * @param value
235      *            the unique value
236      * @param bUnsigned
237      *            true, if these values are unsigned; false otherwise.
238      */
239     public ScilabInteger(short value, boolean bUnsigned) {
240         this(value);
241         this.precision = bUnsigned ? ScilabIntegerTypeEnum.sci_uint16 : ScilabIntegerTypeEnum.sci_int16;
242     }
243
244     /**
245      * Constructor with single signed value
246      *
247      * @param value
248      *            the unique value
249      * @param bUnsigned
250      *            true, if these values are unsigned; false otherwise.
251      */
252     public ScilabInteger(int value, boolean bUnsigned) {
253         this(value);
254         this.precision = bUnsigned ? ScilabIntegerTypeEnum.sci_uint32 : ScilabIntegerTypeEnum.sci_int32;
255     }
256
257     /**
258      * Constructor with single signed value
259      *
260      * @param value
261      *            the unique value
262      * @param bUnsigned
263      *            true, if these values are unsigned; false otherwise.
264      */
265     public ScilabInteger(long value, boolean bUnsigned) {
266         this(value);
267         this.precision = bUnsigned ? ScilabIntegerTypeEnum.sci_uint64 : ScilabIntegerTypeEnum.sci_int64;
268     }
269
270     /**
271      * Set the current values
272      *
273      * @param data
274      *            the values to set
275      * @param bUnsigned
276      *            true, if these values are unsigned; false otherwise.
277      */
278     public void setData(byte[][] data, boolean bUnsigned) {
279         this.byteData = data;
280         if (bUnsigned) {
281             this.precision = ScilabIntegerTypeEnum.sci_uint8;
282         } else {
283             this.precision = ScilabIntegerTypeEnum.sci_int8;
284         }
285     }
286
287     /**
288      * Set the current values
289      *
290      * @param data
291      *            the values to set
292      * @param bUnsigned
293      *            true, if these values are unsigned; false otherwise.
294      */
295     public void setData(short[][] data, boolean bUnsigned) {
296         this.shortData = data;
297         if (bUnsigned) {
298             this.precision = ScilabIntegerTypeEnum.sci_uint16;
299         } else {
300             this.precision = ScilabIntegerTypeEnum.sci_int16;
301         }
302     }
303
304     /**
305      * Set the current values
306      *
307      * @param data
308      *            the values to set
309      * @param bUnsigned
310      *            true, if these values are unsigned; false otherwise.
311      */
312     public void setData(int[][] data, boolean bUnsigned) {
313         this.intData = data;
314         if (bUnsigned) {
315             this.precision = ScilabIntegerTypeEnum.sci_uint32;
316         } else {
317             this.precision = ScilabIntegerTypeEnum.sci_int32;
318         }
319     }
320
321     /**
322      * Set the current values
323      *
324      * @param data
325      *            the values to set
326      * @param bUnsigned
327      *            true, if these values are unsigned; false otherwise.
328      */
329     public void setData(long[][] data, boolean bUnsigned) {
330         this.longData = data;
331         if (bUnsigned) {
332             this.precision = ScilabIntegerTypeEnum.sci_uint64;
333         } else {
334             this.precision = ScilabIntegerTypeEnum.sci_int64;
335         }
336     }
337
338     /**
339      * Return the type of Scilab
340      *
341      * @return the type of Scilab
342      * @since 5.4.0
343      */
344     @Override
345     public ScilabTypeEnum getType() {
346         return ScilabTypeEnum.sci_ints;
347     }
348
349     /**
350      * If the precision is not 64, all values will be converted to long
351      * (attention, the convertion can be long) if precision is 64, just return
352      * the data
353      *
354      * @return the values
355      */
356     public long[][] getData() {
357         long[][] convertedMatrix = new long[this.getHeight()][this.getWidth()];
358         switch (this.getPrec()) {
359
360             case sci_int8:
361             case sci_uint8:
362                 for (int i = 0; i < this.getHeight(); i++) {
363                     for (int j = 0; j < this.getWidth(); j++) {
364                         convertedMatrix[i][j] = Long.valueOf(getByteElement(i, j));
365                     }
366                 }
367                 return convertedMatrix;
368             case sci_int16:
369             case sci_uint16:
370                 for (int i = 0; i < this.getHeight(); i++) {
371                     for (int j = 0; j < this.getWidth(); j++) {
372                         convertedMatrix[i][j] = Long.valueOf(getShortElement(i, j));
373                     }
374                 }
375                 return convertedMatrix;
376             case sci_int32:
377             case sci_uint32:
378                 for (int i = 0; i < this.getHeight(); i++) {
379                     for (int j = 0; j < this.getWidth(); j++) {
380                         convertedMatrix[i][j] = Long.valueOf(getIntElement(i, j));
381                     }
382                 }
383                 return convertedMatrix;
384             case sci_int64:
385             case sci_uint64:
386                 return longData;
387         }
388         return null;
389     }
390
391     /**
392      * Returns the value as the form of short
393      *
394      * @return the values as short
395      */
396     public short[][] getDataAsShort() {
397         return shortData;
398     }
399
400     /**
401      * Returns the value as the form of byte
402      *
403      * @return the values as byte
404      */
405     public byte[][] getDataAsByte() {
406         return byteData;
407     }
408
409     /**
410      * Returns the value as the form of int
411      *
412      * @return the values as int
413      */
414     public int[][] getDataAsInt() {
415         return intData;
416     }
417
418     /**
419      * Returns the value as the form of long Only for Scilab 6.X
420      *
421      * @return the values as long
422      */
423     public long[][] getDataAsLong() {
424         return longData;
425     }
426
427     /**
428      * @return the precision of the values
429      */
430     public ScilabIntegerTypeEnum getPrec() {
431         return precision;
432     }
433
434     /**
435      * @return true, if the values are signed, false otherwise.
436      */
437     public boolean isUnsigned() {
438         switch (precision) {
439             case sci_int8:
440             case sci_int16:
441             case sci_int32:
442             case sci_int64:
443                 return false;
444             case sci_uint8:
445             case sci_uint16:
446             case sci_uint32:
447             case sci_uint64:
448                 return true;
449         }
450         return false;
451     }
452
453     /**
454      * Manage the old representation of IntegerType
455      *
456      * @param typeName
457      *            the typeName (type8, type16, type32, type64)
458      * @param unsigned
459      *            unsigned or not
460      * @return the converted type to ScilabIntegerTypeEnum. null is cannot
461          convert
462      */
463     public static ScilabIntegerTypeEnum convertOldType(String typeName, boolean unsigned) {
464         if (typeName.equals("type8")) {
465             if (unsigned) {
466                 return ScilabIntegerTypeEnum.sci_uint8;
467             } else {
468                 return ScilabIntegerTypeEnum.sci_int8;
469             }
470         }
471         if (typeName.equals("type16")) {
472             if (unsigned) {
473                 return ScilabIntegerTypeEnum.sci_uint16;
474             } else {
475                 return ScilabIntegerTypeEnum.sci_int16;
476             }
477         }
478         if (typeName.equals("type32")) {
479             if (unsigned) {
480                 return ScilabIntegerTypeEnum.sci_uint32;
481             } else {
482                 return ScilabIntegerTypeEnum.sci_int32;
483             }
484         }
485         if (typeName.equals("type64")) {
486             if (unsigned) {
487                 return ScilabIntegerTypeEnum.sci_uint64;
488             } else {
489                 return ScilabIntegerTypeEnum.sci_int64;
490             }
491         }
492         return null;
493     }
494
495     /**
496      * @return the height of the value matrix
497      * @see org.scilab.modules.types.ScilabType#getHeight()
498      */
499     @Override
500     public int getHeight() {
501         if (this.getPrec() == null) {
502             return 0;
503         }
504         switch (this.getPrec()) {
505             case sci_int8:
506             case sci_uint8:
507                 if (byteData == null) {
508                     return 0;
509                 }
510                 return byteData.length;
511             case sci_int16:
512             case sci_uint16:
513                 if (shortData == null) {
514                     return 0;
515                 }
516                 return shortData.length;
517             case sci_int32:
518             case sci_uint32:
519                 if (intData == null) {
520                     return 0;
521                 }
522                 return intData.length;
523             case sci_int64:
524             case sci_uint64:
525                 if (longData == null) {
526                     return 0;
527                 }
528                 return longData.length;
529             default:
530                 return 0;
531         }
532     }
533
534     /**
535      * @return the width of the value matrix
536      * @see org.scilab.modules.types.ScilabType#getWidth()
537      */
538     @Override
539     public int getWidth() {
540         if (this.getPrec() == null) {
541             return 0;
542         }
543         switch (this.getPrec()) {
544             case sci_int8:
545             case sci_uint8:
546                 if (byteData == null) {
547                     return 0;
548                 }
549                 return byteData[0].length;
550             case sci_int16:
551             case sci_uint16:
552                 if (shortData == null) {
553                     return 0;
554                 }
555                 return shortData[0].length;
556             case sci_int32:
557             case sci_uint32:
558                 if (intData == null) {
559                     return 0;
560                 }
561                 return intData[0].length;
562             case sci_int64:
563             case sci_uint64:
564                 if (longData == null) {
565                     return 0;
566                 }
567                 return longData[0].length;
568             default:
569                 return 0;
570         }
571     }
572
573     /**
574      * {@inheritDoc}
575      */
576     @Override
577     public boolean isReference() {
578         return byref;
579     }
580
581     /**
582      * @return true, if there is no values; false otherwise.
583      */
584     @Override
585     public boolean isEmpty() {
586         if (this.getPrec() == null) {
587             return true;
588         }
589         switch (this.getPrec()) {
590             case sci_int8:
591             case sci_uint8:
592                 return byteData == null;
593             case sci_int16:
594             case sci_uint16:
595                 return shortData == null;
596             case sci_int32:
597             case sci_uint32:
598                 return intData == null;
599             case sci_int64:
600             case sci_uint64:
601                 return longData == null;
602             default:
603                 return true;
604         }
605     }
606
607     /**
608      * {@inheritDoc}
609      */
610     @Override
611     public String getVarName() {
612         return varName;
613     }
614
615     /**
616      * {@inheritDoc}
617      */
618     @Override
619     public boolean isSwaped() {
620         return swaped;
621     }
622
623     /**
624      * Get the byte element at position (i, j)
625      * @param i the row index
626      * @param j the column index
627      * @return a byte
628      */
629     public byte getByteElement(final int i, final int j) {
630         return byteData[i][j];
631     }
632
633     /**
634      * Get the short element at position (i, j)
635      * @param i the row index
636      * @param j the column index
637      * @return a short
638      */
639     public short getShortElement(final int i, final int j) {
640         return shortData[i][j];
641     }
642
643     /**
644      * Get the int element at position (i, j)
645      * @param i the row index
646      * @param j the column index
647      * @return a int
648      */
649     public int getIntElement(final int i, final int j) {
650         return intData[i][j];
651     }
652
653     /**
654      * Get the long element at position (i, j)
655      * @param i the row index
656      * @param j the column index
657      * @return a long
658      */
659     public long getLongElement(final int i, final int j) {
660         return longData[i][j];
661     }
662
663     /**
664      * Set the byte element at position (i, j)
665      * @param i the row index
666      * @param j the column index
667      * @param x the byte to set
668      */
669     public void setByteElement(final int i, final int j, final byte x) {
670         byteData[i][j] = x;
671     }
672
673     /**
674      * Set the short element at position (i, j)
675      * @param i the row index
676      * @param j the column index
677      * @param x the short to set
678      */
679     public void setShortElement(final int i, final int j, final short x) {
680         shortData[i][j] = x;
681     }
682
683     /**
684      * Set the int element at position (i, j)
685      * @param i the row index
686      * @param j the column index
687      * @param x the int to set
688      */
689     public void setIntElement(final int i, final int j, final int x) {
690         intData[i][j] = x;
691     }
692
693     /**
694      * Set the long element at position (i, j)
695      * @param i the row index
696      * @param j the column index
697      * @param x the long to set
698      */
699     public void setLongElement(final int i, final int j, final long x) {
700         longData[i][j] = x;
701     }
702
703
704     /**
705      * Get the element at position (i, j) as a long
706      * @param i the row index
707      * @param j the column index
708      * @return a long
709      */
710     public long getElement(final int i, final int j) {
711         switch (this.getPrec()) {
712             case sci_int8:
713             case sci_uint8:
714                 return getByteElement(i, j);
715             case sci_int16:
716             case sci_uint16:
717                 return getShortElement(i, j);
718             case sci_int32:
719             case sci_uint32:
720                 return getIntElement(i, j);
721             case sci_int64:
722             case sci_uint64:
723                 return getLongElement(i, j);
724         }
725
726         return 0;
727     }
728
729     /**
730      * Set the element at position (i, j)
731      * @param i the row index
732      * @param j the column index
733      * @param x a long
734      */
735     public void setElement(final int i, final int j, final long x) {
736         switch (this.getPrec()) {
737             case sci_int8:
738             case sci_uint8:
739                 setByteElement(i, j, (byte) x);
740                 break;
741             case sci_int16:
742             case sci_uint16:
743                 setShortElement(i, j, (short) x);
744                 break;
745             case sci_int32:
746             case sci_uint32:
747                 setIntElement(i, j, (int) x);
748                 break;
749             case sci_int64:
750             case sci_uint64:
751                 setLongElement(i, j, x);
752                 break;
753         }
754     }
755
756     @Override
757     public int hashCode() {
758         final int prime = 31;
759         int result = 1;
760         result = prime * result + Arrays.deepHashCode(byteData);
761         result = prime * result + Arrays.deepHashCode(intData);
762         result = prime * result + Arrays.deepHashCode(longData);
763         result = prime * result + ((precision == null) ? 0 : precision.hashCode());
764         result = prime * result + Arrays.deepHashCode(shortData);
765         return result;
766     }
767
768     /**
769      * @see org.scilab.modules.types.ScilabType#equals(Object)
770      */
771     @Override
772     public boolean equals(Object obj) {
773         if (obj instanceof ScilabInteger) {
774             ScilabInteger sciInt = (ScilabInteger) obj;
775             if (isEmpty() && sciInt.isEmpty()) {
776                 return true;
777             }
778
779             if (this.getWidth() != sciInt.getWidth() || this.getHeight() != sciInt.getHeight()) {
780                 return false;
781             }
782
783             return ScilabTypeUtils.equalsInteger(this.getRawData(), this.isSwaped(), sciInt.getRawData(), sciInt.isSwaped());
784         } else {
785             return false;
786         }
787     }
788
789     /**
790      * Get the data as a array of arrays
791      * @return the data
792      */
793     public Object getCorrectData() {
794         switch (this.getPrec()) {
795             case sci_int8:
796             case sci_uint8:
797                 return byteData;
798             case sci_int16:
799             case sci_uint16:
800                 return shortData;
801             case sci_int32:
802             case sci_uint32:
803                 return intData;
804             case sci_int64:
805             case sci_uint64:
806                 return longData;
807         }
808         return null;
809     }
810
811     /**
812      * Get the data as they are
813      * @return the data
814      */
815     public Object getRawData() {
816         return getCorrectData();
817     }
818
819     /**
820      * {@inheritDoc}
821      */
822     @Override
823     public Object getSerializedObject() {
824         return new Object[] { new int[] { this.getPrec().swigValue() }, getCorrectData() };
825     }
826
827     @Override
828     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
829         int version = in.readInt();
830         switch (version) {
831             case 0:
832                 precision = ScilabIntegerTypeEnum.swigToEnum(in.readInt());
833                 Object data = in.readObject();
834                 switch (precision) {
835                     case sci_int8:
836                     case sci_uint8:
837                         byteData = (byte[][]) data;
838                         break;
839                     case sci_int16:
840                     case sci_uint16:
841                         shortData = (short[][]) data;
842                         break;
843                     case sci_int32:
844                     case sci_uint32:
845                         intData = (int[][]) data;
846                         break;
847                     case sci_int64:
848                     case sci_uint64:
849                         longData = (long[][]) data;
850                         break;
851                 }
852                 varName = (String) in.readObject();
853                 swaped = in.readBoolean();
854                 break;
855             default:
856                 throw new ClassNotFoundException("A class ScilabInteger with a version " + version + " does not exists");
857         }
858     }
859
860     @Override
861     public void writeExternal(ObjectOutput out) throws IOException {
862         out.writeInt(VERSION);
863         out.writeInt(getPrec().swigValue());
864         out.writeObject(getCorrectData());
865         out.writeObject(varName);
866         out.writeBoolean(swaped);
867     }
868
869     /**
870      * Display the representation in the Scilab language of the type<BR>
871      * Note that the representation can be copied/pasted straight into Scilab
872      *
873      * @return the pretty-printed values
874      * @see java.lang.Object#toString()
875      */
876     @Override
877     public String toString() {
878         StringBuilder result = new StringBuilder();
879
880         if (isEmpty()) {
881             return "[]";
882         }
883
884         if (isUnsigned()) {
885             result.append("u");
886         }
887         result.append("int");
888
889         switch (this.getPrec()) {
890             case sci_int8:
891             case sci_uint8:
892                 result.append("8");
893                 break;
894
895             case sci_int16:
896             case sci_uint16:
897                 result.append("16");
898                 break;
899
900             case sci_int32:
901             case sci_uint32:
902                 result.append("32");
903                 break;
904
905             case sci_int64:
906             case sci_uint64:
907                 result.append("64");
908                 break;
909
910             default:
911                 break;
912         }
913
914         result.append("([");
915         appendData(result);
916         result.append("])");
917
918         return result.toString();
919     }
920
921     /**
922      * Put each value on the buffer.
923      *
924      * @param result
925      *            the current buffer
926      */
927     private void appendData(StringBuilder result) {
928         long[][] d = getData();
929         for (int i = 0; i < getHeight(); ++i) {
930             for (int j = 0; j < getWidth(); ++j) {
931
932                 result.append(d[i][j]);
933
934                 if (j != getWidth() - 1) {
935                     result.append(", ");
936                 }
937             }
938             if (i != getHeight() - 1) {
939                 result.append(" ; ");
940             }
941         }
942     }
943 }