adds dig rom rle encoding, closes #824

This commit is contained in:
hneemann 2021-09-11 08:09:47 +02:00
parent 5b90f78ea9
commit 082e3877c1
2 changed files with 121 additions and 36 deletions

View File

@ -16,7 +16,6 @@ import java.util.StringTokenizer;
/** /**
* Optimized converter for data fields * Optimized converter for data fields
* <p>
*/ */
public class DataFieldConverter implements Converter { public class DataFieldConverter implements Converter {
@Override @Override
@ -28,24 +27,46 @@ public class DataFieldConverter implements Converter {
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) { public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
DataField df = (DataField) o; DataField df = (DataField) o;
df.trim(); df.trim();
StringBuilder data = new StringBuilder(); StringBuilder dataStr = new StringBuilder();
long[] data = df.getData();
int pos = 0; int pos = 0;
for (long d : df.getData()) { if (data.length > 0) {
if (data.length() > 0) { long akt = data[0];
data.append(","); int count = 1;
pos++; for (int i = 1; i < data.length; i++) {
} if (dataStr.length() - pos > 60) {
dataStr.append("\n");
pos = dataStr.length();
}
if (pos > 80) { final long now = data[i];
data.append("\n"); if (now == akt)
pos = 0; count++;
else {
writeChunk(dataStr, akt, count);
akt = now;
count = 1;
}
} }
writeChunk(dataStr, akt, count);
final String s = Long.toHexString(d); }
data.append(s); writer.setValue(dataStr.toString());
pos += s.length(); }
private void writeChunk(StringBuilder w, long data, int count) {
if (count < 4) {
for (int j = 0; j < count; j++) {
if (w.length() > 0)
w.append(",");
w.append(Long.toHexString(data));
}
} else {
if (w.length() > 0)
w.append(",");
w.append(count);
w.append('*');
w.append(Long.toHexString(data));
} }
writer.setValue(data.toString());
} }
@Override @Override
@ -70,8 +91,19 @@ public class DataFieldConverter implements Converter {
StringTokenizer st = new StringTokenizer(reader.getValue(), ","); StringTokenizer st = new StringTokenizer(reader.getValue(), ",");
int i = 0; int i = 0;
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
df.setData(i, Bits.decode(st.nextToken().trim(), 0, 16)); String val = st.nextToken().trim();
i++; int p = val.indexOf("*");
if (p < 0) {
df.setData(i, Bits.decode(val, 0, 16));
i++;
} else {
int count = Integer.parseInt(val.substring(0, p));
long v = Bits.decode(val.substring(p + 1), 0, 16);
for (int j = 0; j < count; j++) {
df.setData(i, v);
i++;
}
}
} }
df.trim(); df.trim();
return df; return df;

View File

