Bug 568296: [RJ-Data] Simplify use of raw/byte array data
- Add RRawStore.toRawArray returning a primitive byte array
- Add DefaultRObjectFactory.createRawVector(byte[])
- Add functions to RDataUtils similar to the other data types
Change-Id: I4eb08a22d0c8ed5a66385a09c5707e1ad57c5c17
diff --git a/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/RDataUtilsTest.java b/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/RDataUtilsTest.java
index 7560b2d..cc2c2cb 100644
--- a/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/RDataUtilsTest.java
+++ b/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/RDataUtilsTest.java
@@ -330,4 +330,64 @@
RDataUtils.checkSingleCharValue(FACTORY.createCharVector(2)));
}
+ @Test
+ public void isSingleRaw() {
+ assertTrue(RDataUtils.isSingleRaw(FACTORY.createRawVector(1)));
+ assertTrue(RDataUtils.isSingleRaw(FACTORY.createRawVector(new byte[] { 1 })));
+
+ assertFalse(RDataUtils.isSingleRaw(null));
+ assertFalse(RDataUtils.isSingleRaw(RNullImpl.INSTANCE));
+ assertFalse(RDataUtils.isSingleRaw(FACTORY.createLogiVector(1)));
+ assertFalse(RDataUtils.isSingleRaw(FACTORY.createRawVector(0)));
+ assertFalse(RDataUtils.isSingleRaw(FACTORY.createRawVector(2)));
+ }
+
+ @Test
+ public void checkSingleRaw() {
+ try {
+ assertEquals(Byte.valueOf((byte)0),
+ RDataUtils.checkSingleRaw(FACTORY.createRawVector(1)));
+ assertEquals(Byte.valueOf((byte)1),
+ RDataUtils.checkSingleRaw(FACTORY.createRawVector(new byte[] { 1 })));
+ }
+ catch (final UnexpectedRDataException e) {
+ fail(e);
+ }
+
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRaw(null));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRaw(RNullImpl.INSTANCE));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRaw(FACTORY.createLogiVector(1)));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRaw(FACTORY.createRawVector(0)));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRaw(FACTORY.createRawVector(2)));
+ }
+
+ @Test
+ public void checkSingleRawValue() {
+ try {
+ assertEquals(Byte.valueOf((byte)0),
+ RDataUtils.checkSingleRawValue(FACTORY.createRawVector(1)));
+ assertEquals(Byte.valueOf((byte)1),
+ RDataUtils.checkSingleRawValue(FACTORY.createRawVector(new byte[] { 1 })));
+ }
+ catch (final UnexpectedRDataException e) {
+ fail(e);
+ }
+
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRawValue(null));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRawValue(RNullImpl.INSTANCE));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRawValue(FACTORY.createLogiVector(1)));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRawValue(FACTORY.createRawVector(0)));
+ assertThrows(UnexpectedRDataException.class, () ->
+ RDataUtils.checkSingleRawValue(FACTORY.createRawVector(2)));
+ }
+
}
diff --git a/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/impl/RRawStoreTest.java b/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/impl/RRawStoreTest.java
index 108e72e..9e1db9f 100644
--- a/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/impl/RRawStoreTest.java
+++ b/core/org.eclipse.statet.rj.data-tests/src/org/eclipse/statet/rj/data/impl/RRawStoreTest.java
@@ -211,6 +211,20 @@
assertIndexOutOfBounds(data, store::getRaw, store::getRaw);
}
+ @ParameterizedTest
+ @MethodSource("provideCaseDatas")
+ public void toRawArray(final RawCaseData data) {
+ final RRawStore store= createStore(data);
+
+ final byte[] array= store.toRawArray();
+
+ assertEquals(data.values.length, array.length);
+
+ for (int i= 0; i < data.length; i++) {
+ assertEquals(data.values[i], array[i], arrayDiffersAt(i));
+ }
+ }
+
@ParameterizedTest
@MethodSource("provideCaseDatas")
diff --git a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RDataUtils.java b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RDataUtils.java
index e8f4c02..f10e9d6 100644
--- a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RDataUtils.java
+++ b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RDataUtils.java
@@ -273,6 +273,13 @@
return (RCharacterStore)store;
}
+ private static final RRawStore requireRRawStore(final RStore<?> store) throws UnexpectedRDataException {
+ if (store.getStoreType() != RStore.RAW) {
+ throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(store));
+ }
+ return (RRawStore)store;
+ }
+
private static final void requireLengthEqual1(final RStore<?> store) throws UnexpectedRDataException {
if (store.getLength() != 1) {
throw new UnexpectedRDataException("Unexpected R data length: " + store.getLength() + ", but == 1 expected.");
@@ -338,6 +345,18 @@
return (RVector<RCharacterStore>)obj;
}
+ @SuppressWarnings("unchecked")
+ public static final RVector<RRawStore> checkRRawVector(final @Nullable RObject obj) throws UnexpectedRDataException {
+ if (obj == null) {
+ throw new UnexpectedRDataException("Missing R object.");
+ }
+ if (obj.getRObjectType() != RObject.TYPE_VECTOR) {
+ throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
+ }
+ requireRRawStore(requireObjectData(obj));
+ return (RVector<RRawStore>) obj;
+ }
+
public static final RArray<?> checkRArray(final @Nullable RObject obj) throws UnexpectedRDataException {
if (obj == null) {
@@ -399,6 +418,24 @@
return array;
}
+ @SuppressWarnings("unchecked")
+ public static final RArray<RRawStore> checkRRawArray(final @Nullable RObject obj, final int dim) throws UnexpectedRDataException {
+ if (obj == null) {
+ throw new UnexpectedRDataException("Missing R object.");
+ }
+ if (obj.getRObjectType() != RObject.TYPE_ARRAY) {
+ throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
+ }
+ requireRRawStore(requireObjectData(obj));
+ final var array= (RArray<RRawStore>)obj;
+ if (dim > 0) {
+ if (dim != array.getDim().getLength()) {
+ throw new UnexpectedRDataException("Unexpected R array dimension: " + array.getDim().getLength());
+ }
+ }
+ return array;
+ }
+
public static final RList checkRList(final @Nullable RObject obj) throws UnexpectedRDataException {
if (obj == null) {
@@ -598,6 +635,33 @@
return data.getChar(0);
}
+ public static final boolean isSingleRaw(final @Nullable RObject obj) {
+ final RStore<?> data;
+ return (obj != null && (data= obj.getData()) != null
+ && data.getStoreType() == RStore.RAW
+ && data.getLength() == 1 );
+ }
+
+ public static final Byte checkSingleRaw(final @Nullable RObject obj) throws UnexpectedRDataException {
+ if (obj == null) {
+ throw new UnexpectedRDataException("Missing R object.");
+ }
+ final RRawStore data= requireRRawStore(requireObjectData(obj));
+ requireLengthEqual1(data);
+
+ return data.get(0);
+ }
+
+ public static final byte checkSingleRawValue(final @Nullable RObject obj) throws UnexpectedRDataException {
+ if (obj == null) {
+ throw new UnexpectedRDataException("Missing R object.");
+ }
+ final RRawStore data= requireRRawStore(requireObjectData(obj));
+ requireLengthEqual1(data);
+
+ return data.getRaw(0);
+ }
+
public static final RObject checkType(final @Nullable RObject obj, final byte objectType) throws UnexpectedRDataException {
if (obj == null) {
diff --git a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RRawStore.java b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RRawStore.java
index a0366a6..2441afe 100644
--- a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RRawStore.java
+++ b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/RRawStore.java
@@ -35,6 +35,8 @@
int MAX_INT= (MAX_BYTE & 0xFF);
+ byte[] toRawArray();
+
@Override
Byte get(int idx);
@Override
diff --git a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/DefaultRObjectFactory.java b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/DefaultRObjectFactory.java
index 8238b3a..2841dfd 100644
--- a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/DefaultRObjectFactory.java
+++ b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/DefaultRObjectFactory.java
@@ -217,7 +217,7 @@
* the vector is initialized with "" (empty String) values.</p>
*
* @param length the length of the vector
- * @return the R charcter vector
+ * @return the R character vector
*/
public RVector<RCharacterStore> createCharVector(final int length) {
return createVector(createCharData(length), RObject.CLASSNAME_CHARACTER);
@@ -225,14 +225,29 @@
/**
* Creates an R raw vector of the specified length.
+ *
+ * <p>The vector has the default R class name 'raw'.</p>
+ *
+ * <p>Note that the R vector may use the array directly. For values
+ * see {@link RStore#setRaw(int, byte)}.</p>
+ *
+ * @param raws the raw/byte values of the vector
+ * @return the R raw vector
+ */
+ public RVector<RRawStore> createRawVector(final byte[] raws) {
+ return createVector(createRawData(raws), RObject.CLASSNAME_RAW);
+ }
+
+ /**
+ * Creates an R raw vector of the specified length.
* <p>
* The vector has the default R class name 'raw'.</p>
* <p>
- * The function works analog to the R function <code>raw(length)</code>;
- * the vector is initialized with 0.0 values.</p>
+ * The function works analog to the R function {@code raw(length)};
+ * the vector is initialized with {@code 00} values.</p>
*
* @param length the length of the vector
- * @return the R complex vector
+ * @return the R raw vector
*/
public RVector<RRawStore> createRawVector(final int length) {
return createVector(createRawData(length), RObject.CLASSNAME_RAW);
diff --git a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRaw32Store.java b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRaw32Store.java
index d41339d..e0bdf8a 100644
--- a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRaw32Store.java
+++ b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRaw32Store.java
@@ -18,6 +18,7 @@
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.Arrays;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
@@ -142,6 +143,11 @@
}
@Override
+ public byte[] toRawArray() {
+ return Arrays.copyOf(this.byteValues, this.length);
+ }
+
+ @Override
public void setRaw(final int idx, final byte value) {
this.byteValues[idx]= value;
}
diff --git a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawFix64Store.java b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawFix64Store.java
index 492de46..d06b255 100644
--- a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawFix64Store.java
+++ b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawFix64Store.java
@@ -123,6 +123,18 @@
}
@Override
+ public byte[] toRawArray() {
+ final int l= checkToArrayLength();
+ final var array= new byte [l];
+ for (int i= 0, destIdx= 0; i < this.byteValues.length; i++) {
+ final byte[] raws= this.byteValues[i];
+ System.arraycopy(raws, 0, array, destIdx, raws.length);
+ destIdx+= raws.length;
+ }
+ return array;
+ }
+
+ @Override
public void setRaw(final int idx, final byte value) {
this.byteValues[idx / SEGMENT_LENGTH][idx % SEGMENT_LENGTH] =
value;
diff --git a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawStructStore.java b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawStructStore.java
index b4fb941..7577ddd 100644
--- a/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawStructStore.java
+++ b/core/org.eclipse.statet.rj.data/src/org/eclipse/statet/rj/data/impl/RRawStructStore.java
@@ -14,9 +14,13 @@
package org.eclipse.statet.rj.data.impl;
+import org.eclipse.statet.jcommons.lang.NonNull;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+
import org.eclipse.statet.rj.data.RStore;
+@NonNullByDefault
public class RRawStructStore extends AbstractRawStore {
@@ -58,6 +62,12 @@
@Override
+ public byte[] toRawArray() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ @Override
public Byte get(final int idx) {
throw new UnsupportedOperationException();
}
@@ -68,7 +78,7 @@
}
@Override
- public final Byte[] toArray() {
+ public @NonNull Byte [] toArray() {
throw new UnsupportedOperationException();
}