PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/source/library/Interlace.Pinch/InterlacePython/pinch.py

https://bitbucket.org/VahidN/interlace
Python | 862 lines | 815 code | 21 blank | 26 comment | 4 complexity | 67d4d3b00a97d17beeaea14f3f47f3b9 MD5 | raw file
  1. # Copyright (c) 2007-2012, Computer Consultancy Pty Ltd
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions are met:
  6. # * Redistributions of source code must retain the above copyright
  7. # notice, this list of conditions and the following disclaimer.
  8. # * Redistributions in binary form must reproduce the above copyright
  9. # notice, this list of conditions and the following disclaimer in the
  10. # documentation and/or other materials provided with the distribution.
  11. # * Neither the name of the Computer Consultancy Pty Ltd nor the
  12. # names of its contributors may be used to endorse or promote products
  13. # derived from this software without specific prior written permission.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. # ARE DISCLAIMED. IN NO EVENT SHALL COMPUTER CONSULTANCY PTY LTD BE LIABLE
  19. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  25. # DAMAGE.
  26. import struct, os, cStringIO
  27. PACKED_BYTE_KIND_MASK = 0xc0
  28. PACKED_BYTE_VALUE_MASK = 0x3f
  29. PACKED_SEQUENCE_BYTE = 0xc0
  30. PACKED_PRIMATIVE_BUFFER_BYTE = 0x80
  31. PACKED_PRIMATIVE_ORDINAL_BYTE = 0x40
  32. TAGGED_SEQUENCE_BYTE = 0x03
  33. TAGGED_PRIMATIVE_BUFFER_BYTE = 0x02
  34. TAGGED_PRIMATIVE_ORDINAL_BYTE = 0x01
  35. TAGGED_CHOICE_BYTE = 0x04
  36. NULL = 0x00
  37. TOKEN_SEQUENCE = 1 # The argument is the number of tokens in the sequence, which must then be read.
  38. TOKEN_PRIMITIVE_BUFFER = 2 # The argument is the number of bytes that follow in the buffer.
  39. TOKEN_PRIMITIVE_PACKED_ORDINAL = 3 # The argument is the ordinal value; nothing needs to be read.
  40. TOKEN_PRIMITIVE_TAGGED_ORDINAL = 4 # No argument; the ordinal value must be read.
  41. TOKEN_CHOICE = 5 # The value kind is the argument; the structure follows.
  42. TOKEN_NULL = 6 # No argument and nothing to read after.
  43. class PinchException(Exception):
  44. pass
  45. class PinchEndOfStreamException(PinchException):
  46. pass
  47. class PinchInvalidCodingException(PinchException):
  48. pass
  49. class PinchNullRequiredFieldException(PinchException):
  50. pass
  51. class PinchInvalidFieldTypeException(PinchException):
  52. pass
  53. class PinchDecodingContext(object):
  54. pass
  55. class PinchDecimal(object):
  56. def __init__(self, sign, digits, exponent):
  57. self.sign = sign
  58. self.digits = digits
  59. self.exponent = exponent
  60. def __eq__(self, rhs):
  61. if not isinstance(rhs, PinchDecimal): return False
  62. return \
  63. self.sign == rhs.sign and \
  64. self.digits == rhs.digits and \
  65. self.exponent == rhs.exponent
  66. class PinchDecoder(object):
  67. def __init__(self, file):
  68. self._file = file
  69. self._file_can_seek = True
  70. self._read_required = True
  71. self._read_token_kind = None
  72. self._read_token_argument = None
  73. # Decoding Primitives:
  74. def _read_token_internal(self):
  75. read_byte = self._file.read(1)
  76. if read_byte == "": raise PinchEndOfStreamException()
  77. token_byte = ord(read_byte)
  78. masked_token_byte = token_byte & PACKED_BYTE_KIND_MASK
  79. if masked_token_byte == PACKED_PRIMATIVE_ORDINAL_BYTE:
  80. self._read_token_kind = TOKEN_PRIMITIVE_PACKED_ORDINAL
  81. self._read_token_argument = token_byte & PACKED_BYTE_VALUE_MASK
  82. elif masked_token_byte == PACKED_PRIMATIVE_BUFFER_BYTE:
  83. self._read_token_kind = TOKEN_PRIMITIVE_BUFFER
  84. self._read_token_argument = token_byte & PACKED_BYTE_VALUE_MASK
  85. elif masked_token_byte == PACKED_SEQUENCE_BYTE:
  86. self._read_token_kind = TOKEN_SEQUENCE
  87. self._read_token_argument = token_byte & PACKED_BYTE_VALUE_MASK
  88. elif token_byte == NULL:
  89. self._read_token_kind = TOKEN_NULL
  90. self._read_token_argument = None
  91. elif token_byte == TAGGED_PRIMATIVE_ORDINAL_BYTE:
  92. self._read_token_kind = TOKEN_PRIMITIVE_TAGGED_ORDINAL
  93. self._read_token_argument = None
  94. elif token_byte == TAGGED_PRIMATIVE_BUFFER_BYTE:
  95. self._read_token_kind = TOKEN_PRIMITIVE_BUFFER
  96. self._read_token_argument = self.read_unsigned_tag()
  97. elif token_byte == TAGGED_SEQUENCE_BYTE:
  98. self._read_token_kind = TOKEN_SEQUENCE
  99. self._read_token_argument = self.read_unsigned_tag()
  100. elif token_byte == TAGGED_CHOICE_BYTE:
  101. self._read_token_kind = TOKEN_CHOICE
  102. self._read_token_argument = self.read_unsigned_tag()
  103. def _peek_token(self):
  104. if self._read_required: self._read_token_internal()
  105. self._read_required = False
  106. return self._read_token_kind
  107. def _read_token(self):
  108. if self._read_required: self._read_token_internal()
  109. self._read_required = True
  110. return self._read_token_kind
  111. # Decoding Utilities:
  112. def _read_bytes(self, count):
  113. bytes = self._file.read(count)
  114. if len(bytes) < count: raise PinchEndOfStreamException()
  115. return bytes
  116. def _skip_bytes(self, count):
  117. if count > 32 and self._file_can_seek:
  118. try:
  119. self._file.seek(count, os.SEEK_CUR)
  120. return
  121. except IOError:
  122. self._file_can_seek = False
  123. total_read = 0
  124. while total_read < count:
  125. read = self._read_bytes(min(count, 1024))
  126. total_read += len(read)
  127. def _read_unsigned_tag(self):
  128. shift = 0
  129. tag = 0
  130. while True:
  131. read_byte = self._file.read(1)
  132. if read_byte == "": raise PinchEndOfStreamException()
  133. read_byte = ord(read_byte)
  134. if shift == 28:
  135. if read_byte & 0x70: raise PinchInvalidCodingException()
  136. if read_byte & 0x08: tag = long(tag)
  137. elif shift > 28: raise PinchInvalidCodingException()
  138. tag |= (read_byte & 0x7f) << shift
  139. shift += 7
  140. if (read_byte & 0x80) == 0: break
  141. return tag
  142. def _read_signed_tag(self):
  143. shift = 0
  144. tag = 0
  145. while True:
  146. read_byte = self._file.read(1)
  147. if read_byte == "": raise PinchEndOfStreamException()
  148. read_byte = ord(read_byte)
  149. if shift == 28:
  150. if read_byte & 0x70: raise PinchInvalidCodingException()
  151. if read_byte & 0x08: tag = long(tag)
  152. elif shift > 28: raise PinchInvalidCodingException()
  153. tag |= (read_byte & 0x7f) << shift
  154. shift += 7
  155. if (read_byte & 0x80) == 0: break
  156. if tag & 1:
  157. return int(-(tag >> 1) - 1)
  158. else:
  159. return int(tag >> 1)
  160. def _read_signed_long_tag(self):
  161. shift = 0
  162. tag = 0L
  163. while True:
  164. read_byte = self._file.read(1)
  165. if read_byte == "": raise PinchEndOfStreamException()
  166. read_byte = ord(read_byte)
  167. if shift == 63:
  168. if read_byte & 0x7e: raise PinchInvalidCodingException()
  169. elif shift > 63: raise PinchInvalidCodingException()
  170. tag |= (read_byte & 0x7f) << shift
  171. shift += 7
  172. if (read_byte & 0x80) == 0: break
  173. if tag & 1:
  174. return -(tag >> 1) - 1
  175. else:
  176. return tag >> 1
  177. def _skip_tag(self):
  178. while True:
  179. read_byte = self._file.read(1)
  180. if read_byte == "": raise PinchEndOfStreamException()
  181. if (ord(read_byte) & 0x80) == 0: break
  182. def _read_decimal(self): # decimal
  183. # Read the buffer token and length, ensuring it has enough bytes to be valid:
  184. token = self._read_token()
  185. if token != TOKEN_PRIMITIVE_BUFFER or self._read_token_argument < 2:
  186. raise PinchInvalidCodingException()
  187. bytes = self._read_bytes(self._read_token_argument)
  188. exponent = ord(bytes[0])
  189. is_negative = (ord(bytes[1]) & 0x80) != 0
  190. buffer_length = self._read_token_argument
  191. buffer_used = 2
  192. shift = 0
  193. value = 0L
  194. while buffer_used != buffer_length:
  195. read_byte = ord(bytes[buffer_used])
  196. buffer_used += 1
  197. value |= read_byte << shift
  198. shift += 8
  199. return PinchDecimal(is_negative, value, exponent)
  200. # Decoding Assistants:
  201. def _read_primitive_buffer(self):
  202. token = self._read_token()
  203. if token != TOKEN_PRIMITIVE_BUFFER: raise PinchInvalidCodingException()
  204. return self._read_bytes(self._read_token_argument)
  205. def _read_primitive_buffer_with_expect(self, expected):
  206. token = self._read_token()
  207. if token != TOKEN_PRIMITIVE_BUFFER: raise PinchInvalidCodingException()
  208. if expected != self._read_token_argument:
  209. raise PinchInvalidCodingException()
  210. return self._read_bytes(self._read_token_argument)
  211. def _read_primitive_signed_ordinal(self):
  212. token = self._read_token()
  213. if token == TOKEN_PRIMITIVE_PACKED_ORDINAL:
  214. return self._read_token_argument
  215. elif token == TOKEN_PRIMITIVE_TAGGED_ORDINAL:
  216. return self._read_signed_tag()
  217. else:
  218. raise PinchInvalidCodingException()
  219. def _read_primitive_unsigned_ordinal(self):
  220. token = self._read_token()
  221. if token == TOKEN_PRIMITIVE_PACKED_ORDINAL:
  222. return self._read_token_argument
  223. elif token == TOKEN_PRIMITIVE_TAGGED_ORDINAL:
  224. return self._read_unsigned_tag()
  225. else:
  226. raise PinchInvalidCodingException()
  227. def _read_primitive_long_ordinal(self):
  228. token = self._read_token()
  229. if token == TOKEN_PRIMITIVE_PACKED_ORDINAL:
  230. return long(self._read_token_argument)
  231. elif token == TOKEN_PRIMITIVE_TAGGED_ORDINAL:
  232. return self._read_signed_long_tag()
  233. else:
  234. raise PinchInvalidCodingException()
  235. # Decoder Implementation:
  236. def open_sequence(self):
  237. token = self._read_token()
  238. if token != TOKEN_SEQUENCE: raise PinchInvalidCodingException()
  239. return self._read_token_argument
  240. def decode_choice_marker(self):
  241. token = self._read_token()
  242. if token != TOKEN_CHOICE: raise PinchInvalidCodingException()
  243. return self._read_token_argument
  244. def decode_required_float32(self, properties):
  245. return struct.unpack("!f", self._read_primitive_buffer_with_expect(4))[0]
  246. def decode_required_float64(self, properties):
  247. return struct.unpack("!d", self._read_primitive_buffer_with_expect(8))[0]
  248. def decode_required_int8(self, properties):
  249. return self._read_primitive_unsigned_ordinal()
  250. def decode_required_int16(self, properties):
  251. return self._read_primitive_signed_ordinal()
  252. def decode_required_int32(self, properties):
  253. return self._read_primitive_signed_ordinal()
  254. def decode_required_int64(self, properties):
  255. return self._read_primitive_long_ordinal()
  256. def decode_required_decimal(self, properties):
  257. return self._read_decimal()
  258. def decode_required_bool(self, properties):
  259. return self._read_primitive_unsigned_ordinal() == 1
  260. def decode_required_string(self, properties):
  261. bytes = self._read_primitive_buffer()
  262. return unicode(bytes, "utf-8")
  263. def decode_required_bytes(self, properties):
  264. return self._read_primitive_buffer()
  265. def decode_required_enumeration(self, properties):
  266. return self._read_primitive_unsigned_ordinal()
  267. def decode_required_structure(self, factory, properties):
  268. value = factory(PinchDecodingContext())
  269. value.decode(self)
  270. return value
  271. def _start_optional(self):
  272. if self._peek_token() != TOKEN_NULL:
  273. return True
  274. else:
  275. if self._read_token() != TOKEN_NULL: raise ValueError()
  276. return False
  277. def decode_optional_float32(self, properties):
  278. if self._start_optional():
  279. return struct.unpack("!f", self._read_primitive_buffer_with_expect(4))[0]
  280. else:
  281. return None
  282. def decode_optional_float64(self, properties):
  283. if self._start_optional():
  284. return struct.unpack("!d", self._read_primitive_buffer_with_expect(8))[0]
  285. else:
  286. return None
  287. def decode_optional_int8(self, properties):
  288. if self._start_optional():
  289. return self._read_primitive_unsigned_ordinal()
  290. else:
  291. return None
  292. def decode_optional_int16(self, properties):
  293. if self._start_optional():
  294. return self._read_primitive_signed_ordinal()
  295. else:
  296. return None
  297. def decode_optional_int32(self, properties):
  298. if self._start_optional():
  299. return self._read_primitive_signed_ordinal()
  300. else:
  301. return None
  302. def decode_optional_int64(self, properties):
  303. if self._start_optional():
  304. return self._read_primitive_long_ordinal()
  305. else:
  306. return None
  307. def decode_optional_decimal(self, properties):
  308. if self._start_optional():
  309. return self._read_decimal()
  310. else:
  311. return None
  312. def decode_optional_bool(self, properties):
  313. if self._start_optional():
  314. return self._read_primitive_unsigned_ordinal() == 1
  315. else:
  316. return None
  317. def decode_optional_string(self, properties):
  318. if self._start_optional():
  319. bytes = self._read_primitive_buffer()
  320. return unicode(bytes, "utf-8")
  321. else:
  322. return None
  323. def decode_optional_bytes(self, properties):
  324. if self._start_optional():
  325. return self._read_primitive_buffer()
  326. else:
  327. return None
  328. def decode_optional_enumeration(self, properties):
  329. if self._start_optional():
  330. return self._read_primitive_unsigned_ordinal()
  331. else:
  332. return None
  333. def decode_optional_structure(self, factory, properties):
  334. if self._start_optional():
  335. value = factory(PinchDecodingContext())
  336. value.decode(self)
  337. return value
  338. else:
  339. return None
  340. def skip_fields(self, remaining_fields):
  341. for i in range(remaining_fields):
  342. token = self._read_token
  343. if token == TOKEN_SEQUENCE:
  344. self._skip_fields(self._read_token_argument)
  345. elif token == TOKEN_PRIMITIVE_BUFFER:
  346. self._skip_bytes(self._read_token_argument)
  347. elif token == TOKEN_PRIMITIVE_PACKED_ORDINAL:
  348. pass
  349. elif token == TOKEN_PRIMITIVE_TAGGED_ORDINAL:
  350. self._skip_tag()
  351. elif token == TOKEN_CHOICE:
  352. self._skip_tag()
  353. self._skip_fields(1)
  354. elif token == TOKEN_NULL:
  355. pass
  356. def skip_removed(self):
  357. self.skip_fields(1)
  358. def close_sequence(self):
  359. pass
  360. class PinchEncoder(object):
  361. def __init__(self, file):
  362. self._file = file
  363. # Encoding Utilities:
  364. def _write_unsigned_tag(self, tag):
  365. if tag < 0 or 4294967296L <= tag:
  366. raise PinchInvalidCodingException()
  367. remaining = tag
  368. while remaining > 0x7f:
  369. self._file.write(chr((remaining & 0xff) | 0x80))
  370. remaining = remaining >> 7
  371. self._file.write(chr(remaining))
  372. def _write_signed_tag(self, tag):
  373. if tag < -2147483648 or 2147483647 < tag:
  374. raise PinchInvalidCodingException()
  375. if tag < 0:
  376. tag = -tag - 1
  377. if not tag & 0x40000000:
  378. remaining = (int(tag) << 1) | 1
  379. else:
  380. remaining = (long(tag) << 1) | 1
  381. else:
  382. if not tag & 0x40000000:
  383. remaining = (int(tag) << 1)
  384. else:
  385. remaining = (long(tag) << 1)
  386. while remaining > 0x7f:
  387. self._file.write(chr((remaining & 0xff) | 0x80))
  388. remaining = remaining >> 7
  389. self._file.write(chr(remaining))
  390. def _write_signed_long_tag(self, tag):
  391. if tag < 0:
  392. remaining = ((-long(tag) - 1) << 1) | 1
  393. else:
  394. remaining = tag << 1
  395. while remaining > 0x7f:
  396. self._file.write(chr((remaining & 0xff) | 0x80))
  397. remaining = remaining >> 7
  398. self._file.write(chr(remaining))
  399. # Encoding Primatives:
  400. def _write_sequence_marker(self, count):
  401. if count < 64:
  402. self._file.write(chr(PACKED_SEQUENCE_BYTE | count))
  403. else:
  404. self._file.write(chr(TAGGED_SEQUENCE_BYTE))
  405. self._write_unsigned_tag(count)
  406. def _write_primative_buffer(self, buffer):
  407. if len(buffer) < 64:
  408. self._file.write(chr(PACKED_PRIMATIVE_BUFFER_BYTE | len(buffer)))
  409. else:
  410. self._file.write(chr(TAGGED_PRIMATIVE_BUFFER_BYTE))
  411. self._write_unsigned_tag(len(buffer))
  412. self._file.write(buffer)
  413. def _write_primative_signed_ordinal(self, ordinal):
  414. if 0 <= ordinal < 64:
  415. self._file.write(chr(PACKED_PRIMATIVE_ORDINAL_BYTE | ordinal))
  416. else:
  417. self._file.write(chr(TAGGED_PRIMATIVE_ORDINAL_BYTE))
  418. self._write_signed_tag(ordinal)
  419. def _write_primative_unsigned_ordinal(self, ordinal):
  420. if 0 <= ordinal < 64:
  421. self._file.write(chr(PACKED_PRIMATIVE_ORDINAL_BYTE | ordinal))
  422. else:
  423. self._file.write(chr(TAGGED_PRIMATIVE_ORDINAL_BYTE))
  424. self._write_unsigned_tag(ordinal)
  425. def _write_primative_long_ordinal(self, ordinal):
  426. if 0 <= ordinal < 64:
  427. self._file.write(chr(PACKED_PRIMATIVE_ORDINAL_BYTE | ordinal))
  428. else:
  429. self._file.write(chr(TAGGED_PRIMATIVE_ORDINAL_BYTE))
  430. self._write_signed_long_tag(ordinal)
  431. def _write_null(self):
  432. self._file.write(chr(NULL))
  433. def encode_choice_marker(self, value_kind):
  434. self._file.write(chr(TAGGED_CHOICE_BYTE))
  435. self._write_unsigned_tag(value_kind)
  436. def encode_removed(self):
  437. self._file.write(chr(NULL))
  438. def _write_decimal(self, value):
  439. # Validate the decimal and determine the number of bytes to encode it:
  440. if not isinstance(value, PinchDecimal): raise PinchInvalidCodingException()
  441. if not 0 <= value.exponent <= 255: raise PinchInvalidCodingException()
  442. if not value.digits >= 0: raise PinchInvalidCodingException()
  443. digit_octet_count = 1
  444. digits = value.digits >> 8
  445. while digits > 0:
  446. digit_octet_count += 1
  447. digits = digits >> 8
  448. if digit_octet_count > 8: raise PinchInvalidCodingException()
  449. # Write the tag and encoded decimal:
  450. self._file.write(chr(PACKED_PRIMATIVE_BUFFER_BYTE | (digit_octet_count + 2)))
  451. self._file.write(chr(value.exponent))
  452. if value.sign:
  453. self._file.write(chr(0x80))
  454. else:
  455. self._file.write(chr(0x00))
  456. digits = value.digits
  457. self._file.write(chr(digits & 0xff))
  458. digits = digits >> 8
  459. while digits > 0:
  460. self._file.write(chr(digits & 0xff))
  461. digits = digits >> 8
  462. # Decoder Members:
  463. def open_sequence(self, count):
  464. if count < 0: raise ValueError()
  465. self._write_sequence_marker(count)
  466. def encode_required_float32(self, value, properties):
  467. if type(value) not in (int, long, float):
  468. raise PinchInvalidCodingException()
  469. self._write_primative_buffer(struct.pack("!f", float(value)))
  470. def encode_required_float64(self, value, properties):
  471. if type(value) not in (int, long, float):
  472. raise PinchInvalidCodingException()
  473. self._write_primative_buffer(struct.pack("!d", float(value)))
  474. def encode_required_int8(self, value, properties):
  475. if type(value) not in (int, long):
  476. raise PinchInvalidCodingException()
  477. self._write_primative_unsigned_ordinal(value)
  478. def encode_required_int16(self, value, properties):
  479. if type(value) not in (int, long):
  480. raise PinchInvalidCodingException()
  481. self._write_primative_signed_ordinal(value)
  482. def encode_required_int32(self, value, properties):
  483. if type(value) not in (int, long):
  484. raise PinchInvalidCodingException()
  485. self._write_primative_signed_ordinal(value)
  486. def encode_required_int64(self, value, properties):
  487. if type(value) not in (int, long):
  488. raise PinchInvalidCodingException()
  489. self._write_primative_long_ordinal(value)
  490. def encode_required_decimal(self, value, properties):
  491. if not isinstance(value, PinchDecimal):
  492. raise PinchInvalidCodingException()
  493. self._write_decimal(value)
  494. def encode_required_bool(self, value, properties):
  495. if value:
  496. self._write_primative_unsigned_ordinal(1)
  497. else:
  498. self._write_primative_unsigned_ordinal(0)
  499. def encode_required_string(self, value, properties):
  500. if type(value) is str:
  501. value = unicode(value).encode("utf-8")
  502. elif type(value) is unicode:
  503. value = value.encode("utf-8")
  504. else:
  505. raise PinchInvalidCodingException()
  506. self._write_primative_buffer(value)
  507. def encode_required_bytes(self, value, properties):
  508. if type(value) is not str:
  509. raise PinchInvalidCodingException()
  510. self._write_primative_buffer(value)
  511. def encode_required_enumeration(self, value, properties):
  512. if type(value) not in (int, long):
  513. raise PinchInvalidCodingException()
  514. self._write_primative_unsigned_ordinal(value)
  515. def encode_required_structure(self, value, properties):
  516. value.encode(self)
  517. def encode_optional_float32(self, value, properties):
  518. if value is not None:
  519. if type(value) not in (int, long, float):
  520. raise PinchInvalidCodingException()
  521. self._write_primative_buffer(struct.pack("!f", float(value)))
  522. else:
  523. self._write_null()
  524. def encode_optional_float64(self, value, properties):
  525. if value is not None:
  526. if type(value) not in (int, long, float):
  527. raise PinchInvalidCodingException()
  528. self._write_primative_buffer(struct.pack("!d", float(value)))
  529. else:
  530. self._write_null()
  531. def encode_optional_int8(self, value, properties):
  532. if value is not None:
  533. if type(value) not in (int, long):
  534. raise PinchInvalidCodingException()
  535. self._write_primative_unsigned_ordinal(value)
  536. else:
  537. self._write_null()
  538. def encode_optional_int16(self, value, properties):
  539. if value is not None:
  540. if type(value) not in (int, long):
  541. raise PinchInvalidCodingException()
  542. self._write_primative_signed_ordinal(value)
  543. else:
  544. self._write_null()
  545. def encode_optional_int32(self, value, properties):
  546. if value is not None:
  547. if type(value) not in (int, long):
  548. raise PinchInvalidCodingException()
  549. self._write_primative_signed_ordinal(value)
  550. else:
  551. self._write_null()
  552. def encode_optional_int64(self, value, properties):
  553. if value is not None:
  554. if type(value) not in (int, long):
  555. raise PinchInvalidCodingException()
  556. self._write_primative_long_ordinal(value)
  557. else:
  558. self._write_null()
  559. def encode_optional_decimal(self, value, properties):
  560. if value is not None:
  561. if not isinstance(value, PinchDecimal):
  562. raise PinchInvalidCodingException()
  563. self._write_decimal(value)
  564. else:
  565. self._write_null()
  566. def encode_optional_bool(self, value, properties):
  567. if value is not None:
  568. if value:
  569. self._write_primative_unsigned_ordinal(1)
  570. else:
  571. self._write_primative_unsigned_ordinal(0)
  572. else:
  573. self._write_null()
  574. def encode_optional_string(self, value, properties):
  575. if value is not None:
  576. if type(value) is str:
  577. value = unicode(value).encode("utf-8")
  578. elif type(value) is unicode:
  579. value = value.encode("utf-8")
  580. else:
  581. raise PinchInvalidCodingException()
  582. self._write_primative_buffer(value)
  583. else:
  584. self._write_null()
  585. def encode_optional_bytes(self, value, properties):
  586. if value is not None:
  587. if type(value) is not str:
  588. raise PinchInvalidCodingException()
  589. self._write_primative_buffer(value)
  590. else:
  591. self._write_null()
  592. def encode_optional_enumeration(self, value, properties):
  593. if value is not None:
  594. if type(value) not in (int, long):
  595. raise PinchInvalidCodingException()
  596. self._write_primative_unsigned_ordinal(value)
  597. else:
  598. self._write_null()
  599. def encode_optional_structure(self, value, properties):
  600. if value is not None:
  601. value.encode(self)
  602. else:
  603. self._write_null()
  604. def close_sequence(self):
  605. pass
  606. def decode_from_file(factory, file):
  607. decoder = PinchDecoder(file)
  608. return decoder.decode_required_structure(factory, None)
  609. def decode(factory, encoded):
  610. decoder = PinchDecoder(cStringIO.StringIO(encoded))
  611. return decoder.decode_required_structure(factory, None)
  612. def encode_to_file(value, file):
  613. encoder = PinchEncoder(file)
  614. return encoder.encode_required_structure(value, None)
  615. def encode(value):
  616. encoder = PinchEncoder(cStringIO.StringIO())
  617. encoder.encode_required_structure(value, None)
  618. return encoder._file.getvalue()