LCOV - code coverage report
Current view: top level - path-1.8.0/lib/src/style - windows.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1 68 1.5 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import '../characters.dart' as chars;
       6             : import '../internal_style.dart';
       7             : import '../parsed_path.dart';
       8             : import '../utils.dart';
       9             : 
      10             : // `0b100000` can be bitwise-ORed with uppercase ASCII letters to get their
      11             : // lowercase equivalents.
      12             : const _asciiCaseBit = 0x20;
      13             : 
      14             : /// The style for Windows paths.
      15             : class WindowsStyle extends InternalStyle {
      16          11 :   WindowsStyle();
      17             : 
      18             :   @override
      19             :   final name = 'windows';
      20             :   @override
      21             :   final separator = '\\';
      22             :   final separators = const ['/', '\\'];
      23             : 
      24             :   // Deprecated properties.
      25             : 
      26             :   @override
      27             :   final separatorPattern = RegExp(r'[/\\]');
      28             :   @override
      29             :   final needsSeparatorPattern = RegExp(r'[^/\\]$');
      30             :   @override
      31             :   final rootPattern = RegExp(r'^(\\\\[^\\]+\\[^\\/]+|[a-zA-Z]:[/\\])');
      32             :   @override
      33             :   final relativeRootPattern = RegExp(r'^[/\\](?![/\\])');
      34             : 
      35           0 :   @override
      36           0 :   bool containsSeparator(String path) => path.contains('/');
      37             : 
      38           0 :   @override
      39             :   bool isSeparator(int codeUnit) =>
      40           0 :       codeUnit == chars.slash || codeUnit == chars.backslash;
      41             : 
      42           0 :   @override
      43             :   bool needsSeparator(String path) {
      44           0 :     if (path.isEmpty) return false;
      45           0 :     return !isSeparator(path.codeUnitAt(path.length - 1));
      46             :   }
      47             : 
      48           0 :   @override
      49             :   int rootLength(String path, {bool withDrive = false}) {
      50           0 :     if (path.isEmpty) return 0;
      51           0 :     if (path.codeUnitAt(0) == chars.slash) return 1;
      52           0 :     if (path.codeUnitAt(0) == chars.backslash) {
      53           0 :       if (path.length < 2 || path.codeUnitAt(1) != chars.backslash) return 1;
      54             :       // The path is a network share. Search for up to two '\'s, as they are
      55             :       // the server and share - and part of the root part.
      56           0 :       var index = path.indexOf('\\', 2);
      57           0 :       if (index > 0) {
      58           0 :         index = path.indexOf('\\', index + 1);
      59           0 :         if (index > 0) return index;
      60             :       }
      61           0 :       return path.length;
      62             :     }
      63             :     // If the path is of the form 'C:/' or 'C:\', with C being any letter, it's
      64             :     // a root part.
      65           0 :     if (path.length < 3) return 0;
      66             :     // Check for the letter.
      67           0 :     if (!isAlphabetic(path.codeUnitAt(0))) return 0;
      68             :     // Check for the ':'.
      69           0 :     if (path.codeUnitAt(1) != chars.colon) return 0;
      70             :     // Check for either '/' or '\'.
      71           0 :     if (!isSeparator(path.codeUnitAt(2))) return 0;
      72             :     return 3;
      73             :   }
      74             : 
      75           0 :   @override
      76           0 :   bool isRootRelative(String path) => rootLength(path) == 1;
      77             : 
      78           0 :   @override
      79             :   String? getRelativeRoot(String path) {
      80           0 :     final length = rootLength(path);
      81           0 :     if (length == 1) return path[0];
      82             :     return null;
      83             :   }
      84             : 
      85           0 :   @override
      86             :   String pathFromUri(Uri uri) {
      87           0 :     if (uri.scheme != '' && uri.scheme != 'file') {
      88           0 :       throw ArgumentError("Uri $uri must have scheme 'file:'.");
      89             :     }
      90             : 
      91           0 :     var path = uri.path;
      92           0 :     if (uri.host == '') {
      93             :       // Drive-letter paths look like "file:///C:/path/to/file". The
      94             :       // replaceFirst removes the extra initial slash. Otherwise, leave the
      95             :       // slash to match IE's interpretation of "/foo" as a root-relative path.
      96           0 :       if (path.length >= 3 && path.startsWith('/') && isDriveLetter(path, 1)) {
      97           0 :         path = path.replaceFirst('/', '');
      98             :       }
      99             :     } else {
     100             :       // Network paths look like "file://hostname/path/to/file".
     101           0 :       path = '\\\\${uri.host}$path';
     102             :     }
     103           0 :     return Uri.decodeComponent(path.replaceAll('/', '\\'));
     104             :   }
     105             : 
     106           0 :   @override
     107             :   Uri absolutePathToUri(String path) {
     108           0 :     final parsed = ParsedPath.parse(path, this);
     109           0 :     if (parsed.root!.startsWith(r'\\')) {
     110             :       // Network paths become "file://server/share/path/to/file".
     111             : 
     112             :       // The root is of the form "\\server\share". We want "server" to be the
     113             :       // URI host, and "share" to be the first element of the path.
     114           0 :       final rootParts = parsed.root!.split('\\').where((part) => part != '');
     115           0 :       parsed.parts.insert(0, rootParts.last);
     116             : 
     117           0 :       if (parsed.hasTrailingSeparator) {
     118             :         // If the path has a trailing slash, add a single empty component so the
     119             :         // URI has a trailing slash as well.
     120           0 :         parsed.parts.add('');
     121             :       }
     122             : 
     123           0 :       return Uri(
     124           0 :           scheme: 'file', host: rootParts.first, pathSegments: parsed.parts);
     125             :     } else {
     126             :       // Drive-letter paths become "file:///C:/path/to/file".
     127             : 
     128             :       // If the path is a bare root (e.g. "C:\"), [parsed.parts] will currently
     129             :       // be empty. We add an empty component so the URL constructor produces
     130             :       // "file:///C:/", with a trailing slash. We also add an empty component if
     131             :       // the URL otherwise has a trailing slash.
     132           0 :       if (parsed.parts.isEmpty || parsed.hasTrailingSeparator) {
     133           0 :         parsed.parts.add('');
     134             :       }
     135             : 
     136             :       // Get rid of the trailing "\" in "C:\" because the URI constructor will
     137             :       // add a separator on its own.
     138           0 :       parsed.parts
     139           0 :           .insert(0, parsed.root!.replaceAll('/', '').replaceAll('\\', ''));
     140             : 
     141           0 :       return Uri(scheme: 'file', pathSegments: parsed.parts);
     142             :     }
     143             :   }
     144             : 
     145           0 :   @override
     146             :   bool codeUnitsEqual(int codeUnit1, int codeUnit2) {
     147           0 :     if (codeUnit1 == codeUnit2) return true;
     148             : 
     149             :     /// Forward slashes and backslashes are equivalent on Windows.
     150           0 :     if (codeUnit1 == chars.slash) return codeUnit2 == chars.backslash;
     151           0 :     if (codeUnit1 == chars.backslash) return codeUnit2 == chars.slash;
     152             : 
     153             :     // If this check fails, the code units are definitely different. If it
     154             :     // succeeds *and* either codeUnit is an ASCII letter, they're equivalent.
     155           0 :     if (codeUnit1 ^ codeUnit2 != _asciiCaseBit) return false;
     156             : 
     157             :     // Now we just need to verify that one of the code units is an ASCII letter.
     158           0 :     final upperCase1 = codeUnit1 | _asciiCaseBit;
     159           0 :     return upperCase1 >= chars.lowerA && upperCase1 <= chars.lowerZ;
     160             :   }
     161             : 
     162           0 :   @override
     163             :   bool pathsEqual(String path1, String path2) {
     164             :     if (identical(path1, path2)) return true;
     165           0 :     if (path1.length != path2.length) return false;
     166           0 :     for (var i = 0; i < path1.length; i++) {
     167           0 :       if (!codeUnitsEqual(path1.codeUnitAt(i), path2.codeUnitAt(i))) {
     168             :         return false;
     169             :       }
     170             :     }
     171             :     return true;
     172             :   }
     173             : 
     174           0 :   @override
     175             :   int canonicalizeCodeUnit(int codeUnit) {
     176           0 :     if (codeUnit == chars.slash) return chars.backslash;
     177           0 :     if (codeUnit < chars.upperA) return codeUnit;
     178           0 :     if (codeUnit > chars.upperZ) return codeUnit;
     179           0 :     return codeUnit | _asciiCaseBit;
     180             :   }
     181             : 
     182           0 :   @override
     183           0 :   String canonicalizePart(String part) => part.toLowerCase();
     184             : }

Generated by: LCOV version 1.14