Cache pattern splitters
[openflowjava.git] / util / src / main / java / org / opendaylight / openflowjava / util / ByteBufUtils.java
index f03f19638427b12bb9a065cb4b367203723bc9a2..d68f6f9cd9c83e6811dd203848ff00f4a1eea372 100644 (file)
@@ -9,23 +9,18 @@
 
 package org.opendaylight.openflowjava.util;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.UnsignedBytes;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.UnpooledByteBufAllocator;
-
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-
 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
-import com.google.common.primitives.UnsignedBytes;
-
 /** Class for common operations on ByteBuf
  * @author michal.polkorab
  * @author timotej.kubas
@@ -34,6 +29,12 @@ public abstract class ByteBufUtils {
     public static final Splitter DOT_SPLITTER = Splitter.on('.');
     public static final Splitter COLON_SPLITTER = Splitter.on(':');
     private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
+    private static final Splitter HEXSTRING_SPLITTER =  Splitter.onPattern("\\s+").omitEmptyStrings();
+    private static final Splitter HEXSTRING_NOSPACE_SPLITTER = Splitter.onPattern("(?<=\\G.{2})").omitEmptyStrings();
+
+    private ByteBufUtils() {
+        //not called
+    }
 
     /**
      * Converts ByteBuf into String
@@ -41,7 +42,7 @@ public abstract class ByteBufUtils {
      * @return String
      */
     public static String byteBufToHexString(final ByteBuf bb) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         for (int i = bb.readerIndex(); i < (bb.readerIndex() + bb.readableBytes()); i++) {
             sb.append(String.format(" %02x", bb.getUnsignedByte(i)));
         }
@@ -63,14 +64,9 @@ public abstract class ByteBufUtils {
      * @param withSpaces if there are spaces in string
      * @return byte[] filled with input data
      */
-    public static byte[] hexStringToBytes(final String hexSrc, final boolean withSpaces ) {
-        String splitPattern = "\\s+";
-        if (!withSpaces) {
-            splitPattern = "(?<=\\G.{2})";
-        }
-        Iterable<String> tmp = Splitter.onPattern(splitPattern)
-                .omitEmptyStrings().split(hexSrc);
-        ArrayList<String> byteChips = Lists.newArrayList(tmp);
+    public static byte[] hexStringToBytes(final String hexSrc, final boolean withSpaces) {
+        final Splitter splitter = withSpaces ? HEXSTRING_SPLITTER : HEXSTRING_NOSPACE_SPLITTER;
+        List<String> byteChips = Lists.newArrayList(splitter.split(hexSrc));
         byte[] result = new byte[byteChips.size()];
         int i = 0;
         for (String chip : byteChips) {
@@ -200,7 +196,7 @@ public abstract class ByteBufUtils {
      * @return String
      */
     public static String bytesToHexString(final byte[] array) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         for (byte element : array) {
             sb.append(String.format(" %02x", element));
         }
@@ -222,28 +218,45 @@ public abstract class ByteBufUtils {
     }
 
     /**
-     * Converts macAddress to byte array
+     * Converts macAddress to byte array.
+     * See also {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}.
+     *
      * @param macAddress
      * @return byte representation of mac address
-     * @see {@link MacAddress}
-     *
-     * FIXME: this method does not support shortened values, e.g.
-     *        "0:1:2:3:4:5", only "00:11:22:33:44:55".
      */
     public static byte[] macAddressToBytes(final String macAddress) {
         final byte[] result = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
         final char[] mac = macAddress.toCharArray();
 
-        int offset = 0;
-        for (int i = 0; i < EncodeConstants.MAC_ADDRESS_LENGTH - 1; ++i) {
-            result[i] = UnsignedBytes.checkedCast(
-                    (hexValue(mac[offset++]) << 4) | hexValue(mac[offset++]));
-            Preconditions.checkArgument(mac[offset] == ':', "Invalid value: %s", macAddress);
-            offset++;
-        }
+        try {
+            int offset = 0;
+            for (int i = 0; i < EncodeConstants.MAC_ADDRESS_LENGTH - 1; ++i) {
+                if (mac[offset + EncodeConstants.SIZE_OF_BYTE_IN_BYTES] == ':') {
+                    result[i] = UnsignedBytes.checkedCast(hexValue(mac[offset]));
+                    offset++;
+                } else {
+                    result[i] = UnsignedBytes.checkedCast(
+                            (hexValue(mac[offset]) << 4) | hexValue(mac[offset +1]));
+                    offset += 2;
+                }
+                Preconditions.checkArgument(mac[offset] == ':', "Invalid value: %s", macAddress);
+                offset++;
+            }
 
-        result[EncodeConstants.MAC_ADDRESS_LENGTH - 1] =
-                UnsignedBytes.checkedCast(hexValue(mac[offset++]) << 4 | hexValue(mac[offset]));
+            if (offset == (mac.length - 1)) {
+                result[EncodeConstants.MAC_ADDRESS_LENGTH - 1] = UnsignedBytes.checkedCast(hexValue(mac[offset]));
+            } else {
+                result[EncodeConstants.MAC_ADDRESS_LENGTH - 1] =
+                        UnsignedBytes.checkedCast(hexValue(mac[offset]) << 4 | hexValue(mac[offset +1]));
+                offset++;
+            }
+            if (offset != (mac.length -1)) {
+                throw new IllegalArgumentException("Incorrect MAC address length");
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Unable to serialize MAC address for input: " + macAddress
+                    + ". \n" + e);
+        }
         return result;
     }
 
@@ -261,10 +274,11 @@ public abstract class ByteBufUtils {
     }
 
     /**
-     * Converts a MAC address represented in bytes to String
+     * Converts a MAC address represented in bytes to String.
+     * See also {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}.
+     *
      * @param address
      * @return String representation of a MAC address
-     * @see {@link MacAddress}
      */
     public static String macAddressToString(final byte[] address) {
         Preconditions.checkArgument(address.length == EncodeConstants.MAC_ADDRESS_LENGTH);