Esempio n. 1
0
 def parse(self, line):
     line = octs2str(line).strip(" \t\n\r")
     if line.startswith('#') or len(line)==0:
         # Ignore comment or empty line
         return None,None,None
     oid, tag, value = [ x.strip() for x in octs2str(line).split(',', 2) ]
     return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip())
Esempio n. 2
0
 def parse(self, line):
     line = line.decode('ascii', 'ignore').encode()  # drop possible 8-bits
     try:
         oid, value = octs2str(line).strip().split(' = ', 1)
     except:
         raise error.SnmpsimError('broken record <%s>' % line)
     if oid and oid[0] == '.':
         oid = oid[1:]
     if value.startswith('Wrong Type (should be'):
         value = value[value.index(': ') + 2:]
     if value.startswith('No more variables left in this MIB View'):
         value = 'STRING: '
     try:
         tag, value = value.split(' ', 1)
     except ValueError:
         # this is implicit snmpwalk's fuzziness
         if value == '""' or value == 'STRING:':
             tag = 'STRING:'
             value = ''
         else:
             tag = 'TimeTicks:'
     if oid and tag:
         return oid, tag.upper(), self.filterMap.get(
             tag.upper(), lambda x: x)(value.strip())
     raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 3
0
 def parse(self, line):
     line = octs2str(line).strip(" \t\n\r")
     if line.startswith('#') or len(line)==0:
         # Ignore comment or empty line
         return None,None,None
     splitted = line.split('|', 2)
     return splitted[0],splitted[1],splitted[2]
Esempio n. 4
0
    def parse(self, line):

        filters = {
            'OPAQUE:': self._opaque_filter,
            'INTEGER:': self._integer_filter,
            'STRING:': self._string_filter,
            'BITS:': self._bits_filter,
            'HEX-STRING:': self._hex_string_filter,
            'GAUGE32:': self._gauge_filter,
            'NETWORK ADDRESS:': self._net_address_filter,
            'TIMETICKS:': self._time_ticks_filter
        }

        # drop possible 8-bits
        line = line.decode('ascii', 'ignore').encode()

        try:
            oid, value = octs2str(line).strip().split(' = ', 1)

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        if oid and oid[0] == '.':
            oid = oid[1:]

        if value.startswith('Wrong Type (should be'):
            value = value[value.index(': ') + 2:]

        if value.startswith('No more variables left in this MIB View'):
            value = 'STRING: '

        match = re.match(r'^(\w+(?:[\-\ ]\w+)?:)\ ?(.*)', value)
        if match:
            tag = match.group(1)
            value = match.group(2)

        # this is implicit snmpwalk's fuzziness
        elif value == '""' or value == 'STRING:':
            tag = 'STRING:'
            value = ''

        elif value == 'NULL':
            tag = 'NULL:'
            value = ''

        else:
            tag = 'TimeTicks:'

        if oid and tag:
            handler = filters.get(tag.upper(), lambda x: x)

            # Need rewrite tag for Network Address after filters
            if tag == 'Network Address:':
                tag = 'IpAddress:'

            return oid, tag.upper(), handler(value.strip())

        raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 5
0
 def parse(self, line):
     try:
         oid, tag, value = octs2str(line).strip().split('|', 2)
     except:
         raise error.SnmpsimError('broken record <%s>' % line)
     else:
         if oid and tag:
             return oid, tag, value
         raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 6
0
 def parse(self, line):
     try:
         oid, tag, value = [x.strip() for x in octs2str(line).split(',', 2)]
     except:
         raise error.SnmpsimError('broken record <%s>' % line)
     else:
         if oid and tag:
             return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip())
         raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 7
0
 def parse(self, line):
     try:
         oid, tag, value = octs2str(line).split('|', 2)
     except:
         raise error.SnmpsimError('broken record <%s>' % line)
     else:
         if oid and tag:
             return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip())
         raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 8
