1
0
Fork 0
forked from AbleOS/ableos
ableos/sysdata/libraries/stn/src/string.hb
2024-12-23 20:19:10 +01:00

170 lines
3.1 KiB
Plaintext

.{log, memory} := @use("stn")
reverse := fn(str: []u8): void {
if str.len == 0 return;
j := str.len - 1
i := 0
temp := @as(u8, 0)
loop if i < j {
temp = str[i]
str[i] = str[j]
str[j] = temp
i += 1
j -= 1
} else return
}
$equals := fn(lhs: []u8, rhs: []u8): bool {
return lhs.ptr == rhs.ptr & lhs.len == rhs.len
}
clear := fn(str: []u8): void {
i := 0
loop if i == str.len break else {
str[i] = 0
i += 1
}
}
split_once := fn(haystack: []u8, needle: @Any()): ?[]u8 {
T := @TypeOf(needle)
if T == []u8 {
if needle.len == 0 return null
i := 0
loop if i == haystack.len return null else {
if haystack[i] == needle[0] {
h := i
n := 0
loop {
n += 1
h += 1
if needle[n] == 0 {
return haystack[h..]
} else if haystack[h] == 0 | haystack[h] != needle[n] {
break
}
}
}
i += 1
}
} else if T == u8 {
i := 0
loop if haystack[i] == needle return haystack[i..] else if i == haystack.len return null else i += 1
} else {
@error("Type of needle must be []u8 or u8.")
}
}
SplitIter := fn($T: type): type {
return struct {
str: []u8,
needle: T,
done: bool,
next := fn(self: ^Self): ?[]u8 {
if self.done return null;
if @TypeOf(self.needle) == u8 {
i := 0
loop if i == self.str.len {
self.done = true
return self.str
} else if self.str[i] == self.needle {
result := self.str[..i]
self.str = self.str[i + 1..]
return result
} else {
i += 1
}
} else if @TypeOf(self.needle) == []u8 {
if self.needle.len == 0 return null
i := 0
loop if i == self.str.len {
self.done = true
return self.str
} else if self.str[i] == self.needle[0] {
h := i
n := 0
loop {
n += 1
h += 1
if n == self.needle.len {
result := self.str[..i]
self.str = self.str[h..]
return result
} else if h == self.str.len | self.str[h] != self.needle[n] {
break
}
}
}
i += 1
}
self.done = true
return self.str
}
}
}
split := fn(iter: []u8, needle: @Any()): SplitIter(@TypeOf(needle)) {
T := @TypeOf(needle)
if T != []u8 & T != u8 {
@error("Type of needle must be []u8 or u8.")
}
return .(iter, needle, false)
}
find_once := fn(haystack: ^u8, needle: @Any()): ?uint {
return @bitcast(@inline(split_once, haystack, needle) - haystack)
}
count := fn(haystack: []u8, needle: @Any()): uint {
T := @TypeOf(needle)
c := 0
if T == u8 {
i := 0
loop if haystack[i] == needle {
c += 1
i += 1
} else if i == haystack.len return c else i += 1
} else if T == []u8 {
i := 0
loop if i == haystack.len return c else {
if haystack[i] == needle[0] {
h := i
n := 0
loop {
n += 1
h += 1
if n == needle.len {
c += 1
i = h - 1
break
} else if h == haystack.len | haystack[h] != needle[n] {
break
}
}
}
i += 1
}
} else {
@error("Type of needle must be []u8 or u8.")
}
}
left_trim := fn(str: []u8, sub: []u8): []u8 {
i := 0
if str[0] == sub[0] {
loop if i == sub.len {
return str[i..str.len]
} else if str[i] != sub[i] | i == str.len {
return str
} else {
i += 1
}
}
}