def __init__(self, serializer):
        """

        :param serializer: The object serializer to use for WAMP wire-level serialization.
        :type serializer: An object that implements :class:`autobahn.interfaces.IObjectSerializer`.
        """
        self._serializer = serializer

        self._stats_reset = time_ns()
        self._stats_cycle = 0

        self._serialized_bytes = 0
        self._serialized_messages = 0
        self._serialized_rated_messages = 0

        self._unserialized_bytes = 0
        self._unserialized_messages = 0
        self._unserialized_rated_messages = 0

        self._autoreset_rated_messages = None
        self._autoreset_duration = None
        self._autoreset_callback = None
    def serialize(self, msg):
        """
        Implements :func:`autobahn.wamp.interfaces.ISerializer.serialize`
        """
        data, is_binary = msg.serialize(
            self._serializer), self._serializer.BINARY

        # maintain statistics for serialized WAMP message data
        self._serialized_bytes += len(data)
        self._serialized_messages += 1
        self._serialized_rated_messages += int(
            math.ceil(float(len(data)) / self.RATED_MESSAGE_SIZE))

        # maybe auto-reset and trigger user callback ..
        if self._autoreset_callback and (
            (self._autoreset_duration and
             (time_ns() - self._stats_reset) >= self._autoreset_duration) or
            (self._autoreset_rated_messages and
             self.stats_rated_messages() >= self._autoreset_rated_messages)):
            stats = self.stats(reset=True)
            self._autoreset_callback(stats)

        return data, is_binary
    def unserialize(self, payload, isBinary=None):
        """
        Implements :func:`autobahn.wamp.interfaces.ISerializer.unserialize`
        """
        if isBinary is not None:
            if isBinary != self._serializer.BINARY:
                raise ProtocolError(
                    "invalid serialization of WAMP message (binary {0}, but expected {1})"
                    .format(isBinary, self._serializer.BINARY))
        try:
            raw_msgs = self._serializer.unserialize(payload)
        except Exception as e:
            raise ProtocolError(
                "invalid serialization of WAMP message: {0} {1}".format(
                    type(e).__name__, e))

        if self._serializer.NAME == u'flatbuffers':
            msgs = raw_msgs
        else:
            msgs = []
            for raw_msg in raw_msgs:

                if type(raw_msg) != list:
                    raise ProtocolError(
                        "invalid type {0} for WAMP message".format(
                            type(raw_msg)))

                if len(raw_msg) == 0:
                    raise ProtocolError(
                        u"missing message type in WAMP message")

                message_type = raw_msg[0]

                if type(message_type) not in six.integer_types:
                    # CBOR doesn't roundtrip number types
                    # https://bitbucket.org/bodhisnarkva/cbor/issues/6/number-types-dont-roundtrip
                    raise ProtocolError(
                        "invalid type {0} for WAMP message type".format(
                            type(message_type)))

                Klass = self.MESSAGE_TYPE_MAP.get(message_type)

                if Klass is None:
                    raise ProtocolError(
                        "invalid WAMP message type {0}".format(message_type))

                # this might again raise `ProtocolError` ..
                msg = Klass.parse(raw_msg)

                msgs.append(msg)

        # maintain statistics for unserialized WAMP message data
        self._unserialized_bytes += len(payload)
        self._unserialized_messages += len(msgs)
        self._unserialized_rated_messages += int(
            math.ceil(float(len(payload)) / self.RATED_MESSAGE_SIZE))

        # maybe auto-reset and trigger user callback ..
        if self._autoreset_callback and (
            (self._autoreset_duration and
             (time_ns() - self._stats_reset) >= self._autoreset_duration) or
            (self._autoreset_rated_messages and
             self.stats_rated_messages() >= self._autoreset_rated_messages)):
            stats = self.stats(reset=True)
            self._autoreset_callback(stats)

        return msgs
    def stats(self, reset=True, details=False):
        """
        Get (and reset) serializer statistics.

        :param reset: If ``True``, reset the serializer statistics.
        :type reset: bool

        :param details: If ``True``, return detailed statistics split up by serialization/unserialization.
        :type details: bool

        :return: Serializer statistics, eg:

            .. code-block:: json

                {
                    "timestamp": 1574156576688704693,
                    "duration": 34000000000,
                    "bytes": 0,
                    "messages": 0,
                    "rated_messages": 0
                }

        :rtype: dict
        """
        assert (type(reset) == bool)
        assert (type(details) == bool)

        self._stats_cycle += 1

        if details:
            data = {
                'cycle': self._stats_cycle,
                'serializer': self.SERIALIZER_ID,
                'timestamp': self._stats_reset,
                'duration': time_ns() - self._stats_reset,
                'serialized': {
                    'bytes': self._serialized_bytes,
                    'messages': self._serialized_messages,
                    'rated_messages': self._serialized_rated_messages,
                },
                'unserialized': {
                    'bytes': self._unserialized_bytes,
                    'messages': self._unserialized_messages,
                    'rated_messages': self._unserialized_rated_messages,
                }
            }
        else:
            data = {
                'cycle':
                self._stats_cycle,
                'serializer':
                self.SERIALIZER_ID,
                'timestamp':
                self._stats_reset,
                'duration':
                time_ns() - self._stats_reset,
                'bytes':
                self._serialized_bytes + self._unserialized_bytes,
                'messages':
                self._serialized_messages + self._unserialized_messages,
                'rated_messages':
                self._serialized_rated_messages +
                self._unserialized_rated_messages,
            }
        if reset:
            self._serialized_bytes = 0
            self._serialized_messages = 0
            self._serialized_rated_messages = 0
            self._unserialized_bytes = 0
            self._unserialized_messages = 0
            self._unserialized_rated_messages = 0
            self._stats_reset = time_ns()
        return data