read method

Future<void> read()

Read the index file.

Implementation

Future<void> read() async {
  // Make sure file exists, or causing io exception.
  if (!await _file.exists() || !await _blob.exists()) {
    _valid = false;
    return;
  }

  // If index read before, ignoring to read again.
  // Note: if index or blob file were being changed, this will make chaos,
  //   usually this is an abnormal operation.
  if (_valid) return;

  try {
    Uint8List bytes = await _file.readAsBytes();
    ByteData byteData = bytes.buffer.asByteData();
    int byteLength = byteData.lengthInBytes;
    int index = 0;

    // Reserved units.
    index += 4;

    // Read expiredTime.
    if (index + 8 <= byteLength) {
      expiredTime = DateTime.fromMillisecondsSinceEpoch(byteData.getUint64(index, Endian.little));
      index += 8;
    }

    if (index + 8 <= byteLength) {
      // Read lastUsed.
      lastUsed = DateTime.fromMillisecondsSinceEpoch(byteData.getUint64(index, Endian.little));
      index += 8;
    }

    if (index + 8 <= byteLength) {
      // Read lastModified.
      lastModified = DateTime.fromMillisecondsSinceEpoch(byteData.getUint64(index, Endian.little));
      index += 8;
    }

    if (index + 4 <= byteLength) {
      // Read contentLength.
      contentLength = byteData.getUint32(index, Endian.little);
      index += 4;
    }

    // Invalid cache blob size, mark as invalid.
    if (await _blob.length != contentLength) {
      _valid = false;
      return;
    }

    int urlLength;
    if (index + 4 <= byteLength) {
      // Read url.
      urlLength = byteData.getUint32(index, Endian.little);
      index += 4;
    } else {
      return;
    }

    if (index + urlLength <= byteLength) {
      Uint8List urlValue = bytes.sublist(index, index + urlLength);
      url = utf8.decode(urlValue);
      index += urlLength;
    }

    int eTagLength;
    if (index + 2 <= byteLength) {
      // Read eTag.
      eTagLength = byteData.getUint16(index, Endian.little);
      index += 2;
    } else {
      return;
    }

    if (index + eTagLength <= byteLength) {
      if (eTagLength != 0) {
        Uint8List eTagValue = bytes.sublist(index, index + eTagLength);
        eTag = utf8.decode(eTagValue);
      }
      index += eTagLength;
    }


    int headersLength;
    if (index + 4 <= byteLength) {
      // Read eTag.
      headersLength = byteData.getUint32(index, Endian.little);
      index += 4;
    } else {
      return;
    }

    if (index + headersLength <= byteLength) {
      Uint8List headersValue = bytes.sublist(index, index + headersLength);
      headers = utf8.decode(headersValue);
      index += headersLength;
    }

    _valid = true;
  } catch (message, stackTrace) {
    print('Error while reading cache object for $url');
    print('\n$message');
    print('\n$stackTrace');

    // Remove index file while invalid.
    await remove();
  }
}