0
 def parse(self, line):
     try:
         oid, tag, value = octs2str(line).strip().split('|', 2)
     except:
         raise error.SnmpsimError('broken record <%s>' % line)
     else:
         if oid and tag:
             return oid, tag, value
         raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 9
0
 def prettyOut(self, value):
     if version_info[0] <= 2:
         numbers = tuple((ord(x) for x in value))
     else:
         numbers = tuple(value)
     for x in numbers:
         if x < 32 or x > 126:
             return '0x' + ''.join(('%.2x' % x for x in numbers))
     else:
         return octets.octs2str(value)
Esempio n. 10
0
 def prettyOut(self, value):
     if version_info[0] <= 2:
         numbers = tuple((ord(x) for x in value))
     else:
         numbers = tuple(value)
     for x in numbers:
         if x < 32 or x > 126:
             return '0x' + ''.join(('%.2x' % x for x in numbers))
     else:
         return octets.octs2str(value)
Esempio n. 11
0
    def parse(self, line):
        try:
            oid, tag, value = octs2str(line).split('|', 2)

        except Exception as exc:
            raise error.SnmpsimError(
                'broken record <%s>: %s' % (line, exc))

        else:
            if oid and tag:
                return oid.strip(), tag.strip(), value.strip("\r\n\t")

            raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 12
0
    def parse(self, line):

        filters = {
            'OPAQUE:': self._opaqueFilter,
            'INTEGER:': self._integerFilter,
            'STRING:': self._stringFilter,
            'BITS:': self._bitsFilter,
            'HEX-STRING:': self._hexStringFilter,
            'GAUGE32:': self._gaugeFilter,
            'Network Address:': self._netAddressFilter,
            'TIMETICKS:': self._timeTicksFilter
        }

        # drop possible 8-bits
        line = line.decode('ascii', 'ignore').encode()

        try:
            oid, value = octs2str(line).strip().split(' = ', 1)

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        if oid and oid[0] == '.':
            oid = oid[1:]

        if value.startswith('Wrong Type (should be'):
            value = value[value.index(': ') + 2:]

        if value.startswith('No more variables left in this MIB View'):
            value = 'STRING: '

        try:
            tag, value = value.split(' ', 1)

        except ValueError:
            # this is implicit snmpwalk's fuzziness
            if value == '""' or value == 'STRING:':
                tag = 'STRING:'
                value = ''

            else:
                tag = 'TimeTicks:'

        if oid and tag:
            handler = filters.get(tag.upper(), lambda x: x)
            return oid, tag.upper(), handler(value.strip())

        raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 13
0
    def parse(self, line):

        filters = {
            'OPAQUE:': self._opaqueFilter,
            'INTEGER:': self._integerFilter,
            'STRING:': self._stringFilter,
            'BITS:': self._bitsFilter,
            'HEX-STRING:': self._hexStringFilter,
            'GAUGE32:': self._gaugeFilter,
            'Network Address:': self._netAddressFilter,
            'TIMETICKS:': self._timeTicksFilter
        }

        # drop possible 8-bits
        line = line.decode('ascii', 'ignore').encode()

        try:
            oid, value = octs2str(line).strip().split(' = ', 1)

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        if oid and oid[0] == '.':
            oid = oid[1:]

        if value.startswith('Wrong Type (should be'):
            value = value[value.index(': ') + 2:]

        if value.startswith('No more variables left in this MIB View'):
            value = 'STRING: '

        try:
            tag, value = value.split(' ', 1)

        except ValueError:
            # this is implicit snmpwalk's fuzziness
            if value == '""' or value == 'STRING:':
                tag = 'STRING:'
                value = ''

            else:
                tag = 'TimeTicks:'

        if oid and tag:
            handler = filters.get(tag.upper(), lambda x: x)
            return oid, tag.upper(), handler(value.strip())

        raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 14
