//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the Apache License Version 2.0.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
package com.microsoft.uprove;
import java.util.Arrays;
/**
* Convenience methods for operating on byte arrays.
*/
final class ByteArrays {
/**
* Private constructor to prevent instantiation.
*/
private ByteArrays() {
super();
}
/**
* Indicates whether two arrays of byte arrays are equal.
* @param one an array of byte arrays.
* @param two an array of byte arrays.
* @return <code>true</code> if the two arrays of byte arrays are equal.
*/
public static boolean equals(final byte[][] one, final byte[][] two) {
if (one == two) {
return true;
}
if (one == null || two == null) {
return false;
}
final int len = one.length;
if (len != two.length) {
return false;
}
for (int i = 0; i < len; ++i) {
if (!Arrays.equals(one[i], two[i])) {
return false;
}
}
return true;
}
/**
* Erases a byte array. The array is filled with zero bytes.
* @param data a byte array.
*/
public static void erase(final byte[] data) {
if (data != null) {
Arrays.fill(data, (byte) 0);
}
}
/**
* Erases an array of byte arrays. All byte arrays in the array are
* filled with zero bytes and their references in the main array are
* set to <code>null</code>.
* @param data an array of byte arrays.
*/
public static void erase(final byte[][] data) {
if (data != null) {
for (int i = 0; i < data.length; ++i) {
erase(data[i]);
data[i] = null;
}
}
}
/**
* Computes the hash code for a byte array.
* @param data a byte array.
* @return <code>0</code> if <code>data</code> is <code>null</code>,
* otherwise a hash computed over its elements.
*/
public static int hashCode(final byte[] data) {
if (data == null) {
return 0;
}
int retVal = 17;
for (int i = 0; i < data.length; ++i) {
retVal = retVal * 37 + data[i];
}
return retVal;
}
/**
* Computes the hash code for an array of byte arrays.
* @param data an array of byte arrays.
* @return <code>0</code> if <code>data</code> is <code>null</code>,
* otherwise a hash computed over its elements.
*/
public static int hashCode(final byte[][] data) {
if (data == null) {
return 0;
}
int retVal = 17;
for (int i = 0; i < data.length; ++i) {
retVal = retVal * 37 + hashCode(data[i]);
}
return retVal;
}
/**
* Returns a clone of a byte array.
* @param data a byte array.
* @return <code>null</code> if <code>data</code> is <code>null</code>,
* otherwise a distinct byte array containing the same data as
* <code>data</code>.
*/
public static byte[] clone(final byte[] data) {
if (data == null) {
return null;
}
return (byte[]) data.clone();
}
/**
* Returns a clone of an array of byte arrays.
* @param data an array of byte arrays.
* @return <code>null</code> if <code>data</code> is <code>null</code>,
* otherwise a distinct array containing clones of the byte arrays held
* in the array <code>data</code>.
*/
public static byte[][] clone(final byte[][] data) {
if (data == null) {
return null;
}
byte[][] retVal = new byte[data.length][];
for (int i = 0; i < data.length; ++i) {
retVal[i] = clone(data[i]);
}
return retVal;
}
/**
* Returns a string representation of a byte array.
* @param data a byte array.
* @return <code>"null"</code> if <code>data</code> is <code>null</code>;
* otherwise, the Base64 encoded value of <code>data</code>.
*/
public static String toString(final byte[] data) {
if (data == null) {
return String.valueOf((Object) null);
}
return Base64.encode(data);
}
/**
* Returns a string representation of an array of byte arrays.
* @param data an array of byte arrays.
* @return <code>"null"</code> if <code>data</code> is <code>null</code>;
* otherwise, a list of the Base64 encoded values held in
* <code>data</code>.
*/
public static String toString(final byte[][] data) {
if (data == null) {
return String.valueOf((Object) null);
}
final StringBuffer sb = new StringBuffer("[");
final int len = data.length;
final int lastIdx = len - 1;
for (int i = 0; i < len; ++i) {
sb.append(toString(data[i]));
if (i != lastIdx) {
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
/**
* Returns the concatenation of all the byte arrays. Note that if one
* arrays is <code>null</code>, then it is simply skipped.
* @param arrays array of byte arrays
* @return <code>"null"</code> if <code>arrays</code> is
* <code>null</code>; otherwise, the concatenation of all arrays.
*/
public static byte[] concatenate(final byte[][] arrays) {
if (arrays == null) {
return null;
}
int size = 0;
for (int i = 0; i < arrays.length; i++) {
if (arrays[i] != null) {
size += arrays[i].length;
}
}
byte[] concatenation = new byte[size];
int index = 0;
for (int i = 0; i < arrays.length; i++) {
if (arrays[i] != null) {
System.arraycopy(arrays[i], 0, concatenation, index,
arrays[i].length);
index += arrays[i].length;
}
}
return concatenation;
}
}