1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.util;
17 
18 import java.nio.ByteBuffer;
19 import java.util.Arrays;
20 
21 /**
22  * Utilities to operate on byte array, e.g., convert bytes to integer.
23  *
24  * <p>Java doesn't have an unsigned value type, so expansion is needed to convert an unsigned
25  * integer stored in 4 bytes to a long value, or unsigned short stored in 2 bytes to an integer
26  * value.
27  */
28 public class ByteArrayUtil {
29 
30     /**
31      * Get a {@link ByteBuffer} for the given bytes wrapped in a byte array of given size.
32      *
33      * <p>java doesn't have an unsigned value type, so expansion is needed to convert an unsigned
34      * short stored in 2 bytes to an integer value.
35      *
36      * @param bytes an array of bytes.
37      * @param offset the start offset of the integer data.
38      * @param length the length of the integer data.
39      * @param containerSize the size of the array to store the given bytes, append zero to unfilled
40      *     items.
41      * @return a {@link ByteBuffer} for the given bytes wrapped in a byte array of given size.
42      */
getByteBuffer( byte[] bytes, int offset, int length, int containerSize)43     private static ByteBuffer getByteBuffer(
44             byte[] bytes, int offset, int length, int containerSize) {
45         byte[] data = new byte[containerSize];
46         for (int i = 0; i < length; i++) {
47             data[i] = bytes[offset + i];
48         }
49         return ByteBuffer.wrap(data).order(java.nio.ByteOrder.LITTLE_ENDIAN);
50     }
51 
52     /**
53      * Get an integer from the given bytes.
54      *
55      * <p>java doesn't have an unsigned value type, so expansion is needed to convert an unsigned
56      * short stored in 2 bytes to an integer value.
57      *
58      * @param bytes an array of bytes.
59      * @param offset the start offset of the integer data.
60      * @param length the length of the integer data.
61      * @return an int value from the given bytes.
62      */
getInt(byte[] bytes, int offset, int length)63     public static int getInt(byte[] bytes, int offset, int length) {
64         return getByteBuffer(bytes, offset, length, 4).getInt();
65     }
66 
67     /**
68      * Get a long value from the given bytes.
69      *
70      * <p>java doesn't have an unsigned value type, so expansion is needed to convert an unsigned
71      * integer stored in 4 bytes to a long value.
72      *
73      * @param bytes an array of bytes.
74      * @param offset the start offset of the long value.
75      * @param length the length of the long value.
76      * @return a long value from the given bytes.
77      */
getLong(byte[] bytes, int offset, int length)78     public static long getLong(byte[] bytes, int offset, int length) {
79         return getByteBuffer(bytes, offset, length, 8).getLong();
80     }
81 
82     /**
83      * Get the string from the given bytes.
84      *
85      * @param bytes an array of bytes.
86      * @param offset the start offset of the string data.
87      * @param length the length of the string data.
88      */
getString(byte[] bytes, int offset, int length)89     public static String getString(byte[] bytes, int offset, int length) {
90         return new String(Arrays.copyOfRange(bytes, offset, offset + length));
91     }
92 }
93