-
Notifications
You must be signed in to change notification settings - Fork 129
/
snappy_socket.py
59 lines (46 loc) · 1.48 KB
/
snappy_socket.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from __future__ import absolute_import
import snappy
import socket
import errno
class SnappySocket(object):
def __init__(self, socket):
self._decompressor = snappy.StreamDecompressor()
self._socket = socket
self._bootstrapped = None
def __getattr__(self, name):
return getattr(self._socket, name)
def bootstrap(self, data):
if data:
self._bootstrapped = self._decompressor.decompress(data)
def recv(self, size):
return self._recv(size, self._socket.recv)
def read(self, size):
return self._recv(size, self._socket.read)
def recv_into(self, buf, nbytes=0):
# no real support of efficient recv_into()
n = nbytes or len(buf)
data = self.recv(n)
r = len(data)
if r > n:
self._bootstrapped = data[n:]
r = n
buf[:r] = data[:r]
return r
def _recv(self, size, method):
if self._bootstrapped:
data = self._bootstrapped
self._bootstrapped = None
return data
chunk = method(size)
if not chunk:
return chunk
uncompressed = self._decompressor.decompress(chunk)
if not uncompressed:
raise socket.error(errno.EWOULDBLOCK)
return uncompressed
def send(self, data):
return self._socket.send(data)
class SnappyEncoder(object):
@staticmethod
def encode(data):
return snappy.StreamCompressor().compress(data)