0
    def parse(self, line):

        filters = {'4': self._nullFilter, '6': self._unhexFilter}

        try:
            oid, tag, value = octs2str(line).split('|', 2)

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        else:
            if oid and tag:
                handler = filters.get(tag, lambda x: x)
                return oid, tag, handler(value.strip())

            raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 15
0
    def parse(self, line):

        filters = {'OctetString': self._stringFilter}

        try:
            oid, tag, value = [x.strip() for x in octs2str(line).split(',', 2)]

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        else:
            if oid and tag:
                handler = filters.get(tag, lambda x: x)
                return oid, tag, handler(value.strip())

            raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 16
0
    def parse(self, line):

        filters = {
            'OctetString': self._stringFilter
        }

        try:
            oid, tag, value = [x.strip() for x in octs2str(line).split(',', 2)]

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        else:
            if oid and tag:
                handler = filters.get(tag, lambda x: x)
                return oid, tag, handler(value.strip())

            raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 17
0
 def parse(self, line):
     oid, value = octs2str(line).strip().split(' = ', 1)
     if oid and oid[0] == '.':
         oid = oid[1:]
     if value.startswith('Wrong Type (should be'):
         value = value.partition(': ')[2]
     if value.startswith('No more variables left in this MIB View'):
         value = 'STRING: '
     try:
         tag, value = value.split(' ', 1)
     except ValueError:
         # this is implicit snmpwalk's fuzziness
         if value == '""' or value == 'STRING:':
             tag = 'STRING:'
             value = ''
         else:
             tag = 'TimeTicks:'
     return oid, tag.upper(), self.filterMap.get(tag, lambda x: x)(value.strip())
Esempio n. 18
0
    def parse(self, line):

        filters = {
            '4': self._nullFilter,
            '6': self._unhexFilter
        }

        try:
            oid, tag, value = octs2str(line).split('|', 2)

        except Exception:
            raise error.SnmpsimError('broken record <%s>' % line)

        else:
            if oid and tag:
                handler = filters.get(tag, lambda x: x)
                return oid, tag, handler(value.strip())

            raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 19
0
    def evaluateValue(self, oid, tag, value, **context):
        tag, encodingId = self.unpackTag(tag)

        try:
            if encodingId == 'e':

                value = self.evaluateRawString(value)

                return oid, tag, self.grammar.TAG_MAP[tag](value)

            elif encodingId == 'x':
                if octets.isOctetsType(value):
                    value = octets.octs2str(value)

                return oid, tag, self.grammar.TAG_MAP[tag](hexValue=value)

            else:
                return oid, tag, self.grammar.TAG_MAP[tag](value)

        except Exception:
            raise error.SnmpsimError(
                'value evaluation error for tag %r, value '
                '%r: %s' % (tag, value, sys.exc_info()[1]))
Esempio n. 20
0
    def evaluate_value(self, oid, tag, value, **context):
        tag, encoding_id = self.unpack_tag(tag)

        try:
            if encoding_id == 'e':

                value = self.evaluate_raw_string(value)

                return oid, tag, self.grammar.TAG_MAP[tag](value)

            elif encoding_id == 'x':
                if octets.isOctetsType(value):
                    value = octets.octs2str(value)

                return oid, tag, self.grammar.TAG_MAP[tag](hexValue=value)

            else:
                return oid, tag, self.grammar.TAG_MAP[tag](value)

        except Exception as exc:
            raise error.SnmpsimError(
                'value evaluation error for tag %r, value '
                '%r: %s' % (tag, value, exc))
Esempio n. 21
0
    def evaluateValue(self, oid, tag, value, **context):
        tag, encodingId = self.unpackTag(tag)

        try:
            if encodingId == 'e':

                value = self.evaluateRawString(value)

                return oid, tag, self.grammar.TAG_MAP[tag](value)

            elif encodingId == 'x':
                if octets.isOctetsType(value):
                    value = octets.octs2str(value)

                return oid, tag, self.grammar.TAG_MAP[tag](hexValue=value)

            else:
                return oid, tag, self.grammar.TAG_MAP[tag](value)

        except Exception:
            raise error.SnmpsimError(
                'value evaluation error for tag %r, value '
                '%r: %s' % (tag, value, sys.exc_info()[1]))
