Skip to content

Commit 2ea19d2

Browse files
authored
Merge pull request #337 from scijava/datahandle-endianness
Datahandle test improvements and Endianness fixes
2 parents c5c1d04 + e9f820a commit 2ea19d2

File tree

6 files changed

+545
-335
lines changed

6 files changed

+545
-335
lines changed

src/main/java/org/scijava/io/handle/AbstractDataHandle.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public abstract class AbstractDataHandle<L extends Location> extends
4444
AbstractWrapperPlugin<L> implements DataHandle<L>
4545
{
4646

47+
private byte[] conversionBuffer = new byte[8];
48+
49+
@Override
50+
public byte[] conversionBuffer() {
51+
return conversionBuffer;
52+
}
53+
4754
// -- Fields --
4855

4956
private ByteOrder order = ByteOrder.BIG_ENDIAN;

src/main/java/org/scijava/io/handle/DataHandle.java

Lines changed: 36 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
import org.scijava.io.location.Location;
4545
import org.scijava.plugin.WrapperPlugin;
46+
import org.scijava.util.Bytes;
4647

4748
/**
4849
* A <em>data handle</em> is a plugin which provides both streaming and random
@@ -249,6 +250,11 @@ default void setLittleEndian(final boolean little) {
249250
/** Sets the native encoding of the stream. */
250251
void setEncoding(String encoding);
251252

253+
/**
254+
* @return a 8 byte long buffer array used for type conversions
255+
*/
256+
byte[] conversionBuffer();
257+
252258
/** Reads a string of arbitrary length, terminated by a null char. */
253259
default String readCString() throws IOException {
254260
final String line = findString("\0");
@@ -514,18 +520,10 @@ default int readUnsignedByte() throws IOException {
514520

515521
@Override
516522
default short readShort() throws IOException {
517-
final int ch0;
518-
final int ch1;
519-
if (isBigEndian()) {
520-
ch0 = read();
521-
ch1 = read();
522-
}
523-
else {
524-
ch1 = read();
525-
ch0 = read();
526-
}
527-
if ((ch0 | ch1) < 0) throw new EOFException();
528-
return (short) ((ch0 << 8) + (ch1 << 0));
523+
final byte[] buf = conversionBuffer();
524+
final int read = read(buf, 0, 2);
525+
if (read < 2) throw new EOFException();
526+
return Bytes.toShort(buf, isLittleEndian());
529527
}
530528

531529
@Override
@@ -540,68 +538,20 @@ default char readChar() throws IOException {
540538

541539
@Override
542540
default int readInt() throws IOException {
543-
final int ch0;
544-
final int ch1;
545-
final int ch2;
546-
final int ch3;
547-
if (isBigEndian()) {
548-
ch0 = read();
549-
ch1 = read();
550-
ch2 = read();
551-
ch3 = read();
552-
}
553-
else {
554-
ch3 = read();
555-
ch2 = read();
556-
ch1 = read();
557-
ch0 = read();
558-
}
559-
if ((ch0 | ch1 | ch2 | ch3) < 0) throw new EOFException();
560-
return ((ch0 << 24) + (ch1 << 16) + (ch2 << 8) + (ch3 << 0));
541+
final byte[] buf = conversionBuffer();
542+
final int read = read(buf, 0, 4);
543+
if (read < 4) throw new EOFException();
544+
return Bytes.toInt(buf, isLittleEndian());
561545
}
562546

563547
@Override
564548
default long readLong() throws IOException {
565-
final int ch0;
566-
final int ch1;
567-
final int ch2;
568-
final int ch3;
569-
final int ch4;
570-
final int ch5;
571-
final int ch6;
572-
final int ch7;
573-
if (isBigEndian()) {
574-
ch0 = read();
575-
ch1 = read();
576-
ch2 = read();
577-
ch3 = read();
578-
ch4 = read();
579-
ch5 = read();
580-
ch6 = read();
581-
ch7 = read();
582-
}
583-
else {
584-
ch7 = read();
585-
ch6 = read();
586-
ch5 = read();
587-
ch4 = read();
588-
ch3 = read();
589-
ch2 = read();
590-
ch1 = read();
591-
ch0 = read();
592-
}
593-
if ((ch0 | ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7) < 0) {
549+
final byte[] buf = conversionBuffer();
550+
final int read = read(buf, 0, 8);
551+
if (read < 8) {
594552
throw new EOFException();
595553
}
596-
// TODO: Double check this inconsistent code.
597-
return ((long) ch0 << 56) + //
598-
((long) (ch1 & 255) << 48) + //
599-
((long) (ch2 & 255) << 40) + //
600-
((long) (ch3 & 255) << 32) + //
601-
((long) (ch4 & 255) << 24) + //
602-
((ch5 & 255) << 16) + //
603-
((ch6 & 255) << 8) + //
604-
((ch7 & 255) << 0);
554+
return Bytes.toLong(buf, isLittleEndian());
605555
}
606556

607557
@Override
@@ -618,7 +568,7 @@ default double readDouble() throws IOException {
618568
default String readLine() throws IOException {
619569
// NB: Adapted from java.io.RandomAccessFile.readLine().
620570

621-
final StringBuffer input = new StringBuffer();
571+
final StringBuilder input = new StringBuilder();
622572
int c = -1;
623573
boolean eol = false;
624574

@@ -669,76 +619,42 @@ default void writeByte(final int v) throws IOException {
669619

670620
@Override
671621
default void writeShort(final int v) throws IOException {
672-
if (isBigEndian()) {
673-
write((v >>> 8) & 0xFF);
674-
write((v >>> 0) & 0xFF);
675-
}
676-
else {
677-
write((v >>> 0) & 0xFF);
678-
write((v >>> 8) & 0xFF);
679-
}
622+
final byte[] buf = conversionBuffer();
623+
Bytes.unpack(v, buf, 0, 2, isLittleEndian());
624+
write(buf, 0, 2);
680625
}
681626

682627
@Override
683628
default void writeChar(final int v) throws IOException {
684-
if (isBigEndian()) {
685-
write((v >>> 8) & 0xFF);
686-
write((v >>> 0) & 0xFF);
687-
}
688-
else {
689-
write((v >>> 0) & 0xFF);
690-
write((v >>> 8) & 0xFF);
691-
}
629+
writeShort(v);
692630
}
693631

694632
@Override
695633
default void writeInt(final int v) throws IOException {
696-
if (isBigEndian()) {
697-
write((v >>> 24) & 0xFF);
698-
write((v >>> 16) & 0xFF);
699-
write((v >>> 8) & 0xFF);
700-
write((v >>> 0) & 0xFF);
701-
}
702-
else {
703-
write((v >>> 0) & 0xFF);
704-
write((v >>> 8) & 0xFF);
705-
write((v >>> 16) & 0xFF);
706-
write((v >>> 24) & 0xFF);
707-
}
634+
final byte[] buf = conversionBuffer();
635+
Bytes.unpack(v, buf, 0, 4, isLittleEndian());
636+
write(buf, 0, 4);
708637
}
709638

710639
@Override
711640
default void writeLong(final long v) throws IOException {
712-
if (isBigEndian()) {
713-
write((byte) (v >>> 56));
714-
write((byte) (v >>> 48));
715-
write((byte) (v >>> 40));
716-
write((byte) (v >>> 32));
717-
write((byte) (v >>> 24));
718-
write((byte) (v >>> 16));
719-
write((byte) (v >>> 8));
720-
write((byte) (v >>> 0));
721-
}
722-
else {
723-
write((byte) (v >>> 0));
724-
write((byte) (v >>> 8));
725-
write((byte) (v >>> 16));
726-
write((byte) (v >>> 24));
727-
write((byte) (v >>> 32));
728-
write((byte) (v >>> 40));
729-
write((byte) (v >>> 48));
730-
write((byte) (v >>> 56));
731-
}
641+
final byte[] buf = conversionBuffer();
642+
Bytes.unpack(v, buf, 0, 8, isLittleEndian());
643+
write(buf, 0, 8);
732644
}
733645

734646
@Override
735647
default void writeFloat(final float v) throws IOException {
736-
writeInt(Float.floatToIntBits(v));
648+
final byte[] buf = conversionBuffer();
649+
Bytes.unpack(Float.floatToIntBits(v), buf, 0, 4, isLittleEndian());
650+
write(buf, 0, 4);
737651
}
738652

739653
@Override
740654
default void writeDouble(final double v) throws IOException {
741-
writeLong(Double.doubleToLongBits(v));
655+
final byte[] buf = conversionBuffer();
656+
Bytes.unpack(Double.doubleToLongBits(v), buf, 0, 8, isLittleEndian());
657+
write(buf, 0, 8);
742658
}
743659

744660
@Override
@@ -750,9 +666,7 @@ default void writeBytes(final String s) throws IOException {
750666
default void writeChars(final String s) throws IOException {
751667
final int len = s.length();
752668
for (int i = 0; i < len; i++) {
753-
final int v = s.charAt(i);
754-
write((v >>> 8) & 0xFF);
755-
write((v >>> 0) & 0xFF);
669+
writeChar(s.charAt(i));
756670
}
757671
}
758672

src/main/java/org/scijava/io/handle/FileHandle.java

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -151,21 +151,6 @@ public byte readByte() throws IOException {
151151
return reader().readByte();
152152
}
153153

154-
@Override
155-
public char readChar() throws IOException {
156-
return reader().readChar();
157-
}
158-
159-
@Override
160-
public double readDouble() throws IOException {
161-
return reader().readDouble();
162-
}
163-
164-
@Override
165-
public float readFloat() throws IOException {
166-
return reader().readFloat();
167-
}
168-
169154
@Override
170155
public void readFully(final byte[] b) throws IOException {
171156
reader().readFully(b);
@@ -178,36 +163,16 @@ public void readFully(final byte[] b, final int off, final int len)
178163
reader().readFully(b, off, len);
179164
}
180165

181-
@Override
182-
public int readInt() throws IOException {
183-
return reader().readInt();
184-
}
185-
186166
@Override
187167
public String readLine() throws IOException {
188168
return reader().readLine();
189169
}
190170

191-
@Override
192-
public long readLong() throws IOException {
193-
return reader().readLong();
194-
}
195-
196-
@Override
197-
public short readShort() throws IOException {
198-
return reader().readShort();
199-
}
200-
201171
@Override
202172
public int readUnsignedByte() throws IOException {
203173
return reader().readUnsignedByte();
204174
}
205175

206-
@Override
207-
public int readUnsignedShort() throws IOException {
208-
return reader().readUnsignedShort();
209-
}
210-
211176
@Override
212177
public String readUTF() throws IOException {
213178
return reader().readUTF();
@@ -252,41 +217,11 @@ public void writeBytes(final String s) throws IOException {
252217
writer().writeBytes(s);
253218
}
254219

255-
@Override
256-
public void writeChar(final int v) throws IOException {
257-
writer().writeChar(v);
258-
}
259-
260220
@Override
261221
public void writeChars(final String s) throws IOException {
262222
writer().writeChars(s);
263223
}
264224

265-
@Override
266-
public void writeDouble(final double v) throws IOException {
267-
writer().writeDouble(v);
268-
}
269-
270-
@Override
271-
public void writeFloat(final float v) throws IOException {
272-
writer().writeFloat(v);
273-
}
274-
275-
@Override
276-
public void writeInt(final int v) throws IOException {
277-
writer().writeInt(v);
278-
}
279-
280-
@Override
281-
public void writeLong(final long v) throws IOException {
282-
writer().writeLong(v);
283-
}
284-
285-
@Override
286-
public void writeShort(final int v) throws IOException {
287-
writer().writeShort(v);
288-
}
289-
290225
@Override
291226
public void writeUTF(final String str) throws IOException {
292227
writer().writeUTF(str);

0 commit comments

Comments
 (0)