1module builtin
2
3pub struct string {
4pub:
5	str byteptr
6	len int
7}
8
9pub fn strlen(s byteptr) int {
10	mut i := 0
11	for ; s[i] != 0; i++ {}
12	return i
13}
14
15pub fn tos(s byteptr, len int) string {
16	if s == 0 {
17		panic('tos(): nil string')
18	}
19	return string {
20		str: s
21		len: len
22	}
23}
24
25fn (s string) add(a string) string {
26	new_len := a.len + s.len
27	mut res := string {
28		len: new_len
29		str: malloc(new_len + 1)
30	}
31	for j in 0..s.len {
32		res[j] = s[j]
33	}
34	for j in 0..a.len {
35		res[s.len + j] = a[j]
36	}
37	res[new_len] = `\0`// V strings are not null terminated, but just in case
38	return res
39}
40
41/*
42pub fn tos_clone(s byteptr) string {
43	if s == 0 {
44		panic('tos: nil string')
45	}
46	return tos2(s).clone()
47}
48*/
49
50// Same as `tos`, but calculates the length. Called by `string(bytes)` casts.
51// Used only internally.
52pub fn tos2(s byteptr) string {
53	if s == 0 {
54		panic('tos2: nil string')
55	}
56	return string {
57		str: s
58		len: strlen(s)
59	}
60}
61
62pub fn tos3(s charptr) string {
63	if s == 0 {
64		panic('tos3: nil string')
65	}
66	return string {
67		str: byteptr(s)
68		len: strlen(byteptr(s))
69	}
70}
71
72pub fn string_eq (s1, s2 string) bool {
73	if s1.len != s2.len { return false }
74	for i in 0..s1.len {
75		if s1[i] != s2[i] { return false }
76	}
77	return true
78}
79pub fn string_ne (s1, s2 string) bool {
80	return !string_eq(s1,s2)
81}
82
83
84pub fn i64_tos(buf byteptr, len int, n0 i64, base int) string {
85	if base < 2 { panic("base must be >= 2")}
86	if base > 36 { panic("base must be <= 36")}
87
88	mut b := tos(buf, len)
89	mut i := len-1
90
91	mut n := n0
92	neg := n < 0
93	if neg { n = -n }
94
95	b[i--] = 0
96
97	for {
98		c := (n%base) + 48
99		b[i--] = if c > 57 {c+7} else {c}
100		if i < 0 { panic ("buffer to small") }
101		n /= base
102		if n < 1 {break}
103	}
104	if neg {
105		if i < 0 { panic ("buffer to small") }
106		b[i--] = 45
107	}
108	offset := i+1
109	b.str = b.str + offset
110	b.len -= (offset+1)
111	return b
112}
113
114pub fn i64_str(n0 i64, base int) string {
115	buf := malloc(80)
116	return i64_tos(buf, 79, n0, base)
117}
118
119pub fn ptr_str(ptr voidptr) string {
120  buf := [16]byte
121  hex := i64_tos(buf, 15, i64(ptr), 16)
122  res := '0x' + hex
123  return res
124}
125
126pub fn (a string) clone() string {
127	mut b := string {
128		len: a.len
129		str: malloc(a.len + 1)
130	}
131	mem_copy(b.str, a.str, a.len)
132	b[a.len] = `\0`
133	return b
134}
135