netarch/binary.py

92 lines
2.2 KiB
Python

"""Endianness conversions.
This is a blatant rip-off of the golang binary library.
I'm not too proud to steal a nicely-thought-out API.
"""
def byte(v):
return v & 0xff
class ByteOrder:
"A ByteOrder specifies how to convert byte sequences into 16-, 32-, or 64-bit unsigned integers."
pass
class LittleEndian(ByteOrder):
"Little-Endian byte order"
def Uint16(self, b:bytes) -> int:
return b[0] | (b[1]<<8)
def PutUint16(self, v:int) -> bytes:
return bytes([
byte(v),
byte(v>>8),
])
def Uint32(self, b:bytes) -> int:
return b[0] | (b[1]<<8) | (b[2]<<16) | (b[3]<<24)
def PutUint16(self, v:int) -> bytes:
return bytes([
byte(v),
byte(v>>8),
byte(v>>16),
byte(v>>24),
])
def Uint64(self, b:bytes) -> int:
return b[0] | (b[1]<<8) | (b[2]<<16) | (b[3]<<24) | \
(b[4]<<32) | (b[5]<<40) | (b[6]<<48) | (b[7]<<56)
def PutUint64(self, v:int) -> bytes:
return bytes([
byte(v),
byte(v>>8),
byte(v>>16),
byte(v>>24),
byte(v>>32),
byte(v>>40),
byte(v>>48),
byte(v>>56),
])
class BigEndian(ByteOrder):
"Big-Endian byte order"
def Uint16(self, b:bytes) -> int:
return b[1] | (b[0]<<8)
def PutUint16(self, v:int) -> bytes:
return bytes([
byte(v>>8),
byte(v),
])
def Uint32(self, b:bytes) -> int:
return b[3] | (b[2]<<8) | (b[1]<<16) | (b[0]<<24)
def PutUint16(self, v:int) -> bytes:
return bytes([
byte(v>>24),
byte(v>>16),
byte(v>>8),
byte(v),
])
def Uint64(self, b:bytes) -> int:
return b[7] | (b[6]<<8) | (b[5]<<16) | (b[4]<<24) | \
(b[3]<<32) | (b[2]<<40) | (b[1]<<48) | (b[0]<<56)
def PutUint64(self, v:int) -> bytes:
return bytes([
byte(v>>56),
byte(v>>48),
byte(v>>40),
byte(v>>32),
byte(v>>24),
byte(v>>16),
byte(v>>8),
byte(v),
])