Skip to content

Commit

Permalink
Support reading DOUBLE(O) values
Browse files Browse the repository at this point in the history
Fixes #102
  • Loading branch information
albfernandez committed Jan 18, 2024
1 parent 7e29122 commit 62a0e9c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 173 deletions.
15 changes: 11 additions & 4 deletions src/main/java/com/linuxense/javadbf/DBFReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -486,13 +486,13 @@ protected Object getFieldValue(DBFField field) throws IOException {
return readMemoField(field);
case BINARY:
if (field.getLength() == 8) {
return readDoubleField(field);
return readDoubleField_B(field);
}
else {
return readMemoField(field);
}
case DOUBLE:
return readDoubleField(field);
return readDoubleField_O(field);
case NULL_FLAGS:
byte [] data1 = new byte[field.getLength()];
this.dataInputStream.readFully(data1);
Expand All @@ -503,11 +503,18 @@ protected Object getFieldValue(DBFField field) throws IOException {
}
}

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

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

private Object readMemoField(DBFField field) throws IOException {
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/com/linuxense/javadbf/DBFUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,35 @@ protected static BitSet getBitSet(byte[] bytes) {
return BitSet.valueOf(bytes);
}

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

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


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

if (d != 0.0) {
d = -d;
}
if (d == -0.0) {
d = 0.0;
}
return d;

}


Expand Down
218 changes: 50 additions & 168 deletions src/test/java/com/linuxense/javadbf/UtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
Expand All @@ -36,6 +37,8 @@
import org.junit.Ignore;
import org.junit.Test;

import com.linuxense.javadbf.testutils.DbfToTxtTest;



// TODO Rename to DBFUtilsTest
Expand Down Expand Up @@ -166,195 +169,69 @@ 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};
public void testConvertDoubleBinary_valueOne() {
double expected = 1.0;
byte[] data = {0,0,0,0,0,0, (byte) 0xF0, 0x3F};
System.out.println(toHexString(data));
System.out.println(toBinaryString(data));


double calculated = convertBigInteger(data);
double calculated = DBFUtils.toDoubleBinary(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};
public void testConvertDoubleDouble_valueOne() {
double expected = 1.0;
byte[] data = {(byte) 0xBF,(byte) 0xF0,0,0,0,0, 0, 0};
System.out.println(toHexString(data));
System.out.println(toBinaryString(data));

//405A6283785A7EF9
//c05a6283785a7ef9
double calculated = convertBigInteger(data);
double calculated = DBFUtils.toDoubleDouble(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);

}
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 class Pair {
byte[] data;
double expected;

private Pair(byte[] data, double expected) {
this.data = data;
this.expected = expected;
}
}

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);

@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.toDoubleDouble(p.data), 0.01);
}
}
//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);
Expand All @@ -377,4 +254,9 @@ private String byteToHex(byte num) {
return new String(hexDigits);
}

@Test
public void testPrintNumbers() throws Exception {
DbfToTxtTest.writeToConsole(new File("src/test/resources/numbers2.dbf") );
}

}
Binary file added src/test/resources/numbers2.dbf
Binary file not shown.

0 comments on commit 62a0e9c

Please sign in to comment.