aboutsummaryrefslogtreecommitdiff
path: root/shared/fs/fat32/read/stack.zig
blob: ded95eba752147d47d844fca1522cef33e03fce5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! FAT32 Stack Operations

const types = @import("../types/types.zig");

const StackEntry = types.StackEntry;

pub const LocationError = error{
    NotFound,
    NotAStack,
    InvalidLocation,
};

/// Case-insensitive comparison for identities
pub fn identities_equal(a: []const u8, b: []const u8) bool {
    if (a.len != b.len) {
        return false;
    }
    for (a, b) |char_a, char_b| {
        const upper_a = if (char_a >= 'a' and char_a <= 'z') char_a - 32 else char_a;
        const upper_b = if (char_b >= 'a' and char_b <= 'z') char_b - 32 else char_b;
        if (upper_a != upper_b) {
            return false;
        }
    }
    return true;
}

/// Location component iterator
pub const LocationIterator = struct {
    location: []const u8,
    position: usize,

    pub fn init(location: []const u8) LocationIterator {
        var start: usize = 0;
        // Skip leading separator
        if (location.len > 0 and (location[0] == '/' or location[0] == '\\')) {
            start = 1;
        }
        return LocationIterator{
            .location = location,
            .position = start,
        };
    }

    pub fn next(self: *LocationIterator) ?[]const u8 {
        // Skip empty components
        while (self.position < self.location.len and
            (self.location[self.position] == '/' or self.location[self.position] == '\\'))
        {
            self.position += 1;
        }

        if (self.position >= self.location.len) {
            return null;
        }

        const start = self.position;
        while (self.position < self.location.len and
            self.location[self.position] != '/' and
            self.location[self.position] != '\\')
        {
            self.position += 1;
        }

        if (self.position == start) {
            return null;
        }

        return self.location[start..self.position];
    }
};

/// Check if entry matches an identity (case-insensitive)
pub fn entry_matches_identity(entry: *const StackEntry, identity: []const u8) bool {
    var short_identity_buf: [12]u8 = undefined;
    const short_identity_len = entry.get_short_identity(&short_identity_buf);
    return identities_equal(short_identity_buf[0..short_identity_len], identity);
}