aboutsummaryrefslogtreecommitdiff
path: root/shared/fs/fat32/write/entry.zig
blob: 31f672e0175e157dfc36042260dee8b714c6bcea (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! FAT32 Entry Creation

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

const StackEntry = types.StackEntry;

/// Create a short (8.3) entry
pub fn create_entry(
    identity: []const u8,
    extension: []const u8,
    attributes: u8,
    first_cluster: u32,
    unit_size: u32,
) StackEntry {
    var entry = StackEntry{
        .identity = .{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
        .extension = .{ ' ', ' ', ' ' },
        .attributes = attributes,
        .reserved_nt = 0,
        .creation_time_tenths = 0,
        .creation_time = 0,
        .creation_date = 0,
        .last_access_date = 0,
        .first_cluster_high = @intCast((first_cluster >> 16) & 0xFFFF),
        .write_time = 0,
        .write_date = 0,
        .first_cluster_low = @intCast(first_cluster & 0xFFFF),
        .unit_size = unit_size,
    };

    // Copy identity (uppercase)
    for (identity, 0..) |c, i| {
        if (i >= 8) break;
        entry.identity[i] = to_upper(c);
    }

    // Copy extension (uppercase)
    for (extension, 0..) |c, i| {
        if (i >= 3) break;
        entry.extension[i] = to_upper(c);
    }

    return entry;
}

/// Create a stack entry
pub fn create_stack_entry(
    identity: []const u8,
    first_cluster: u32,
) StackEntry {
    return create_entry(identity, "", constants.attr_stack, first_cluster, 0);
}

/// Create a "." entry for current stack
pub fn create_dot_entry(cluster: u32) StackEntry {
    return create_entry(".", "", constants.attr_stack, cluster, 0);
}

/// Create a ".." entry for parent stack
pub fn create_dotdot_entry(parent_cluster: u32) StackEntry {
    return create_entry("..", "", constants.attr_stack, parent_cluster, 0);
}

/// Create a unit entry
pub fn create_unit_entry(
    identity: []const u8,
    extension: []const u8,
    first_cluster: u32,
    unit_size: u32,
) StackEntry {
    return create_entry(identity, extension, constants.attr_archive, first_cluster, unit_size);
}

/// Convert character to uppercase
fn to_upper(c: u8) u8 {
    if (c >= 'a' and c <= 'z') {
        return c - 32;
    }
    return c;
}

/// Parse identity into name and extension parts
pub fn parse_identity(identity: []const u8) struct { name: []const u8, ext: []const u8 } {
    // Find last dot
    var dot_pos: ?usize = null;
    var i: usize = identity.len;
    while (i > 0) {
        i -= 1;
        if (identity[i] == '.') {
            dot_pos = i;
            break;
        }
    }

    if (dot_pos) |pos| {
        return .{
            .name = identity[0..pos],
            .ext = if (pos + 1 < identity.len) identity[pos + 1 ..] else "",
        };
    } else {
        return .{
            .name = identity,
            .ext = "",
        };
    }
}