@@ -15,23 +15,47 @@ def flush(self) -> bytes | None | Literal[False]:
15
15
"""Ensures that the bytes transform is flushed, for chunked encodings this will produce a new chunk."""
16
16
17
17
18
- class GZipDecoder (BytesTransform ):
19
- __slots__ = [ "decompressor" ]
18
+ class IdemCodec (BytesTransform ):
19
+ """A codec that doesn't change anything, can be used when you need to swap in another codec."""
20
20
21
- def __init__ (self ) -> None :
21
+ def feed (self , chunk : bytes , more : bool = False ) -> bytes | None | Literal [False ]:
22
+ return chunk
23
+
24
+ def flush (
25
+ self ,
26
+ ) -> bytes | None | Literal [False ]:
27
+ return None
28
+
29
+
30
+ class PipelineCodec (BytesTransform ):
31
+ """A way to compose transforms together."""
32
+
33
+ def __init__ (self , transforms : list [BytesTransform ]):
22
34
super ().__init__ ()
23
- self .decompressor = zlib .decompressobj (wbits = zlib .MAX_WBITS | 32 )
35
+ self .transforms : list [BytesTransform ] = transforms
36
+
37
+ def decoder (self ) -> "PipelineCodec" :
38
+ """Returns the decoder/coder pipeline for this codec"""
39
+ return PipelineCodec (reversed (self .transforms ))
24
40
25
41
def feed (self , chunk : bytes , more : bool = False ) -> bytes | None | Literal [False ]:
26
- return self .decompressor .decompress (chunk )
42
+ res : bytes | Literal [False ] | None = chunk
43
+ for t in self .transforms :
44
+ if not res :
45
+ return res
46
+ else :
47
+ res = t .feed (res )
48
+ return res
27
49
28
50
def flush (
29
51
self ,
30
52
) -> bytes | None | Literal [False ]:
31
- return self . decompressor . flush ()
53
+ return None
32
54
33
55
34
56
class GZipEncoder (BytesTransform ):
57
+ """Encode bytes as Gzip"""
58
+
35
59
__slots__ = ["compressor" ]
36
60
37
61
def __init__ (self , compression_level : int = 6 ) -> None :
@@ -47,8 +71,28 @@ def flush(self) -> bytes | None | Literal[False]:
47
71
return self .compressor .flush ()
48
72
49
73
74
+ class GZipDecoder (BytesTransform ):
75
+ """Decodes bytes as Gzip"""
76
+
77
+ __slots__ = ["decompressor" ]
78
+
79
+ def __init__ (self ) -> None :
80
+ super ().__init__ ()
81
+ self .decompressor = zlib .decompressobj (wbits = zlib .MAX_WBITS | 32 )
82
+
83
+ def feed (self , chunk : bytes , more : bool = False ) -> bytes | None | Literal [False ]:
84
+ return self .decompressor .decompress (chunk )
85
+
86
+ def flush (
87
+ self ,
88
+ ) -> bytes | None | Literal [False ]:
89
+ return self .decompressor .flush ()
90
+
91
+
50
92
# SEE: https://httpwg.org/specs/rfc9112.html#chunked.encoding
51
93
class ChunkedEncoder (BytesTransform ):
94
+ """Encodes as chunks"""
95
+
52
96
__slots__ = ["buffer" ]
53
97
54
98
def __init__ (self ) -> None :
@@ -70,6 +114,8 @@ def flush(self) -> bytes | None | Literal[False]:
70
114
71
115
72
116
class ChunkedDecoder (BytesTransform ):
117
+ """Decodes as chunks"""
118
+
73
119
__slots__ = ["buffer" , "chunkSize" , "readingSize" ]
74
120
75
121
def __init__ (self ) -> None :
0 commit comments