HTD

Merge lp:~ahayzen/htd/31.fix.1059893 into lp:htd/3.1

Proposed by Andrew Hayzen
Status: Merged
Approved by: Andrew Hayzen
Approved revision: 25
Merged at revision: 25
Proposed branch: lp:~ahayzen/htd/31.fix.1059893
Merge into: lp:htd/3.1
Diff against target: 474 lines (+307/-68)
1 file modified
htd31/_base/types.py (+307/-68)
To merge this branch: bzr merge lp:~ahayzen/htd/31.fix.1059893
Reviewer Review Type Date Requested Status
Andrew Hayzen Approve
Review via email: mp+127872@code.launchpad.net

Description of the change

Data Types retain ordering

To post a comment you must log in.
Revision history for this message
Andrew Hayzen (ahayzen) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'htd31/_base/types.py'
2--- htd31/_base/types.py 2012-08-13 20:06:11 +0000
3+++ htd31/_base/types.py 2012-10-03 20:46:22 +0000
4@@ -35,6 +35,20 @@
5 reg_dtype = Register.register_dtype # Register dtypes
6
7
8+if sys.version_info < (3, 0):
9+ char = chr
10+else:
11+ def char(data):
12+ return chr(int(data)).encode("ISO-8859-1")
13+
14+
15+if sys.version_info < (3, 0):
16+ ordi = ord
17+else:
18+ def ordi(raw):
19+ return raw
20+
21+
22 #--------------------------------------------------------------- Raw data types
23 class BOOL(DType):
24 idn = b"\x01"
25@@ -167,80 +181,141 @@
26
27
28 #------------------------------------------------------------ Number data types
29-class NumBase(DType):
30+class BYTE(DType):
31 can_range = True
32-
33- def sanitise(self, real):
34- return pack(self._c, real)
35-
36- def unsanitise(self, raw):
37- return unpack(self._c, raw)[0]
38-
39-
40-class BYTE(NumBase):
41 idn = b"\x0f"
42- _c = "b"
43- can_range = True
44 size = 1
45
46+ def sanitise(self, real):
47+ return char(real + 128)
48+
49 def type_check(self, real):
50 return type(real) is int
51
52-
53-class UBYTE(NumBase):
54+ def unsanitise(self, raw):
55+ return ordi(raw) - 128
56+
57+
58+class UBYTE(DType):
59+ can_range = True
60 idn = b"\x10"
61- _c = "B"
62- can_range = True
63 size = 1
64
65+ def sanitise(self, real):
66+ return char(real)
67+
68 def type_check(self, real):
69 return type(real) is int
70
71-
72-class SHORT(NumBase):
73+ def unsanitise(self, raw):
74+ return ordi(raw)
75+
76+
77+class SHORT(DType):
78+ can_range = True
79 idn = b"\x11"
80- _c = "h"
81- can_range = True
82 size = 2
83
84+ def sanitise(self, real):
85+ real += 32768
86+
87+ a, b = divmod(real, 256)
88+
89+ return b"".join([char(a), char(b)])
90+
91 def type_check(self, real):
92 return type(real) is int
93
94-
95-class USHORT(NumBase):
96+ def unsanitise(self, raw):
97+ a, b = raw
98+
99+ return (ordi(a) * 256 + ordi(b)) - 32768
100+
101+
102+class USHORT(DType):
103+ can_range = True
104 idn = b"\x12"
105- _c = "H"
106- can_range = True
107 size = 2
108
109+ def sanitise(self, real):
110+ a, b = divmod(real, 256)
111+
112+ return b"".join([char(a), char(b)])
113+
114 def type_check(self, real):
115 return type(real) is int
116
117-
118-class INTEGER(NumBase):
119+ def unsanitise(self, raw):
120+ a, b = raw
121+
122+ return (ordi(a) * 256) + ordi(b)
123+
124+
125+class INTEGER():
126+ can_range = True
127 idn = b"\x13"
128- _c = "i"
129- can_range = True
130 size = 4
131
132+ def sanitise(self, real):
133+ real += 2147483648
134+
135+ a, real = divmod(real, 256 ** 3)
136+ b, real = divmod(real, 256 ** 2)
137+ c, d = divmod(real, 256)
138+
139+ return b"".join([char(a), char(b), char(c), char(d)])
140+
141 def type_check(self, real):
142 return type(real) is int
143
144-
145-class UINTEGER(NumBase):
146+ def unsanitise(self, raw):
147+ a, b, c, d = raw
148+
149+ return ((ordi(a) * 256 ** 3) + (ordi(b) * 256 ** 2) +
150+ (ordi(c) * 256) + ordi(d) - 2147483648)
151+
152+
153+class UINTEGER(DType):
154+ can_range = True
155 idn = b"\x14"
156- _c = "I"
157 size = 4
158
159+ def sanitise(self, real):
160+ a, real = divmod(real, 256 ** 3)
161+ b, real = divmod(real, 256 ** 2)
162+ c, d = divmod(real, 256)
163+
164+ return b"".join([char(a), char(b), char(c), char(d)])
165+
166 def type_check(self, real):
167 return type(real) is int
168
169-
170-class LONG(NumBase):
171+ def unsanitise(self, raw):
172+ a, b, c, d = raw
173+
174+ return ((ordi(a) * 256 ** 3) + (ordi(b) * 256 ** 2) +
175+ (ordi(c) * 256) + d)
176+
177+
178+class LONG():
179+ can_range = True
180 idn = b"\x15"
181- _c = "q"
182 size = 8
183
184+ def sanitise(self, real):
185+ real += 9223372036854775808
186+
187+ a, real = divmod(real, 256 ** 7)
188+ b, real = divmod(real, 256 ** 6)
189+ c, real = divmod(real, 256 ** 5)
190+ d, real = divmod(real, 256 ** 4)
191+ e, real = divmod(real, 256 ** 3)
192+ f, real = divmod(real, 256 ** 2)
193+ g, h = divmod(real, 256)
194+
195+ return b"".join([char(a), char(b), char(c), char(d), char(e), char(f),
196+ char(g), char(h)])
197+
198 if sys.version_info < (3, 0):
199 def type_check(self, real):
200 return type(real) is long
201@@ -248,12 +323,32 @@
202 def type_check(self, real):
203 return type(real) is int
204
205-
206-class ULONG(NumBase):
207+ def unsanitise(self, raw):
208+ a, b, c, d, e, f, g, h = raw
209+
210+ return ((ordi(a) * 256 ** 7) + (ordi(b) * 256 ** 6) +
211+ (ordi(c) * 256 ** 5) + (ordi(d) * 256 ** 4) +
212+ (ordi(e) * 256 ** 3) + (ordi(f) * 256 ** 2) +
213+ (ordi(g) * 256) + ordi(h)) - 9223372036854775808
214+
215+
216+class ULONG():
217+ can_range = True
218 idn = b"\x16"
219- _c = "Q"
220 size = 8
221
222+ def sanitise(self, real):
223+ a, real = divmod(real, 256 ** 7)
224+ b, real = divmod(real, 256 ** 6)
225+ c, real = divmod(real, 256 ** 5)
226+ d, real = divmod(real, 256 ** 4)
227+ e, real = divmod(real, 256 ** 3)
228+ f, real = divmod(real, 256 ** 2)
229+ g, h = divmod(real, 256)
230+
231+ return b"".join([char(a), char(b), char(c), char(d), char(e), char(f),
232+ char(g), char(h)])
233+
234 if sys.version_info < (3, 0):
235 def type_check(self, real):
236 return type(real) is long
237@@ -261,24 +356,180 @@
238 def type_check(self, real):
239 return type(real) is int
240
241-
242-class FLOAT(NumBase):
243+ def unsanitise(self, raw):
244+ a, b, c, d, e, f, g, h = raw
245+
246+ return ((ordi(a) * 256 ** 7) + (ordi(b) * 256 ** 6) +
247+ (ordi(c) * 256 ** 5) + (ordi(d) * 256 ** 4) +
248+ (ordi(e) * 256 ** 3) + (ordi(f) * 256 ** 2) +
249+ (ordi(g) * 256) + ordi(h))
250+
251+
252+#------------------------------------------------------- Float helper functions
253+def float_sanitise(real):
254+ raw = str(abs(real))
255+
256+ if "e" in raw:
257+ raw, ex = raw.split("e")
258+ ex = char(int(ex) + 127)
259+ else:
260+ ex = False
261+
262+ if "." in raw:
263+ ex = 0
264+ d = False
265+
266+ for i in raw:
267+ if i not in ["0", "."]:
268+ d = True
269+
270+ if i != "." and d:
271+ ex += 1
272+
273+ if (i == "." or ex < 0) and d:
274+ break
275+
276+ if i in [".", "0"] and not d:
277+ ex -= 1
278+
279+ if real < 0:
280+ if ex < 0:
281+ ex = 255 + ex
282+ else:
283+ ex = 127 - ex
284+ else:
285+ ex += 127
286+
287+ ex = char(ex)
288+ w, d = raw.split(".")
289+ else:
290+ w = raw
291+ d = ""
292+
293+ n = "".join([w, d]).lstrip("0")[:9]
294+ n = n.ljust(9, "0")
295+ n = int(n)
296+
297+ # Convert to negative offset
298+ if real < 0:
299+ n = -n
300+ neg = b"\x00"
301+ else:
302+ neg = b"\x01"
303+
304+ return n, neg, ex
305+
306+
307+def float_unsanitise(n, neg, ex):
308+ # Calc exponent
309+ if neg == 0:
310+ if ex > 128:
311+ ex -= 255
312+ else:
313+ ex = 127 - ex
314+ else:
315+ ex -= 127
316+
317+ n = list(str(n))
318+
319+ # Build exp and data
320+ if neg == 0:
321+ off = 1
322+ else:
323+ off = 0
324+
325+ if ex < 0:
326+ for _ in range(0, abs(ex)):
327+ n.insert(off, "0")
328+
329+ n.insert(abs(ex) + off, ".")
330+ elif ex > 0:
331+ while len(n) + off < ex:
332+ n.append("0")
333+
334+ n.insert(ex + off, ".")
335+
336+ return float("".join(n))
337+
338+
339+class FLOAT(DType):
340+ can_range = True
341 idn = b"\x1e"
342- _c = "f"
343- size = 4
344+ size = 6
345+
346+ def sanitise(self, real):
347+ if real == 0.0:
348+ return b"\x01\x00\x00\x00\x00\x00"
349+
350+ # Convert to raw int
351+ n, neg, ex = float_sanitise(real)
352+
353+ # Convert to hex
354+ n += 2147483648
355+
356+ a, n = divmod(n, 256 ** 3)
357+ b, n = divmod(n, 256 ** 2)
358+ c, d = divmod(n, 256)
359+
360+ return b"".join([neg, ex, char(a), char(b), char(c), char(d)])
361
362 def type_check(self, real):
363 return type(real) is float
364
365-
366-class DFLOAT(NumBase):
367+ def unsanitise(self, raw):
368+ if raw == b"\x01\x00\x00\x00\x00\x00":
369+ return 0.0
370+
371+ neg, ex, a, b, c, d = raw
372+
373+ n = ((ordi(a) * 256 ** 3) + (ordi(b) * 256 ** 2) + (ordi(c) * 256) +
374+ ordi(d) - 2147483648)
375+
376+ return float_unsanitise(n, ordi(neg), ordi(ex))
377+
378+
379+class DFLOAT(DType):
380+ can_range = True
381 idn = b"\x1f"
382- _c = "d"
383 size = 8
384
385+ def sanitise(self, real):
386+ if real == 0.0:
387+ return b"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
388+
389+ # Convert to raw int
390+ n, neg, ex = float_sanitise(real)
391+
392+ # Convert to hex
393+ n += 9223372036854775808
394+
395+ a, n = divmod(n, 256 ** 7)
396+ b, n = divmod(n, 256 ** 6)
397+ c, n = divmod(n, 256 ** 5)
398+ d, n = divmod(n, 256 ** 4)
399+ e, n = divmod(n, 256 ** 3)
400+ f, n = divmod(n, 256 ** 2)
401+ g, h = divmod(n, 256)
402+
403+ return b"".join([neg, ex, char(a), char(b), char(c), char(d), char(e),
404+ char(f), char(g), char(h)])
405+
406 def type_check(self, real):
407 return type(real) is float
408
409+ def unsanitise(self, raw):
410+ if raw == b"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00":
411+ return 0.0
412+
413+ neg, ex, a, b, c, d, e, f, g, h = raw
414+
415+ n = ((ordi(a) * 256 ** 7) + (ordi(b) * 256 ** 6) +
416+ (ordi(c) * 256 ** 5) + (ordi(d) * 256 ** 4) +
417+ (ordi(e) * 256 ** 3) + (ordi(f) * 256 ** 2) +
418+ (ordi(g) * 256) + ordi(h)) - 9223372036854775808
419+
420+ return float_unsanitise(n, ordi(neg), ordi(ex))
421+
422
423 reg_dtype(BYTE)
424 reg_dtype(UBYTE)
425@@ -356,8 +607,8 @@
426 x = getattr(DataType, Register.dtype_codes[ty])
427 if isinstance(x, PRESERVE) is False and x.type_check(real):
428 try:
429- tmp = b"".join([x.sanitise(real), ty])
430- except struct_error:
431+ tmp = b"".join([ty, x.sanitise(real)])
432+ except (ValueError, OverflowError, struct_error):
433 continue
434 else:
435 return tmp
436@@ -374,28 +625,16 @@
437
438 return False
439
440- if sys.version_info < (3, 0):
441- def unsanitise(self, raw):
442- ty = raw[-1]
443- raw = raw[:-1]
444-
445- if ty in Register.dtype_codes:
446- x = getattr(DataType, Register.dtype_codes[ty])
447- else:
448- raise TypeError("Could not restore type.")
449-
450- return x.unsanitise(raw)
451- else:
452- def unsanitise(self, raw):
453- ty = chr(raw[-1]).encode("ISO-8859-1")
454- raw = raw[:-1]
455-
456- if ty in Register.dtype_codes:
457- x = getattr(DataType, Register.dtype_codes[ty])
458- else:
459- raise TypeError("Could not restore type.")
460-
461- return x.unsanitise(raw)
462+ def unsanitise(self, raw):
463+ ty = char(raw[0])
464+ raw = raw[1:]
465+
466+ if ty in Register.dtype_codes:
467+ x = getattr(DataType, Register.dtype_codes[ty])
468+ else:
469+ raise TypeError("Could not restore type.")
470+
471+ return x.unsanitise(raw)
472
473
474 reg_dtype(PRESERVE)

Subscribers

People subscribed via source and target branches

to all changes: