1 /* 2 * Copyright (C) 2015 Samsung System LSI 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 package com.android.bluetooth; 17 18 import com.android.bluetooth.map.BluetoothMapUtils; 19 20 import java.io.UnsupportedEncodingException; 21 import java.util.Objects; 22 23 /** 24 * Class to represent a 128bit value using two long member variables. Has functionality to convert 25 * to/from hex-strings. Mind that since signed variables are used to store the value internally is 26 * used, the MSB/LSB long values can be negative. 27 */ 28 public class SignedLongLong implements Comparable<SignedLongLong> { 29 30 private long mMostSigBits; 31 private long mLeastSigBits; 32 SignedLongLong(long leastSigBits, long mostSigBits)33 public SignedLongLong(long leastSigBits, long mostSigBits) { 34 this.mMostSigBits = mostSigBits; 35 this.mLeastSigBits = leastSigBits; 36 } 37 38 /** 39 * Create a SignedLongLong from a Hex-String without "0x" prefix 40 * 41 * @param value the hex-string 42 * @return the created object 43 * @throws UnsupportedEncodingException if "US-ASCII" charset is not supported, 44 * @throws NullPointerException if the string {@code value} is null, 45 * @throws NumberFormatException if the string {@code value} contains invalid characters. 46 */ fromString(String value)47 public static SignedLongLong fromString(String value) throws UnsupportedEncodingException { 48 String lsbStr, msbStr; 49 long msb = 0; 50 51 lsbStr = msbStr = null; 52 if (value == null) { 53 throw new NullPointerException(); 54 } 55 value = value.trim(); 56 int valueLength = value.length(); 57 if (valueLength == 0 || valueLength > 32) { 58 throw new NumberFormatException("invalid string length: " + valueLength); 59 } 60 if (valueLength <= 16) { 61 lsbStr = value; 62 } else { 63 lsbStr = value.substring(valueLength - 16, valueLength); 64 msbStr = value.substring(0, valueLength - 16); 65 msb = BluetoothMapUtils.getLongFromString(msbStr); 66 } 67 long lsb = BluetoothMapUtils.getLongFromString(lsbStr); 68 return new SignedLongLong(lsb, msb); 69 } 70 71 @Override compareTo(SignedLongLong another)72 public int compareTo(SignedLongLong another) { 73 if (mMostSigBits == another.mMostSigBits) { 74 if (mLeastSigBits == another.mLeastSigBits) { 75 return 0; 76 } 77 if (mLeastSigBits < another.mLeastSigBits) { 78 return -1; 79 } 80 return 1; 81 } 82 if (mMostSigBits < another.mMostSigBits) { 83 return -1; 84 } 85 return 1; 86 } 87 88 @Override toString()89 public String toString() { 90 return toHexString(); 91 } 92 93 /** 94 * @return a hex-string representation of the object values 95 */ toHexString()96 public String toHexString() { 97 return BluetoothMapUtils.getLongLongAsString(mLeastSigBits, mMostSigBits); 98 } 99 100 @Override equals(Object obj)101 public boolean equals(Object obj) { 102 if (this == obj) { 103 return true; 104 } 105 if (obj == null) { 106 return false; 107 } 108 if (!(obj instanceof SignedLongLong)) { 109 return false; 110 } 111 SignedLongLong other = (SignedLongLong) obj; 112 if (mLeastSigBits != other.mLeastSigBits) { 113 return false; 114 } 115 if (mMostSigBits != other.mMostSigBits) { 116 return false; 117 } 118 return true; 119 } 120 121 @Override hashCode()122 public int hashCode() { 123 return Objects.hash(mLeastSigBits, mMostSigBits); 124 } 125 getMostSignificantBits()126 public long getMostSignificantBits() { 127 return mMostSigBits; 128 } 129 getLeastSignificantBits()130 public long getLeastSignificantBits() { 131 return mLeastSigBits; 132 } 133 } 134