Use ByteBuf.readRetainedSlice()
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / util / ByteUtil.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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 package org.opendaylight.openflowplugin.openflow.md.util;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.io.BaseEncoding;
12 import com.google.common.primitives.Longs;
13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.math.BigInteger;
15 import java.util.Arrays;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.yangtools.yang.common.Uint16;
18 import org.opendaylight.yangtools.yang.common.Uint32;
19 import org.opendaylight.yangtools.yang.common.Uint64;
20
21 public final class ByteUtil {
22     private ByteUtil() {
23     }
24
25     /** default hex string separator. */
26     private static final String DEFAULT_HEX_SEPARATOR = ":";
27
28     /** basic hex string encoding. */
29     private static final BaseEncoding PLAIN_HEX_16_ENCODING = BaseEncoding.base16().lowerCase();
30
31     /** hex string encoding involving {@link #DEFAULT_HEX_SEPARATOR} as separator. */
32     private static final BaseEncoding HEX_16_ENCODING = PLAIN_HEX_16_ENCODING.withSeparator(DEFAULT_HEX_SEPARATOR, 2);
33
34     /**
35      * Converts bytes to a hex string.
36      *
37      * @param bytes bytes that needs to be converted to hex
38      * @param delimiter string delimiter
39      * @return hexString containing bytes, separated with delimiter
40      */
41     public static String bytesToHexstring(final byte[] bytes, final String delimiter) {
42         BaseEncoding be = HEX_16_ENCODING;
43         if (!DEFAULT_HEX_SEPARATOR.equals(delimiter)) {
44             be = PLAIN_HEX_16_ENCODING.withSeparator(delimiter, 2);
45         }
46         return be.encode(bytes);
47     }
48
49     /**
50      * Utility method to convert BigInteger to n element byte array.
51      *
52      * @param bigInteger big integer value that needs to be converted to byte
53      * @param numBytes convert to number of bytes
54      * @return byte array containing n * 8 bits.
55      */
56     @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
57     public static byte @Nullable[] convertBigIntegerToNBytes(final @Nullable BigInteger bigInteger,
58             final int numBytes) {
59         if (bigInteger == null) {
60             return null;
61         }
62         byte[] inputArray = bigInteger.toByteArray();
63         byte[] outputArray = new byte[numBytes];
64         if (bigInteger.compareTo(BigInteger.ZERO) < 0) {
65             Arrays.fill(outputArray, (byte) -1);
66         } else {
67             Arrays.fill(outputArray, (byte) 0);
68         }
69         System.arraycopy(inputArray,
70                 Math.max(0, inputArray.length - outputArray.length),
71                 outputArray,
72                 Math.max(0, outputArray.length - inputArray.length),
73                 Math.min(outputArray.length, inputArray.length));
74         return outputArray;
75     }
76
77     /**
78      * Utility method to convert an Uint64 to an 8-byte array.
79      *
80      * @param uint Unsigned long, potentially null.
81      * @return byte array, or null if input was null.
82      */
83     @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
84     public static byte @Nullable[] uint64toBytes(@Nullable final Uint64 uint) {
85         return uint == null ? null : Longs.toByteArray(uint.longValue());
86     }
87
88     /**
89      * Converts a 4 byte array of unsigned bytes to unsigned int.
90      *
91      * @param bytes an array of 4 unsigned bytes
92      * @return a long representing the unsigned int
93      */
94     public static Uint32 bytesToUnsignedInt(final byte[] bytes) {
95         Preconditions.checkArgument(bytes.length == 4, "Input byte array must be exactly four bytes long.");
96         int unsignedInt = 0;
97         unsignedInt |= bytes[0] & 0xFF;
98         unsignedInt <<= 8;
99         unsignedInt |= bytes[1] & 0xFF;
100         unsignedInt <<= 8;
101         unsignedInt |= bytes[2] & 0xFF;
102         unsignedInt <<= 8;
103         unsignedInt |= bytes[3] & 0xFF;
104         return Uint32.fromIntBits(unsignedInt);
105     }
106
107     /**
108      * Converts a 3 byte array of unsigned bytes to unsigned int.
109      *
110      * @param bytes an array of 4 unsigned bytes
111      * @return a long representing the unsigned int
112      */
113     public static long bytesToUnsignedMedium(final byte[] bytes) {
114         Preconditions.checkArgument(bytes.length == 3, "Input byte array must be exactly three bytes long.");
115         long unsignedMedium = 0;
116         unsignedMedium |= bytes[0] & 0xFF;
117         unsignedMedium <<= 8;
118         unsignedMedium |= bytes[1] & 0xFF;
119         unsignedMedium <<= 8;
120         unsignedMedium |= bytes[2] & 0xFF;
121         return unsignedMedium;
122     }
123
124     /**
125      * Converts a 2 byte array of unsigned bytes to unsigned short.
126      *
127      * @param bytes an array of 2 unsigned bytes
128      * @return an int representing the unsigned short
129      */
130     public static int bytesToUnsignedShort(final byte[] bytes) {
131         Preconditions.checkArgument(bytes.length == 2, "Input byte array must be exactly two bytes long.");
132         int unsignedShort = 0;
133         unsignedShort |= bytes[0] & 0xFF;
134         unsignedShort <<= 8;
135         unsignedShort |= bytes[1] & 0xFF;
136         return unsignedShort;
137     }
138
139     /**
140      * Converts unsigned integer to a 4 byte array of unsigned bytes.
141      *
142      * @param unsignedInt representing the unsigned integer
143      * @return bytes an array of 4 unsigned bytes
144      */
145     public static byte[] unsignedIntToBytes(final Long unsignedInt) {
146         return unsignedIntToBytes(unsignedInt.longValue());
147     }
148
149     /**
150      * Converts unsigned integer to a 4 byte array of unsigned bytes.
151      *
152      * @param unsignedInt representing the unsigned integer
153      * @return bytes an array of 4 unsigned bytes
154      */
155     public static byte[] unsignedIntToBytes(final Uint32 unsignedInt) {
156         return unsignedIntToBytes(unsignedInt.toJava());
157     }
158
159     /**
160      * Converts unsigned integer to a 4 byte array of unsigned bytes.
161      *
162      * @param unsignedInt representing the unsigned integer
163      * @return bytes an array of 4 unsigned bytes
164      */
165     private static byte[] unsignedIntToBytes(final long unsignedInt) {
166         byte[] bytes = new byte[4];
167         bytes[3] = (byte) (unsignedInt & 0xFF);
168         bytes[2] = (byte) (unsignedInt >> 8 & 0xFF);
169         bytes[1] = (byte) (unsignedInt >> 16 & 0xFF);
170         bytes[0] = (byte) (unsignedInt >> 24 & 0xFF);
171         return bytes;
172     }
173
174     /**
175      * Converts unsigned integer to a 3 byte array of unsigned bytes.
176      *
177      * @param unsignedInt representing the unsigned integer
178      * @return bytes an array of 3 unsigned bytes
179      */
180     public static byte[] unsignedMediumToBytes(final Long unsignedInt) {
181         return unsignedMediumToBytes(unsignedInt.longValue());
182     }
183
184     /**
185      * Converts unsigned integer to a 3 byte array of unsigned bytes.
186      *
187      * @param unsignedInt representing the unsigned integer
188      * @return bytes an array of 3 unsigned bytes
189      */
190     public static byte[] unsignedMediumToBytes(final Uint32 unsignedInt) {
191         return unsignedMediumToBytes(unsignedInt.toJava());
192     }
193
194     /**
195      * Converts unsigned integer to a 3 byte array of unsigned bytes.
196      *
197      * @param unsignedInt representing the unsigned integer
198      * @return bytes an array of 3 unsigned bytes
199      */
200     private static byte[] unsignedMediumToBytes(final long unsignedInt) {
201         byte[] bytes = new byte[3];
202         bytes[2] = (byte) (unsignedInt & 0xFF);
203         bytes[1] = (byte) (unsignedInt >> 8 & 0xFF);
204         bytes[0] = (byte) (unsignedInt >> 16 & 0xFF);
205         return bytes;
206     }
207
208     /**
209      * Converts unsigned short to a 2 byte array of unsigned bytes.
210      *
211      * @param unsignedShort representing the unsigned short
212      * @return bytes an array of 2 unsigned bytes
213      */
214     public static byte[] unsignedShortToBytes(final Integer unsignedShort) {
215         return unsignedShortToBytes(unsignedShort.intValue());
216     }
217
218     /**
219      * Converts unsigned short to a 2 byte array of unsigned bytes.
220      *
221      * @param unsignedShort representing the unsigned short
222      * @return bytes an array of 2 unsigned bytes
223      */
224     public static byte[] unsignedShortToBytes(final Uint16 unsignedShort) {
225         return unsignedShortToBytes(unsignedShort.toJava());
226     }
227
228     /**
229      * Converts unsigned short to a 2 byte array of unsigned bytes.
230      *
231      * @param unsignedShort representing the unsigned short
232      * @return bytes an array of 2 unsigned bytes
233      */
234     private static byte[] unsignedShortToBytes(final int unsignedShort) {
235         byte[] bytes = new byte[2];
236         bytes[1] = (byte) (unsignedShort & 0xFF);
237         bytes[0] = (byte) (unsignedShort >> 8 & 0xFF);
238         return bytes;
239     }
240 }