11/* This file is part of the EMA project and is
2- * Copyright (c) 2005 Robert Alten Simons (info@cohort .com).
2+ * Copyright (c) 2005 Robert Simons (CoHortSoftware@gmail .com).
33 * See the MIT/X-like license in LICENSE.txt.
4- * For more information visit www.cohort.com or contact info@cohort .com.
4+ * For more information visit www.cohort.com or contact CoHortSoftware@gmail .com.
55 */
66package com .cohort .array ;
77
@@ -36,6 +36,21 @@ public class ByteArray extends PrimitiveArray {
3636 */
3737 public byte [] array ;
3838
39+ /** This indicates if this class' type (e.g., short.class) can be contained in a long.
40+ * The integer type classes override this.
41+ */
42+ public boolean isIntegerType () {
43+ return true ;
44+ }
45+
46+ /**
47+ * This returns for cohort missing value for this class (e.g., Integer.MAX_VALUE),
48+ * expressed as a double. FloatArray and StringArray return Double.NaN.
49+ */
50+ public double missingValue () {
51+ return Byte .MAX_VALUE ;
52+ }
53+
3954 /**
4055 * A constructor for a capacity of 8 elements. The initial 'size' will be 0.
4156 */
@@ -389,11 +404,30 @@ public void addLong(long value) {
389404 /**
390405 * This adds an element from another PrimitiveArray.
391406 *
392- * @param otherPA
393- * @param otherIndex
394- */
395- public void addFromPA (PrimitiveArray otherPA , int otherIndex ) {
396- addInt (otherPA .getInt (otherIndex ));
407+ * @param otherPA the source PA
408+ * @param otherIndex the start index in otherPA
409+ * @param nValues the number of values to be added
410+ * @return 'this' for convenience
411+ */
412+ public PrimitiveArray addFromPA (PrimitiveArray otherPA , int otherIndex , int nValues ) {
413+
414+ //add from same type
415+ if (otherPA .elementClass () == elementClass ()) {
416+ if (otherIndex + nValues > otherPA .size )
417+ throw new IllegalArgumentException (String2 .ERROR +
418+ " in CharArray.addFromPA: otherIndex=" + otherIndex +
419+ " + nValues=" + nValues +
420+ " > otherPA.size=" + otherPA .size );
421+ ensureCapacity (size + nValues );
422+ System .arraycopy (((ByteArray )otherPA ).array , otherIndex , array , size , nValues );
423+ size += nValues ;
424+ return this ;
425+ }
426+
427+ //add from different type
428+ for (int i = 0 ; i < nValues ; i ++)
429+ addInt (otherPA .getInt (otherIndex ++)); //does error checking
430+ return this ;
397431 }
398432
399433 /**
@@ -631,6 +665,20 @@ public int getInt(int index) {
631665 return i == Byte .MAX_VALUE ? Integer .MAX_VALUE : i ;
632666 }
633667
668+ /**
669+ * Return a value from the array as an int.
670+ * This "raw" variant leaves missingValue from smaller data types
671+ * (e.g., ByteArray missingValue=127) AS IS.
672+ * Floating point values are rounded.
673+ *
674+ * @param index the index number 0 ... size-1
675+ * @return the value as an int. String values are parsed
676+ * with String2.parseInt and so may return Integer.MAX_VALUE.
677+ */
678+ public int getRawInt (int index ) {
679+ return get (index );
680+ }
681+
634682 /**
635683 * Set a value in the array as an int.
636684 *
@@ -702,6 +750,35 @@ public double getDouble(int index) {
702750 return b == Byte .MAX_VALUE ? Double .NaN : b ;
703751 }
704752
753+ /**
754+ * Return a value from the array as a double.
755+ * FloatArray converts float to double in a simplistic way.
756+ * For this variant: Integer source values will be treated as unsigned.
757+ *
758+ * @param index the index number 0 ... size-1
759+ * @return the value as a double. String values are parsed
760+ * with String2.parseDouble and so may return Double.NaN.
761+ */
762+ public double getUnsignedDouble (int index ) {
763+ //or see http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/reference/faq.html#Unsigned
764+ return Byte .toUnsignedInt (get (index ));
765+ }
766+
767+ /**
768+ * Return a value from the array as a double.
769+ * This "raw" variant leaves missingValue from integer data types
770+ * (e.g., ByteArray missingValue=127) AS IS.
771+ *
772+ * <p>All integerTypes override this.
773+ *
774+ * @param index the index number 0 ... size-1
775+ * @return the value as a double. String values are parsed
776+ * with String2.parseDouble and so may return Double.NaN.
777+ */
778+ public double getRawDouble (int index ) {
779+ return get (index );
780+ }
781+
705782 /**
706783 * Set a value in the array as a double.
707784 *
@@ -717,13 +794,30 @@ public void setDouble(int index, double d) {
717794 * Return a value from the array as a String.
718795 *
719796 * @param index the index number 0 ..
720- * @return For numeric types, this returns (String.valueOf(ar[index])), or "" for NaN or infinity.
797+ * @return For numeric types, this returns (String.valueOf(ar[index])),
798+ * or "" for NaN or infinity.
721799 */
722800 public String getString (int index ) {
723801 byte b = get (index );
724802 return b == Byte .MAX_VALUE ? "" : String .valueOf (b );
725803 }
726804
805+ /**
806+ * Return a value from the array as a String.
807+ * This "raw" variant leaves missingValue from integer data types
808+ * (e.g., ByteArray missingValue=127) AS IS.
809+ * FloatArray and DoubleArray return "" if the stored value is NaN.
810+ *
811+ * <p>All integerTypes override this.
812+ *
813+ * @param index the index number 0 ... size-1
814+ * @return the value as a double. String values are parsed
815+ * with String2.parseDouble and so may return Double.NaN.
816+ */
817+ public String getRawString (int index ) {
818+ return String .valueOf (get (index ));
819+ }
820+
727821 /**
728822 * Set a value in the array as a String.
729823 *
@@ -1050,26 +1144,41 @@ public static void rafWriteDouble(RandomAccessFile raf, long start, long index,
10501144 }
10511145
10521146 /**
1053- * This appends the data in another primitiveArray to the current data.
1054- * WARNING: information may be lost from the incoming primitiveArray if this
1147+ * This appends the data in another pa to the current data.
1148+ * WARNING: information may be lost from the incoming pa if this
10551149 * primitiveArray is of a simpler type.
10561150 *
1057- * @param primitiveArray primitiveArray must be the same or a narrower
1151+ * @param pa pa must be the same or a narrower
10581152 * data type, or the data will be narrowed with Math2.narrowToByte.
10591153 */
1060- public void append (PrimitiveArray primitiveArray ) {
1061- int otherSize = primitiveArray .size (); //this avoids infinite loop if primitiveArray == this
1154+ public void append (PrimitiveArray pa ) {
1155+ int otherSize = pa .size ();
10621156 ensureCapacity (size + (long )otherSize );
1063- if (primitiveArray instanceof ByteArray ) {
1064- System .arraycopy (((ByteArray )primitiveArray ).array , 0 , array , size , otherSize );
1157+ if (pa instanceof ByteArray ) {
1158+ System .arraycopy (((ByteArray )pa ).array , 0 , array , size , otherSize );
10651159 } else {
10661160 for (int i = 0 ; i < otherSize ; i ++) {
1067- array [size + i ] = Math2 .narrowToByte (primitiveArray .getInt (i )); //this converts mv's
1161+ array [size + i ] = Math2 .narrowToByte (pa .getInt (i )); //this converts mv's
10681162 }
10691163 }
10701164 size += otherSize ; //do last to minimize concurrency problems
10711165 }
10721166
1167+ /**
1168+ * This appends the data in another pa to the current data.
1169+ * This "raw" variant leaves missingValue from smaller data types
1170+ * (e.g., ByteArray missingValue=127) AS IS.
1171+ * WARNING: information may be lost from the incoming pa if this
1172+ * primitiveArray is of a simpler type.
1173+ *
1174+ * @param pa pa must be the same or a narrower
1175+ * data type, or the data will be narrowed with Math2.narrowToByte.
1176+ */
1177+ public void rawAppend (PrimitiveArray pa ) {
1178+ //since there are no smaller data types than byte, rawAppend() = append()
1179+ append (pa );
1180+ }
1181+
10731182 /**
10741183 * This populates 'indices' with the indices (ranks) of the values in this ByteArray
10751184 * (ties get the same index). For example, 10,10,25,3 returns 1,1,2,0.
@@ -1283,6 +1392,35 @@ public static void test() throws Throwable {
12831392
12841393 //** test default constructor and many of the methods
12851394 ByteArray anArray = new ByteArray ();
1395+ Test .ensureEqual (anArray .isIntegerType (), true , "" );
1396+ Test .ensureEqual (anArray .missingValue (), Byte .MAX_VALUE , "" );
1397+ anArray .addString ("" );
1398+ Test .ensureEqual (anArray .get (0 ), Byte .MAX_VALUE , "" );
1399+ Test .ensureEqual (anArray .getRawInt (0 ), Byte .MAX_VALUE , "" );
1400+ Test .ensureEqual (anArray .getRawDouble (0 ), Byte .MAX_VALUE , "" );
1401+ Test .ensureEqual (anArray .getUnsignedDouble (0 ), Byte .MAX_VALUE , "" );
1402+ Test .ensureEqual (anArray .getRawString (0 ), "" + Byte .MAX_VALUE , "" );
1403+ Test .ensureEqual (anArray .getRawNiceDouble (0 ), Byte .MAX_VALUE , "" );
1404+ Test .ensureEqual (anArray .getInt (0 ), Integer .MAX_VALUE , "" );
1405+ Test .ensureEqual (anArray .getDouble (0 ), Double .NaN , "" );
1406+ Test .ensureEqual (anArray .getString (0 ), "" , "" );
1407+
1408+ anArray .set (0 , (byte )-128 ); Test .ensureEqual (anArray .getUnsignedDouble (0 ), 128 , "" );
1409+ anArray .set (0 , (byte )-127 ); Test .ensureEqual (anArray .getUnsignedDouble (0 ), 129 , "" );
1410+ anArray .set (0 , (byte ) -1 ); Test .ensureEqual (anArray .getUnsignedDouble (0 ), 255 , "" );
1411+ anArray .clear ();
1412+
1413+ //unsignedFactory, which uses unsignedAppend
1414+ anArray = (ByteArray )unsignedFactory (byte .class ,
1415+ new ByteArray (new byte [] {0 , 1 , Byte .MAX_VALUE , Byte .MIN_VALUE , -1 }));
1416+ Test .ensureEqual (anArray .toString (), "0, 1, 127, 127, 127" , "" ); // -> mv
1417+ anArray .clear ();
1418+
1419+ anArray = (ByteArray )unsignedFactory (byte .class ,
1420+ new ShortArray (new short [] {0 , 1 , Short .MAX_VALUE , Short .MIN_VALUE , -1 }));
1421+ Test .ensureEqual (anArray .toString (), "0, 1, 127, 127, 127" , "" ); // -> mv
1422+ anArray .clear ();
1423+
12861424 Test .ensureEqual (anArray .size (), 0 , "" );
12871425 anArray .add ((byte )120 );
12881426 Test .ensureEqual (anArray .size (), 1 , "" );
0 commit comments