_utils.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """
  2. websocket - WebSocket client library for Python
  3. Copyright (C) 2010 Hiroki Ohtani(liris)
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  15. """
  16. import six
  17. __all__ = ["NoLock", "validate_utf8", "extract_err_message", "extract_error_code"]
  18. class NoLock(object):
  19. def __enter__(self):
  20. pass
  21. def __exit__(self, exc_type, exc_value, traceback):
  22. pass
  23. try:
  24. # If wsaccel is available we use compiled routines to validate UTF-8
  25. # strings.
  26. from wsaccel.utf8validator import Utf8Validator
  27. def _validate_utf8(utfbytes):
  28. return Utf8Validator().validate(utfbytes)[0]
  29. except ImportError:
  30. # UTF-8 validator
  31. # python implementation of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
  32. _UTF8_ACCEPT = 0
  33. _UTF8_REJECT = 12
  34. _UTF8D = [
  35. # The first part of the table maps bytes to character classes that
  36. # to reduce the size of the transition table and create bitmasks.
  37. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  38. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  39. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  40. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  41. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  42. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  43. 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  44. 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
  45. # The second part is a transition table that maps a combination
  46. # of a state of the automaton and a character class to a state.
  47. 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
  48. 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
  49. 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
  50. 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
  51. 12,36,12,12,12,12,12,12,12,12,12,12, ]
  52. def _decode(state, codep, ch):
  53. tp = _UTF8D[ch]
  54. codep = (ch & 0x3f) | (codep << 6) if (
  55. state != _UTF8_ACCEPT) else (0xff >> tp) & ch
  56. state = _UTF8D[256 + state + tp]
  57. return state, codep
  58. def _validate_utf8(utfbytes):
  59. state = _UTF8_ACCEPT
  60. codep = 0
  61. for i in utfbytes:
  62. if six.PY2:
  63. i = ord(i)
  64. state, codep = _decode(state, codep, i)
  65. if state == _UTF8_REJECT:
  66. return False
  67. return True
  68. def validate_utf8(utfbytes):
  69. """
  70. validate utf8 byte string.
  71. utfbytes: utf byte string to check.
  72. return value: if valid utf8 string, return true. Otherwise, return false.
  73. """
  74. return _validate_utf8(utfbytes)
  75. def extract_err_message(exception):
  76. if exception.args:
  77. return exception.args[0]
  78. else:
  79. return None
  80. def extract_error_code(exception):
  81. if exception.args and len(exception.args) > 1:
  82. return exception.args[0] if isinstance(exception.args[0], int) else None