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