Esempio n. 22
0
 def parse(self, line):
     line = line.decode('ascii', 'ignore').encode() # drop possible 8-bits
     try:
         oid, value = octs2str(line).strip().split(' = ', 1)
     except:
         raise error.SnmpsimError('broken record <%s>' % line)
     if oid and oid[0] == '.':
         oid = oid[1:]
     if value.startswith('Wrong Type (should be'):
         value = value[value.index(': ')+2:]
     if value.startswith('No more variables left in this MIB View'):
         value = 'STRING: '
     try:
         tag, value = value.split(' ', 1)
     except ValueError:
         # this is implicit snmpwalk's fuzziness
         if value == '""' or value == 'STRING:':
             tag = 'STRING:'
             value = ''
         else:
             tag = 'TimeTicks:'
     if oid and tag:
         return oid, tag.upper(), self.filterMap.get(tag.upper(), lambda x: x)(value.strip())
     raise error.SnmpsimError('broken record <%s>' % line)
Esempio n. 23
0
 def parse(self, line):
     line = octs2str(line).strip(" \t\n\r").decode('ascii', 'ignore').encode() # drop possible 8-bits
     if line.startswith('#') or len(line)==0:
         # Ignore comment or empty line
         return None,None,None
     splitted = line.split(' = ', 1)
     oid   = splitted[0]
     value = splitted[1]
     if oid and oid[0] == '.':
         oid = oid[1:]
     if value.startswith('Wrong Type (should be'):
         value = value[value.index(': ')+2:]
     if value.startswith('No more variables left in this MIB View'):
         value = 'STRING: '
     try:
         tag, value = value.split(' ', 1)
     except ValueError:
         # this is implicit snmpwalk's fuzziness
         if value == '""' or value == 'STRING:':
             tag = 'STRING:'
             value = ''
         else:
             tag = 'TimeTicks:'
     return oid, tag.upper(), self.filterMap.get(tag, lambda x: x)(value.strip())
Esempio n. 24
0
 def test_octs2str(self):
     assert '\x01\x02\x03' == octets.octs2str(bytes([1, 2, 3]))
Esempio n. 25
0
 def test_octs2str_empty(self):
     assert not octets.octs2str('')
Esempio n. 26
0
 def test_octs2str(self):
     assert '\x01\x02\x03' == octets.octs2str('\x01\x02\x03')
Esempio n. 27
0
 def test_octs2str_empty(self):
     assert not octets.octs2str(bytes([]))
Esempio n. 28
0
 def test_octs2str(self):
     assert '\x01\x02\x03' == octets.octs2str(bytes([1, 2, 3]))
Esempio n. 29
0
    def prettyIn(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT parsing into base SNMP value

        Proper parsing seems impossible due to ambiguities.
        Here we are trying to do our best, but be prepared
        for failures on complicated DISPLAY-HINTs.

        Keep in mind that this parser only works with "text"
        input meaning `unicode` (Py2) or `str` (Py3).
        """
        for base in inspect.getmro(self.__class__):
            if not issubclass(base, TextualConvention) and issubclass(base, Asn1Item):
                break
        else:
            raise SmiError('TEXTUAL-CONVENTION has no underlying SNMP base type')

        if self.displayHint and (self.__integer.isSuperTypeOf(self, matchConstraints=False) and
                                 self.getNamedValues() or
                                 self.__unsigned32.isSuperTypeOf(self, matchConstraints=False) or
                                 self.__timeticks.isSuperTypeOf(self, matchConstraints=False)):
            value = str(value)

            _ = lambda t, f=0: (t, f)
            displayHintType, decimalPrecision = _(*self.displayHint.split('-'))
            if displayHintType == 'x' and (value.startswith('0x') or value.startswith('-0x')):
                try:
                    if value.startswith('-'):
                        return base.prettyIn(self, -int(value[3:], 16))
                    else:
                        return base.prettyIn(self, int(value[2:], 16))
                except Exception as exc:
                    raise SmiError(
                        'integer evaluation error: %s' % exc
                    )
            elif displayHintType == 'd':
                try:
                    return base.prettyIn(self, int(float(value) * 10**int(decimalPrecision)))
                except Exception as exc:
                    raise SmiError(
                        'float evaluation error: %s' % exc
                    )
            elif displayHintType == 'o' and (value.startswith('0') or value.startswith('-0')):
                try:
                    return base.prettyIn(self, int(value, 8))
                except Exception as exc:
                    raise SmiError(
                        'octal evaluation error: %s' % exc
                    )
            elif displayHintType == 'b' and (value.startswith('B') or value.startswith('-B')):
                negative = value.startswith('-')
                if negative:
                    value = value[2:]
                else:
                    value = value[1:]
                value = [x != '0' and 1 or 0 for x in value]
                binValue = 0
                while value:
                    binValue <<= value[0]
                    del value[0]
                return base.prettyIn(self, binValue)
            else:
                raise SmiError(
                    'Unsupported numeric type spec "%s" at %s' % (displayHintType, self.__class__.__name__)
                )

        elif self.displayHint and self.__octetString.isSuperTypeOf(self, matchConstraints=False):
            numBase = {
                'x': 16,
                'd': 10,
                'o': 8
            }
            numDigits = {
                'x': octets.str2octs(string.hexdigits),
                'o': octets.str2octs(string.octdigits),
                'd': octets.str2octs(string.digits)
            }

            # how do we know if object is initialized with display-hint
            # formatted text? based on "text" input maybe?
            # That boils down to `str` object on Py3 or `unicode` on Py2.
            if octets.isStringType(value) and not octets.isOctetsType(value):
                value = base.prettyIn(self, value)
            else:
                return base.prettyIn(self, value)

            outputValue = octets.str2octs('')
            runningValue = value
            displayHint = self.displayHint

            while runningValue and displayHint:
                # 1 this information is totally lost, just fail explicitly
                if displayHint[0] == '*':
                    raise SmiError(
                        'Can\'t parse "*" in DISPLAY-HINT (%s)' % self.__class__.__name__
                    )

                # 2 this becomes ambiguous when it comes to rendered value
                octetLength = ''
                while displayHint and displayHint[0] in string.digits:
                    octetLength += displayHint[0]
                    displayHint = displayHint[1:]

                # length is mandatory but people ignore that
                if not octetLength:
                    octetLength = len(runningValue)

                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise SmiError(
                        'Bad octet length: %s' % octetLength
                    )

                if not displayHint:
                    raise SmiError(
                        'Short octet length: %s' % self.displayHint
                    )

                # 3
                displayFormat = displayHint[0]
                displayHint = displayHint[1:]

                # 4 this is the lifesaver -- we could use it as an anchor
                if displayHint and displayHint[0] not in string.digits and displayHint[0] != '*':
                    displaySep = displayHint[0]
                    displayHint = displayHint[1:]
                else:
                    displaySep = ''

                # 5 is probably impossible to support

                if displayFormat in ('a', 't'):
                    outputValue += runningValue[:octetLength]
                elif displayFormat in numBase:
                    if displaySep:
                        guessedOctetLength = runningValue.find(octets.str2octs(displaySep))
                        if guessedOctetLength == -1:
                            guessedOctetLength = len(runningValue)
                    else:
                        for idx in range(len(runningValue)):
                            if runningValue[idx] not in numDigits[displayFormat]:
                                guessedOctetLength = idx
                                break
                        else:
                            guessedOctetLength = len(runningValue)

                    try:
                        num = int(octets.octs2str(runningValue[:guessedOctetLength]), numBase[displayFormat])
                    except Exception as exc:
                        raise SmiError(
                            'Display format eval failure: %s: %s'
                            % (runningValue[:guessedOctetLength], exc)
                        )

                    num_as_bytes = []
                    if num:
                        while num:
                            num_as_bytes.append(num & 0xFF)
                            num >>= 8
                    else:
                        num_as_bytes = [0]

                    while len(num_as_bytes) < octetLength:
                        num_as_bytes.append(0)

                    num_as_bytes.reverse()

                    outputValue += octets.ints2octs(num_as_bytes)

                    if displaySep:
                        guessedOctetLength += 1

                    octetLength = guessedOctetLength
                else:
                    raise SmiError(
                        'Unsupported display format char: %s' %
                        displayFormat
                    )

                runningValue = runningValue[octetLength:]

                if not displayHint:
                    displayHint = self.displayHint

            return base.prettyIn(self, outputValue)

        else:
            return base.prettyIn(self, value)
Esempio n. 30
0
def evalsha(dbConn, *args):
    ret = dbConn.evalsha(*args)
    if ret is not None:
        ret = octets.octs2str(ret)

    return ret
Esempio n. 31
0
 def parse(self, line):
     oid, tag, value = [ x.strip() for x in octs2str(line).split(',', 2) ]
     return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip())
Esempio n. 32
0
def get(dbConn, *args):
    ret = dbConn.get(*args)
    if ret is not None:
        ret = octets.octs2str(ret)

    return ret
Esempio n. 33
0
 def test_octs2str_empty(self):
     assert not octets.octs2str(bytes([]))
Esempio n. 34
0
def lindex(dbConn, *args):
    ret = dbConn.lindex(*args)
    if ret is not None:
        ret = octets.octs2str(ret)

    return ret
Esempio n. 35
0
 def test_octs2str(self):
     assert '\x01\x02\x03' == octets.octs2str('\x01\x02\x03')
Esempio n. 36
0
    def prettyIn(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT parsing into base SNMP value

        Proper parsing seems impossible due to ambiguities.
        Here we are trying to do our best, but be prepared
        for failures on complicated DISPLAY-HINTs.

        Keep in mind that this parser only works with "text"
        input meaning `unicode` (Py2) or `str` (Py3).
        """
        for base in inspect.getmro(self.__class__):
            if not issubclass(base, TextualConvention) and issubclass(
                    base, Asn1Item):
                break
        else:
            raise SmiError(
                'TEXTUAL-CONVENTION has no underlying SNMP base type')

        if self.displayHint and (
                self.__integer.isSuperTypeOf(self, matchConstraints=False)
                and self.getNamedValues() or self.__unsigned32.isSuperTypeOf(
                    self, matchConstraints=False) or
                self.__timeticks.isSuperTypeOf(self, matchConstraints=False)):
            value = str(value)

            _ = lambda t, f=0: (t, f)
            displayHintType, decimalPrecision = _(*self.displayHint.split('-'))
            if displayHintType == 'x' and (value.startswith('0x')
                                           or value.startswith('-0x')):
                try:
                    if value.startswith('-'):
                        return base.prettyIn(self, -int(value[3:], 16))
                    else:
                        return base.prettyIn(self, int(value[2:], 16))
                except Exception:
                    raise SmiError('integer evaluation error: %s' %
                                   sys.exc_info()[1])
            elif displayHintType == 'd':
                try:
                    return base.prettyIn(
                        self, int(float(value) * 10**int(decimalPrecision)))
                except Exception:
                    raise SmiError('float evaluation error: %s' %
                                   sys.exc_info()[1])
            elif displayHintType == 'o' and (value.startswith('0')
                                             or value.startswith('-0')):
                try:
                    return base.prettyIn(self, int(value, 8))
                except Exception:
                    raise SmiError('octal evaluation error: %s' %
                                   sys.exc_info()[1])
            elif displayHintType == 'b' and (value.startswith('B')
                                             or value.startswith('-B')):
                negative = value.startswith('-')
                if negative:
                    value = value[2:]
                else:
                    value = value[1:]
                value = [x != '0' and 1 or 0 for x in value]
                binValue = 0
                while value:
                    binValue <<= value[0]
                    del value[0]
                return base.prettyIn(self, binValue)
            else:
                raise SmiError('Unsupported numeric type spec "%s" at %s' %
                               (displayHintType, self.__class__.__name__))

        elif self.displayHint and self.__octetString.isSuperTypeOf(
                self, matchConstraints=False):
            numBase = {'x': 16, 'd': 10, 'o': 8}
            numDigits = {
                'x': octets.str2octs(string.hexdigits),
                'o': octets.str2octs(string.octdigits),
                'd': octets.str2octs(string.digits)
            }

            # how do we know if object is initialized with display-hint
            # formatted text? based on "text" input maybe?
            # That boils down to `str` object on Py3 or `unicode` on Py2.
            if octets.isStringType(value) and not octets.isOctetsType(value):
                value = base.prettyIn(self, value)
            else:
                return base.prettyIn(self, value)

            outputValue = octets.str2octs('')
            runningValue = value
            displayHint = self.displayHint

            while runningValue and displayHint:
                # 1 this information is totally lost, just fail explicitly
                if displayHint[0] == '*':
                    raise SmiError('Can\'t parse "*" in DISPLAY-HINT (%s)' %
                                   self.__class__.__name__)

                # 2 this becomes ambiguous when it comes to rendered value
                octetLength = ''
                while displayHint and displayHint[0] in string.digits:
                    octetLength += displayHint[0]
                    displayHint = displayHint[1:]

                # length is mandatory but people ignore that
                if not octetLength:
                    octetLength = len(runningValue)

                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise SmiError('Bad octet length: %s' % octetLength)

                if not displayHint:
                    raise SmiError('Short octet length: %s' % self.displayHint)

                # 3
                displayFormat = displayHint[0]
                displayHint = displayHint[1:]

                # 4 this is the lifesaver -- we could use it as an anchor
                if displayHint and displayHint[
                        0] not in string.digits and displayHint[0] != '*':
                    displaySep = displayHint[0]
                    displayHint = displayHint[1:]
                else:
                    displaySep = ''

                # 5 is probably impossible to support

                if displayFormat in ('a', 't'):
                    outputValue += runningValue[:octetLength]
                elif displayFormat in numBase:
                    if displaySep:
                        guessedOctetLength = runningValue.find(
                            octets.str2octs(displaySep))
                        if guessedOctetLength == -1:
                            guessedOctetLength = len(runningValue)
                    else:
                        for idx in range(len(runningValue)):
                            if runningValue[idx] not in numDigits[
                                    displayFormat]:
                                guessedOctetLength = idx
                                break
                        else:
                            guessedOctetLength = len(runningValue)

                    try:
                        num = int(
                            octets.octs2str(runningValue[:guessedOctetLength]),
                            numBase[displayFormat])
                    except Exception:
                        raise SmiError('Display format eval failure: %s: %s' %
                                       (runningValue[:guessedOctetLength],
                                        sys.exc_info()[1]))

                    num_as_bytes = []
                    if num:
                        while num:
                            num_as_bytes.append(num & 0xFF)
                            num >>= 8
                    else:
                        num_as_bytes = [0]

                    while len(num_as_bytes) < octetLength:
                        num_as_bytes.append(0)

                    num_as_bytes.reverse()

                    outputValue += octets.ints2octs(num_as_bytes)

                    if displaySep:
                        guessedOctetLength += 1

                    octetLength = guessedOctetLength
                else:
                    raise SmiError('Unsupported display format char: %s' %
                                   displayFormat)

                runningValue = runningValue[octetLength:]

                if not displayHint:
                    displayHint = self.displayHint

            return base.prettyIn(self, outputValue)

        else:
            return base.prettyIn(self, value)
Esempio n. 37
0
 def test_octs2str_empty(self):
     assert not octets.octs2str('')