hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

cstrings.ha (1608B)


      1 // License: MPL-2.0
      2 // (c) 2021 Drew DeVault <sir@cmpwn.com>
      3 // (c) 2021 Ember Sawady <ecs@d2evs.net>
      4 // (c) 2022 Vlad-Stefan Harbuz <vlad@vladh.net>
      5 use encoding::utf8;
      6 use types;
      7 
      8 // Computes the length of a NUL-terminated C string, in octets, in O(n). The
      9 // computed length does not include the NUL terminator.
     10 export fn cstrlen(cstr: *const char) size = {
     11 	const ptr = cstr: *[*]u8;
     12 	let ln = 0z;
     13 	for (ptr[ln] != 0; ln += 1) void;
     14 	return ln;
     15 };
     16 
     17 // Converts a C string to a Hare string in O(n), and does not check if it's
     18 // valid UTF-8.
     19 export fn fromc_unsafe(cstr: *const char) const str = {
     20 	const l = cstrlen(cstr);
     21 	const s = types::string {
     22 		data = cstr: *[*]u8,
     23 		length = l,
     24 		capacity = l + 1,
     25 	};
     26 	return *(&s: *const str);
     27 };
     28 
     29 // Converts a C string to a Hare string in O(n). If the string is not valid
     30 // UTF-8, return [[encoding::utf8::invalid.]]
     31 export fn fromc(cstr: *const char) (const str | utf8::invalid) = {
     32 	let s = fromc_unsafe(cstr);
     33 	return if (utf8::valid(s)) s else utf8::invalid;
     34 };
     35 
     36 // Converts a Hare string to a C string. The result is allocated; the caller
     37 // must free it when they're done.
     38 export fn to_c(s: const str) *char = {
     39 	let slice: []u8 = alloc([0...], len(s) + 1);
     40 	return to_cbuf(s, slice);
     41 };
     42 
     43 // Converts a Hare string to a C string. The result is stored into a
     44 // user-supplied buffer.
     45 export fn to_cbuf(s: const str, sl: []u8) *char = {
     46 	if (len(sl) < len(s) + 1) {
     47 		abort("to_cbuf: buffer has insufficient space for string plus NUL");
     48 	};
     49 
     50 	const s = &s: *[]u8;
     51 	sl[..len(s)] = s[..];
     52 	sl[len(s)] = 0;
     53 
     54 	return (*(&sl: *types::slice)).data: *char;
     55 };