aboutsummaryrefslogtreecommitdiff
path: root/core/strings
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-05-12 12:54:14 +0100
committergingerBill <bill@gingerbill.org>2022-05-12 12:54:14 +0100
commitccb38c3dc684ece829c7ca1066867cc5212533c3 (patch)
tree48a2cf15e14f4e18bb6cf7f5b7ca28402b79e94c /core/strings
parentcc81057d21f1dbe9a377637b1458dfc5a16f5fd0 (diff)
Add _safe versions
Diffstat (limited to 'core/strings')
-rw-r--r--core/strings/strings.odin43
1 files changed, 43 insertions, 0 deletions
diff --git a/core/strings/strings.odin b/core/strings/strings.odin
index a3d9fa93e..2429b451d 100644
--- a/core/strings/strings.odin
+++ b/core/strings/strings.odin
@@ -14,6 +14,13 @@ clone :: proc(s: string, allocator := context.allocator, loc := #caller_location
return string(c[:len(s)])
}
+// returns a clone of the string `s` allocated using the `allocator`
+clone_safe :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (str: string, err: mem.Allocator_Error) {
+ c := make([]byte, len(s), allocator, loc) or_return
+ copy(c, s)
+ return string(c[:len(s)]), nil
+}
+
// returns a clone of the string `s` allocated using the `allocator` as a cstring
// a nul byte is appended to the clone, to make the cstring safe
clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> cstring {
@@ -260,6 +267,25 @@ join :: proc(a: []string, sep: string, allocator := context.allocator) -> string
return string(b)
}
+join_safe :: proc(a: []string, sep: string, allocator := context.allocator) -> (str: string, err: mem.Allocator_Error) {
+ if len(a) == 0 {
+ return "", nil
+ }
+
+ n := len(sep) * (len(a) - 1)
+ for s in a {
+ n += len(s)
+ }
+
+ b := make([]byte, n, allocator) or_return
+ i := copy(b, a[0])
+ for s in a[1:] {
+ i += copy(b[i:], sep)
+ i += copy(b[i:], s)
+ }
+ return string(b), nil
+}
+
/*
returns a combined string from the slice of strings `a` without a seperator
allocates the string using the `allocator`
@@ -285,6 +311,23 @@ concatenate :: proc(a: []string, allocator := context.allocator) -> string {
return string(b)
}
+concatenate_safe :: proc(a: []string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) {
+ if len(a) == 0 {
+ return "", nil
+ }
+
+ n := 0
+ for s in a {
+ n += len(s)
+ }
+ b := make([]byte, n, allocator) or_return
+ i := 0
+ for s in a {
+ i += copy(b[i:], s)
+ }
+ return string(b), nil
+}
+
/*
`rune_offset` and `rune_length` are in runes, not bytes.
If `rune_length` <= 0, then it'll return the remainder of the string starting at `rune_offset`.