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