1# 2# This file is part of pyasn1 software. 3# 4# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com> 5# License: http://snmplabs.com/pyasn1/license.html 6# 7import logging 8 9from pyasn1 import __version__ 10from pyasn1 import error 11from pyasn1.compat.octets import octs2ints 12 13__all__ = ['Debug', 'setLogger', 'hexdump'] 14 15flagNone = 0x0000 16flagEncoder = 0x0001 17flagDecoder = 0x0002 18flagAll = 0xffff 19 20flagMap = { 21 'none': flagNone, 22 'encoder': flagEncoder, 23 'decoder': flagDecoder, 24 'all': flagAll 25} 26 27 28class Printer(object): 29 # noinspection PyShadowingNames 30 def __init__(self, logger=None, handler=None, formatter=None): 31 if logger is None: 32 logger = logging.getLogger('pyasn1') 33 34 logger.setLevel(logging.DEBUG) 35 36 if handler is None: 37 handler = logging.StreamHandler() 38 39 if formatter is None: 40 formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s') 41 42 handler.setFormatter(formatter) 43 handler.setLevel(logging.DEBUG) 44 logger.addHandler(handler) 45 46 self.__logger = logger 47 48 def __call__(self, msg): 49 self.__logger.debug(msg) 50 51 def __str__(self): 52 return '<python logging>' 53 54 55if hasattr(logging, 'NullHandler'): 56 NullHandler = logging.NullHandler 57 58else: 59 # Python 2.6 and older 60 class NullHandler(logging.Handler): 61 def emit(self, record): 62 pass 63 64 65class Debug(object): 66 defaultPrinter = Printer() 67 68 def __init__(self, *flags, **options): 69 self._flags = flagNone 70 71 if 'loggerName' in options: 72 # route our logs to parent logger 73 self._printer = Printer( 74 logger=logging.getLogger(options['loggerName']), 75 handler=NullHandler() 76 ) 77 78 elif 'printer' in options: 79 self._printer = options.get('printer') 80 81 else: 82 self._printer = self.defaultPrinter 83 84 self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags))) 85 86 for flag in flags: 87 inverse = flag and flag[0] in ('!', '~') 88 if inverse: 89 flag = flag[1:] 90 try: 91 if inverse: 92 self._flags &= ~flagMap[flag] 93 else: 94 self._flags |= flagMap[flag] 95 except KeyError: 96 raise error.PyAsn1Error('bad debug flag %s' % flag) 97 98 self._printer("debug category '%s' %s" % (flag, inverse and 'disabled' or 'enabled')) 99 100 def __str__(self): 101 return 'logger %s, flags %x' % (self._printer, self._flags) 102 103 def __call__(self, msg): 104 self._printer(msg) 105 106 def __and__(self, flag): 107 return self._flags & flag 108 109 def __rand__(self, flag): 110 return flag & self._flags 111 112 113logger = 0 114 115 116def setLogger(userLogger): 117 global logger 118 119 if userLogger: 120 logger = userLogger 121 else: 122 logger = 0 123 124 125def hexdump(octets): 126 return ' '.join( 127 ['%s%.2X' % (n % 16 == 0 and ('\n%.5d: ' % n) or '', x) 128 for n, x in zip(range(len(octets)), octs2ints(octets))] 129 ) 130 131 132class Scope(object): 133 def __init__(self): 134 self._list = [] 135 136 def __str__(self): return '.'.join(self._list) 137 138 def push(self, token): 139 self._list.append(token) 140 141 def pop(self): 142 return self._list.pop() 143 144 145scope = Scope() 146