|
7 | 7 | """ |
8 | 8 | from __future__ import division |
9 | 9 |
|
| 10 | +import struct |
| 11 | + |
10 | 12 | from future.types.newbytes import newbytes |
11 | 13 | from future.utils import PY3, isint, istext, isbytes, with_metaclass |
12 | 14 |
|
@@ -274,5 +276,76 @@ def __bool__(self): |
274 | 276 | def __native__(self): |
275 | 277 | return long(self) |
276 | 278 |
|
| 279 | + def to_bytes(self, length, byteorder='big', signed=False): |
| 280 | + """ |
| 281 | + Return an array of bytes representing an integer. |
| 282 | +
|
| 283 | + The integer is represented using length bytes. An OverflowError is |
| 284 | + raised if the integer is not representable with the given number of |
| 285 | + bytes. |
| 286 | +
|
| 287 | + The byteorder argument determines the byte order used to represent the |
| 288 | + integer. If byteorder is 'big', the most significant byte is at the |
| 289 | + beginning of the byte array. If byteorder is 'little', the most |
| 290 | + significant byte is at the end of the byte array. To request the native |
| 291 | + byte order of the host system, use `sys.byteorder' as the byte order value. |
| 292 | +
|
| 293 | + The signed keyword-only argument determines whether two's complement is |
| 294 | + used to represent the integer. If signed is False and a negative integer |
| 295 | + is given, an OverflowError is raised. |
| 296 | + """ |
| 297 | + if signed: |
| 298 | + raise NotImplementedError("Not yet implemented. Please contribute a patch at http://python-future.org") |
| 299 | + else: |
| 300 | + if self < 0: |
| 301 | + raise OverflowError("can't convert negative int to unsigned") |
| 302 | + num = self |
| 303 | + if byteorder not in ('little', 'big'): |
| 304 | + raise ValueError("byteorder must be either 'little' or 'big'") |
| 305 | + if length < 0: |
| 306 | + raise ValueError("length argument must be non-negative") |
| 307 | + if length == 0 and num == 0: |
| 308 | + return bytes() |
| 309 | + h = b'%x' % num |
| 310 | + s = newbytes((b'0'*(len(h) % 2) + h).zfill(length*2).decode('hex')) |
| 311 | + if len(s) > length: |
| 312 | + raise OverflowError("int too big to convert") |
| 313 | + return s if byteorder == 'big' else s[::-1] |
| 314 | + |
| 315 | + @classmethod |
| 316 | + def from_bytes(cls, bytes, byteorder='big', signed=False): |
| 317 | + """ |
| 318 | + Return the integer represented by the given array of bytes. |
| 319 | +
|
| 320 | + The bytes argument must either support the buffer protocol or be an |
| 321 | + iterable object producing bytes. Bytes and bytearray are examples of |
| 322 | + built-in objects that support the buffer protocol. |
| 323 | +
|
| 324 | + The byteorder argument determines the byte order used to represent the |
| 325 | + integer. If byteorder is 'big', the most significant byte is at the |
| 326 | + beginning of the byte array. If byteorder is 'little', the most |
| 327 | + significant byte is at the end of the byte array. To request the native |
| 328 | + byte order of the host system, use `sys.byteorder' as the byte order value. |
| 329 | +
|
| 330 | + The signed keyword-only argument indicates whether two's complement is |
| 331 | + used to represent the integer. |
| 332 | + """ |
| 333 | + if signed: |
| 334 | + raise NotImplementedError("Not yet implemented. Please contribute a patch at http://python-future.org") |
| 335 | + if byteorder not in ('little', 'big'): |
| 336 | + raise ValueError("byteorder must be either 'little' or 'big'") |
| 337 | + b = bytes if byteorder == 'big' else bytes[::-1] |
| 338 | + if len(b) == 0: |
| 339 | + b = b'\x00' |
| 340 | + num = int(b.encode('hex'), 16) |
| 341 | + return cls(num) |
| 342 | + |
| 343 | + |
| 344 | +# def _twos_comp(val, bits): |
| 345 | +# """compute the 2's compliment of int value val""" |
| 346 | +# if( (val&(1<<(bits-1))) != 0 ): |
| 347 | +# val = val - (1<<bits) |
| 348 | +# return val |
| 349 | + |
277 | 350 |
|
278 | 351 | __all__ = ['newint'] |
0 commit comments