from ..compat import OrderedDict
from ..stream_utils import read_bytes

from .base_packet_body import BasePacketBody


class GenericPacketBody(BasePacketBody):
    """
    Provides a generic `__init__` and `raw` method but no decoded data.
    Useful for packets we don't yet know how to decode or as a parent class
    of specific packet body types.
    """

    @classmethod
    def from_stream(cls, f, body_start, body_length):
        obj = cls()
        obj.f = f
        obj._body_start = body_start
        obj._body_length = body_length
        return obj

    def __init__(self):
        self.f = None
        self._body_start = None
        self._body_length = None

    @property
    def raw(self):
        self.f.seek(self._body_start)
        # Beware: Now we're loading into memory.
        return read_bytes(self.f, self._body_length)

    @property
    def decoded(self):
        return None

    def serialize(self):
        return OrderedDict([
            ('raw', self.raw),
            ('decoded', self.decoded),
        ])

@@ -63,16 +63,62 @@
 ad_bytes
+%0Afrom ..exceptions import MalformedPacketError
 %0A%0Afrom .
@@ -470,16 +470,203 @@
 ength):%0A
+        if body_start %3C 0:%0A            raise ValueError('body_start must be zero or above')%0A        if body_length %3C 1:%0A            raise ValueError('body must be at least 1 byte long')%0A%0A
         
@@ -1023,16 +1023,16 @@
 memory.%0A
-
         
@@ -1074,16 +1074,38 @@
 y_length
+, MalformedPacketError
 )%0A%0A    @

Fix `GenericPacketBody` failing tests