2 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.openflowjava.util;
10 import com.google.common.base.Splitter;
11 import com.google.common.collect.Lists;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.UnpooledByteBufAllocator;
14 import java.nio.ByteBuffer;
15 import java.nio.charset.StandardCharsets;
16 import java.util.List;
18 import java.util.Map.Entry;
19 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
28 * Class for common operations on ByteBuf.
30 * @author michal.polkorab
31 * @author timotej.kubas
33 public abstract class ByteBufUtils {
34 public static final Splitter DOT_SPLITTER = Splitter.on('.');
35 public static final Splitter COLON_SPLITTER = Splitter.on(':');
36 private static final Splitter HEXSTRING_SPLITTER = Splitter.onPattern("\\s+").omitEmptyStrings();
37 private static final Splitter HEXSTRING_NOSPACE_SPLITTER = Splitter.onPattern("(?<=\\G.{2})").omitEmptyStrings();
39 private ByteBufUtils() {
44 * Converts ByteBuf into String.
46 * @param bb input ByteBuf
49 public static String byteBufToHexString(final ByteBuf bb) {
50 StringBuilder sb = new StringBuilder();
51 for (int i = bb.readerIndex(); i < bb.readerIndex() + bb.readableBytes(); i++) {
52 sb.append(String.format(" %02x", bb.getUnsignedByte(i)));
54 return sb.toString().trim();
58 * Converts String into byte[].
60 * @param hexSrc input String
61 * @return byte[] filled with input data
63 public static byte[] hexStringToBytes(final String hexSrc) {
64 return hexStringToBytes(hexSrc, true);
68 * Converts String into byte[].
70 * @param hexSrc input String
71 * @param withSpaces if there are spaces in string
72 * @return byte[] filled with input data
74 public static byte[] hexStringToBytes(final String hexSrc, final boolean withSpaces) {
75 final Splitter splitter = withSpaces ? HEXSTRING_SPLITTER : HEXSTRING_NOSPACE_SPLITTER;
76 List<String> byteChips = Lists.newArrayList(splitter.split(hexSrc));
77 byte[] result = new byte[byteChips.size()];
79 for (String chip : byteChips) {
80 result[index] = (byte) Short.parseShort(chip, 16);
87 * Creates ByteBuf filled with specified data.
89 * @param hexSrc input String of bytes in hex format
90 * @return ByteBuf with specified hexString converted
92 public static ByteBuf hexStringToByteBuf(final String hexSrc) {
93 ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
94 hexStringToByteBuf(hexSrc, out);
99 * Creates ByteBuf filled with specified data.
101 * @param hexSrc input String of bytes in hex format
102 * @param out ByteBuf with specified hexString converted
104 public static void hexStringToByteBuf(final String hexSrc, final ByteBuf out) {
105 out.writeBytes(hexStringToBytes(hexSrc));
109 * Create standard OF header.
111 * @param msgType message code
112 * @param message POJO
113 * @param out writing buffer
114 * @param length ofheader length
116 public static <E extends OfHeader> void writeOFHeader(final byte msgType, final E message, final ByteBuf out,
118 out.writeByte(message.getVersion().toJava());
119 out.writeByte(msgType);
120 out.writeShort(length);
121 out.writeInt(message.getXid().intValue());
125 * Write length standard OF header.
127 * @param out writing buffer
129 public static void updateOFHeaderLength(final ByteBuf out) {
130 out.setShort(EncodeConstants.OFHEADER_LENGTH_INDEX, out.readableBytes());
134 * Write length OF header.
136 * @param out writing buffer
137 * @param index writing index
139 public static void updateOFHeaderLength(final ByteBuf out, final int index) {
140 out.setShort(index + EncodeConstants.OFHEADER_LENGTH_INDEX, out.writerIndex() - index);
144 * Fills the bitmask from boolean map where key is bit position.
146 * @param booleanMap bit to boolean mapping
149 public static int fillBitMaskFromMap(final Map<Integer, Boolean> booleanMap) {
152 for (Entry<Integer, Boolean> iterator : booleanMap.entrySet()) {
153 if (iterator.getValue() != null && iterator.getValue().booleanValue()) {
154 bitmask |= 1 << iterator.getKey();
161 * Fills the bitmask from a set of bit values, starting at specified offset.
163 * @param offset Bit offset to start at
164 * @param values boolean bit values to fill
165 * @return Filled-in bitmask
167 public static int fillBitMask(final int offset, final boolean... values) {
171 for (boolean v : values) {
173 bitmask |= 1 << index;
182 * Fills the bitmask from boolean list where key is bit position.
184 * @param booleanList bit to boolean mapping
187 public static int[] fillBitMaskFromList(final List<Boolean> booleanList) {
191 if (booleanList.size() % Integer.SIZE != 0) {
192 bitmask = new int[booleanList.size() / Integer.SIZE + 1];
194 bitmask = new int[booleanList.size() / Integer.SIZE];
196 for (Boolean currElement : booleanList) {
197 if (currElement != null && currElement.booleanValue()) {
198 bitmask[arrayIndex] |= 1 << index;
201 arrayIndex = index / Integer.SIZE;
207 * Converts byte array into String.
209 * @param array input byte array
212 public static String bytesToHexString(final byte[] array) {
213 StringBuilder sb = new StringBuilder();
214 for (byte element : array) {
215 sb.append(String.format(" %02x", element));
217 return sb.toString().trim();
221 * Reads and parses null-terminated string from ByteBuf.
223 * @param rawMessage the message to parse
224 * @param length maximal length of String
225 * @return String with name of port
227 public static String decodeNullTerminatedString(final ByteBuf rawMessage, final int length) {
228 byte[] name = new byte[length];
229 rawMessage.readBytes(name);
230 return new String(name, StandardCharsets.UTF_8).trim();
233 public static Ipv4Address readIetfIpv4Address(final ByteBuf buf) {
234 return IetfInetUtil.ipv4AddressFor(buf.readInt());
237 public static Ipv6Address readIetfIpv6Address(final ByteBuf buf) {
238 final byte[] tmp = new byte[16];
240 return IetfInetUtil.ipv6AddressFor(tmp);
243 public static MacAddress readIetfMacAddress(final ByteBuf buf) {
244 final byte[] tmp = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
246 return IetfYangUtil.macAddressFor(tmp);
249 public static byte[] serializeList(final List<Short> list) {
250 ByteBuffer byteBuffer = ByteBuffer.allocate(list.size() * 2);
251 for (Short shortValue : list) {
252 byteBuffer.putShort(shortValue);
254 return byteBuffer.array();