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