1 # Copyright 2014 Google Inc. All rights reserved. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 import collections 16 import struct 17 18 from . import packer 19 from .compat import import_numpy, NumpyRequiredForThisFeature 20 21 np = import_numpy() 22 23 # For reference, see: 24 # https://docs.python.org/2/library/ctypes.html#ctypes-fundamental-data-types-2 25 26 # These classes could be collections.namedtuple instances, but those are new 27 # in 2.6 and we want to work towards 2.5 compatability. 28 29 class BoolFlags(object): 30 bytewidth = 1 31 min_val = False 32 max_val = True 33 py_type = bool 34 name = "bool" 35 packer_type = packer.boolean 36 37 38 class Uint8Flags(object): 39 bytewidth = 1 40 min_val = 0 41 max_val = (2**8) - 1 42 py_type = int 43 name = "uint8" 44 packer_type = packer.uint8 45 46 47 class Uint16Flags(object): 48 bytewidth = 2 49 min_val = 0 50 max_val = (2**16) - 1 51 py_type = int 52 name = "uint16" 53 packer_type = packer.uint16 54 55 56 class Uint32Flags(object): 57 bytewidth = 4 58 min_val = 0 59 max_val = (2**32) - 1 60 py_type = int 61 name = "uint32" 62 packer_type = packer.uint32 63 64 65 class Uint64Flags(object): 66 bytewidth = 8 67 min_val = 0 68 max_val = (2**64) - 1 69 py_type = int 70 name = "uint64" 71 packer_type = packer.uint64 72 73 74 class Int8Flags(object): 75 bytewidth = 1 76 min_val = -(2**7) 77 max_val = (2**7) - 1 78 py_type = int 79 name = "int8" 80 packer_type = packer.int8 81 82 83 class Int16Flags(object): 84 bytewidth = 2 85 min_val = -(2**15) 86 max_val = (2**15) - 1 87 py_type = int 88 name = "int16" 89 packer_type = packer.int16 90 91 92 class Int32Flags(object): 93 bytewidth = 4 94 min_val = -(2**31) 95 max_val = (2**31) - 1 96 py_type = int 97 name = "int32" 98 packer_type = packer.int32 99 100 101 class Int64Flags(object): 102 bytewidth = 8 103 min_val = -(2**63) 104 max_val = (2**63) - 1 105 py_type = int 106 name = "int64" 107 packer_type = packer.int64 108 109 110 class Float32Flags(object): 111 bytewidth = 4 112 min_val = None 113 max_val = None 114 py_type = float 115 name = "float32" 116 packer_type = packer.float32 117 118 119 class Float64Flags(object): 120 bytewidth = 8 121 min_val = None 122 max_val = None 123 py_type = float 124 name = "float64" 125 packer_type = packer.float64 126 127 128 class SOffsetTFlags(Int32Flags): 129 pass 130 131 132 class UOffsetTFlags(Uint32Flags): 133 pass 134 135 136 class VOffsetTFlags(Uint16Flags): 137 pass 138 139 140 def valid_number(n, flags): 141 if flags.min_val is None and flags.max_val is None: 142 return True 143 return flags.min_val <= n <= flags.max_val 144 145 146 def enforce_number(n, flags): 147 if flags.min_val is None and flags.max_val is None: 148 return 149 if not flags.min_val <= n <= flags.max_val: 150 raise TypeError("bad number %s for type %s" % (str(n), flags.name)) 151 152 153 def float32_to_uint32(n): 154 packed = struct.pack("<1f", n) 155 (converted,) = struct.unpack("<1L", packed) 156 return converted 157 158 159 def uint32_to_float32(n): 160 packed = struct.pack("<1L", n) 161 (unpacked,) = struct.unpack("<1f", packed) 162 return unpacked 163 164 165 def float64_to_uint64(n): 166 packed = struct.pack("<1d", n) 167 (converted,) = struct.unpack("<1Q", packed) 168 return converted 169 170 171 def uint64_to_float64(n): 172 packed = struct.pack("<1Q", n) 173 (unpacked,) = struct.unpack("<1d", packed) 174 return unpacked 175 176 177 def to_numpy_type(number_type): 178 if np is not None: 179 return np.dtype(number_type.name).newbyteorder('<') 180 else: 181 raise NumpyRequiredForThisFeature('Numpy was not found.') 182