Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

getWin32PathType

Get the path type of a Win32 namespace path. Similar to RtlDetermineDosPathNameType_U. If T is u16, then path should be encoded as WTF-16LE.

path.getWin32PathType
pub fn getWin32PathType(comptime T: type, path: []const T) Win32PathType

File

lib/std/fs/path.zig:2590

Code

pub fn getWin32PathType(comptime T: type, path: []const T) Win32PathType {
    if (path.len < 1) return .relative;

    const windows_path = std.fs.path.PathType.windows;
    if (windows_path.isSep(T, path[0])) {
        // \x
        if (path.len < 2 or !windows_path.isSep(T, path[1])) return .rooted;
        // \\. or \\?
        if (path.len > 2 and (path[2] == mem.nativeToLittle(T, '.') or path[2] == mem.nativeToLittle(T, '?'))) {
            // exactly \\. or \\? with nothing trailing
            if (path.len == 3) return .root_local_device;
            // \\.\x or \\?\x
            if (windows_path.isSep(T, path[3])) return .local_device;
        }
        // \\x
        return .unc_absolute;
    } else {
        // Some choice has to be made about how non-ASCII code points as drive-letters are handled, since
        // path[0] is a different size for WTF-16 vs WTF-8, leading to a potential mismatch in classification
        // for a WTF-8 path and its WTF-16 equivalent. For example, `€:\` encoded in WTF-16 is three code
        // units `<0x20AC>:\` whereas `€:\` encoded as WTF-8 is 6 code units `<0xE2><0x82><0xAC>:\` so
        // checking path[0], path[1] and path[2] would not behave the same between WTF-8/WTF-16.
        //
        // `RtlDetermineDosPathNameType_U` exclusively deals with WTF-16 and considers
        // `€:\` a drive-absolute path, but code points that take two WTF-16 code units to encode get
        // classified as a relative path (e.g. with U+20000 as the drive-letter that'd be encoded
        // in WTF-16 as `<0xD840><0xDC00>:\` and be considered a relative path).
        //
        // The choice made here is to emulate the behavior of `RtlDetermineDosPathNameType_U` for both
        // WTF-16 and WTF-8. This is because, while unlikely and not supported by the Disk Manager GUI,
        // drive letters are not actually restricted to A-Z. Using `SetVolumeMountPointW` will allow you
        // to set any byte value as a drive letter, and going through `IOCTL_MOUNTMGR_CREATE_POINT` will
        // allow you to set any WTF-16 code unit as a drive letter.
        //
        // Non-A-Z drive letters don't interact well with most of Windows, but certain things do work, e.g.
        // `cd /D €:\` will work, filesystem functions still work, etc.
        //
        // The unfortunate part of this is that this makes handling WTF-8 more complicated as we can't
        // just check path[0], path[1], path[2].
        const colon_i: usize = switch (T) {
            u8 => i: {
                const code_point_len = std.unicode.utf8ByteSequenceLength(path[0]) catch return .relative;
                // Conveniently, 4-byte sequences in WTF-8 have the same starting code point
                // as 2-code-unit sequences in WTF-16.
                if (code_point_len > 3) return .relative;
                break :i code_point_len;
            },
            u16 => 1,
            else => @compileError("unsupported type: " ++ @typeName(T)),
        };
        // x
        if (path.len < colon_i + 1 or path[colon_i] != mem.nativeToLittle(T, ':')) return .relative;
        // x:\
        if (path.len > colon_i + 1 and windows_path.isSep(T, path[colon_i + 1])) return .drive_absolute;
        // x:
        return .drive_relative;
    }
}