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