URIParser constructor

URIParser(
  1. String? data, {
  2. List<String> networkSchemes = kDefaultNetworkSchemes,
})

URIParser

Parses a String URI to usable File, Directory or Uri result.

Implementation

URIParser(this.data, {List<String> networkSchemes = kDefaultNetworkSchemes}) {
  var value = data?.trim();
  if (value == null || value.isEmpty) return;
  // Get rid of quotes, if any.
  if (value.startsWith('"') && value.endsWith('"')) {
    value = value.substring(1, value.length - 1);
  }
  // Dart's [Uri] & [File] classes on Windows use (based on testing & user-feedback so far):
  // * Three slashes i.e. file:/// for storage file paths.
  // * Two slashes i.e. file:// for network paths.
  // Make sure to convert:
  // * Storage file URI with two slashes to three slashes for correct parsing.
  // * Network file URI with three slashes to two slashes for correct parsing.
  if (Platform.isWindows && value.toLowerCase().startsWith(kFileScheme2)) {
    bool storage = true;
    try {
      // Check if the first character after file:// is a number.
      final character = value
          .split(kFileScheme2)
          .last
          .split('/')
          .firstWhere((e) => e.isNotEmpty)[0];
      storage = int.tryParse(character) == null;
    } catch (_) {}
    if (storage) {
      // Replace two slashes with three slashes.
      if (value.toLowerCase().startsWith(kFileScheme2) &&
          !value.toLowerCase().startsWith(kFileScheme3)) {
        value = '$kFileScheme3${value.substring(kFileScheme2.length)}';
      }
    } else {
      // Replace three slashes with two slashes.
      if (value.toLowerCase().startsWith(kFileScheme3)) {
        value = '$kFileScheme2${value.substring(kFileScheme3.length)}';
      }
    }
  }
  try {
    final resource = Uri.parse(value);
    // Resolve the network scheme.
    bool network = false;
    for (final scheme in networkSchemes) {
      if (resource.isScheme(scheme)) {
        network = true;
        break;
      }
    }
    // Resolve the FILE scheme.
    if (resource.isScheme('FILE')) {
      var path = resource.toFilePath();
      if (FS.typeSync_(path) == FileSystemEntityType.file) {
        if (Platform.isWindows) {
          path = path.replaceAll('\\', '/');
        }
        type = URIType.file;
        file = File(path);
      }
      if (FS.typeSync_(path) == FileSystemEntityType.directory) {
        if (Platform.isWindows) {
          path = path.replaceAll('\\', '/');
        }
        type = URIType.directory;
        directory = Directory(path);
      }
    } else if (network) {
      type = URIType.network;
      uri = resource;
    }
  } catch (_) {}
  // Resolve direct file or directory paths.
  if (type == URIType.other) {
    try {
      if (FS.typeSync_(value) == FileSystemEntityType.file) {
        if (Platform.isWindows) {
          value = value.replaceAll('\\', '/');
        }
        type = URIType.file;
        file = File(value);
      }
      if (FS.typeSync_(value) == FileSystemEntityType.directory) {
        if (Platform.isWindows) {
          value = value.replaceAll('\\', '/');
        }
        type = URIType.directory;
        directory = Directory(value);
      }
    } catch (_) {}
  }
}