Browse Source

Add new package strings procedures: trim_prefix, trim_suffix, to_valid_utf8

gingerBill 4 years ago
parent
commit
063c0548b0
1 changed files with 69 additions and 0 deletions
  1. 69 0
      core/strings/strings.odin

+ 69 - 0
core/strings/strings.odin

@@ -660,6 +660,19 @@ trim_null :: proc(s: string) -> string {
 	return trim_right_null(trim_left_null(s));
 }
 
+trim_prefix :: proc(s, prefix: string) -> string {
+	if has_prefix(s, prefix) {
+		return s[len(prefix):];
+	}
+	return s;
+}
+
+trim_suffix :: proc(s, suffix: string) -> string {
+	if has_suffix(s, suffix) {
+		return s[:len(s)-len(suffix)];
+	}
+	return s;
+}
 
 split_multi :: proc(s: string, substrs: []string, skip_empty := false, allocator := context.allocator) -> []string #no_bounds_check {
 	if s == "" || len(substrs) <= 0 {
@@ -1106,6 +1119,62 @@ right_justify :: proc(str: string, length: int, pad: string, allocator := contex
 }
 
 
+
+to_valid_utf8 :: proc(s, replacement: string, allocator := context.allocator) -> string {
+	if len(s) == 0 {
+		return "";
+	}
+
+	b := make_builder_len_cap(0, 0, allocator);
+
+	s := s;
+	for c, i in s {
+		if c != utf8.RUNE_ERROR {
+			continue;
+		}
+
+		_, w := utf8.decode_rune_in_string(s[i:]);
+		if w == 1 {
+			grow_builder(&b, len(s) + len(replacement));
+			write_string(&b, s[:i]);
+			s = s[i:];
+			break;
+		}
+	}
+
+	if builder_cap(b) == 0 {
+		return clone(s, allocator);
+	}
+
+	invalid := false;
+
+	for i := 0; i < len(s); /**/ {
+		c := s[i];
+		if c < utf8.RUNE_SELF {
+			i += 1;
+			invalid = false;
+			write_byte(&b, c);
+			continue;
+		}
+
+		_, w := utf8.decode_rune_in_string(s[i:]);
+		if w == 1 {
+			i += 1;
+			if !invalid {
+				invalid = true;
+				write_string(&b, replacement);
+			}
+			continue;
+		}
+		invalid = false;
+		write_string(&b, s[i:][:w]);
+		i += w;
+	}
+	return to_string(b);
+}
+
+
+
 @private
 write_pad_string :: proc(b: ^Builder, pad: string, pad_len, remains: int) {
 	repeats := remains / pad_len;