Release 2.3.3
[amule.git] / src / kademlia / utils / UInt128.h
blob46efb816bb10ec59ec1cb4b5cab9e24825accb7e
1 // -*- C++ -*-
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2008-2011 Dévai Tamás ( gonosztopi@amule.org )
5 // Copyright (c) 2004-2011 Angel Vidal ( kry@amule.org )
6 // Copyright (c) 2004-2011 aMule Team ( admin@amule.org / http://www.amule.org )
7 // Copyright (c) 2003-2011 Barry Dunne (http://www.emule-project.net)
8 //
9 // Any parts of this program derived from the xMule, lMule or eMule project,
10 // or contributed by third-party developers are copyrighted by their
11 // respective authors.
13 // This program is free software; you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation; either version 2 of the License, or
16 // (at your option) any later version.
18 // This program is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
23 // You should have received a copy of the GNU General Public License
24 // along with this program; if not, write to the Free Software
25 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 // Note To Mods //
30 Please do not change anything here and release it..
31 There is going to be a new forum created just for the Kademlia side of the client..
32 If you feel there is an error or a way to improve something, please
33 post it in the forum first and let us look at it.. If it is a real improvement,
34 it will be added to the offical client.. Changing something without knowing
35 what all it does can cause great harm to the network if released in mass form..
36 Any mod that changes anything within the Kademlia side will not be allowed to advertise
37 there client on the eMule forum..
40 #ifndef __UINT128_H__
41 #define __UINT128_H__
43 #include "../../Types.h"
45 ////////////////////////////////////////
46 namespace Kademlia {
47 ////////////////////////////////////////
49 /**
50 * Class representing an unsigned 128-bit integer.
52 * Not all operations are valid, especially multiplicative operations
53 * (multiply, divide) and shift right are not implemented.
55 * @if maint
56 * Internal representation: The number is stored as a whole little-endian
57 * 128-bit number.
58 * @endif
60 class CUInt128
62 public:
63 CUInt128(const CUInt128& value) throw()
65 SetValue(value);
68 explicit CUInt128(bool fill = false) throw()
70 m_data.u64_data[0] = m_data.u64_data[1] = (fill ? (uint64_t)-1 : 0);
73 explicit CUInt128(uint32_t value) throw()
75 SetValue(value);
78 explicit CUInt128(const uint8_t *valueBE) throw()
80 SetValueBE(valueBE);
83 /**
84 * Generates a new number, copying the most significant 'numBits' bits from 'value'.
85 * The remaining bits are randomly generated.
87 CUInt128(const CUInt128& value, unsigned numBits);
89 /* Bit at level 0 being most significant. */
90 unsigned GetBitNumber(unsigned bit) const throw()
92 return bit <= 127 ? (m_data.u32_data[(127 - bit) / 32] >> ((127 - bit) % 32)) & 1 : 0;
95 /* Bit at level 0 being most significant. */
96 CUInt128& SetBitNumber(unsigned bit, unsigned value)
98 wxCHECK(bit <= 127, *this);
100 if (value)
101 m_data.u32_data[(127 - bit) / 32] |= 1 << ((127 - bit) % 32);
102 else
103 m_data.u32_data[(127 - bit) / 32] &= ~(1 << ((127 - bit) % 32));
105 return *this;
108 /* Chunk 0 being the most significant */
109 uint32_t Get32BitChunk(unsigned val) const throw()
111 return val < 4 ? m_data.u32_data[3 - val] : 0;
114 /* Chunk 0 being the most significant */
115 void Set32BitChunk(unsigned chunk, uint32_t value)
117 wxCHECK2(chunk < 4, return);
119 m_data.u32_data[3 - chunk] = value;
122 CUInt128& SetValueBE(const uint8_t *valueBE) throw();
124 wxString ToHexString() const;
125 wxString ToBinaryString(bool trim = false) const;
126 void ToByteArray(uint8_t *b) const;
129 * Stores value used by the crypt functions.
131 * Since eMule started to use the value as-is (four little-endian 32-bit integers in big-endian order),
132 * we have to reproduce that same representation on every platform.
134 * @param buf Buffer to hold the value. Must be large enough to hold the data (16 bytes at least),
135 * and must not be NULL.
137 void StoreCryptValue(uint8_t *buf) const;
139 private:
140 int CompareTo(const CUInt128& other) const throw();
141 int CompareTo(uint32_t value) const throw();
142 CUInt128& Add(const CUInt128& value) throw();
143 CUInt128& Add(uint32_t value) throw() { return value ? Add(CUInt128(value)) : *this; }
144 CUInt128& Subtract(const CUInt128& value) throw();
145 CUInt128& Subtract(uint32_t value) throw() { return value ? Subtract(CUInt128(value)) : *this; }
146 CUInt128& ShiftLeft(unsigned bits) throw();
148 CUInt128& XOR(const CUInt128& value) throw()
150 m_data.u64_data[0] ^= value.m_data.u64_data[0];
151 m_data.u64_data[1] ^= value.m_data.u64_data[1];
153 return *this;
156 bool IsZero() const throw() { return (m_data.u64_data[0] | m_data.u64_data[1]) == 0; }
158 public:
159 bool operator< (const CUInt128& value) const throw() { return (CompareTo(value) < 0); }
160 bool operator> (const CUInt128& value) const throw() { return (CompareTo(value) > 0); }
161 bool operator<=(const CUInt128& value) const throw() { return (CompareTo(value) <= 0); }
162 bool operator>=(const CUInt128& value) const throw() { return (CompareTo(value) >= 0); }
163 bool operator==(const CUInt128& value) const throw() { return (CompareTo(value) == 0); }
164 bool operator!=(const CUInt128& value) const throw() { return (CompareTo(value) != 0); }
166 bool operator< (uint32_t value) const throw() { return (CompareTo(value) < 0); }
167 bool operator> (uint32_t value) const throw() { return (CompareTo(value) > 0); }
168 bool operator<=(uint32_t value) const throw() { return (CompareTo(value) <= 0); }
169 bool operator>=(uint32_t value) const throw() { return (CompareTo(value) >= 0); }
170 bool operator==(uint32_t value) const throw() { return (CompareTo(value) == 0); }
171 bool operator!=(uint32_t value) const throw() { return (CompareTo(value) != 0); }
173 CUInt128& operator= (const CUInt128& value) throw() { SetValue(value); return *this; }
174 CUInt128& operator+=(const CUInt128& value) throw() { return Add(value); }
175 CUInt128& operator-=(const CUInt128& value) throw() { return Subtract(value); }
176 CUInt128& operator^=(const CUInt128& value) throw() { return XOR(value); }
178 CUInt128& operator= (uint32_t value) throw() { SetValue(value); return *this; }
179 CUInt128& operator+=(uint32_t value) throw() { return Add(value); }
180 CUInt128& operator-=(uint32_t value) throw() { return Subtract(value); }
181 CUInt128& operator^=(uint32_t value) throw() { return value ? XOR(CUInt128(value)) : *this; }
183 CUInt128& operator<<=(unsigned bits) throw() { return ShiftLeft(bits); }
185 CUInt128 operator+(const CUInt128& value) const throw() { return CUInt128(*this).operator+=(value); }
186 CUInt128 operator-(const CUInt128& value) const throw() { return CUInt128(*this).operator-=(value); }
187 CUInt128 operator^(const CUInt128& value) const throw() { return CUInt128(*this).operator^=(value); }
189 CUInt128 operator+(uint32_t value) const throw() { return CUInt128(*this).operator+=(value); }
190 CUInt128 operator-(uint32_t value) const throw() { return CUInt128(*this).operator-=(value); }
191 CUInt128 operator^(uint32_t value) const throw() { return CUInt128(*this).operator^=(value); }
193 CUInt128 operator<<(unsigned bits) const throw() { return CUInt128(*this).operator<<=(bits); }
196 private:
197 void SetValue(const CUInt128& other) throw()
199 m_data.u64_data[0] = other.m_data.u64_data[0];
200 m_data.u64_data[1] = other.m_data.u64_data[1];
203 void SetValue(uint32_t value) throw()
205 m_data.u32_data[0] = value;
206 m_data.u32_data[1] = 0;
207 m_data.u64_data[1] = 0;
210 union {
211 uint32_t u32_data[4];
212 uint64_t u64_data[2];
213 } m_data;
216 inline bool operator==(uint32_t x, const CUInt128& y) throw() { return y.operator==(x); }
217 inline bool operator!=(uint32_t x, const CUInt128& y) throw() { return y.operator!=(x); }
218 inline bool operator<(uint32_t x, const CUInt128& y) throw() { return y.operator>(x); }
219 inline bool operator>(uint32_t x, const CUInt128& y) throw() { return y.operator<(x); }
220 inline bool operator<=(uint32_t x, const CUInt128& y) throw() { return y.operator>=(x); }
221 inline bool operator>=(uint32_t x, const CUInt128& y) throw() { return y.operator<=(x); }
222 inline CUInt128 operator+(uint32_t x, const CUInt128& y) throw() { return y.operator+(x); }
223 inline CUInt128 operator-(uint32_t x, const CUInt128& y) throw() { return CUInt128(x).operator-(y); }
224 inline CUInt128 operator^(uint32_t x, const CUInt128& y) throw() { return y.operator^(x); }
226 } // End namespace
228 #endif
229 // File_checked_for_headers