:: limine / common / lib / guid.c 2.6 KB raw

1
#include <stddef.h>
2
#include <stdint.h>
3
#include <stdbool.h>
4
#include <lib/guid.h>
5
#include <lib/misc.h>
6
7
bool is_valid_guid(const char *s) {
8
    for (size_t i = 0; ; i++) {
9
        switch (i) {
10
            case 8:
11
            case 13:
12
            case 18:
13
            case 23:
14
                if (s[i] != '-')
15
                    return false;
16
                break;
17
            case 36:
18
                return s[i] == 0;
19
            default:
20
                if (digit_to_int(s[i]) == -1)
21
                    return false;
22
                break;
23
        }
24
    }
25
}
26
27
static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
28
    size_t p = 0;
29
    for (int i = len - 1; i >= 0; i--) {
30
        int val = digit_to_int(s[i]);
31
32
        i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
33
    }
34
}
35
36
static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
37
    size_t p = 0;
38
    for (int i = 0; i < len; i++) {
39
        int val = digit_to_int(s[i]);
40
41
        i % 2 ? (dest[p++] |= val) : (dest[p] = val << 4);
42
    }
43
}
44
45
bool string_to_guid_be(struct guid *guid, const char *s) {
46
    if (!is_valid_guid(s))
47
        return false;
48
49
    guid_convert_be_cluster((uint8_t *)guid + 0,  s + 0,  8);
50
    guid_convert_be_cluster((uint8_t *)guid + 4,  s + 9,  4);
51
    guid_convert_be_cluster((uint8_t *)guid + 6,  s + 14, 4);
52
    guid_convert_be_cluster((uint8_t *)guid + 8,  s + 19, 4);
53
    guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
54
55
    return true;
56
}
57
58
bool string_to_guid_mixed(struct guid *guid, const char *s) {
59
    if (!is_valid_guid(s))
60
        return false;
61
62
    guid_convert_le_cluster((uint8_t *)guid + 0,  s + 0,  8);
63
    guid_convert_le_cluster((uint8_t *)guid + 4,  s + 9,  4);
64
    guid_convert_le_cluster((uint8_t *)guid + 6,  s + 14, 4);
65
    guid_convert_be_cluster((uint8_t *)guid + 8,  s + 19, 4);
66
    guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
67
68
    return true;
69
}
70
71
static void uint_to_hex(uint32_t num, char *dest, int len) {
72
    const char digits[] = "0123456789abcdef";
73
    for (int i = 0; i < len; i++) {
74
        dest[i] = digits[(num >> ((len - 1 - i) * 4)) & 0xf];
75
    }
76
}
77
78
void guid_to_string(const struct guid *guid, char *s) {
79
    uint_to_hex(guid->a, s, 8);
80
    s[8] = '-';
81
    uint_to_hex(guid->b, s + 9, 4);
82
    s[13] = '-';
83
    uint_to_hex(guid->c, s + 14, 4);
84
    s[18] = '-';
85
    uint_to_hex(guid->d[0], s + 19, 2);
86
    uint_to_hex(guid->d[1], s + 21, 2);
87
    s[23] = '-';
88
    uint_to_hex(guid->d[2], s + 24, 2);
89
    uint_to_hex(guid->d[3], s + 26, 2);
90
    uint_to_hex(guid->d[4], s + 28, 2);
91
    uint_to_hex(guid->d[5], s + 30, 2);
92
    uint_to_hex(guid->d[6], s + 32, 2);
93
    uint_to_hex(guid->d[7], s + 34, 2);
94
    s[36] = 0;
95
}
tab: 248 wrap: offon