mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-08 04:52:30 +00:00
Initial release
The initial release contains the most basic implementation of TLSharp core. This is also fully untested, since no test can be done until more work is done.
This commit is contained in:
87
utils/binary_reader.py
Normal file
87
utils/binary_reader.py
Normal file
@@ -0,0 +1,87 @@
|
||||
from io import BytesIO, BufferedReader
|
||||
import os
|
||||
|
||||
|
||||
class BinaryReader:
|
||||
"""
|
||||
Small utility class to read binary data.
|
||||
Also creates a "Memory Stream" if necessary
|
||||
"""
|
||||
def __init__(self, data=None, stream=None):
|
||||
if data:
|
||||
self.stream = BytesIO(data)
|
||||
elif stream:
|
||||
self.stream = stream
|
||||
else:
|
||||
raise ValueError("Either bytes or a stream must be provided")
|
||||
|
||||
self.reader = BufferedReader(self.stream)
|
||||
|
||||
# region Reading
|
||||
|
||||
def read_int(self, signed=True):
|
||||
return int.from_bytes(self.reader.read(4), signed=signed, byteorder='big')
|
||||
|
||||
def read_long(self, signed=True):
|
||||
return int.from_bytes(self.reader.read(8), signed=signed, byteorder='big')
|
||||
|
||||
def read(self, length):
|
||||
return self.reader.read(length)
|
||||
|
||||
def get_bytes(self):
|
||||
return self.stream.getbuffer()
|
||||
|
||||
# endregion
|
||||
|
||||
# region Telegram custom reading
|
||||
|
||||
def tgread_bytes(self):
|
||||
first_byte = self.read(1)
|
||||
if first_byte == 254:
|
||||
length = self.read(1) | (self.read(1) << 8) | (self.read(1) << 16)
|
||||
padding = length % 4
|
||||
else:
|
||||
length = first_byte
|
||||
padding = (length + 1) % 4
|
||||
|
||||
data = self.read(length)
|
||||
if padding > 0:
|
||||
padding = 4 - padding
|
||||
self.read(padding)
|
||||
|
||||
return data
|
||||
|
||||
def tgread_string(self):
|
||||
return str(self.tgread_bytes(), encoding='utf-8')
|
||||
|
||||
# endregion
|
||||
|
||||
def close(self):
|
||||
self.reader.close()
|
||||
# TODO Do I need to close the underlying stream?
|
||||
|
||||
# region Position related
|
||||
|
||||
def tell_position(self):
|
||||
"""Tells the current position on the stream"""
|
||||
return self.reader.tell()
|
||||
|
||||
def set_position(self, position):
|
||||
"""Sets the current position on the stream"""
|
||||
self.reader.seek(position)
|
||||
|
||||
def seek(self, offset):
|
||||
"""Seeks the stream position given an offset from the current position. May be negative"""
|
||||
self.reader.seek(offset, os.SEEK_CUR)
|
||||
|
||||
# endregion
|
||||
|
||||
# region with block
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.close()
|
||||
|
||||
# endregion
|
Reference in New Issue
Block a user