1 /*
2  * Copyright (C) 2009 The Guava Authors
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 
17 package com.google.common.primitives;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 
22 import com.google.common.annotations.VisibleForTesting;
23 
24 // BEGIN android-changed
25 //import sun.misc.Unsafe;
26 // END android-changed
27 
28 import java.lang.reflect.Field;
29 import java.nio.ByteOrder;
30 import java.security.AccessController;
31 import java.security.PrivilegedAction;
32 import java.util.Comparator;
33 
34 /**
35  * Static utility methods pertaining to {@code byte} primitives that interpret
36  * values as <i>unsigned</i> (that is, any negative value {@code b} is treated
37  * as the positive value {@code 256 + b}). The corresponding methods that treat
38  * the values as signed are found in {@link SignedBytes}, and the methods for
39  * which signedness is not an issue are in {@link Bytes}.
40  *
41  * @author Kevin Bourrillion
42  * @author Martin Buchholz
43  * @author Hiroshi Yamauchi
44  * @since 1.0
45  */
46 public final class UnsignedBytes {
UnsignedBytes()47   private UnsignedBytes() {}
48 
49   /**
50    * The largest power of two that can be represented as an unsigned {@code byte}.
51    *
52    * @since 10.0
53    */
54   public static final byte MAX_POWER_OF_TWO = (byte) (1 << 7);
55 
56   /**
57    * Returns the value of the given byte as an integer, when treated as
58    * unsigned. That is, returns {@code value + 256} if {@code value} is
59    * negative; {@code value} itself otherwise.
60    *
61    * @since 6.0
62    */
toInt(byte value)63   public static int toInt(byte value) {
64     return value & 0xFF;
65   }
66 
67   /**
68    * Returns the {@code byte} value that, when treated as unsigned, is equal to
69    * {@code value}, if possible.
70    *
71    * @param value a value between 0 and 255 inclusive
72    * @return the {@code byte} value that, when treated as unsigned, equals
73    *     {@code value}
74    * @throws IllegalArgumentException if {@code value} is negative or greater
75    *     than 255
76    */
checkedCast(long value)77   public static byte checkedCast(long value) {
78     checkArgument(value >> 8 == 0, "out of range: %s", value);
79     return (byte) value;
80   }
81 
82   /**
83    * Returns the {@code byte} value that, when treated as unsigned, is nearest
84    * in value to {@code value}.
85    *
86    * @param value any {@code long} value
87    * @return {@code (byte) 255} if {@code value >= 255}, {@code (byte) 0} if
88    *     {@code value <= 0}, and {@code value} cast to {@code byte} otherwise
89    */
saturatedCast(long value)90   public static byte saturatedCast(long value) {
91     if (value > 255) {
92       return (byte) 255; // -1
93     }
94     if (value < 0) {
95       return (byte) 0;
96     }
97     return (byte) value;
98   }
99 
100   /**
101    * Compares the two specified {@code byte} values, treating them as unsigned
102    * values between 0 and 255 inclusive. For example, {@code (byte) -127} is
103    * considered greater than {@code (byte) 127} because it is seen as having
104    * the value of positive {@code 129}.
105    *
106    * @param a the first {@code byte} to compare
107    * @param b the second {@code byte} to compare
108    * @return a negative value if {@code a} is less than {@code b}; a positive
109    *     value if {@code a} is greater than {@code b}; or zero if they are equal
110    */
compare(byte a, byte b)111   public static int compare(byte a, byte b) {
112     return toInt(a) - toInt(b);
113   }
114 
115   /**
116    * Returns the least value present in {@code array}.
117    *
118    * @param array a <i>nonempty</i> array of {@code byte} values
119    * @return the value present in {@code array} that is less than or equal to
120    *     every other value in the array
121    * @throws IllegalArgumentException if {@code array} is empty
122    */
min(byte... array)123   public static byte min(byte... array) {
124     checkArgument(array.length > 0);
125     int min = toInt(array[0]);
126     for (int i = 1; i < array.length; i++) {
127       int next = toInt(array[i]);
128       if (next < min) {
129         min = next;
130       }
131     }
132     return (byte) min;
133   }
134 
135   /**
136    * Returns the greatest value present in {@code array}.
137    *
138    * @param array a <i>nonempty</i> array of {@code byte} values
139    * @return the value present in {@code array} that is greater than or equal
140    *     to every other value in the array
141    * @throws IllegalArgumentException if {@code array} is empty
142    */
max(byte... array)143   public static byte max(byte... array) {
144     checkArgument(array.length > 0);
145     int max = toInt(array[0]);
146     for (int i = 1; i < array.length; i++) {
147       int next = toInt(array[i]);
148       if (next > max) {
149         max = next;
150       }
151     }
152     return (byte) max;
153   }
154 
155   /**
156    * Returns a string containing the supplied {@code byte} values separated by
157    * {@code separator}. For example, {@code join(":", (byte) 1, (byte) 2,
158    * (byte) 255)} returns the string {@code "1:2:255"}.
159    *
160    * @param separator the text that should appear between consecutive values in
161    *     the resulting string (but not at the start or end)
162    * @param array an array of {@code byte} values, possibly empty
163    */
join(String separator, byte... array)164   public static String join(String separator, byte... array) {
165     checkNotNull(separator);
166     if (array.length == 0) {
167       return "";
168     }
169 
170     // For pre-sizing a builder, just get the right order of magnitude
171     StringBuilder builder = new StringBuilder(array.length * 5);
172     builder.append(toInt(array[0]));
173     for (int i = 1; i < array.length; i++) {
174       builder.append(separator).append(toInt(array[i]));
175     }
176     return builder.toString();
177   }
178 
179   /**
180    * Returns a comparator that compares two {@code byte} arrays
181    * lexicographically. That is, it compares, using {@link
182    * #compare(byte, byte)}), the first pair of values that follow any common
183    * prefix, or when one array is a prefix of the other, treats the shorter
184    * array as the lesser. For example, {@code [] < [0x01] < [0x01, 0x7F] <
185    * [0x01, 0x80] < [0x02]}. Values are treated as unsigned.
186    *
187    * <p>The returned comparator is inconsistent with {@link
188    * Object#equals(Object)} (since arrays support only identity equality), but
189    * it is consistent with {@link java.util.Arrays#equals(byte[], byte[])}.
190    *
191    * @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
192    *     Lexicographical order article at Wikipedia</a>
193    * @since 2.0
194    */
lexicographicalComparator()195   public static Comparator<byte[]> lexicographicalComparator() {
196     return LexicographicalComparatorHolder.BEST_COMPARATOR;
197   }
198 
199   @VisibleForTesting
lexicographicalComparatorJavaImpl()200   static Comparator<byte[]> lexicographicalComparatorJavaImpl() {
201     return LexicographicalComparatorHolder.PureJavaComparator.INSTANCE;
202   }
203 
204   /**
205    * Provides a lexicographical comparator implementation; either a Java
206    * implementation or a faster implementation based on {@link Unsafe}.
207    *
208    * <p>Uses reflection to gracefully fall back to the Java implementation if
209    * {@code Unsafe} isn't available.
210    */
211   @VisibleForTesting
212   static class LexicographicalComparatorHolder {
213     static final String UNSAFE_COMPARATOR_NAME =
214         LexicographicalComparatorHolder.class.getName() + "$UnsafeComparator";
215 
216     // BEGIN android-changed
217 
218     static final Comparator<byte[]> BEST_COMPARATOR = lexicographicalComparatorJavaImpl();
219 
220     // @VisibleForTesting
221     // enum UnsafeComparator implements Comparator<byte[]> {
222     //   INSTANCE;
223 
224     //   static final boolean littleEndian =
225     //       ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
226 
227     //   /*
228     //    * The following static final fields exist for performance reasons.
229     //    *
230     //    * In UnsignedBytesBenchmark, accessing the following objects via static
231     //    * final fields is the fastest (more than twice as fast as the Java
232     //    * implementation, vs ~1.5x with non-final static fields, on x86_32)
233     //    * under the Hotspot server compiler. The reason is obviously that the
234     //    * non-final fields need to be reloaded inside the loop.
235     //    *
236     //    * And, no, defining (final or not) local variables out of the loop still
237     //    * isn't as good because the null check on the theUnsafe object remains
238     //    * inside the loop and BYTE_ARRAY_BASE_OFFSET doesn't get
239     //    * constant-folded.
240     //    *
241     //    * The compiler can treat static final fields as compile-time constants
242     //    * and can constant-fold them while (final or not) local variables are
243     //    * run time values.
244     //    */
245 
246     //   static final Unsafe theUnsafe;
247 
248     //   /** The offset to the first element in a byte array. */
249     //   static final int BYTE_ARRAY_BASE_OFFSET;
250 
251     //   static {
252     //     theUnsafe = (Unsafe) AccessController.doPrivileged(
253     //         new PrivilegedAction<Object>() {
254     //           @Override
255     //           public Object run() {
256     //             try {
257     //               Field f = Unsafe.class.getDeclaredField("theUnsafe");
258     //               f.setAccessible(true);
259     //               return f.get(null);
260     //             } catch (NoSuchFieldException e) {
261     //               // It doesn't matter what we throw;
262     //               // it's swallowed in getBestComparator().
263     //               throw new Error();
264     //             } catch (IllegalAccessException e) {
265     //               throw new Error();
266     //             }
267     //           }
268     //         });
269 
270     //     BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
271 
272     //     // sanity check - this should never fail
273     //     if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
274     //       throw new AssertionError();
275     //     }
276     //   }
277 
278     //   @Override public int compare(byte[] left, byte[] right) {
279     //     int minLength = Math.min(left.length, right.length);
280     //     int minWords = minLength / Longs.BYTES;
281 
282     //     /*
283     //      * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a
284     //      * time is no slower than comparing 4 bytes at a time even on 32-bit.
285     //      * On the other hand, it is substantially faster on 64-bit.
286     //      */
287     //     for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) {
288     //       long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
289     //       long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
290     //       long diff = lw ^ rw;
291 
292     //       if (diff != 0) {
293     //         if (!littleEndian) {
294     //           return UnsignedLongs.compare(lw, rw);
295     //         }
296 
297     //         // Use binary search
298     //         int n = 0;
299     //         int y;
300     //         int x = (int) diff;
301     //         if (x == 0) {
302     //           x = (int) (diff >>> 32);
303     //           n = 32;
304     //         }
305 
306     //         y = x << 16;
307     //         if (y == 0) {
308     //           n += 16;
309     //         } else {
310     //           x = y;
311     //         }
312 
313     //         y = x << 8;
314     //         if (y == 0) {
315     //           n += 8;
316     //         }
317     //         return (int) (((lw >>> n) & 0xFFL) - ((rw >>> n) & 0xFFL));
318     //       }
319     //     }
320 
321     //     // The epilogue to cover the last (minLength % 8) elements.
322     //     for (int i = minWords * Longs.BYTES; i < minLength; i++) {
323     //       int result = UnsignedBytes.compare(left[i], right[i]);
324     //       if (result != 0) {
325     //         return result;
326     //       }
327     //     }
328     //     return left.length - right.length;
329     //   }
330     // }
331 
332     // END android-changed
333 
334     enum PureJavaComparator implements Comparator<byte[]> {
335       INSTANCE;
336 
compare(byte[] left, byte[] right)337       @Override public int compare(byte[] left, byte[] right) {
338         int minLength = Math.min(left.length, right.length);
339         for (int i = 0; i < minLength; i++) {
340           int result = UnsignedBytes.compare(left[i], right[i]);
341           if (result != 0) {
342             return result;
343           }
344         }
345         return left.length - right.length;
346       }
347     }
348 
349     // BEGIN android-changed
350 
351     // /**
352     //  * Returns the Unsafe-using Comparator, or falls back to the pure-Java
353     //  * implementation if unable to do so.
354     //  */
355     // static Comparator<byte[]> getBestComparator() {
356     //   try {
357     //     Class<?> theClass = Class.forName(UNSAFE_COMPARATOR_NAME);
358 
359     //     // yes, UnsafeComparator does implement Comparator<byte[]>
360     //     @SuppressWarnings("unchecked")
361     //     Comparator<byte[]> comparator =
362     //         (Comparator<byte[]>) theClass.getEnumConstants()[0];
363     //     return comparator;
364     //   } catch (Throwable t) { // ensure we really catch *everything*
365     //     return lexicographicalComparatorJavaImpl();
366     //   }
367     // }
368 
369     // END android-changed
370 
371   }
372 }
373 
374