@ -10,6 +10,7 @@ import de.neemann.digital.XStreamValid;
import junit.framework.TestCase; import junit.framework.TestCase;
/** /**
*
*/ */
public class DataFieldConverterTest extends TestCase { public class DataFieldConverterTest extends TestCase {
@ -21,7 +22,7 @@ public class DataFieldConverterTest extends TestCase {
return xStream; return xStream;
} }
public void testMarshal() throws Exception { public void testMarshal() {
DataField d = new DataField(1000); DataField d = new DataField(1000);
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
d.setData(i, i); d.setData(i, i);
@ -32,7 +33,7 @@ public class DataFieldConverterTest extends TestCase {
assertEquals("<?xml version=\"1.0\" ?><dataField>0,1,2,3,4,5,6,7,8,9</dataField>", xml); assertEquals("<?xml version=\"1.0\" ?><dataField>0,1,2,3,4,5,6,7,8,9</dataField>", xml);
} }
public void testUnmarshal() throws Exception { public void testUnmarshal() {
XStream xStream = getxStream(); XStream xStream = getxStream();
DataField df = (DataField) xStream.fromXML("<dataField size=\"1000\">0,1,2,3,4,5,6,7,8,9</dataField>"); DataField df = (DataField) xStream.fromXML("<dataField size=\"1000\">0,1,2,3,4,5,6,7,8,9</dataField>");
@ -43,8 +44,8 @@ public class DataFieldConverterTest extends TestCase {
} }
private static class Test { private static class Test {
private DataField d1; private final DataField d1;
private DataField d2; private final DataField d2;
public Test(DataField d1, DataField d2) { public Test(DataField d1, DataField d2) {
this.d1 = d1; this.d1 = d1;
@ -52,7 +53,7 @@ public class DataFieldConverterTest extends TestCase {
} }
} }
public void testMarshalObj() throws Exception { public void testMarshalObj() {
final DataField d1 = new DataField(20); final DataField d1 = new DataField(20);
d1.setData(0, 1); d1.setData(0, 1);
d1.setData(5, 2); d1.setData(5, 2);
@ -60,22 +61,52 @@ public class DataFieldConverterTest extends TestCase {
final DataField d2 = new DataField(20); final DataField d2 = new DataField(20);
d2.setData(0, 3); d2.setData(0, 3);
d2.setData(8, 4); d2.setData(8, 4);
Test t = new Test(d1, d2);
XStream xs = getxStream(); XStream xs = getxStream();
String xml = xs.toXML(t); String xml = xs.toXML(new Test(d1, d2));
assertEquals("<?xml version=\"1.0\" ?><test>" + assertEquals("<?xml version=\"1.0\" ?><test>" +
"<d1>1,0,0,0,0,2</d1>" + "<d1>1,4*0,2</d1>" +
"<d2>3,0,0,0,0,0,0,0,4</d2>" + "<d2>3,7*0,4</d2>" +
"</test>", xml); "</test>", xml);
} }
public void testUnarshalObj() throws Exception { public void testMarshalObj2() {
final DataField d1 = new DataField(20);
d1.setData(5, 2);
final DataField d2 = new DataField(20);
d2.setData(8, 4);
XStream xs = getxStream();
String xml = xs.toXML(new Test(d1, d2));
assertEquals("<?xml version=\"1.0\" ?><test>" +
"<d1>5*0,2</d1>" +
"<d2>8*0,4</d2>" +
"</test>", xml);
}
public void testMarshalObj3() {
final DataField d1 = new DataField(20);
for (int i = 0; i < 11; i++)
d1.setData(i, 2);
final DataField d2 = new DataField(20);
for (int i = 0; i < 11; i++)
d2.setData(i, 11);
XStream xs = getxStream();
String xml = xs.toXML(new Test(d1, d2));
assertEquals("<?xml version=\"1.0\" ?><test>" +
"<d1>11*2</d1>" +
"<d2>11*b</d2>" +
"</test>", xml);
}
public void testUnmarshalObj() {
XStream xs = getxStream(); XStream xs = getxStream();
Test t = (Test) xs.fromXML("<test>\n" + Test t = (Test) xs.fromXML("<test>\n" +
" <d1>1,0,0,0,0,2</d1>\n" + " <d1>1,4*0,2</d1>\n" +
" <d2>3,0,0,0,0,0,0,0,4</d2>\n" + " <d2>3,7*0,4</d2>\n" +
"</test>"); "</test>");
assertEquals(6, t.d1.getData().length); assertEquals(6, t.d1.getData().length);
@ -86,8 +117,29 @@ public class DataFieldConverterTest extends TestCase {
assertEquals(4, t.d2.getDataWord(8)); assertEquals(4, t.d2.getDataWord(8));
} }
public void testUnmarshalObj2() {
XStream xs = getxStream();
Test t = (Test) xs.fromXML("<test>\n" +
" <d1>1,10*a,2</d1>\n" +
" <d2>3,11*b,4</d2>\n" +
"</test>");
public void testMarshalMuch() throws Exception { assertEquals(12, t.d1.getData().length);
assertEquals(1, t.d1.getDataWord(0));
assertEquals(10, t.d1.getDataWord(1));
assertEquals(10, t.d1.getDataWord(2));
assertEquals(10, t.d1.getDataWord(3));
assertEquals(2, t.d1.getDataWord(11));
assertEquals(13, t.d2.getData().length);
assertEquals(3, t.d2.getDataWord(0));
assertEquals(11, t.d2.getDataWord(1));
assertEquals(11, t.d2.getDataWord(2));
assertEquals(11, t.d2.getDataWord(11));
assertEquals(4, t.d2.getDataWord(12));
}
public void testMarshalMuch() {
DataField d = new DataField(1000); DataField d = new DataField(1000);
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
d.setData(i, i); d.setData(i, i);
@ -95,13 +147,14 @@ public class DataFieldConverterTest extends TestCase {
XStream xStream = getxStream(); XStream xStream = getxStream();
String xml = xStream.toXML(d); String xml = xStream.toXML(d);
assertEquals("<?xml version=\"1.0\" ?><dataField>0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,\n" + assertEquals("<?xml version=\"1.0\" ?><dataField>0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12,13,14,15,16,17,18,19\n" +
"21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,30,31,32,33,34,35,36,37,38,39,3a,3b,\n" + ",1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e\n" +
"3c,3d,3e,3f,40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,\n" + ",2f,30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,40,41,42,43\n" +
"57,58,59,5a,5b,5c,5d,5e,5f,60,61,62,63</dataField>", xml); ",44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58\n" +
",59,5a,5b,5c,5d,5e,5f,60,61,62,63</dataField>", xml);
} }
public void testUnmarshalMuch() throws Exception { public void testUnmarshalMuch() {
XStream xStream = getxStream(); XStream xStream = getxStream();
DataField df = (DataField) xStream.fromXML("<dataField>0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,\n" + DataField df = (DataField) xStream.fromXML("<dataField>0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,\n" +