Skip to content

Commit

Permalink
Support reading DOUBLE(O) values
Browse files Browse the repository at this point in the history
  • Loading branch information
albfernandez committed Jan 19, 2024
1 parent 7b84fe1 commit 79e2499
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 238 deletions.
16 changes: 11 additions & 5 deletions src/main/java/com/linuxense/javadbf/DBFReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,13 @@ protected Object getFieldValue(DBFField field) throws IOException {
return readMemoField(field);
case BINARY:
if (field.getLength() == 8) {
return readDoubleField(field);
return readDoubleFieldLittleEndian(field);
}
else {
return readMemoField(field);
}
case DOUBLE:
return readDoubleField(field);
return readDoubleFieldBigEndian(field);
case NULL_FLAGS:
byte [] data1 = new byte[field.getLength()];
this.dataInputStream.readFully(data1);
Expand All @@ -505,12 +505,18 @@ protected Object getFieldValue(DBFField field) throws IOException {
}
}

private Object readDoubleField(DBFField field) throws IOException {
private Object readDoubleFieldLittleEndian(DBFField field) throws IOException {
byte[] data = new byte[field.getLength()];
// return this.dataInputStream.readDouble();
this.dataInputStream.readFully(data);
return DBFUtils.toDouble(field, data);
return DBFUtils.toDoubleLittleEndian(data);
}

private Object readDoubleFieldBigEndian(DBFField field) throws IOException {
byte[] data = new byte[field.getLength()];
this.dataInputStream.readFully(data);
return DBFUtils.toDoubleBigEndian(data);
}


private Object readMemoField(DBFField field) throws IOException {
Number nBlock = null;
Expand Down
41 changes: 17 additions & 24 deletions src/main/java/com/linuxense/javadbf/DBFUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -425,33 +425,26 @@ protected static BitSet getBitSet(byte[] bytes) {
return bits;
}

protected static double toDouble(byte[] data) {
double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble();
if (d!= 0.0) {
d = -d;
protected static double toDoubleLittleEndian(byte[] data) {
double d = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getDouble();
if (d == -0.0) {
d = 0.0;
}
return d;
}
return d;
}

// FIXME delete
@Deprecated
protected static double toDouble(DBFField field, byte[] data) {
double d = toDouble(data);
StringBuilder sb = new StringBuilder() ;
for(byte b: data) {
if (sb.length() == 0) {
sb.append("{");
}
else {
sb.append(",");
}
sb.append(b);
}
sb.append("}");
System.out.println(field.getName() + " " + sb + "; " + d);
if (d!= 0.0) {

protected static double toDoubleBigEndian(byte[] data) {
double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble();

if (d != 0.0) {
// For some reason sign is swapped
d = -d;
}
if (d == -0.0) {
d = 0.0;
}
return d;
return d;
}

}
237 changes: 28 additions & 209 deletions src/test/java/com/linuxense/javadbf/UtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,16 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;



// TODO Rename to DBFUtilsTest
public class UtilsTest {

private static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
Expand Down Expand Up @@ -166,215 +160,40 @@ public void testTrimRightSpaces() {
}


@Test
@Ignore
public void testConverterDoublePostive() throws Exception {
double expected = 193786.00;
byte[] data = new byte[] {-63, 7, -89, -48, 0, 0, 0, 0};

System.out.println(toHexString(data));
System.out.println(toBinaryString(data));

double calculated = convertBigInteger(data);
Assert.assertEquals(expected, calculated, 0.01);
}

@Test
@Ignore
public void testConverterDoubleNegative() throws Exception {
// MaxPeakNoUnit {-64,-73,122,80,-76,-95,104,-121}; -6010.315256202716
// MinPeakNoUnit {63,-98,8,64,16,-128,33,-113}; 0.029328347212897617

double expected = -143.74;
byte[] data = new byte[] {63,-98,8,64,16,-128,33,-113};
System.out.println(toHexString(data));
System.out.println(toBinaryString(data));


double calculated = convertBigInteger(data);
Assert.assertEquals(expected, calculated, 0.01);
}

@Test
@Ignore
//Tz {-64,90,98,-125,120,90,126,-7}; -105.5392742999792
public void testConverterDouble2() throws Exception {
double expected = 105.539;
byte[] data = new byte[] {-64,90,98,-125,120,90,126,-7};
System.out.println(toHexString(data));
System.out.println(toBinaryString(data));
private class Pair {
byte[] data;
double expected;

//405A6283785A7EF9
//c05a6283785a7ef9
double calculated = convertBigInteger(data);
Assert.assertEquals(expected, calculated, 0.01);
}


@Test
public void testDoubles() throws Exception {

List<Double> expectedList = new ArrayList<Double>(Arrays.asList(193786.00, 193786.00, 105.539, -143.74, -110488.58));
List<byte[]> rawDataList = new ArrayList<byte[]>(Arrays.asList(
new byte[] {-63, 7, -89, -48, 0, 0, 0, 0},
new byte[] {65, 7, -89, -48, 0, 0, 0, 0},
new byte[] {-64,90,98,-125,120,90,126,-7},
new byte[] {63,-98,8,64,16,-128,33,-113},
new byte[] {63,5,6,118,-63,114,-45,-118}
));

for (int i = 0; i < expectedList.size(); i++) {
double expected = expectedList.get(i);
byte[] data = rawDataList.get(i);
double bigInteger = convertBigInteger(data);
double byteBufferBE = convertByteBufferBigEndian(data);
double byteBufferLE = convertByteBufferLittleEndian(data);
System.out.println("---");
System.out.println(toHexString(data));
System.out.println(toBinaryString(data));
System.out.println(expected);
System.out.println("biginteger =" + bigInteger);
System.out.println("bytebufferBE=" + byteBufferBE);
System.out.println("bytebufferLE=" + byteBufferLE);

private Pair(byte[] data, double expected) {
this.data = data;
this.expected = expected;
}
for (byte[] data : rawDataList) {
System.out.println("raw=" + toBinaryString(data));
}

long a = 0xFFFFFFFF;
a = a & new BigInteger(new byte[] {63,-98,8,64,16,-128,33,-113}).longValue();
a = a & new BigInteger(new byte[] {63,5,6,118,-63,114,-45,-118}).longValue();
System.out.println("long=" + Long.toBinaryString(a));


}

/*
* MaxPeakNoUnit {-64,-73,122,80,-76,-95,104,-121}; 6010.315256202716
MinPeakNoUnit {63,-98,8,64,16,-128,33,-113}; -0.029328347212897617
T1 {-65,15,-54,102,-98,53,-91,-17}; 6.063581147481764E-5
T2 {-128,0,0,0,0,0,0,0}; -0.0
Tp {-128,0,0,0,0,0,0,0}; -0.0
Td {-128,0,0,0,0,0,0,0}; -0.0
Tc {-128,0,0,0,0,0,0,0}; -0.0
Tz {-64,90,98,-125,120,90,126,-7}; 105.5392742999792
BetaDash {-65,-59,-10,25,-76,122,28,-53}; 0.17157288849214178
FreqOsc {-128,0,0,0,0,0,0,0}; -0.0
Urms {-128,0,0,0,0,0,0,0}; -0.0
FreqAC {-128,0,0,0,0,0,0,0}; -0.0
Udc {-128,0,0,0,0,0,0,0}; -0.0
UpValue {-128,0,0,0,0,0,0,0}; -0.0
SpareF1 {-64,89,0,0,0,0,0,0}; 100.0
SpareF2 {0,0,0,0,0,0,0,0}; 0.0
SpareF3 {0,0,0,0,0,0,0,0}; 0.0
MinPeakNoUnit=0.029328347212897617
MaxPeakNoUnit=-6010.315256202716
MinPeakN=-143.74 A
MaxPeak=6.010 kA
*/

/*
* DataNumber {-63,7,-88,64,0,0,0,0}; 193800.0
ChannelNum {-65,-16,0,0,0,0,0,0}; 1.0
TerminalDi {-64,117,-32,0,0,0,0,0}; 350.0
CurveType {-65,-16,0,0,0,0,0,0}; 1.0
FilterCoun {-128,0,0,0,0,0,0,0}; -0.0
ErrorMessa {0,0,0,0,0,0,0,0}; 0.0
MaxPeakNoUnit {63,5,6,118,-63,114,-45,-118}; -4.010248101719075E-5
MinPeakNoUnit {-128,0,0,0,0,0,0,0}; -0.0
T1 {-66,-80,-109,-69,93,70,-61,1}; 9.880708279169888E-7
T2 {-65,5,-121,107,-35,50,-104,55}; 4.1063288926765735E-5
Tp {-128,0,0,0,0,0,0,0}; -0.0
Td {-128,0,0,0,0,0,0,0}; -0.0
Tc {-128,0,0,0,0,0,0,0}; -0.0
Tz {-64,-98,109,31,-5,-6,-36,115}; 1947.2812346646358
BetaDash {-64,42,-90,-117,42,-118,-51,29}; 13.325280503695973
FreqOsc {-128,0,0,0,0,0,0,0}; -0.0
Urms {-128,0,0,0,0,0,0,0}; -0.0
FreqAC {-128,0,0,0,0,0,0,0}; -0.0
Udc {-128,0,0,0,0,0,0,0}; -0.0
UpValue {-128,0,0,0,0,0,0,0}; -0.0
SpareF1 {-64,89,0,0,0,0,0,0}; 100.0
SpareF2 {0,0,0,0,0,0,0,0}; 0.0
SpareF3 {0,0,0,0,0,0,0,0}; 0.0
MinPeakNoUnit=-0.0
MaxPeakNoUnit=4.010248101719075E-5
MinPeakN=0.000 V
MaxPeak=-110.48 kV
*/

private double convertByteBufferLittleEndian(byte[] data) {
// double d = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getDouble();
ByteBuffer buffer = ByteBuffer.allocate(8);
// buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.put(data,0,data.length);
buffer.order(ByteOrder.BIG_ENDIAN);
double d = buffer.getDouble(0);
return d;
}
private double convertByteBufferBigEndian(byte[] data) {
double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble();
// if (d!= 0.0) {
// d = -d;
// }
return d;
}

private double convertBigInteger(byte[] data) {
long longValue = new BigInteger(data).longValue();
double d = Double.longBitsToDouble(longValue);
// if (d != 0) {
// return -d;
// }
return d;
// return DBFUtils.toDouble(data);

}
//0011111100000101000001100111011011000001011100101101001110001010 <- memo
//1100000011111010111110011000100101000111101011100001010001111011 <- calculado

// 193786.00
//1100000100000111101001111101000000000000000000000000000000000000 <- memo
//0100000100000111101001111101000000000000000000000000000000000000 <-caculado


// 105.539
// 1100000001011010011000101000001101111000010110100111111011111001 <- memo
// c05a6283785a7ef9
// 0100000001011010011000101000001101111000010110100111111011111001 <- calculado
// 405A6283785A7EF9

//-143.74
//3f9e08401080218f
//C061F7AE147AE148
/*
1100000001011010011000101000001101111000010110100111111011111001
105.539
biginteger =-105.5392742999792
bytebufferBE=-105.5392742999792
bytebufferLE=-105.5392742999792
*/

private String toBinaryString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE);
for (int i = 0; i < Byte.SIZE * bytes.length; i++) {
sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
@Test
public void testDoublesDouble() throws Exception {
List<Pair> list = new ArrayList<Pair>();
list.add(new Pair(new byte[] {-128,0,0,0,0,0,0,0}, 0.0));
list.add(new Pair(new byte[] {0,0,0,0,0,0,0,0}, 0.0));
list.add(new Pair(new byte[] {-65,-16,0,0,0,0,0,0}, 1.0));
list.add(new Pair(new byte[] {-64,-73,122,80,-76,-95,104,-121}, 6010.315256202716));
list.add(new Pair(new byte[] {63,-98,8,64,16,-128,33,-113}, -0.029328347212897617));
list.add(new Pair(new byte[] {-65,15,-54,102,-98,53,-91,-17}, 6.063581147481764E-5));
list.add(new Pair(new byte[] {-64,90,98,-125,120,90,126,-7}, 105.5392742999792));
list.add(new Pair(new byte[] {-65,-59,-10,25,-76,122,28,-53}, 0.17157288849214178));
list.add(new Pair(new byte[] {-64,89,0,0,0,0,0,0}, 100.0));
list.add(new Pair(new byte[] {-63,7,-88,64,0,0,0,0}, 193800.0));
list.add(new Pair(new byte[] {-64,117,-32,0,0,0,0,0}, 350.0));
list.add(new Pair(new byte[] {63,5,6,118,-63,114,-45,-118}, -4.010248101719075E-5));
list.add(new Pair(new byte[] {-66,-80,-109,-69,93,70,-61,1}, 9.880708279169888E-7));
list.add(new Pair(new byte[] {-65,5,-121,107,-35,50,-104,55}, 4.1063288926765735E-5));
list.add(new Pair(new byte[] {-64,-98,109,31,-5,-6,-36,115}, 1947.2812346646358));
list.add(new Pair(new byte[] {-64,42,-90,-117,42,-118,-51,29}, 13.325280503695973));

for (Pair p : list) {
Assert.assertEquals(p.expected, DBFUtils.toDoubleBigEndian(p.data), 0.01);
}
return sb.toString();
}
private String toHexString(byte[] byteArray) {
StringBuffer hexStringBuffer = new StringBuffer();
for (int i = 0; i < byteArray.length; i++) {
hexStringBuffer.append(byteToHex(byteArray[i]));
}
return hexStringBuffer.toString();
}
private String byteToHex(byte num) {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
hexDigits[1] = Character.forDigit((num & 0xF), 16);
return new String(hexDigits);
}

}

0 comments on commit 79e2499

Please sign in to comment.