read method
Reads data from the connection.
If length
is provided, reads exactly that many bytes.
Otherwise, reads whatever is available.
Implementation
@override
Future<Uint8List> read([int? length]) async {
_log.finer('SecuredConnection.read: Called with length: $length, _decryptedBuffer.length: ${_decryptedBuffer.length}'); // ADDED
if (length == 0) {
_log.finer('SecuredConnection.read: Requested length is 0, returning empty Uint8List.'); // ADDED
return Uint8List(0); // Handle zero length request immediately
}
if (length == null) {
if (!_decryptedBuffer.isEmpty) {
final data = _decryptedBuffer.takeAll();
_log.finer('SecuredConnection.read (length=null): Returning buffered data of length ${data.length}. Data preview: ${data.take(20).toList()}'); // ADDED
return data;
}
final decryptedMessage = await _readAndDecryptMessage();
_log.finer('SecuredConnection.read (length=null): Returning directly from _readAndDecryptMessage, length ${decryptedMessage.length}. Data preview: ${decryptedMessage.take(20).toList()}'); // ADDED
return decryptedMessage;
}
// length is not null here
while (_decryptedBuffer.length < length) {
Uint8List decryptedChunk;
try {
_log.finer('SecuredConnection.read (length=$length): _decryptedBuffer.length (${_decryptedBuffer.length}) < requested ($length). Calling _readAndDecryptMessage().'); // ADDED
decryptedChunk = await _readAndDecryptMessage();
} catch (e) {
_log.finer('SecuredConnection.read (length=$length): Error in _readAndDecryptMessage: $e. Current _decryptedBuffer.length: ${_decryptedBuffer.length}'); // ADDED
if (_decryptedBuffer.length < length) {
rethrow;
}
// If we have enough buffered data despite the error, we can proceed to return it.
break;
}
if (decryptedChunk.isEmpty) { // EOF from _readAndDecryptMessage
_log.finer('SecuredConnection.read (length=$length): _readAndDecryptMessage returned empty (EOF). Breaking loop.'); // ADDED
break;
}
// Use optimized buffer - no more array reallocations!
_decryptedBuffer.add(decryptedChunk);
_log.finer('SecuredConnection.read (length=$length): Added ${decryptedChunk.length} bytes to _decryptedBuffer. New _decryptedBuffer.length: ${_decryptedBuffer.length}'); // ADDED
}
if (_decryptedBuffer.isEmpty) {
_log.finer('SecuredConnection.read (length=$length): _decryptedBuffer is empty after loop. Returning empty Uint8List.'); // ADDED
return Uint8List(0);
}
if (_decryptedBuffer.length >= length) {
final dataToReturn = _decryptedBuffer.takeBytes(length);
_log.finer('SecuredConnection.read (length=$length): Returning ${dataToReturn.length} bytes. Remaining _decryptedBuffer.length: ${_decryptedBuffer.length}. Data preview: ${dataToReturn.take(20).toList()}'); // ADDED
return dataToReturn;
} else { // Less data than requested due to EOF
final dataToReturn = _decryptedBuffer.takeAll();
_log.finer('SecuredConnection.read (length=$length): Returning ${dataToReturn.length} bytes (less than requested due to EOF). _decryptedBuffer is now empty. Data preview: ${dataToReturn.take(20).toList()}'); // ADDED
return dataToReturn;
}
}