From 5634a1e55586f5f4feeef9f59633bdb7d5bd2ce2 Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Wed, 22 May 2024 15:29:53 +0200 Subject: [PATCH] Use bytes instead of chars --- .../document/ArrayCharBag.java | 16 +++++++++++---- .../shareclientcore/document/Char.java | 10 +++++----- .../shareclientcore/document/CharBag.java | 15 ++++++++++---- .../document/DocumentListener.java | 2 +- .../document/SharedDocument.java | 20 ++++++++++++++++--- .../shareclientcore/DocumentTest.java | 8 ++++---- .../shareclientcore/MessageTest.java | 6 +++--- 7 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/main/java/me/mrletsplay/shareclientcore/document/ArrayCharBag.java b/src/main/java/me/mrletsplay/shareclientcore/document/ArrayCharBag.java index a8ccf84..1890ebc 100644 --- a/src/main/java/me/mrletsplay/shareclientcore/document/ArrayCharBag.java +++ b/src/main/java/me/mrletsplay/shareclientcore/document/ArrayCharBag.java @@ -1,5 +1,6 @@ package me.mrletsplay.shareclientcore.document; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -51,10 +52,17 @@ public class ArrayCharBag implements CharBag { } @Override - public String toString() { - return chars.stream() - .map(c -> c.value()) - .reduce(new StringBuilder(), (b, s) -> b.append(s), (a, b) -> a.append(b)).toString(); + public byte[] getContents() { + byte[] bytes = new byte[chars.size()]; + for(int i = 0; i < bytes.length; i++) { + bytes[i] = chars.get(i).value(); + } + return bytes; + } + + @Override + public String getContentsAsString() { + return new String(getContents(), StandardCharsets.UTF_8); } } diff --git a/src/main/java/me/mrletsplay/shareclientcore/document/Char.java b/src/main/java/me/mrletsplay/shareclientcore/document/Char.java index b17fe01..eb9ae67 100644 --- a/src/main/java/me/mrletsplay/shareclientcore/document/Char.java +++ b/src/main/java/me/mrletsplay/shareclientcore/document/Char.java @@ -8,10 +8,10 @@ import java.util.Objects; import me.mrletsplay.shareclientcore.connection.SerializableObject; -public record Char(Identifier[] position, int lamport, char value) implements SerializableObject { +public record Char(Identifier[] position, int lamport, byte value) implements SerializableObject { - public static final Char START_OF_DOCUMENT = new Char(new Identifier[] { new Identifier(1, Identifier.DEFAULT_SITE) }, 0, '^'); - public static final Char END_OF_DOCUMENT = new Char(new Identifier[] { new Identifier(Util.BASE - 1, Identifier.DEFAULT_SITE) }, 0, '$'); + public static final Char START_OF_DOCUMENT = new Char(new Identifier[] { new Identifier(1, Identifier.DEFAULT_SITE) }, 0, (byte) '^'); + public static final Char END_OF_DOCUMENT = new Char(new Identifier[] { new Identifier(Util.BASE - 1, Identifier.DEFAULT_SITE) }, 0, (byte) '$'); @Override public int hashCode() { @@ -44,7 +44,7 @@ public record Char(Identifier[] position, int lamport, char value) implements Se } out.writeInt(lamport); - out.writeChar(value); + out.writeByte(value); } public static Char deserialize(DataInputStream in) throws IOException { @@ -54,7 +54,7 @@ public record Char(Identifier[] position, int lamport, char value) implements Se } int lamport = in.readInt(); - char value = in.readChar(); + byte value = in.readByte(); return new Char(pos, lamport, value); } diff --git a/src/main/java/me/mrletsplay/shareclientcore/document/CharBag.java b/src/main/java/me/mrletsplay/shareclientcore/document/CharBag.java index 59c9a5c..99b807d 100644 --- a/src/main/java/me/mrletsplay/shareclientcore/document/CharBag.java +++ b/src/main/java/me/mrletsplay/shareclientcore/document/CharBag.java @@ -1,5 +1,6 @@ package me.mrletsplay.shareclientcore.document; +import java.nio.charset.StandardCharsets; import java.util.List; public interface CharBag { @@ -38,10 +39,16 @@ public interface CharBag { public List toList(); /** - * Collects the chars in this bag ordered by their position into a string - * @return A string containing the chars + * Collects the chars in this bag ordered by their position into a byte array + * @return A byte array containing the contents of this bag */ - @Override - public String toString(); + public byte[] getContents(); + + /** + * Collects the chars in this bag ordered by their position into a string using the {@link StandardCharsets#UTF_8 UTF-8} charset.
+ * Note: This will not work properly for binary contents, make sure to only call this on bags containing text! + * @return A string containing the contents of this bag + */ + public String getContentsAsString(); } diff --git a/src/main/java/me/mrletsplay/shareclientcore/document/DocumentListener.java b/src/main/java/me/mrletsplay/shareclientcore/document/DocumentListener.java index a63de06..e1a2a03 100644 --- a/src/main/java/me/mrletsplay/shareclientcore/document/DocumentListener.java +++ b/src/main/java/me/mrletsplay/shareclientcore/document/DocumentListener.java @@ -5,7 +5,7 @@ package me.mrletsplay.shareclientcore.document; */ public interface DocumentListener { - public void onInsert(int index, char character); + public void onInsert(int index, byte b); public void onDelete(int index); diff --git a/src/main/java/me/mrletsplay/shareclientcore/document/SharedDocument.java b/src/main/java/me/mrletsplay/shareclientcore/document/SharedDocument.java index 8513086..475626d 100644 --- a/src/main/java/me/mrletsplay/shareclientcore/document/SharedDocument.java +++ b/src/main/java/me/mrletsplay/shareclientcore/document/SharedDocument.java @@ -1,5 +1,6 @@ package me.mrletsplay.shareclientcore.document; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -46,7 +47,7 @@ public class SharedDocument implements MessageListener { Char charBefore = charBag.get(index); Char charAfter = charBag.get(index +1); - char[] chars = str.toCharArray(); + byte[] chars = str.getBytes(StandardCharsets.UTF_8); Change[] changes = new Change[chars.length]; for(int i = 0; i < chars.length; i++) { Identifier[] newPos = Util.generatePositionBetween(charBefore.position(), charAfter.position(), site); @@ -144,8 +145,21 @@ public class SharedDocument implements MessageListener { return chars.subList(1, chars.size() - 1); } - public String getContents() { - String contents = charBag.toString(); + /** + * @return The contents of the document + * @see CharBag#getContents() + */ + public byte[] getContents() { + byte[] contents = charBag.getContents(); + return Arrays.copyOfRange(contents, 1, contents.length - 1); + } + + /** + * @return The contents of the document converted to a UTF-8 encoded string + * @see CharBag#getContentsAsString() + */ + public String getContentsAsString() { + String contents = charBag.getContentsAsString(); return contents.substring(1, contents.length() - 1); } diff --git a/src/test/java/me/mrletsplay/shareclientcore/DocumentTest.java b/src/test/java/me/mrletsplay/shareclientcore/DocumentTest.java index 5b534b8..036d2b8 100644 --- a/src/test/java/me/mrletsplay/shareclientcore/DocumentTest.java +++ b/src/test/java/me/mrletsplay/shareclientcore/DocumentTest.java @@ -14,11 +14,11 @@ public class DocumentTest { public void testLocalInsert() { SharedDocument doc = new SharedDocument(new DummyConnection(), "test"); doc.localInsert(0, "Hello"); - assertEquals("Hello", doc.getContents()); + assertEquals("Hello", doc.getContentsAsString()); doc.localInsert(5, " World"); - assertEquals("Hello World", doc.getContents()); + assertEquals("Hello World", doc.getContentsAsString()); doc.localInsert(5, " Test"); - assertEquals("Hello Test World", doc.getContents()); + assertEquals("Hello Test World", doc.getContentsAsString()); } @Test @@ -34,7 +34,7 @@ public class DocumentTest { SharedDocument doc = new SharedDocument(new DummyConnection(), "test"); doc.localInsert(0, "Hello World!"); doc.localDelete(5, 6); - assertEquals("Hello!", doc.getContents()); + assertEquals("Hello!", doc.getContentsAsString()); } @Test diff --git a/src/test/java/me/mrletsplay/shareclientcore/MessageTest.java b/src/test/java/me/mrletsplay/shareclientcore/MessageTest.java index 497d493..5a98855 100644 --- a/src/test/java/me/mrletsplay/shareclientcore/MessageTest.java +++ b/src/test/java/me/mrletsplay/shareclientcore/MessageTest.java @@ -42,7 +42,7 @@ public class MessageTest { @Test public void testChangeMessage() throws IOException { - Change change = new Change("Project:src/test.txt", ChangeType.ADD, new Char(new Identifier[] {new Identifier(0, 1), new Identifier(1, 3)}, 42, 'e')); + Change change = new Change("Project:src/test.txt", ChangeType.ADD, new Char(new Identifier[] {new Identifier(0, 1), new Identifier(1, 3)}, 42, (byte) 'e')); ChangeMessage m = new ChangeMessage(change); assertEquals(deserialize(serialize(m)), m, "Deserialized message must equal message"); } @@ -80,8 +80,8 @@ public class MessageTest { @Test public void testFullSyncMessage() throws IOException { List chars = Arrays.asList( - new Char(new Identifier[] {new Identifier(0, 1), new Identifier(1, 3)}, 42, 'e'), - new Char(new Identifier[] {new Identifier(0, 1), new Identifier(1, 3), new Identifier(1, 4)}, 333, 'f') + new Char(new Identifier[] {new Identifier(0, 1), new Identifier(1, 3)}, 42, (byte) 'e'), + new Char(new Identifier[] {new Identifier(0, 1), new Identifier(1, 3), new Identifier(1, 4)}, 333, (byte) 'f') ); FullSyncMessage m = new FullSyncMessage(2, "Project:src/test.txt", chars); assertEquals(deserialize(serialize(m)), m, "Deserialized message must equal message");