• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.util;
18 
19 import com.google.crypto.tink.subtle.Hex;
20 import com.google.errorprone.annotations.Immutable;
21 import java.util.Arrays;
22 
23 /**
24  * Immutable Wrapper around a byte array.
25  *
26  * <p>Wrap a bytearray so it prevents callers from modifying its contents. It does this by making a
27  * copy upon initialization, and also makes a copy if the underlying bytes are requested.
28  *
29  * @since 1.0.0
30  */
31 @Immutable
32 public final class Bytes {
33   /**
34    * @param data the byte array to be wrapped.
35    * @return an immutable wrapper around the provided bytes.
36    */
copyFrom(final byte[] data)37   public static Bytes copyFrom(final byte[] data) {
38     if (data == null) {
39       throw new NullPointerException("data must be non-null");
40     }
41     return copyFrom(data, 0, data.length);
42   }
43 
44   /**
45    * Wrap an immutable byte array over a slice of a Bytes
46    *
47    * @param data the byte array to be wrapped.
48    * @param start the starting index of the slice
49    * @param len the length of the slice. If start + len is larger than the size of {@code data}, the
50    *     remaining data will be returned.
51    * @return an immutable wrapper around the bytes in the slice from {@code start} to {@code start +
52    *     len}
53    */
copyFrom(byte[] data, int start, int len)54   public static Bytes copyFrom(byte[] data, int start, int len) {
55     if (data == null) {
56       throw new NullPointerException("data must be non-null");
57     }
58     if (start + len > data.length) {
59       len = data.length - start;
60     }
61     return new Bytes(data, start, len);
62   }
63 
64   /**
65    * @return a copy of the bytes wrapped by this object.
66    */
toByteArray()67   public byte[] toByteArray() {
68     byte[] result = new byte[data.length];
69     System.arraycopy(data, 0, result, 0, data.length);
70     return result;
71   }
72 
73   /**
74    * @return the length of the bytes wrapped by this object.
75    */
size()76   public int size() {
77     return data.length;
78   }
79 
Bytes(final byte[] buf, final int start, final int len)80   private Bytes(final byte[] buf, final int start, final int len) {
81     data = new byte[len];
82     System.arraycopy(buf, start, data, 0, len);
83   }
84 
85   @Override
equals(Object o)86   public boolean equals(Object o) {
87     if (!(o instanceof Bytes)) {
88       return false;
89     }
90     Bytes other = (Bytes) o;
91     return Arrays.equals(other.data, data);
92   }
93 
94   @Override
hashCode()95   public int hashCode() {
96     return Arrays.hashCode(data);
97   }
98 
99   @Override
toString()100   public String toString() {
101     return "Bytes(" + Hex.encode(data) + ")";
102   }
103 
104   @SuppressWarnings("Immutable") // We copy the data on input and output.
105   private final byte[] data;
106 }
107