001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2011-2011 Pentaho and others 008// All Rights Reserved. 009*/ 010package mondrian.util; 011 012import java.io.Serializable; 013import java.util.Arrays; 014 015/** 016 * Collection of bytes. 017 * 018 * <p>ByteString is to bytes what {@link String} is to chars: It is immutable, 019 * implements equality (hashCode and equals), comparison (compareTo) and 020 * serialization correctly.</p> 021 * 022 * @author jhyde 023 */ 024public class ByteString implements Comparable<ByteString>, Serializable { 025 private final byte[] bytes; 026 027 private static final char[] digits = { 028 '0', '1', '2', '3', '4', '5', '6', '7', 029 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 030 }; 031 032 /** 033 * Creates a ByteString. 034 * 035 * @param bytes Bytes 036 */ 037 public ByteString(byte[] bytes) { 038 this.bytes = bytes.clone(); 039 } 040 041 @Override 042 public int hashCode() { 043 return Arrays.hashCode(bytes); 044 } 045 046 @Override 047 public boolean equals(Object obj) { 048 return obj instanceof ByteString 049 && Arrays.equals(bytes, ((ByteString) obj).bytes); 050 } 051 052 public int compareTo(ByteString that) { 053 final byte[] v1 = bytes; 054 final byte[] v2 = that.bytes; 055 final int n = Math.min(v1.length, v2.length); 056 for (int i = 0; i < n; i++) { 057 byte c1 = v1[i]; 058 byte c2 = v2[i]; 059 if (c1 != c2) { 060 return c1 - c2; 061 } 062 } 063 return v1.length - v2.length; 064 } 065 066 /** 067 * Returns this byte string in hexadecimal format. 068 * 069 * @return Hexadecimal string 070 */ 071 @Override 072 public String toString() { 073 char[] chars = new char[bytes.length * 2]; 074 for (int i = 0, j = 0; i < bytes.length; i++) { 075 byte b = bytes[i]; 076 chars[j++] = digits[(b & 0xF0) >> 4]; 077 chars[j++] = digits[b & 0x0F]; 078 } 079 return new String(chars); 080 } 081 082 @SuppressWarnings({ 083 "CloneDoesntCallSuperClone", 084 "CloneDoesntDeclareCloneNotSupportedException" 085 }) 086 @Override 087 public Object clone() { 088 return this; 089 } 090 091 /** 092 * Returns the number of bytes in this byte string. 093 * 094 * @return Length of this byte string 095 */ 096 public int length() { 097 return bytes.length; 098 } 099 100 /** 101 * Returns the byte at a given position in the byte string. 102 * 103 * @param i Index 104 * @throws IndexOutOfBoundsException 105 * if the <tt>index</tt> argument is negative or not less than 106 * <tt>length()</tt> 107 * @return Byte at given position 108 */ 109 public byte byteAt(int i) { 110 return bytes[i]; 111 } 112} 113 114// End ByteString.java