Exemple #1
0
    def writeDate(self, d):
        """
        Writes a date to the data stream.

        @type d: Instance of C{datetime.datetime}
        @param d: The date to be encoded to the AMF0 data stream.
        """
        if isinstance(d, datetime.time):
            raise pyamf.EncodeError(
                'A datetime.time instance was found but AMF0 has no way to '
                'encode time objects. Please use datetime.datetime instead '
                '(got:%r)' % (d,)
            )

        # According to the Red5 implementation of AMF0, dates references are
        # created, but not used.
        if self.timezone_offset is not None:
            d -= self.timezone_offset

        secs = util.get_timestamp(d)
        tz = 0

        self.writeType(TYPE_DATE)
        self.stream.write_double(secs * 1000.0)
        self.stream.write_short(tz)
Exemple #2
0
    def writeDate(self, n):
        """
        Writes a C{datetime} instance to the stream.

        @type n: L{datetime}
        @param n: The C{Date} data to be encoded to the AMF3 data stream.
        """
        if isinstance(n, datetime.time):
            raise pyamf.EncodeError(
                'A datetime.time instance was found but '
                'AMF3 has no way to encode time objects. Please use '
                'datetime.datetime instead (got:%r)' % (n, ))

        self.stream.write(TYPE_DATE)

        ref = self.context.getObjectReference(n)

        if ref != -1:
            self._writeInteger(ref << 1)

            return

        self.context.addObject(n)

        self.stream.write_uchar(REFERENCE_BIT)

        if self.timezone_offset is not None:
            n -= self.timezone_offset

        ms = util.get_timestamp(n)
        self.stream.write_double(ms * 1000.0)
Exemple #3
0
    def writeType(self, type):
        """
        Writes the type to the stream.

        @type   type: C{int}
        @param  type: ActionScript type.

        @raise pyamf.EncodeError: AMF0 type is not recognized.
        """
        if type not in ACTIONSCRIPT_TYPES:
            raise pyamf.EncodeError("Unknown AMF0 type 0x%02x at %d" %
                                    (type, self.stream.tell() - 1))

        self.stream.write_uchar(type)
Exemple #4
0
    def writeElement(self, data):
        """
        Writes the data.

        @type data: C{mixed}
        @param data: The data to be encoded to the AMF0 data stream.
        @raise EncodeError: Cannot find encoder func.
        """
        func = self._writeElementFunc(data)

        if func is None:
            raise pyamf.EncodeError("Cannot find encoder func for %r" %
                                    (data, ))

        func(data)
Exemple #5
0
def convert_Decimal(x, encoder):
    """
    Called when an instance of U{decimal.Decimal<http://
    docs.python.org/library/decimal.html#decimal-objects>} is about to be
    encoded to an AMF stream.

    @return: If the encoder is in 'strict' mode then C{x} will be converted to
        a float. Otherwise an L{pyamf.EncodeError} with a friendly message is
        raised.
    """
    if encoder.strict is False:
        return float(x)

    raise pyamf.EncodeError(
        'Unable to encode decimal.Decimal instances as there is no way to '
        'guarantee exact conversion. Use strict=False to convert to a float.')
Exemple #6
0
    def _getObjectAttrs(self, o, alias):
        obj_attrs = None

        if alias is not None:
            attrs = alias.getAttrs(o)

            if attrs is not None:
                obj_attrs = {}

                for at in attrs:
                    obj_attrs[at] = getattr(o, at)

        if obj_attrs is None:
            obj_attrs = util.get_attrs(o)

        if obj_attrs is None:
            raise pyamf.EncodeError('Unable to determine object attributes')

        return obj_attrs
Exemple #7
0
    def _getObjectAttrs(self, o, alias):
        """
        @raise pyamf.EncodeError: Unable to determine object attributes.
        """
        obj_attrs = None

        if alias is not None:
            obj_attrs = {}

            for attrs in alias.getAttributes(o):
                obj_attrs.update(attrs)

        if obj_attrs is None:
            obj_attrs = util.get_attrs(o)

        if obj_attrs is None:
            raise pyamf.EncodeError('Unable to determine object attributes')

        return obj_attrs
Exemple #8
0
    def writeElement(self, data):
        """
        Encodes C{data} to AMF. If the data is not able to be matched to an AMF
        type, then L{pyamf.EncodeError} will be raised.
        """
        key = type(data)
        func = None

        try:
            func = self._func_cache[key]
        except KeyError:
            func = self.getTypeFunc(data)

            if func is None:
                raise pyamf.EncodeError('Unable to encode %r (type %r)' %
                                        (data, key))

            self._func_cache[key] = func

        func(data)
