1 /* 2 * hunt-proton: AMQP Protocol library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.proton.amqp.UnsignedLong; 13 14 import hunt.math; 15 import hunt.Number; 16 import std.algorithm.comparison; 17 import std.conv : to; 18 import hunt.logging; 19 20 import std.concurrency : initOnce; 21 22 23 class UnsignedLong : Number 24 { 25 static UnsignedLong[] cachedValues ; 26 static BigInteger TWO_TO_THE_SIXTY_FOUR; 27 static BigInteger LONG_MAX_VALUE; 28 static UnsignedLong ZERO; 29 30 static UnsignedLong[] initCachedValues() 31 { 32 UnsignedLong[] cachedVal = new UnsignedLong[256]; 33 for(int i = 0; i<256; i++) 34 { 35 cachedValues[i] = new UnsignedLong(i); 36 } 37 return cachedVal; 38 } 39 40 //static UnsignedLong[] cachedValues() { 41 // __gshared UnsignedLong[] inst; 42 // return initOnce!inst(initCachedValues); 43 //} 44 45 46 47 static this() 48 { 49 cachedValues = new UnsignedLong[256]; 50 for(int i = 0; i<256; i++) 51 { 52 cachedValues[i] = new UnsignedLong(i); 53 } 54 UnsignedLong.TWO_TO_THE_SIXTY_FOUR = new BigInteger([1,0,0,0,0,0,0,0,0]); 55 UnsignedLong.LONG_MAX_VALUE = BigInteger.valueOf(0x7FFFFFFFFFFFFFFF); 56 UnsignedLong.ZERO = cachedValues[0]; 57 } 58 59 60 61 private long _underlying; 62 63 64 this(long underlying) 65 { 66 _underlying = underlying; 67 } 68 69 override 70 public int intValue() 71 { 72 return cast(int) _underlying; 73 } 74 75 override 76 public long longValue() 77 { 78 return _underlying; 79 } 80 81 public BigInteger bigIntegerValue() 82 { 83 if(_underlying >= 0L) 84 { 85 return BigInteger.valueOf(_underlying); 86 } 87 else 88 { 89 return TWO_TO_THE_SIXTY_FOUR.add(BigInteger.valueOf(_underlying)); 90 } 91 } 92 93 override 94 public float floatValue() 95 { 96 return cast(float) (longValue()); 97 } 98 99 override 100 public double doubleValue() 101 { 102 return cast(double) (longValue()); 103 } 104 105 override bool opEquals(Object o) 106 { 107 if (this is o) 108 { 109 return true; 110 } 111 if (o is null || (cast(UnsignedLong)o is null)) 112 { 113 return false; 114 } 115 116 UnsignedLong that = cast(UnsignedLong)o; 117 118 if (_underlying != that._underlying) 119 { 120 return false; 121 } 122 123 return true; 124 } 125 126 override int opCmp(Object o) 127 { 128 UnsignedLong that = cast(UnsignedLong)(o); 129 return cast(int)(longValue() - that.longValue()); 130 } 131 132 //override size_t toHash() @trusted nothrow { 133 // size_t hashcode = 0; 134 // hashcode = price * 20; 135 // hashcode += hashOf(item); 136 // return hashcode; 137 //} 138 139 override 140 public size_t toHash() @trusted nothrow 141 { 142 return cast(size_t)(_underlying ^ (_underlying >>> 32)); 143 } 144 // 145 //public string toString() 146 //{ 147 // return String.valueOf(bigIntegerValue()); 148 //} 149 150 public static UnsignedLong valueOf(long underlying) 151 { 152 if((underlying & 0xFFL) == underlying) 153 { 154 return cachedValues[cast(int)(underlying)]; 155 } 156 else 157 { 158 return new UnsignedLong(underlying); 159 } 160 } 161 162 public static UnsignedLong valueOf(string value) 163 { 164 BigInteger bigInt = new BigInteger(value); 165 166 return valueOf(bigInt); 167 } 168 169 public static UnsignedLong valueOf(BigInteger bigInt) 170 { 171 if(bigInt.signum() == -1 || bigInt.bitLength() > 64) 172 { 173 // throw new NumberFormatException("Value \""+bigInt+"\" lies outside the range [0 - 2^64)."); 174 logError("Value lies outside the range [0 - 2^64)."); 175 return null; 176 } 177 else if(bigInt.compareTo(LONG_MAX_VALUE)>=0) 178 { 179 return UnsignedLong.valueOf(bigInt.longValue()); 180 } 181 else 182 { 183 return UnsignedLong.valueOf(TWO_TO_THE_SIXTY_FOUR.subtract(bigInt).negate().longValue()); 184 } 185 } 186 187 188 override 189 byte byteValue() 190 { 191 return 1; 192 } 193 194 override short shortValue() 195 { 196 return 1; 197 } 198 199 override string toString() 200 { 201 return ""; 202 } 203 }