read method

  1. @override
Future<Uint8List> read([
  1. int? length
])
override

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;
  }
}