mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-29 02:40:05 +00:00
Make the string type elements "immutable", akin to char const * in C
Allows for extra security and optimization benefits
This commit is contained in:
+21
-4
@@ -418,11 +418,24 @@ default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code
|
||||
|
||||
|
||||
@builtin
|
||||
copy :: proc "contextless" (dst, src: $T/[]$E) -> int {
|
||||
copy_slice :: proc "contextless" (dst, src: $T/[]$E) -> int {
|
||||
n := max(0, min(len(dst), len(src)));
|
||||
if n > 0 do mem_copy(&dst[0], &src[0], n*size_of(E));
|
||||
return n;
|
||||
}
|
||||
@builtin
|
||||
copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int {
|
||||
n := max(0, min(len(dst), len(src)));
|
||||
if n > 0 {
|
||||
d := &dst[0];
|
||||
s := (transmute(Raw_String)src).data;
|
||||
mem_copy(d, s, n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@builtin
|
||||
copy :: proc{copy_slice, copy_from_string};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -559,6 +572,10 @@ append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location)
|
||||
a.len += arg_len;
|
||||
}
|
||||
}
|
||||
@builtin
|
||||
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) {
|
||||
append_elem(array, transmute([]E)arg, loc);
|
||||
}
|
||||
|
||||
@builtin
|
||||
reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
|
||||
@@ -754,7 +771,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l
|
||||
}
|
||||
}
|
||||
|
||||
@builtin append :: proc{append_elem, append_elems};
|
||||
@builtin append :: proc{append_elem, append_elems, append_elem_string};
|
||||
@builtin append_soa :: proc{append_soa_elem, append_soa_elems};
|
||||
|
||||
|
||||
@@ -1091,11 +1108,11 @@ _fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 {
|
||||
default_hash :: proc(data: []byte) -> u64 {
|
||||
return _fnv64a(data);
|
||||
}
|
||||
default_hash_string :: proc(s: string) -> u64 do return default_hash(([]byte)(s));
|
||||
default_hash_string :: proc(s: string) -> u64 do return default_hash(transmute([]byte)(s));
|
||||
|
||||
|
||||
source_code_location_hash :: proc(s: Source_Code_Location) -> u64 {
|
||||
hash := _fnv64a(cast([]byte)s.file_path);
|
||||
hash := _fnv64a(transmute([]byte)s.file_path);
|
||||
hash = hash ~ (u64(s.line) * 0x100000001b3);
|
||||
hash = hash ~ (u64(s.column) * 0x100000001b3);
|
||||
return hash;
|
||||
|
||||
@@ -369,17 +369,27 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_
|
||||
return 0;
|
||||
}
|
||||
|
||||
@private
|
||||
Raw_String :: struct {
|
||||
data: ^byte,
|
||||
len: int,
|
||||
};
|
||||
|
||||
string_eq :: proc "contextless" (a, b: string) -> bool {
|
||||
x := transmute(Raw_String)a;
|
||||
y := transmute(Raw_String)b;
|
||||
switch {
|
||||
case len(a) != len(b): return false;
|
||||
case len(a) == 0: return true;
|
||||
case &a[0] == &b[0]: return true;
|
||||
case x.len != y.len: return false;
|
||||
case x.len == 0: return true;
|
||||
case x.data == y.data: return true;
|
||||
}
|
||||
return string_cmp(a, b) == 0;
|
||||
}
|
||||
|
||||
string_cmp :: proc "contextless" (a, b: string) -> int {
|
||||
return memory_compare(&a[0], &b[0], min(len(a), len(b)));
|
||||
x := transmute(Raw_String)a;
|
||||
y := transmute(Raw_String)b;
|
||||
return memory_compare(x.data, y.data, min(x.len, y.len));
|
||||
}
|
||||
|
||||
string_ne :: inline proc "contextless" (a, b: string) -> bool { return !string_eq(a, b); }
|
||||
@@ -398,10 +408,6 @@ cstring_len :: proc "contextless" (s: cstring) -> int {
|
||||
}
|
||||
|
||||
cstring_to_string :: proc "contextless" (s: cstring) -> string {
|
||||
Raw_String :: struct {
|
||||
data: ^byte,
|
||||
len: int,
|
||||
};
|
||||
if s == nil do return "";
|
||||
ptr := (^byte)(s);
|
||||
n := cstring_len(s);
|
||||
|
||||
Reference in New Issue
Block a user