Workaround for bug in Python's math.log function
[bitcoin:eloipool.git] / bitcoin / varlen.py
1 # Eloipool - Python Bitcoin pool server
2 # Copyright (C) 2011-2012  Luke Dashjr <luke-jr+eloipool@utopios.org>
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as
6 # published by the Free Software Foundation, either version 3 of the
7 # License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 from struct import pack, unpack
18
19 _ignoredrc = [0]
20
21 def varlenDecode(b, rc = _ignoredrc):
22         if b[0] == 0xff:
23                 rc[0] += 9
24                 return (unpack('<Q', b[1:9])[0], b[9:])
25         if b[0] == 0xfe:
26                 rc[0] += 5
27                 return (unpack('<L', b[1:5])[0], b[5:])
28         if b[0] == 0xfd:
29                 rc[0] += 3
30                 return (unpack('<H', b[1:3])[0], b[3:])
31         rc[0] += 1
32         return (b[0], b[1:])
33
34 def varlenEncode(n):
35         if n < 0xfd:
36                 return pack('<B', n)
37         if n <= 0xffff:
38                 return b'\xfd' + pack('<H', n)
39         if n <= 0xffffffff:
40                 return b'\xfe' + pack('<L', n)
41         return b'\xff' + pack('<Q', n)
42
43 # tests
44 def _test():
45         assert b'\0' == varlenEncode(0)
46         assert b'\xfc' == varlenEncode(0xfc)
47         assert b'\xfd\xfd\0' == varlenEncode(0xfd)
48         assert b'\xfd\xff\xff' == varlenEncode(0xffff)
49         assert b'\xfe\0\0\1\0' == varlenEncode(0x10000)
50         assert b'\xfe\xff\xff\xff\xff' == varlenEncode(0xffffffff)
51         assert b'\xff\0\0\0\0\1\0\0\0' == varlenEncode(0x100000000)
52         assert b'\xff\xff\xff\xff\xff\xff\xff\xff\xff' == varlenEncode(0xffffffffffffffff)
53
54 _test()