61 @brief Encodes the frame into bytes.
63 @details The encoding process includes:
64 - Converting the stream ID to bytes.
65 - Setting the type field based on the presence of offset, length, and fin attributes.
66 - Appending the offset, length, and data to the values list if they are present.
67 - Combining all parts into a single bytes object.
69 @return The encoded frame as bytes.
71 values = [self.
stream_id.to_bytes(Constants.STREAM_ID_LENGTH,
'big')]
72 type_field = Constants.MIN_TYPE_FIELD
74 type_field = type_field | Constants.OFF_BIT
75 values.append(self.
offset.to_bytes(Constants.OFFSET_LENGTH,
'big'))
77 type_field = type_field | Constants.LEN_BIT
78 values.append(self.
length.to_bytes(Constants.LEN_LENGTH,
'big'))
80 type_field = type_field | Constants.FIN_BIT
82 encoded_frame = type_field.to_bytes(Constants.FRAME_TYPE_FIELD_LENGTH,
'big')
102 @brief Decodes a frame encoded in bytes into a FrameStream instance.
104 @details The decoding process includes:
105 - Extracting the offset, length, fin flag, stream ID, and stream data from the frame.
106 - Creating a new FrameStream instance with the extracted values.
108 @param frame The encoded frame as bytes.
109 @return A new FrameStream instance with the decoded values.
111 offset = Constants.ZERO
112 length = Constants.ZERO
114 type_field = int.from_bytes(frame[:Constants.FRAME_TYPE_FIELD_LENGTH],
'big')
115 index = Constants.FRAME_TYPE_FIELD_LENGTH
116 stream_id = int.from_bytes(frame[index:index + Constants.STREAM_ID_LENGTH],
'big')
117 index += Constants.STREAM_ID_LENGTH
118 if type_field & Constants.OFF_BIT:
119 offset = int.from_bytes(frame[index:index + Constants.OFFSET_LENGTH],
'big')
120 index += Constants.OFFSET_LENGTH
123 if type_field & Constants.LEN_BIT:
124 length = int.from_bytes(frame[index:index + Constants.LEN_LENGTH],
'big')
125 index += Constants.LEN_LENGTH
128 if type_field & Constants.FIN_BIT:
131 return FrameStream(stream_id=stream_id, offset=offset, length=length, fin=fin, data=frame[index:])
136 @brief Determines the end position of the attributes in the frame.
138 @details The process includes:
139 - Calculating the initial end position based on the frame type field length and stream ID length.
140 - Checking if the offset bit is set in the type field and adjusting the end position accordingly.
141 - Checking if the length bit is set in the type field and adjusting the end position accordingly.
143 @param frame The encoded frame as bytes.
144 @return The end position of the attributes in the frame.
146 end_of_data = Constants.FRAME_TYPE_FIELD_LENGTH + Constants.STREAM_ID_LENGTH
147 type_field = int.from_bytes(frame[:Constants.FRAME_TYPE_FIELD_LENGTH],
'big')
148 if type_field & Constants.OFF_BIT:
149 end_of_data += Constants.OFFSET_LENGTH
150 if type_field & Constants.LEN_BIT:
151 end_of_data += Constants.LEN_LENGTH
157 @brief Determines the length of the data in the frame.
159 @details The process includes:
160 - Checking if the end of attributes is less than or equal to the sum of the frame type
161 field length and stream ID length.
162 - If the end of attributes is less than or equal to the sum of the frame type field
163 length and stream ID length plus the offset length.
164 - Otherwise, the length is extracted from the frame after the offset length.
166 @param frame The encoded frame as bytes.
167 @param end_of_attrs The end position of the attributes in the frame.
168 @return The length of the data in the frame.
170 if end_of_attrs <= Constants.FRAME_TYPE_FIELD_LENGTH + Constants.STREAM_ID_LENGTH:
171 return Constants.ZERO
172 index = Constants.FRAME_TYPE_FIELD_LENGTH + Constants.STREAM_ID_LENGTH
173 if end_of_attrs <= index + Constants.OFFSET_LENGTH:
174 return int.from_bytes(frame[index:index + Constants.LEN_LENGTH],
"big")
175 index += Constants.OFFSET_LENGTH
176 return int.from_bytes(frame[index:index + Constants.LEN_LENGTH],
"big")