blob: f655a6e04f1e213e46defac146d0a886cd233d2c [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) 2015-2017, The Linux Foundation.
*/
/*
* Copyright 2013 Giesecke & Devrient GmbH.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.se.internal;
/** Utilities class. */
public final class ByteArrayConverter {
/** Override the default constructor to make it private. */
private ByteArrayConverter() {
}
/**
* Forms a FileViewProvider-compatible path String (i.e., transforms the byte array {0x3F, 0x00,
* 0x2F, 0xE2} into the String "3F00:2FE2").
*
* @param rawPath The byte array containing the path component.
* @return A FileViewProvider-compatible path String.
* @throws IllegalArgumentException if the path has a bad coding.
*/
public static String byteArrayToPathString(byte[] rawPath) throws IllegalArgumentException {
if (rawPath.length % 2 != 0) {
throw new IllegalArgumentException("Invald path");
}
byte[] buffer = new byte[2];
String path = "";
for (int i = 0; i < rawPath.length; i += 2) {
System.arraycopy(rawPath, i, buffer, 0, 2);
String fid = byteArrayToHexString(buffer);
if (fid.equalsIgnoreCase("3F00")) {
// MF should not be included in path
continue;
}
path = path.concat(fid);
if (i != rawPath.length - 2) {
path = path.concat(":");
}
}
return path;
}
/**
* Forms an hex-encoded String of the specified byte array.
*
* @param array The byte array to be hex-encoded.
* @param offset The start position.
* @param length The number of bytes to be converted.
* @return A hex-encoded String of the specified byte array.
*/
public static String byteArrayToHexString(byte[] array, int offset, int length) {
if (array == null) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(String.format("%02x", array[offset + i] & 0xFF));
}
return sb.toString();
}
/** Converts the byte array to Hex String from a given offset */
public static String byteArrayToHexString(byte[] array, int offset) {
StringBuffer s = new StringBuffer();
for (int i = offset; i < array.length; i++) {
s.append(Integer.toHexString(0x100 + (array[i] & 0xff)).substring(1));
}
return s.toString();
}
/**
* Forms an hex-encoded String of the specified byte array.
*
* @param byteArray The byte array to be hex-encoded.
* @return A hex-encoded String of the specified byte array.
*/
public static String byteArrayToHexString(byte[] byteArray) {
if (byteArray == null) {
return "";
}
return byteArrayToHexString(byteArray, 0, byteArray.length);
}
/**
* Forms a byte array containing the values of the hex-encoded string.
*
* @param str The hex-encoded string to be converted to byte-array.
* @param offset The start position.
* @param length The number of chars to be converted (must be multiple of 2).
* @return A byte array containing the values of the hex-encoded string.
*/
public static byte[] hexStringToByteArray(String str, int offset, int length) {
if (length % 2 != 0) {
throw new IllegalArgumentException("length must be multiple of 2");
}
str = str.toUpperCase();
byte[] outputBytes = new byte[str.length() / 2];
for (int i = 0; i < length; i += 2) {
char c1 = str.charAt(i + offset);
char c2 = str.charAt(i + 1 + offset);
if (!isHexChar(c1) || !isHexChar(c2)) {
throw new IllegalArgumentException("Invalid char found");
}
outputBytes[i / 2] = (byte) ((Character.digit(c1, 16) << 4) + Character.digit(c2, 16));
}
return outputBytes;
}
/**
* Forms a byte array containing the values of the hex-encoded string.
*
* @param str The hex-encoded string to be converted to byte-array.
* @return A byte array containing the values of the hex-encoded string.
*/
public static byte[] hexStringToByteArray(String str) {
return hexStringToByteArray(str, 0, str.length());
}
/**
* Forms a byte array containing the specified integer value.
*
* @param value The integer value to be converted to byte array.
* @return A byte array containing the specified integer value.
*/
public static byte[] intToByteArray(int value) {
return new byte[]{
(byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value
};
}
/**
* Forms an integer from a byte array.
*
* @param byteArray The byte array from where to form the integer.
* @return The integer value representing the specified byte array. 0 if the array is empty. If
* the array is longer than 4 bytes, only bytes 0 to 3 will be considered.
*/
public static int byteArrayToInt(byte[] byteArray) {
switch (byteArray.length) {
case 0:
return 0;
case 1:
return (byteArray[0] & 0xFF);
case 2:
return (byteArray[0] & 0xFF) << 8 | (byteArray[1] & 0xFF);
case 3:
return (byteArray[0] & 0xFF) << 16 | (byteArray[1] & 0xFF) << 8 | (byteArray[2]
& 0xFF);
default:
return (byteArray[0] & 0xFF) << 24
| (byteArray[1] & 0xFF) << 16
| (byteArray[2] & 0xFF) << 8
| byteArray[3] & 0xFF;
}
}
/**
* Decides whether a char is a valid hex value or not.
*
* @param c The char to be evaluated.
* @return true if the specified char is a valid hex value, false otherwise.
*/
public static boolean isHexChar(char c) {
if (Character.isLowerCase(c)) {
c = Character.toUpperCase(c);
}
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F');
}
}