File size: 5,535 Bytes
0aee47a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
"""

bilibili_api.BytesReader



读字节流助手。

"""
import struct

from .varint import read_varint


class BytesReader:
    """

    读字节流助手类。

    """

    def __init__(self, stream: bytes):
        """



        Args:

            stream (bytes): 字节流

        """
        self.__stream = stream
        self.__offset: int = 0

    def has_end(self) -> bool:  # pylint: disable=used-before-assignment
        """

        是否已读到末尾



        Returns:

            bool。

        """
        return self.__offset >= len(self.__stream)

    def double(self, LE=False) -> float:  # pylint: disable=used-before-assignment
        """

        读 double。



        Args:

            LE (bool): 为小端。



        Returns:

            float。

        """
        data = struct.unpack(
            "<d" if LE else ">d", self.__stream[self.__offset : self.__offset + 8]
        )
        self.__offset += 8
        return data[0]

    def float(self, LE=False) -> float:
        """

        读 float。



        Args:

            LE (bool): 为小端。



        Returns:

            float。

        """
        stream = self.__stream[self.__offset : self.__offset + 4]
        data = struct.unpack("<f" if LE else ">f", stream)
        self.__offset += 4
        return data[0]

    def varint(self) -> int:
        """

        读 varint。



        Returns:

            int。

        """
        d, l = read_varint(self.__stream[self.__offset :])
        self.__offset += l
        return d

    def byte(self) -> int:
        """

        读 byte。



        Returns:

            int。

        """
        data = self.__stream[self.__offset]
        self.__offset += 1
        return data

    def string(self, encoding="utf8") -> str:
        """

        读 string。



        Args:

            encoding (str):  编码方式。



        Returns:

            str。

        """
        str_len = self.varint()
        data = self.__stream[self.__offset : self.__offset + str_len]
        self.__offset += str_len
        return data.decode(encoding=encoding, errors="ignore")

    def bool(self) -> bool:
        """

        读 bool。



        Returns:

            bool。

        """
        data = self.__stream[self.__offset]
        self.__offset += 1
        return data == 1

    def bytes_string(self) -> bytes:
        """

        读原始字节流。



        Returns:

            bytes。

        """
        str_len = self.varint()
        data = self.__stream[self.__offset : self.__offset + str_len]
        self.__offset += str_len
        return data

    def fixed16(self, LE=False) -> int:
        """

        读 Fixed int16。



        Args:

            LE (bool): 为小端。



        Returns:

            int。

        """
        data = struct.unpack(
            "<h" if LE else ">h", self.__stream[self.__offset : self.__offset + 2]
        )
        self.__offset += 2
        return data[0]

    def fixed32(self, LE=False) -> int:
        """

        读 Fixed int32.



        Args:

            LE (bool): 为小端。



        Returns:

            int。

        """
        data = struct.unpack(
            "<i" if LE else ">i", self.__stream[self.__offset : self.__offset + 4]
        )
        self.__offset += 4
        return data[0]

    def fixed64(self, LE=False) -> int:
        """

        读 Fixed int64。



        Args:

            LE (bool): 为小端。



        Returns:

            int。

        """
        data = struct.unpack(
            "<q" if LE else ">q", self.__stream[self.__offset : self.__offset + 8]
        )
        self.__offset += 8
        return data[0]

    def ufixed16(self, LE=False) -> int:
        """

        读 Unsigned fixed Int16。



        Args:

            LE (bool): 为小端。



        Returns:

            int。

        """
        data = struct.unpack(
            "<H" if LE else ">H", self.__stream[self.__offset : self.__offset + 2]
        )
        self.__offset += 2
        return data[0]

    def ufixed32(self, LE=False) -> int:
        """

        读 Unsigned fixed Int32。



        Args:

            LE (bool): 为小端。



        Returns:

            int。

        """
        data = struct.unpack(
            "<I" if LE else ">I", self.__stream[self.__offset : self.__offset + 4]
        )
        self.__offset += 4
        return data[0]

    def ufixed64(self, LE=False) -> int:
        """

        读 Unsigned fixed Int64。



        Args:

            LE (bool): 为小端。



        Returns:

            int。

        """
        data = struct.unpack(
            "<Q" if LE else ">Q", self.__stream[self.__offset : self.__offset + 8]
        )
        self.__offset += 8
        return data[0]

    def set_pos(self, pos: int) -> None:
        """

        设置读取起始位置。



        Args:

            pos (int): 读取起始位置。

        """
        if pos < 0:
            raise Exception("读取位置不能小于 0")

        if pos >= len(self.__stream):
            raise Exception("读取位置超过字节流长度")

        self.__offset = pos

    def get_pos(self) -> int:
        """

        获取当前位置。



        Returns:

            int, 当前位置。

        """
        return self.__offset