Skip to content

Commit 42186c7

Browse files
authored
Merge pull request #1380 from tdrwenski/fix-checksum-error
Fix invalid checksum error
2 parents 1dac294 + b320279 commit 42186c7

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

cdm/core/src/main/java/ucar/nc2/filter/Shuffle.java

+23-17
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public int getId() {
3939

4040
@Override
4141
public byte[] encode(byte[] dataIn) {
42-
if (dataIn.length % elemSize != 0 || elemSize <= 1) {
42+
if (elemSize <= 1) {
4343
return dataIn;
4444
}
4545

@@ -56,29 +56,35 @@ public byte[] encode(byte[] dataIn) {
5656
}
5757
}
5858

59+
int leftoverBytes = dataIn.length % this.elemSize;
60+
System.arraycopy(dataIn, dataIn.length - leftoverBytes, result, result.length - leftoverBytes, leftoverBytes);
61+
5962
return result;
6063
}
6164

6265
@Override
6366
public byte[] decode(byte[] dataIn) {
64-
if (dataIn.length % this.elemSize == 0 && this.elemSize > 1) {
65-
int nElems = dataIn.length / this.elemSize;
66-
byte[] result = new byte[dataIn.length];
67-
68-
for (int j = 0; j < this.elemSize; ++j) {
69-
int sourceIndex = j * nElems;
70-
int destIndex = j;
71-
for (int i = 0; i < nElems; ++i) {
72-
result[destIndex] = dataIn[sourceIndex];
73-
sourceIndex++;
74-
destIndex += this.elemSize;
75-
}
76-
}
77-
78-
return result;
79-
} else {
67+
if (elemSize <= 1) {
8068
return dataIn;
8169
}
70+
71+
int nElems = dataIn.length / this.elemSize;
72+
byte[] result = new byte[dataIn.length];
73+
74+
for (int j = 0; j < this.elemSize; ++j) {
75+
int sourceIndex = j * nElems;
76+
int destIndex = j;
77+
for (int i = 0; i < nElems; ++i) {
78+
result[destIndex] = dataIn[sourceIndex];
79+
sourceIndex++;
80+
destIndex += this.elemSize;
81+
}
82+
}
83+
84+
int leftoverBytes = dataIn.length % this.elemSize;
85+
System.arraycopy(dataIn, dataIn.length - leftoverBytes, result, result.length - leftoverBytes, leftoverBytes);
86+
87+
return result;
8288
}
8389

8490
public static class Provider implements FilterProvider {

cdm/core/src/test/java/ucar/nc2/filter/TestFilters.java

+22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import ucar.unidata.io.RandomAccessFile;
1212

1313
import java.io.IOException;
14+
import java.nio.ByteBuffer;
1415
import java.nio.charset.StandardCharsets;
1516
import java.util.HashMap;
1617
import java.util.Map;
@@ -59,6 +60,27 @@ public void testShuffle() throws IOException {
5960
testEncodeDecode(filter, "shuffle");
6061
}
6162

63+
@Test
64+
public void shouldShuffleDoublesAndLeaveIntAtEnd() throws IOException {
65+
ByteBuffer bb = ByteBuffer.allocate(2 * 8 + 4);
66+
bb.putDouble(-1.0);
67+
bb.putDouble(1.0);
68+
// to represent a checksum at the end of a chunk of doubles
69+
bb.putInt(12345);
70+
byte[] bytes = bb.array();
71+
72+
Map<String, Object> props = new HashMap<>();
73+
props.put("id", "shuffle");
74+
props.put("elementsize", 8);
75+
Filter filter = new Shuffle(props);
76+
77+
byte[] expected = new byte[] {-65, 63, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 57};
78+
byte[] encoded = filter.encode(bytes);
79+
assertThat(encoded).isEqualTo(expected);
80+
byte[] decoded = filter.decode(encoded);
81+
assertThat(decoded).isEqualTo(bytes);
82+
}
83+
6284
@Test
6385
public void testChecksum32() throws IOException {
6486
// test Adler32

0 commit comments

Comments
 (0)