OLD | NEW |
(Empty) | |
| 1 # -*- coding: utf-8 -*- |
| 2 # |
| 3 # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> |
| 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at |
| 8 # |
| 9 # https://www.apache.org/licenses/LICENSE-2.0 |
| 10 # |
| 11 # Unless required by applicable law or agreed to in writing, software |
| 12 # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 # See the License for the specific language governing permissions and |
| 15 # limitations under the License. |
| 16 |
| 17 """Python compatibility wrappers.""" |
| 18 |
| 19 from __future__ import absolute_import |
| 20 |
| 21 import sys |
| 22 from struct import pack |
| 23 |
| 24 try: |
| 25 MAX_INT = sys.maxsize |
| 26 except AttributeError: |
| 27 MAX_INT = sys.maxint |
| 28 |
| 29 MAX_INT64 = (1 << 63) - 1 |
| 30 MAX_INT32 = (1 << 31) - 1 |
| 31 MAX_INT16 = (1 << 15) - 1 |
| 32 |
| 33 # Determine the word size of the processor. |
| 34 if MAX_INT == MAX_INT64: |
| 35 # 64-bit processor. |
| 36 MACHINE_WORD_SIZE = 64 |
| 37 elif MAX_INT == MAX_INT32: |
| 38 # 32-bit processor. |
| 39 MACHINE_WORD_SIZE = 32 |
| 40 else: |
| 41 # Else we just assume 64-bit processor keeping up with modern times. |
| 42 MACHINE_WORD_SIZE = 64 |
| 43 |
| 44 try: |
| 45 # < Python3 |
| 46 unicode_type = unicode |
| 47 except NameError: |
| 48 # Python3. |
| 49 unicode_type = str |
| 50 |
| 51 # Fake byte literals. |
| 52 if str is unicode_type: |
| 53 def byte_literal(s): |
| 54 return s.encode('latin1') |
| 55 else: |
| 56 def byte_literal(s): |
| 57 return s |
| 58 |
| 59 # ``long`` is no more. Do type detection using this instead. |
| 60 try: |
| 61 integer_types = (int, long) |
| 62 except NameError: |
| 63 integer_types = (int,) |
| 64 |
| 65 b = byte_literal |
| 66 |
| 67 # To avoid calling b() multiple times in tight loops. |
| 68 ZERO_BYTE = b('\x00') |
| 69 EMPTY_BYTE = b('') |
| 70 |
| 71 |
| 72 def is_bytes(obj): |
| 73 """ |
| 74 Determines whether the given value is a byte string. |
| 75 |
| 76 :param obj: |
| 77 The value to test. |
| 78 :returns: |
| 79 ``True`` if ``value`` is a byte string; ``False`` otherwise. |
| 80 """ |
| 81 return isinstance(obj, bytes) |
| 82 |
| 83 |
| 84 def is_integer(obj): |
| 85 """ |
| 86 Determines whether the given value is an integer. |
| 87 |
| 88 :param obj: |
| 89 The value to test. |
| 90 :returns: |
| 91 ``True`` if ``value`` is an integer; ``False`` otherwise. |
| 92 """ |
| 93 return isinstance(obj, integer_types) |
| 94 |
| 95 |
| 96 def byte(num): |
| 97 """ |
| 98 Converts a number between 0 and 255 (both inclusive) to a base-256 (byte) |
| 99 representation. |
| 100 |
| 101 Use it as a replacement for ``chr`` where you are expecting a byte |
| 102 because this will work on all current versions of Python:: |
| 103 |
| 104 :param num: |
| 105 An unsigned integer between 0 and 255 (both inclusive). |
| 106 :returns: |
| 107 A single byte. |
| 108 """ |
| 109 return pack("B", num) |
| 110 |
| 111 |
| 112 def get_word_alignment(num, force_arch=64, |
| 113 _machine_word_size=MACHINE_WORD_SIZE): |
| 114 """ |
| 115 Returns alignment details for the given number based on the platform |
| 116 Python is running on. |
| 117 |
| 118 :param num: |
| 119 Unsigned integral number. |
| 120 :param force_arch: |
| 121 If you don't want to use 64-bit unsigned chunks, set this to |
| 122 anything other than 64. 32-bit chunks will be preferred then. |
| 123 Default 64 will be used when on a 64-bit machine. |
| 124 :param _machine_word_size: |
| 125 (Internal) The machine word size used for alignment. |
| 126 :returns: |
| 127 4-tuple:: |
| 128 |
| 129 (word_bits, word_bytes, |
| 130 max_uint, packing_format_type) |
| 131 """ |
| 132 max_uint64 = 0xffffffffffffffff |
| 133 max_uint32 = 0xffffffff |
| 134 max_uint16 = 0xffff |
| 135 max_uint8 = 0xff |
| 136 |
| 137 if force_arch == 64 and _machine_word_size >= 64 and num > max_uint32: |
| 138 # 64-bit unsigned integer. |
| 139 return 64, 8, max_uint64, "Q" |
| 140 elif num > max_uint16: |
| 141 # 32-bit unsigned integer |
| 142 return 32, 4, max_uint32, "L" |
| 143 elif num > max_uint8: |
| 144 # 16-bit unsigned integer. |
| 145 return 16, 2, max_uint16, "H" |
| 146 else: |
| 147 # 8-bit unsigned integer. |
| 148 return 8, 1, max_uint8, "B" |
OLD | NEW |