common.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #
  2. # Copyright (C) 2014-2015 UAVCAN Development Team <uavcan.org>
  3. #
  4. # This software is distributed under the terms of the MIT License.
  5. #
  6. # Author: Pavel Kirienko <pavel.kirienko@zubax.com>
  7. # Ben Dyer <ben_dyer@mac.com>
  8. #
  9. from __future__ import division, absolute_import, print_function, unicode_literals
  10. import os
  11. import struct
  12. from uavcan import UAVCANException
  13. class DsdlException(UAVCANException):
  14. '''
  15. This exception is raised in case of a parser failure.
  16. Fields:
  17. file Source file path where the error has occurred. Optional, will be None if unknown.
  18. line Source file line number where the error has occurred. Optional, will be None if unknown.
  19. '''
  20. def __init__(self, text, file=None, line=None):
  21. Exception.__init__(self, text)
  22. self.file = file
  23. self.line = line
  24. def __str__(self):
  25. '''Returns nicely formatted error string in GCC-like format (can be parsed by e.g. Eclipse error parser)'''
  26. if self.file and self.line:
  27. return '%s:%d: %s' % (pretty_filename(self.file), self.line, Exception.__str__(self))
  28. if self.file:
  29. return '%s: %s' % (pretty_filename(self.file), Exception.__str__(self))
  30. return Exception.__str__(self)
  31. def pretty_filename(filename):
  32. '''Returns a nice human readable path to 'filename'.'''
  33. a = os.path.abspath(filename)
  34. r = os.path.relpath(filename)
  35. return a if '..' in r else r
  36. def crc16_from_bytes(bytes, initial=0xFFFF):
  37. # CRC-16-CCITT
  38. # Initial value: 0xFFFF
  39. # Poly: 0x1021
  40. # Reverse: no
  41. # Output xor: 0
  42. # Check string: '123456789'
  43. # Check value: 0x29B1
  44. try:
  45. if isinstance(bytes, basestring): # Python 2.7 compatibility
  46. bytes = map(ord, bytes)
  47. except NameError:
  48. if isinstance(bytes, str): # This branch will be taken on Python 3
  49. bytes = map(ord, bytes)
  50. crc = initial
  51. for byte in bytes:
  52. crc ^= byte << 8
  53. for bit in range(8):
  54. if crc & 0x8000:
  55. crc = ((crc << 1) ^ 0x1021) & 0xFFFF
  56. else:
  57. crc = (crc << 1) & 0xFFFF
  58. return crc & 0xFFFF
  59. def bytes_from_crc64(crc64):
  60. # Cast to str explicitly for Python 2.7 compatibility when
  61. # unicode_literals is enabled
  62. return bytes(struct.pack(str("<Q"), crc64))