Home | History | Annotate | Download | only in flatbuffers
      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