• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
15import collections
16import struct
17
18from . import packer
19
20
21# For reference, see:
22# https://docs.python.org/2/library/ctypes.html#ctypes-fundamental-data-types-2
23
24# These classes could be collections.namedtuple instances, but those are new
25# in 2.6 and we want to work towards 2.5 compatability.
26
27class BoolFlags(object):
28    bytewidth = 1
29    min_val = False
30    max_val = True
31    py_type = bool
32    name = "bool"
33    packer_type = packer.boolean
34
35
36class Uint8Flags(object):
37    bytewidth = 1
38    min_val = 0
39    max_val = (2**8) - 1
40    py_type = int
41    name = "uint8"
42    packer_type = packer.uint8
43
44
45class Uint16Flags(object):
46    bytewidth = 2
47    min_val = 0
48    max_val = (2**16) - 1
49    py_type = int
50    name = "uint16"
51    packer_type = packer.uint16
52
53
54class Uint32Flags(object):
55    bytewidth = 4
56    min_val = 0
57    max_val = (2**32) - 1
58    py_type = int
59    name = "uint32"
60    packer_type = packer.uint32
61
62
63class Uint64Flags(object):
64    bytewidth = 8
65    min_val = 0
66    max_val = (2**64) - 1
67    py_type = int
68    name = "uint64"
69    packer_type = packer.uint64
70
71
72class Int8Flags(object):
73    bytewidth = 1
74    min_val = -(2**7)
75    max_val = (2**7) - 1
76    py_type = int
77    name = "int8"
78    packer_type = packer.int8
79
80
81class Int16Flags(object):
82    bytewidth = 2
83    min_val = -(2**15)
84    max_val = (2**15) - 1
85    py_type = int
86    name = "int16"
87    packer_type = packer.int16
88
89
90class Int32Flags(object):
91    bytewidth = 4
92    min_val = -(2**31)
93    max_val = (2**31) - 1
94    py_type = int
95    name = "int32"
96    packer_type = packer.int32
97
98
99class Int64Flags(object):
100    bytewidth = 8
101    min_val = -(2**63)
102    max_val = (2**63) - 1
103    py_type = int
104    name = "int64"
105    packer_type = packer.int64
106
107
108class Float32Flags(object):
109    bytewidth = 4
110    min_val = None
111    max_val = None
112    py_type = float
113    name = "float32"
114    packer_type = packer.float32
115
116
117class Float64Flags(object):
118    bytewidth = 8
119    min_val = None
120    max_val = None
121    py_type = float
122    name = "float64"
123    packer_type = packer.float64
124
125
126class SOffsetTFlags(Int32Flags):
127    pass
128
129
130class UOffsetTFlags(Uint32Flags):
131    pass
132
133
134class VOffsetTFlags(Uint16Flags):
135    pass
136
137
138def valid_number(n, flags):
139    if flags.min_val is None and flags.max_val is None:
140        return True
141    return flags.min_val <= n <= flags.max_val
142
143
144def enforce_number(n, flags):
145    if flags.min_val is None and flags.max_val is None:
146        return
147    if not flags.min_val <= n <= flags.max_val:
148        raise TypeError("bad number %s for type %s" % (str(n), flags.name))
149
150
151def float32_to_uint32(n):
152    packed = struct.pack("<1f", n)
153    (converted,) = struct.unpack("<1L", packed)
154    return converted
155
156
157def uint32_to_float32(n):
158    packed = struct.pack("<1L", n)
159    (unpacked,) = struct.unpack("<1f", packed)
160    return unpacked
161
162
163def float64_to_uint64(n):
164    packed = struct.pack("<1d", n)
165    (converted,) = struct.unpack("<1Q", packed)
166    return converted
167
168
169def uint64_to_float64(n):
170    packed = struct.pack("<1Q", n)
171    (unpacked,) = struct.unpack("<1d", packed)
172    return unpacked
173