diff --git a/src/main/java/de/neemann/digital/core/memory/DataFieldConverter.java b/src/main/java/de/neemann/digital/core/memory/DataFieldConverter.java index 356afc2c9..a6a17d253 100644 --- a/src/main/java/de/neemann/digital/core/memory/DataFieldConverter.java +++ b/src/main/java/de/neemann/digital/core/memory/DataFieldConverter.java @@ -16,7 +16,6 @@ import java.util.StringTokenizer; /** * Optimized converter for data fields - *

*/ public class DataFieldConverter implements Converter { @Override @@ -28,24 +27,46 @@ public class DataFieldConverter implements Converter { public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) { DataField df = (DataField) o; df.trim(); - StringBuilder data = new StringBuilder(); + StringBuilder dataStr = new StringBuilder(); + long[] data = df.getData(); int pos = 0; - for (long d : df.getData()) { - if (data.length() > 0) { - data.append(","); - pos++; - } + if (data.length > 0) { + long akt = data[0]; + int count = 1; + for (int i = 1; i < data.length; i++) { + if (dataStr.length() - pos > 60) { + dataStr.append("\n"); + pos = dataStr.length(); + } - if (pos > 80) { - data.append("\n"); - pos = 0; + final long now = data[i]; + if (now == akt) + count++; + else { + writeChunk(dataStr, akt, count); + akt = now; + count = 1; + } } - - final String s = Long.toHexString(d); - data.append(s); - pos += s.length(); + writeChunk(dataStr, akt, count); + } + writer.setValue(dataStr.toString()); + } + + 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 @@ -70,8 +91,19 @@ public class DataFieldConverter implements Converter { StringTokenizer st = new StringTokenizer(reader.getValue(), ","); int i = 0; while (st.hasMoreTokens()) { - df.setData(i, Bits.decode(st.nextToken().trim(), 0, 16)); - i++; + String val = st.nextToken().trim(); + 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(); return df; diff --git a/src/test/java/de/neemann/digital/core/memory/DataFieldConverterTest.java b/src/test/java/de/neemann/digital/core/memory/DataFieldConverterTest.java index 6e4f2716b..6036c549d 100644 --- a/src/test/java/de/neemann/digital/core/memory/DataFieldConverterTest.java +++ b/src/test/java/de/neemann/digital/core/memory/DataFieldConverterTest.java @@ -10,6 +10,7 @@ import de.neemann.digital.XStreamValid; import junit.framework.TestCase; /** + * */ public class DataFieldConverterTest extends TestCase { @@ -21,7 +22,7 @@ public class DataFieldConverterTest extends TestCase { return xStream; } - public void testMarshal() throws Exception { + public void testMarshal() { DataField d = new DataField(1000); for (int i = 0; i < 10; i++) d.setData(i, i); @@ -32,7 +33,7 @@ public class DataFieldConverterTest extends TestCase { assertEquals("0,1,2,3,4,5,6,7,8,9", xml); } - public void testUnmarshal() throws Exception { + public void testUnmarshal() { XStream xStream = getxStream(); DataField df = (DataField) xStream.fromXML("0,1,2,3,4,5,6,7,8,9"); @@ -43,8 +44,8 @@ public class DataFieldConverterTest extends TestCase { } private static class Test { - private DataField d1; - private DataField d2; + private final DataField d1; + private final DataField d2; public Test(DataField d1, DataField d2) { 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); d1.setData(0, 1); d1.setData(5, 2); @@ -60,22 +61,52 @@ public class DataFieldConverterTest extends TestCase { final DataField d2 = new DataField(20); d2.setData(0, 3); d2.setData(8, 4); - Test t = new Test(d1, d2); XStream xs = getxStream(); - String xml = xs.toXML(t); + String xml = xs.toXML(new Test(d1, d2)); assertEquals("" + - "1,0,0,0,0,2" + - "3,0,0,0,0,0,0,0,4" + + "1,4*0,2" + + "3,7*0,4" + "", 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("" + + "5*0,2" + + "8*0,4" + + "", 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("" + + "11*2" + + "11*b" + + "", xml); + } + + public void testUnmarshalObj() { XStream xs = getxStream(); Test t = (Test) xs.fromXML("\n" + - " 1,0,0,0,0,2\n" + - " 3,0,0,0,0,0,0,0,4\n" + + " 1,4*0,2\n" + + " 3,7*0,4\n" + ""); assertEquals(6, t.d1.getData().length); @@ -86,8 +117,29 @@ public class DataFieldConverterTest extends TestCase { assertEquals(4, t.d2.getDataWord(8)); } + public void testUnmarshalObj2() { + XStream xs = getxStream(); + Test t = (Test) xs.fromXML("\n" + + " 1,10*a,2\n" + + " 3,11*b,4\n" + + ""); - 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); for (int i = 0; i < 100; i++) d.setData(i, i); @@ -95,13 +147,14 @@ public class DataFieldConverterTest extends TestCase { XStream xStream = getxStream(); String xml = xStream.toXML(d); - assertEquals("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" + - "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" + - "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" + - "57,58,59,5a,5b,5c,5d,5e,5f,60,61,62,63", xml); + assertEquals("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" + + ",1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e\n" + + ",2f,30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,40,41,42,43\n" + + ",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", xml); } - public void testUnmarshalMuch() throws Exception { + public void testUnmarshalMuch() { XStream xStream = getxStream(); DataField df = (DataField) xStream.fromXML("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" +