Merge "OF1.3 matchSerializer (Ipv6 address) fix + test"
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / ByteBufUtils.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
2 \r
3 package org.opendaylight.openflowjava.protocol.impl.util;\r
4 \r
5 import io.netty.buffer.ByteBuf;\r
6 import io.netty.buffer.UnpooledByteBufAllocator;\r
7 \r
8 import java.util.ArrayList;\r
9 import java.util.Arrays;\r
10 import java.util.List;\r
11 import java.util.Map;\r
12 import java.util.Map.Entry;\r
13 \r
14 import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer;\r
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;\r
17 \r
18 import com.google.common.base.Joiner;\r
19 \r
20 /** Class for common operations on ByteBuf\r
21  * @author michal.polkorab\r
22  * @author timotej.kubas\r
23  */\r
24 public abstract class ByteBufUtils {\r
25 \r
26     /**\r
27      * Converts ByteBuf into String\r
28      * @param bb input ByteBuf\r
29      * @return String\r
30      */\r
31     public static String byteBufToHexString(ByteBuf bb) {\r
32         StringBuffer sb = new StringBuffer();\r
33         for (int i = 0; i < bb.readableBytes(); i++) {\r
34             short b = bb.getUnsignedByte(i);\r
35             sb.append(String.format("%02x ", b));\r
36         }\r
37         return sb.toString();\r
38     }\r
39     \r
40     /**\r
41      * Converts String into byte[]\r
42      * @param hexSrc input String\r
43      * @return byte[] filled with input data\r
44      */\r
45     public static byte[] hexStringToBytes(String hexSrc) {\r
46         return hexStringToBytes(hexSrc, true);\r
47     }\r
48     \r
49     /**\r
50      * Converts String into byte[]\r
51      * @param hexSrc input String\r
52      * @param withSpaces if there are spaces in string \r
53      * @return byte[] filled with input data\r
54      */\r
55     public static byte[] hexStringToBytes(String hexSrc, boolean withSpaces ) {\r
56         String splitPattern = "\\s+";\r
57         if (!withSpaces) {\r
58             splitPattern = "(?<=\\G.{2})";\r
59         }\r
60         \r
61         String[] byteChips = hexSrc.split(splitPattern);\r
62         byte[] result = new byte[byteChips.length];\r
63         for (int i = 0; i < byteChips.length; i++) {\r
64             result[i] = (byte) Short.parseShort(byteChips[i], 16);\r
65         }\r
66         return result;\r
67     }\r
68     \r
69     /**\r
70      * Creates ByteBuf filled with specified data\r
71      * @param hexSrc input String of bytes in hex format\r
72      * @return ByteBuf with specified hexString converted\r
73      */\r
74     public static ByteBuf hexStringToByteBuf(String hexSrc) {\r
75         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();\r
76         hexStringToByteBuf(hexSrc, out);\r
77         return out;\r
78     }\r
79     \r
80     /**\r
81      * Creates ByteBuf filled with specified data\r
82      * @param hexSrc input String of bytes in hex format\r
83      * @param out ByteBuf with specified hexString converted\r
84      */\r
85     public static void hexStringToByteBuf(String hexSrc, ByteBuf out) {\r
86         out.writeBytes(hexStringToBytes(hexSrc));\r
87     }\r
88     \r
89     /**\r
90      * Fills specified ByteBuf with 0 (zeros) of desired length, used for padding\r
91      * @param length\r
92      * @param out ByteBuf to be padded\r
93      */\r
94     public static void padBuffer(int length, ByteBuf out) {\r
95         for (int i = 0; i < length; i++) {\r
96             out.writeByte(0);\r
97         }\r
98     }\r
99     \r
100     /**\r
101      * Create standard OF header\r
102      * @param factory serialization factory \r
103      * @param message POJO\r
104      * @param out writing buffer\r
105      */\r
106     public static <E extends OfHeader> void writeOFHeader(OFSerializer<E> factory, E message, ByteBuf out) { \r
107         out.writeByte(message.getVersion());\r
108         out.writeByte(factory.getMessageType());\r
109         out.writeShort(factory.computeLength(message));\r
110         out.writeInt(message.getXid().intValue());\r
111 \r
112     }\r
113 \r
114     /**\r
115      * Fills the bitmask from boolean map where key is bit position\r
116      * @param booleanMap bit to boolean mapping\r
117      * @return bit mask\r
118      */\r
119     public static int fillBitMaskFromMap(Map<Integer, Boolean> booleanMap) {\r
120         int bitmask = 0;\r
121         \r
122         for (Entry<Integer, Boolean> iterator : booleanMap.entrySet()) {\r
123             if (iterator.getValue() != null && iterator.getValue().booleanValue()) {\r
124                 bitmask |= 1 << iterator.getKey();\r
125             }\r
126         }\r
127         return bitmask;\r
128     }\r
129     \r
130     /**\r
131      * Fills the bitmask from boolean list where key is bit position\r
132      * @param booleanList bit to boolean mapping\r
133      * @return bit mask\r
134      */\r
135     public static int[] fillBitMaskFromList(List<Boolean> booleanList) {\r
136         int[] bitmask;\r
137         int index = 0;\r
138         int arrayIndex = 0;\r
139         if ((booleanList.size() % Integer.SIZE) != 0) {\r
140             bitmask = new int[booleanList.size() / Integer.SIZE + 1];\r
141         } else {\r
142             bitmask = new int[booleanList.size() / Integer.SIZE];\r
143         }\r
144         for (Boolean currElement : booleanList) {\r
145             if (currElement != null && currElement.booleanValue()) {\r
146                 bitmask[arrayIndex] |= 1 << index;\r
147             }\r
148             index++;\r
149             arrayIndex = index / Integer.SIZE;\r
150         }\r
151         return bitmask;\r
152     }\r
153 \r
154     /**\r
155      * Converts byte array into String\r
156      * @param array input byte array\r
157      * @return String\r
158      */\r
159     public static String bytesToHexString(byte[] array) {\r
160         StringBuffer sb = new StringBuffer();\r
161         for (int i = 0; i < array.length; i++) {\r
162             short b = array[i];\r
163             sb.append(String.format("%02x ", b));\r
164         }\r
165         return sb.toString();\r
166     }\r
167     \r
168     /**\r
169      * Converts macAddress to byte array\r
170      * @param macAddress\r
171      * @return byte representation of mac address\r
172      * @see {@link MacAddress}\r
173      */\r
174     public static byte[] macAddressToBytes(String macAddress) {\r
175         String[] sequences = macAddress.split(":");\r
176         byte[] result = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];\r
177         for (int i = 0; i < sequences.length; i++) {\r
178              result[i] = (byte) Short.parseShort(sequences[i], 16);\r
179         }\r
180         return result;\r
181     }\r
182     \r
183     /**\r
184      * Converts mac address represented in bytes to String\r
185      * @param address\r
186      * @return String representation of mac address\r
187      * @see {@link MacAddress}\r
188      */\r
189     public static String macAddressToString(byte[] address) {\r
190         List<String> groups = new ArrayList<>();\r
191         for(int i=0; i < EncodeConstants.MAC_ADDRESS_LENGTH; i++){\r
192             groups.add(String.format("%02X", address[i]));\r
193         }\r
194         Joiner joiner = Joiner.on(":");\r
195         return joiner.join(groups); \r
196     }\r
197     \r
198     /**\r
199      * Reads and parses port name from ByteBuf\r
200      * @param rawMessage\r
201      * @param length maximal length of String\r
202      * @return String with name of port\r
203      */\r
204     public static String decodeNullTerminatedString(ByteBuf rawMessage, int length) {\r
205         byte[] name = new byte[EncodeConstants.MAX_PORT_NAME_LENGTH];\r
206         rawMessage.readBytes(name);\r
207         int index = 0;\r
208         for (int i = 0; i < name.length; i++) {\r
209             if (name[i] != 0) {\r
210                 index++;\r
211             } else {\r
212                 break;\r
213             }\r
214         }\r
215         byte[] correctName = Arrays.copyOf(name, index);\r
216         return new String(correctName);\r
217     }\r
218 }\r