mercurial/thirdparty/cbor/cbor2/compat.py
changeset 37129 4bd73a955ab0
equal deleted inserted replaced
37128:6f570c501e3e 37129:4bd73a955ab0
       
     1 from math import ldexp
       
     2 import struct
       
     3 import sys
       
     4 
       
     5 
       
     6 if sys.version_info.major < 3:
       
     7     from datetime import tzinfo, timedelta
       
     8 
       
     9     class timezone(tzinfo):
       
    10         def __init__(self, offset):
       
    11             self.offset = offset
       
    12 
       
    13         def utcoffset(self, dt):
       
    14             return self.offset
       
    15 
       
    16         def dst(self, dt):
       
    17             return timedelta(0)
       
    18 
       
    19         def tzname(self, dt):
       
    20             return 'UTC+00:00'
       
    21 
       
    22     def as_unicode(string):
       
    23         return string.decode('utf-8')
       
    24 
       
    25     def iteritems(self):
       
    26         return self.iteritems()
       
    27 
       
    28     def bytes_from_list(values):
       
    29         return bytes(bytearray(values))
       
    30 
       
    31     byte_as_integer = ord
       
    32     timezone.utc = timezone(timedelta(0))
       
    33     xrange = xrange  # noqa: F821
       
    34     long = long  # noqa: F821
       
    35     unicode = unicode  # noqa: F821
       
    36 else:
       
    37     from datetime import timezone
       
    38 
       
    39     def byte_as_integer(bytestr):
       
    40         return bytestr[0]
       
    41 
       
    42     def as_unicode(string):
       
    43         return string
       
    44 
       
    45     def iteritems(self):
       
    46         return self.items()
       
    47 
       
    48     xrange = range
       
    49     long = int
       
    50     unicode = str
       
    51     bytes_from_list = bytes
       
    52 
       
    53 
       
    54 if sys.version_info.major >= 3 and sys.version_info.minor >= 6:
       
    55     # Python 3.6 added 16 bit floating point to struct
       
    56 
       
    57     def pack_float16(value):
       
    58         try:
       
    59             return struct.pack('>Be', 0xf9, value)
       
    60         except OverflowError:
       
    61             return False
       
    62 
       
    63     def unpack_float16(payload):
       
    64         return struct.unpack('>e', payload)[0]
       
    65 else:
       
    66     def pack_float16(value):
       
    67         # Based on node-cbor by hildjj
       
    68         # which was based in turn on Carsten Borman's cn-cbor
       
    69         u32 = struct.pack('>f', value)
       
    70         u = struct.unpack('>I', u32)[0]
       
    71 
       
    72         if u & 0x1FFF != 0:
       
    73             return False
       
    74 
       
    75         s16 = (u >> 16) & 0x8000
       
    76         exponent = (u >> 23) & 0xff
       
    77         mantissa = u & 0x7fffff
       
    78 
       
    79         if 113 <= exponent <= 142:
       
    80             s16 += ((exponent - 112) << 10) + (mantissa >> 13)
       
    81         elif 103 <= exponent < 113:
       
    82             if mantissa & ((1 << (126 - exponent)) - 1):
       
    83                 return False
       
    84 
       
    85             s16 += ((mantissa + 0x800000) >> (126 - exponent))
       
    86         else:
       
    87             return False
       
    88 
       
    89         return struct.pack('>BH', 0xf9, s16)
       
    90 
       
    91     def unpack_float16(payload):
       
    92         # Code adapted from RFC 7049, appendix D
       
    93         def decode_single(single):
       
    94             return struct.unpack("!f", struct.pack("!I", single))[0]
       
    95 
       
    96         payload = struct.unpack('>H', payload)[0]
       
    97         value = (payload & 0x7fff) << 13 | (payload & 0x8000) << 16
       
    98         if payload & 0x7c00 != 0x7c00:
       
    99             return ldexp(decode_single(value), 112)
       
   100 
       
   101         return decode_single(value | 0x7f800000)