Exemple #9
0
def convert_Decimal(x, encoder):
    """
    Called when an instance of L{decimal.Decimal} is about to be encoded to
    an AMF stream.

    @param x: The L{decimal.Decimal} instance to encode.
    @param encoder: The L{pyamf.BaseEncoder} instance about to perform the
        operation.
    @return: If the encoder is in 'strict' mode then C{x} will be converted to
        a float. Otherwise an L{pyamf.EncodeError} with a friendly message is
        raised.
    """
    if encoder is not None and isinstance(encoder, pyamf.BaseEncoder):
        if encoder.strict is False:
            return float(x)

    raise pyamf.EncodeError(
        'Unable to encode decimal.Decimal instances as '
        'there is no way to guarantee exact conversion. Use strict=False to '
        'convert to a float.')
Exemple #10
0
    def writeElement(self, data):
        """
        Writes the data.

        @type data: C{mixed}
        @param data: The data to be encoded to the AMF0 data stream.
        @raise EncodeError: Cannot find encoder func.
        """
        func = self._writeElementFunc(data)

        if func is None:
            raise pyamf.EncodeError("Cannot find encoder func for %r" % (data,))
        else:
            try:
                func(data)
            except (KeyboardInterrupt, SystemExit):
                raise
            except pyamf.EncodeError:
                raise
            except:
                #raise pyamf.EncodeError("Unable to encode '%r'" % (data,))
                raise
Exemple #11
0
    def writeDict(self, n):
        """
        Writes a C{dict} to the stream.

        @type n: C{__builtin__.dict}
        @param n: The C{dict} data to be encoded to the AMF3 data stream.
        @raise ValueError: Non C{int}/C{str} key value found in the C{dict}
        @raise EncodeError: C{dict} contains empty string keys.
        """
        # Design bug in AMF3 that cannot read/write empty key strings
        # for more info
        if '' in n:
            raise pyamf.EncodeError("dicts cannot contain empty string keys")

        if self.use_proxies:
            self.writeProxy(n)

            return

        self.stream.write(TYPE_ARRAY)

        ref = self.context.getObjectReference(n)

        if ref != -1:
            self._writeInteger(ref << 1)

            return

        self.context.addObject(n)

        # The AMF3 spec demands that all str based indicies be listed first
        keys = list(n.keys())
        int_keys = []
        str_keys = []

        for x in keys:
            if isinstance(x, python.int_types):
                int_keys.append(x)
            elif isinstance(x, python.str_types):
                str_keys.append(x)
            else:
                raise ValueError("Non int/str key value found in dict")

        # Make sure the integer keys are within range
        l = len(int_keys)

        for x in int_keys:
            if l < x <= 0:
                # treat as a string key
                str_keys.append(x)
                del int_keys[int_keys.index(x)]

        int_keys.sort()

        # If integer keys don't start at 0, they will be treated as strings
        if len(int_keys) > 0 and int_keys[0] != 0:
            for x in int_keys:
                str_keys.append(str(x))
                del int_keys[int_keys.index(x)]

        self._writeInteger(len(int_keys) << 1 | REFERENCE_BIT)

        for x in str_keys:
            self.serialiseString(x)
            self.writeElement(n[x])

        self.stream.write_uchar(0x01)

        for k in int_keys:
            self.writeElement(n[k])
def encode_time_property(obj, prop, value):
    # PyAMF supports datetime.datetime objects and won't decide what date to
    # add to this time value. Users will have to figure it out themselves
    raise pyamf.EncodeError('ndb.TimeProperty is not supported by PyAMF')
 def __writeamf__(self, data_output):
     raise pyamf.EncodeError("__writeamf__ is not implemented for this class: %s." % self)
 def __readamf__(self, data_input):
     raise pyamf.EncodeError("__readamf__ is not implemented for this class: %s." % self)
Exemple #15
0
 def writeFunc(self, *args, **kwargs):
     """
     Functions cannot be serialised.
     """
     raise pyamf.EncodeError("Callables cannot be serialised")
Exemple #16
0
 def writeClass(self, *args, **kwargs):
     """
     Classes cannot be serialised.
     """
     raise pyamf.EncodeError("Class objects cannot be serialised")