Created
June 2, 2017 09:13
-
-
Save alexandnpu/5bd3f2d84dc09466dffed7e47a6dd9b2 to your computer and use it in GitHub Desktop.
During my work, i have to use a python client to talk to a protobuf server based on netty. I can not find some python helpers to parse the length prepender that netty adds to each protobuf message. So I wrote the following code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# the following is talk to protobuf server based on netty 4.1.11.Final | |
ONE_BYTE_MASK = 0xffffffff << 7 | |
TWO_BYTES_MASK = 0xffffffff << 14 | |
THREE_BYTES_MASK = 0xffffffff << 21 | |
FOUR_BYTES_MASK = 0xffffffff << 28 | |
def how_many_bytes_this_length_take(package_len): | |
result = package_len & ONE_BYTE_MASK | |
if result == 0: | |
return 1 | |
result = package_len & TWO_BYTES_MASK | |
if result == 0: | |
return 2 | |
result = package_len & THREE_BYTES_MASK | |
if result == 0: | |
return 3 | |
result = package_len & FOUR_BYTES_MASK | |
if result == 0: | |
return 4 | |
return 5 | |
def get_packet_len(sock): | |
one_byte = sock.recv(1) | |
one_byte_value, = unpack(">B", one_byte) | |
if one_byte_value >= 0: | |
return one_byte_value | |
result = one_byte_value & 127 | |
one_byte = sock.recv(1) | |
one_byte_value, = unpack(">B", one_byte) | |
if one_byte_value >= 0: | |
one_byte_value = one_byte_value << 7 | |
return result | one_byte_value | |
one_byte_value = (one_byte_value & 127) << 7 | |
result = result | one_byte_value | |
one_byte = sock.recv(1) | |
one_byte_value, = unpack(">B", one_byte) | |
if one_byte_value >= 0: | |
one_byte_value = one_byte_value << 14 | |
return result | one_byte_value | |
one_byte_value = (one_byte_value & 127) << 14 | |
result = result | one_byte_value | |
one_byte = sock.recv(1) | |
one_byte_value, = unpack(">B", one_byte) | |
if one_byte_value >= 0: | |
one_byte_value = one_byte_value << 21 | |
return result | one_byte_value | |
one_byte_value = (one_byte_value & 127) << 21 | |
result = result | one_byte_value | |
one_byte = sock.recv(1) | |
one_byte_value, = unpack(">B", one_byte) | |
if one_byte_value < 0: | |
raise Exception("malformed package") | |
one_byte_value = (one_byte_value & 127) << 28 | |
return result | one_byte_value | |
def generate_length_prepender(length): | |
num_of_bytes = how_many_bytes_this_length_take(length) | |
format_str = ">" | |
for i in range(num_of_bytes): | |
format_str += "B" | |
return pack(format_str, length) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment