summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/psmb4j/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/keuin/psmb4j/util')
-rw-r--r--src/main/java/com/keuin/psmb4j/util/InputStreamUtils.java56
-rw-r--r--src/main/java/com/keuin/psmb4j/util/StringUtils.java14
-rw-r--r--src/main/java/com/keuin/psmb4j/util/error/SocketClosedException.java15
-rw-r--r--src/main/java/com/keuin/psmb4j/util/error/StringLengthExceededException.java9
4 files changed, 94 insertions, 0 deletions
diff --git a/src/main/java/com/keuin/psmb4j/util/InputStreamUtils.java b/src/main/java/com/keuin/psmb4j/util/InputStreamUtils.java
new file mode 100644
index 0000000..7b3fd9c
--- /dev/null
+++ b/src/main/java/com/keuin/psmb4j/util/InputStreamUtils.java
@@ -0,0 +1,56 @@
+package com.keuin.psmb4j.util;
+
+import com.keuin.psmb4j.util.error.SocketClosedException;
+import com.keuin.psmb4j.util.error.StringLengthExceededException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class InputStreamUtils {
+ /**
+ * Read until '\0', the trailing '\0' is dropped.
+ */
+ public static String readCString(InputStream stream) throws IOException {
+ var sb = new StringBuilder();
+ int c;
+ while ((c = stream.read()) > 0) {
+ sb.append((char) c);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Read a C style string, with a length limit.
+ * If the string is longer than given limit,
+ * a {@link StringLengthExceededException} will be thrown.
+ */
+ public static String readCString(InputStream stream, long maxLength) throws IOException {
+ var sb = new StringBuilder();
+ int c;
+ long length = 0;
+ while ((c = stream.read()) > 0) {
+ sb.append((char) c);
+ if (++length > maxLength) {
+ throw new StringLengthExceededException(maxLength);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Read fixed length bytes from stream.
+ * If not enough, a {@link SocketClosedException} will be thrown.
+ */
+ public static byte[] readBytes(InputStream stream, int length) throws IOException {
+ var buffer = new byte[length];
+ int c;
+ for (int i = 0; i < length; i++) {
+ if ((c = stream.read()) >= 0) {
+ buffer[i] = (byte) c;
+ } else {
+ throw new SocketClosedException(length, i);
+ }
+ }
+ return buffer;
+ }
+}
diff --git a/src/main/java/com/keuin/psmb4j/util/StringUtils.java b/src/main/java/com/keuin/psmb4j/util/StringUtils.java
new file mode 100644
index 0000000..036a560
--- /dev/null
+++ b/src/main/java/com/keuin/psmb4j/util/StringUtils.java
@@ -0,0 +1,14 @@
+package com.keuin.psmb4j.util;
+
+import java.nio.charset.StandardCharsets;
+
+public class StringUtils {
+ /**
+ * If the string can be encoded into binary using ASCII.
+ */
+ @SuppressWarnings("BooleanMethodIsAlwaysInverted")
+ public static boolean isPureAscii(String v) {
+ return StandardCharsets.US_ASCII.newEncoder().canEncode(v);
+ // or "ISO-8859-1" for ISO Latin 1
+ }
+}
diff --git a/src/main/java/com/keuin/psmb4j/util/error/SocketClosedException.java b/src/main/java/com/keuin/psmb4j/util/error/SocketClosedException.java
new file mode 100644
index 0000000..e7c9b2d
--- /dev/null
+++ b/src/main/java/com/keuin/psmb4j/util/error/SocketClosedException.java
@@ -0,0 +1,15 @@
+package com.keuin.psmb4j.util.error;
+
+import java.io.IOException;
+
+/**
+ * The socket closed before enough bytes have been read out.
+ */
+public class SocketClosedException extends IOException {
+ public SocketClosedException() {
+ }
+
+ public SocketClosedException(long expected, long actual) {
+ super(String.format("expected %d bytes, EOF after reading %d bytes", expected, actual));
+ }
+}
diff --git a/src/main/java/com/keuin/psmb4j/util/error/StringLengthExceededException.java b/src/main/java/com/keuin/psmb4j/util/error/StringLengthExceededException.java
new file mode 100644
index 0000000..afb08b6
--- /dev/null
+++ b/src/main/java/com/keuin/psmb4j/util/error/StringLengthExceededException.java
@@ -0,0 +1,9 @@
+package com.keuin.psmb4j.util.error;
+
+import java.io.IOException;
+
+public class StringLengthExceededException extends IOException {
+ public StringLengthExceededException(long length) {
+ super(String.format("String is too long (%d Bytes)", length));
+ }
+}