فهرست منبع

new: FormatHex#parse

Mariusz Sieroń 6 سال پیش
والد
کامیت
dc7d6e349f

+ 67 - 30
assira/src/main/java/net/ranides/assira/text/FormatHex.java

@@ -6,53 +6,90 @@
  */
 package net.ranides.assira.text;
 
-import java.nio.ByteBuffer;
-import net.ranides.assira.io.BufferAdapter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+
+import lombok.experimental.UtilityClass;
 
 /**
  *
  * @author ranides
  */
+@UtilityClass
 public final class FormatHex {
     
     private static final char[] HC_TABLE = {
         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
     };
 
-    private FormatHex() { }
-    
-    public static StringBuilder format(StringBuilder target, byte value) {
-        int ivalue = value & 0xFF;
-        target.append( HC_TABLE[ivalue >>> 4] );
-        target.append( HC_TABLE[ivalue & 0xF] );
-        return target;
+    private static final byte[] CH_TABLE = new byte[128];
+
+    static {
+        CH_TABLE['0'] = 0;
+        CH_TABLE['1'] = 1;
+        CH_TABLE['2'] = 2;
+        CH_TABLE['3'] = 3;
+        CH_TABLE['4'] = 4;
+        CH_TABLE['5'] = 5;
+        CH_TABLE['6'] = 6;
+        CH_TABLE['7'] = 7;
+        CH_TABLE['8'] = 8;
+        CH_TABLE['9'] = 9;
+        CH_TABLE['A'] = 10;
+        CH_TABLE['a'] = 10;
+        CH_TABLE['B'] = 11;
+        CH_TABLE['b'] = 11;
+        CH_TABLE['C'] = 12;
+        CH_TABLE['c'] = 12;
+        CH_TABLE['D'] = 13;
+        CH_TABLE['d'] = 13;
+        CH_TABLE['E'] = 14;
+        CH_TABLE['e'] = 14;
+        CH_TABLE['F'] = 15;
+        CH_TABLE['f'] = 15;
     }
-    
-    public static StringBuilder format(StringBuilder target, byte[] raw) {
-        boolean isFirst = true;
-        for (byte b : raw) {
-            if( !isFirst ) { 
-                target.append(' '); 
-            } else {
-                isFirst = false;
+
+    public static String format(byte[] raw) {
+        return format(new StrBuffer(3*raw.length), raw).toString();
+    }
+
+    public static <T extends Appendable> T format(T target, byte[] raw) {
+        try {
+            int n= raw.length;
+            if(n > 0) {
+                append(target, raw[0]);
+            }
+            for(int i=1; i<n; i++) {
+                target.append(' ');
+                append(target, raw[i]);
             }
-            format(target, b);
+            return target;
+        } catch (IOException cause) {
+            throw new UncheckedIOException(cause);
         }
-        return target;
     }
-    
-    public static String format(byte value) {
+
+    private static void append(Appendable target, byte value) throws IOException {
         int ivalue = value & 0xFF;
-        char[] out = new char[]{ HC_TABLE[ivalue >>> 4], HC_TABLE[ivalue & 0xF] };
-        return new String(out);
-    }
-    
-    public static String format(byte[] raw) {
-        return format(new StringBuilder(3 * raw.length), raw).toString();
+        target.append(HC_TABLE[ivalue >>> 4]);
+        target.append(HC_TABLE[ivalue & 0xF]);
     }
-    
-    public static String format(ByteBuffer raw) {
-        return format(BufferAdapter.toArray(raw));
+
+    public static byte[] parse(CharSequence text) {
+        int bytes = (text.length()+1) / 3;
+        byte[] target = new byte[bytes];
+        int c = 0;
+        int i = 0;
+        int n=text.length()-2;
+        while(i<n) {
+            byte a = CH_TABLE[text.charAt(i++)];
+            byte b = CH_TABLE[text.charAt(i++)];
+            target[c++] = (byte)( (a<<4) | (b&0xF) );
+            i++;
+        }
+
+        target[c] = (byte)( (CH_TABLE[text.charAt(i)] <<4) | (CH_TABLE[text.charAt(i+1)] &0xF) );
+        return target;
     }
 
 }

+ 2 - 2
assira/src/test/java/net/ranides/assira/io/IOStreamsTest.java

@@ -527,10 +527,10 @@ public class IOStreamsTest {
                 events.add(event.source() + " [flush]");
             });
             listener.addEventListener(IOEvent.Read.class, event -> {
-                events.add(event.source() + " [read] " + FormatHex.format(event.data()));
+                events.add(event.source() + " [read] " + FormatHex.format(BufferAdapter.toArray(event.data())));
             });
             listener.addEventListener(IOEvent.Write.class, event -> {
-                events.add(event.source() + " [write] " + FormatHex.format(event.data()));
+                events.add(event.source() + " [write] " + FormatHex.format(BufferAdapter.toArray(event.data())));
             });
             listener.addEventListener(IOEvent.Close.class, event -> {
                 events.add(event.source() + " [close]");

+ 10 - 7
assira/src/test/java/net/ranides/assira/text/FormatHexTest.java

@@ -7,6 +7,9 @@
 package net.ranides.assira.text;
 
 import org.junit.Test;
+
+import java.util.Arrays;
+
 import static org.junit.Assert.*;
 
 /**
@@ -17,16 +20,16 @@ public class FormatHexTest {
 
     @Test
     public void testFormatBuilder() {
-        assertEquals("0x34", FormatHex.format(new StringBuilder("0x"), (byte)0x34).toString());
-        assertEquals("0x97", FormatHex.format(new StringBuilder("0x"), (byte)0x97).toString());
-        assertEquals("H:34 97", FormatHex.format(new StringBuilder("H:"), new byte[]{(byte)0x34, (byte)0x97}).toString());
+        assertEquals("H:34 97 32 71", FormatHex.format(new StringBuilder("H:"), new byte[]{(byte)0x34, (byte)0x97, (byte)0x32, (byte)0x71}).toString());
     }
     
     @Test
     public void testFormat() {
-        assertEquals("34", FormatHex.format((byte)0x34));
-        assertEquals("97", FormatHex.format((byte)0x97));
-        assertEquals("34 97", FormatHex.format(new byte[]{(byte)0x34, (byte)0x97}));
+        assertEquals("34 97 32 71", FormatHex.format(new byte[]{(byte)0x34, (byte)0x97, (byte)0x32, (byte)0x71}));
+    }
+
+    @Test
+    public void testParse() {
+        assertArrayEquals(new byte[]{(byte)0x34, (byte)0x97, (byte)0x32, (byte)0x71, (byte)0x9a, (byte)0xa9}, FormatHex.parse("34 97 32 71 9A a9"));
     }
-    
 }