blob: e94b955b9bf2cbb13a879f339dd5ddaddcb7f6a3 (
plain) (
blame)
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
|
#include "pathbuf.h"
// Read the next byte of the path buffer, or zero if all bytes have been read.
u8 pathbuf_read(PathBuf *buf) {
u8 output = buf->mem[buf->p];
if (output) buf->p++;
return output;
}
// Clear a path buffer.
void pathbuf_clear(PathBuf *buf) {
for (int i=0; i<256; i++) buf->mem[i] = 0;
buf->p = 0;
}
// Move the pointer to either the start of the path buffer or to the start of
// the final path component.
void pathbuf_set_pointer(PathBuf *buf, bool to_final_component) {
buf->p = 0;
if (to_final_component) {
for (int i=0; i<255; i++) {
if (buf->mem[i] == '/') {
buf->p = i+1;
} else if (buf->mem[i] == 0) {
break;
}
}
}
}
// Populate a path buffer with a bytestring.
void pathbuf_populate(PathBuf *buf, u8 *path) {
pathbuf_clear(buf);
u8 c;
for (int i=0; i<256; i++) {
c = path[i];
buf->mem[i] = c;
if (c == 0) return;
};
}
// Push a byte to a path buffer, return true and reset pointer if byte is null.
bool pathbuf_push(PathBuf *buf, u8 byte) {
buf->mem[buf->p++] = byte;
return byte == 0;
}
// Check if a path buffer is empty.
bool pathbuf_is_empty(PathBuf *buf) {
return buf->mem[0] == 0;
}
// Check if a path buffer contains the path of the root directory.
bool pathbuf_is_root(PathBuf *buf) {
return buf->mem[0] == '/' && buf->mem[1] == 0;
}
// Check if a path buffer contains a valid path.
bool pathbuf_is_valid(PathBuf *buf) {
// Test that path begins with a forward slash and ends with a null byte.
if (buf->mem[0x00] != '/') return false;
if (buf->mem[0xFF] != 0 ) return false;
// Find the length of the path.
int len = 0;
for (; len<256; len++) if (buf->mem[len] == 0) break;
// End early if path is the root directory.
if (len == 1) return true;
// Test that path contains no control characters.
for (int i=0; i<len; i++) if (buf->mem[i] < 0x20) return false;
// Test that path contains no empty or relative components. This also
// happens to test that it doesn't end with a slash.
bool is_empty = false;
bool all_dots = false;
int dot_count = 0;
u8 c;
for (int i=0; i<=len; i++) {
c = buf->mem[i];
if (c == '/' || c == 0) {
// Test if component is empty.
if (is_empty) return false;
// Test if component is one or two periods.
if (all_dots && dot_count < 3) return false;
// Reset flags.
is_empty = true;
all_dots = true;
dot_count = 0;
} else {
is_empty = false;
if (c == '.') {
dot_count++;
} else {
all_dots = false;
}
}
}
return true;
}
|