parseAndroid method

Future<void> parseAndroid(
  1. Socket socket,
  2. Uri uri,
  3. List<String> responseHeaders,
  4. int requestRangeStart,
  5. int requestRangeEnd,
  6. Map<String, String> headers,
)

Parses and responds to range requests on Android.

Handles segmented download and response for large files.

Implementation

Future<void> parseAndroid(
  Socket socket,
  Uri uri,
  List<String> responseHeaders,
  int requestRangeStart,
  int requestRangeEnd,
  Map<String, String> headers,
) async {
  DownloadTask task =
      DownloadTask(uri: uri, startRange: 0, endRange: 1, headers: headers);
  Uint8List? data = await cache(task);
  int contentLength = 0;
  if (data != null) {
    contentLength = int.tryParse(Utf8Codec().decode(data)) ?? 0;
  }
  if (contentLength == 0) {
    contentLength = await head(uri, headers: headers);
    String filePath = '${await FileExt.createCachePath(task.uri.generateMd5)}'
        '/${task.saveFileName}';
    File file = File(filePath);
    file.writeAsString(contentLength.toString());
    LruCacheSingleton().storagePut(task.matchUrl, file);
  }

  requestRangeEnd = contentLength - 1;
  responseHeaders.add('content-length: ${contentLength - requestRangeStart}');
  responseHeaders.add('content-range: bytes '
      '$requestRangeStart-$requestRangeEnd/$contentLength');
  await socket.append(responseHeaders.join('\r\n'));

  bool downloading = true;
  int startRange =
      requestRangeStart - (requestRangeStart % Config.segmentSize);
  int endRange = startRange + Config.segmentSize - 1;
  int retry = 3;
  while (downloading) {
    DownloadTask task = DownloadTask(
      uri: uri,
      startRange: startRange,
      endRange: endRange,
      headers: headers,
    );
    logD('Request range:${task.startRange}-${task.endRange}');

    Uint8List? data = await cache(task);
    if (data == null) {
      concurrent(task, headers);
      task.priority += 10;
      data = await download(task);
    }
    if (data == null) {
      retry--;
      if (retry == 0) {
        downloading = false;
        break;
      }
      continue;
    }

    int startIndex = 0;
    int? endIndex;
    if (startRange < requestRangeStart) {
      startIndex = requestRangeStart - startRange;
    }
    if (endRange > requestRangeEnd) {
      endIndex = requestRangeEnd - startRange + 1;
    }
    data = data.sublist(startIndex, endIndex);
    socket.done.then((value) {
      downloading = false;
    }).catchError((e) {
      downloading = false;
    });
    bool success = await socket.append(data);
    if (!success) downloading = false;
    startRange += Config.segmentSize;
    endRange = startRange + Config.segmentSize - 1;
    if (startRange > requestRangeEnd) {
      downloading = false;
    }
  }
}