builtin: unsafe vlib pointer indexing (#5836)
parent
cc7c8009a1
commit
f5e6a83a05
|
@ -488,13 +488,19 @@ pub fn (b []byte) hex() string {
|
|||
mut dst_i := 0
|
||||
for i in b {
|
||||
n0 := i >> 4
|
||||
unsafe {
|
||||
hex[dst_i++] = if n0 < 10 { n0 + `0` } else { n0 + byte(87) }
|
||||
}
|
||||
n1 := i & 0xF
|
||||
unsafe {
|
||||
hex[dst_i++] = if n1 < 10 { n1 + `0` } else { n1 + byte(87) }
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
hex[dst_i] = `\0`
|
||||
return tos(hex,dst_i)
|
||||
}
|
||||
}
|
||||
|
||||
// copy copies the `src` byte array elements to the `dst` byte array.
|
||||
// The number of the elements copied is the minimum of the length of both arrays.
|
||||
|
|
|
@ -72,14 +72,18 @@ pub fn (nn int) str_l(max int) string {
|
|||
}
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
n1 := n / 100
|
||||
d = ((n - (n1 * 100)) << 1)
|
||||
n = n1
|
||||
unsafe {
|
||||
buf[index--] = digit_pairs.str[d++]
|
||||
buf[index--] = digit_pairs.str[d]
|
||||
}
|
||||
}
|
||||
index++
|
||||
|
||||
// remove head zero
|
||||
|
@ -90,13 +94,15 @@ pub fn (nn int) str_l(max int) string {
|
|||
// Prepend - if it's negative
|
||||
if is_neg {
|
||||
index--
|
||||
unsafe {
|
||||
buf[index] = `-`
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
}
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
||||
|
@ -126,14 +132,18 @@ pub fn (nn u32) str() string {
|
|||
mut buf := malloc(max + 1)
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
n1 := n / u32(100)
|
||||
d = ((n - (n1 * u32(100))) << u32(1))
|
||||
n = n1
|
||||
unsafe {
|
||||
buf[index--] = digit_pairs[d++]
|
||||
buf[index--] = digit_pairs[d]
|
||||
}
|
||||
}
|
||||
index++
|
||||
|
||||
// remove head zero
|
||||
|
@ -143,8 +153,8 @@ pub fn (nn u32) str() string {
|
|||
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
}
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
||||
|
@ -169,14 +179,18 @@ pub fn (nn i64) str() string {
|
|||
}
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
n1 := n / i64(100)
|
||||
d = ((n - (n1 * i64(100))) << i64(1))
|
||||
n = n1
|
||||
unsafe {
|
||||
buf[index--] = digit_pairs[d++]
|
||||
buf[index--] = digit_pairs[d]
|
||||
}
|
||||
}
|
||||
index++
|
||||
|
||||
// remove head zero
|
||||
|
@ -187,13 +201,15 @@ pub fn (nn i64) str() string {
|
|||
// Prepend - if it's negative
|
||||
if is_neg {
|
||||
index--
|
||||
unsafe {
|
||||
buf[index] = `-`
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
}
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
||||
|
@ -207,14 +223,18 @@ pub fn (nn u64) str() string {
|
|||
mut buf := vcalloc(max + 1)
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
n1 := n / 100
|
||||
d = ((n - (n1 * 100)) << 1)
|
||||
n = n1
|
||||
unsafe {
|
||||
buf[index--] = digit_pairs[d++]
|
||||
buf[index--] = digit_pairs[d]
|
||||
}
|
||||
}
|
||||
index++
|
||||
|
||||
// remove head zero
|
||||
|
@ -224,8 +244,8 @@ pub fn (nn u64) str() string {
|
|||
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
}
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
||||
|
@ -258,12 +278,16 @@ pub fn (nn byte) hex() string {
|
|||
mut buf := malloc(max + 1)
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
d := n & 0xF
|
||||
n = n >> 4
|
||||
unsafe {
|
||||
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
|
||||
}
|
||||
}
|
||||
//buf[index--] = `x`
|
||||
//buf[index] = `0`
|
||||
index++
|
||||
|
@ -287,12 +311,16 @@ pub fn (nn u16) hex() string {
|
|||
mut buf := malloc(max + 1)
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
d := byte(n & 0xF)
|
||||
n = n >> 4
|
||||
unsafe {
|
||||
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
|
||||
}
|
||||
}
|
||||
//buf[index--] = `x`
|
||||
//buf[index] = `0`
|
||||
index++
|
||||
|
@ -316,12 +344,16 @@ pub fn (nn u32) hex() string {
|
|||
mut buf := malloc(max + 1)
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
d := byte(n & 0xF)
|
||||
n = n >> 4
|
||||
unsafe {
|
||||
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
|
||||
}
|
||||
}
|
||||
//buf[index--] = `x`
|
||||
//buf[index] = `0`
|
||||
index++
|
||||
|
@ -349,20 +381,24 @@ pub fn (nn u64) hex() string {
|
|||
mut buf := malloc(max + 1)
|
||||
|
||||
mut index := max
|
||||
unsafe {
|
||||
buf[index--] = `\0`
|
||||
}
|
||||
for n > 0 {
|
||||
d := byte(n & 0xF)
|
||||
n = n >> 4
|
||||
unsafe {
|
||||
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
|
||||
}
|
||||
}
|
||||
//buf[index--] = `x`
|
||||
//buf[index] = `0`
|
||||
index++
|
||||
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
}
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
||||
|
@ -405,8 +441,10 @@ pub fn (c byte) str() string {
|
|||
str: malloc(2)
|
||||
len: 1
|
||||
}
|
||||
unsafe {
|
||||
str.str[0] = c
|
||||
str.str[1] = `\0`
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
|
|
|
@ -120,12 +120,14 @@ fn new_dense_array(value_bytes int) DenseArray {
|
|||
fn (mut d DenseArray) push(key string, value voidptr) u32 {
|
||||
if d.cap == d.len {
|
||||
d.cap += d.cap >> 3
|
||||
unsafe {
|
||||
d.keys = &string(v_realloc(d.keys, sizeof(string) * d.cap))
|
||||
d.values = v_realloc(d.values, u32(d.value_bytes) * d.cap)
|
||||
}
|
||||
}
|
||||
push_index := d.len
|
||||
d.keys[push_index] = key
|
||||
unsafe {
|
||||
d.keys[push_index] = key
|
||||
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
|
||||
}
|
||||
d.len++
|
||||
|
@ -148,11 +150,13 @@ fn (mut d DenseArray) zeros_to_end() {
|
|||
mut tmp_value := malloc(d.value_bytes)
|
||||
mut count := u32(0)
|
||||
for i in 0 .. d.len {
|
||||
if d.keys[i].str != 0 {
|
||||
if unsafe {d.keys[i]}.str != 0 {
|
||||
// swap keys
|
||||
unsafe {
|
||||
tmp_key := d.keys[count]
|
||||
d.keys[count] = d.keys[i]
|
||||
d.keys[i] = tmp_key
|
||||
}
|
||||
// swap values (TODO: optimize)
|
||||
unsafe {
|
||||
C.memcpy(tmp_value, d.values + count * u32(d.value_bytes), d.value_bytes)
|
||||
|
@ -166,9 +170,11 @@ fn (mut d DenseArray) zeros_to_end() {
|
|||
d.deletes = 0
|
||||
d.len = count
|
||||
d.cap = if count < 8 { u32(8) } else { count }
|
||||
unsafe {
|
||||
d.keys = &string(v_realloc(d.keys, sizeof(string) * d.cap))
|
||||
d.values = v_realloc(d.values, u32(d.value_bytes) * d.cap)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct map {
|
||||
// Number of bytes of a value
|
||||
|
@ -229,7 +235,7 @@ fn (m &map) key_to_index(key string) (u32,u32) {
|
|||
fn (m &map) meta_less(_index u32, _metas u32) (u32,u32) {
|
||||
mut index := _index
|
||||
mut meta := _metas
|
||||
for meta < m.metas[index] {
|
||||
for meta < unsafe {m.metas[index]} {
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
}
|
||||
|
@ -241,20 +247,26 @@ fn (mut m map) meta_greater(_index u32, _metas u32, kvi u32) {
|
|||
mut meta := _metas
|
||||
mut index := _index
|
||||
mut kv_index := kvi
|
||||
for m.metas[index] != 0 {
|
||||
if meta > m.metas[index] {
|
||||
for unsafe {m.metas[index]} != 0 {
|
||||
if meta > unsafe {m.metas[index]} {
|
||||
unsafe {
|
||||
tmp_meta := m.metas[index]
|
||||
m.metas[index] = meta
|
||||
meta = tmp_meta
|
||||
tmp_index := m.metas[index + 1]
|
||||
}
|
||||
tmp_index := unsafe {m.metas[index + 1]}
|
||||
unsafe {
|
||||
m.metas[index + 1] = kv_index
|
||||
}
|
||||
kv_index = tmp_index
|
||||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
}
|
||||
unsafe {
|
||||
m.metas[index] = meta
|
||||
m.metas[index + 1] = kv_index
|
||||
}
|
||||
probe_count := (meta >> hashbits) - 1
|
||||
m.ensure_extra_metas(probe_count)
|
||||
}
|
||||
|
@ -287,9 +299,9 @@ fn (mut m map) set(k string, value voidptr) {
|
|||
mut index,mut meta := m.key_to_index(key)
|
||||
index,meta = m.meta_less(index, meta)
|
||||
// While we might have a match
|
||||
for meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
for meta == unsafe {m.metas[index]} {
|
||||
kv_index := unsafe {m.metas[index + 1]}
|
||||
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
|
||||
unsafe {
|
||||
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
|
||||
}
|
||||
|
@ -326,13 +338,15 @@ fn (mut m map) expand() {
|
|||
// the max_load_factor in an operation.
|
||||
fn (mut m map) rehash() {
|
||||
meta_bytes := sizeof(u32) * (m.cap + 2 + m.extra_metas)
|
||||
unsafe {
|
||||
m.metas = &u32(v_realloc(m.metas, meta_bytes))
|
||||
C.memset(m.metas, 0, meta_bytes)
|
||||
}
|
||||
for i := u32(0); i < m.key_values.len; i++ {
|
||||
if m.key_values.keys[i].str == 0 {
|
||||
if unsafe {m.key_values.keys[i]}.str == 0 {
|
||||
continue
|
||||
}
|
||||
mut index,mut meta := m.key_to_index(m.key_values.keys[i])
|
||||
mut index,mut meta := m.key_to_index(unsafe {m.key_values.keys[i]})
|
||||
index,meta = m.meta_less(index, meta)
|
||||
m.meta_greater(index, meta, i)
|
||||
}
|
||||
|
@ -345,16 +359,16 @@ fn (mut m map) cached_rehash(old_cap u32) {
|
|||
m.metas = &u32(vcalloc(int(sizeof(u32) * (m.cap + 2 + m.extra_metas))))
|
||||
old_extra_metas := m.extra_metas
|
||||
for i := u32(0); i <= old_cap + old_extra_metas; i += 2 {
|
||||
if old_metas[i] == 0 {
|
||||
if unsafe {old_metas[i]} == 0 {
|
||||
continue
|
||||
}
|
||||
old_meta := old_metas[i]
|
||||
old_meta := unsafe {old_metas[i]}
|
||||
old_probe_count := ((old_meta >> hashbits) - 1) << 1
|
||||
old_index := (i - old_probe_count) & (m.cap >> 1)
|
||||
mut index := (old_index | (old_meta << m.shift)) & m.cap
|
||||
mut meta := (old_meta & hash_mask) | probe_inc
|
||||
index,meta = m.meta_less(index, meta)
|
||||
kv_index := old_metas[i + 1]
|
||||
kv_index := unsafe {old_metas[i + 1]}
|
||||
m.meta_greater(index, meta, kv_index)
|
||||
}
|
||||
unsafe{
|
||||
|
@ -369,9 +383,9 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
|||
for {
|
||||
mut index,mut meta := m.key_to_index(key)
|
||||
for {
|
||||
if meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
if meta == unsafe {m.metas[index]} {
|
||||
kv_index := unsafe {m.metas[index + 1]}
|
||||
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
|
||||
unsafe {
|
||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||
}
|
||||
|
@ -379,7 +393,7 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
|||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
if meta > m.metas[index] { break }
|
||||
if meta > unsafe {m.metas[index]} { break }
|
||||
}
|
||||
// Key not found, insert key with zero-value
|
||||
m.set(key, zero)
|
||||
|
@ -392,9 +406,9 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
|||
fn (m map) get(key string, zero voidptr) voidptr {
|
||||
mut index,mut meta := m.key_to_index(key)
|
||||
for {
|
||||
if meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
if meta == unsafe {m.metas[index]} {
|
||||
kv_index := unsafe {m.metas[index + 1]}
|
||||
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
|
||||
unsafe {
|
||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||
}
|
||||
|
@ -402,7 +416,7 @@ fn (m map) get(key string, zero voidptr) voidptr {
|
|||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
if meta > m.metas[index] { break }
|
||||
if meta > unsafe {m.metas[index]} { break }
|
||||
}
|
||||
return zero
|
||||
}
|
||||
|
@ -411,15 +425,15 @@ fn (m map) get(key string, zero voidptr) voidptr {
|
|||
fn (m map) exists(key string) bool {
|
||||
mut index,mut meta := m.key_to_index(key)
|
||||
for {
|
||||
if meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
if meta == unsafe {m.metas[index]} {
|
||||
kv_index := unsafe {m.metas[index + 1]}
|
||||
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
if meta > m.metas[index] { break }
|
||||
if meta > unsafe {m.metas[index]} { break }
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -429,20 +443,26 @@ pub fn (mut m map) delete(key string) {
|
|||
mut index,mut meta := m.key_to_index(key)
|
||||
index,meta = m.meta_less(index, meta)
|
||||
// Perform backwards shifting
|
||||
for meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
for (m.metas[index + 2] >> hashbits) > 1 {
|
||||
for meta == unsafe {m.metas[index]} {
|
||||
kv_index := unsafe {m.metas[index + 1]}
|
||||
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
|
||||
for (unsafe {m.metas[index + 2]} >> hashbits) > 1 {
|
||||
unsafe {
|
||||
m.metas[index] = m.metas[index + 2] - probe_inc
|
||||
m.metas[index + 1] = m.metas[index + 3]
|
||||
}
|
||||
index += 2
|
||||
}
|
||||
m.len--
|
||||
unsafe {
|
||||
m.metas[index] = 0
|
||||
}
|
||||
m.key_values.deletes++
|
||||
// Mark key as deleted
|
||||
unsafe {
|
||||
m.key_values.keys[kv_index].free()
|
||||
C.memset(&m.key_values.keys[kv_index], 0, sizeof(string))
|
||||
}
|
||||
if m.key_values.len <= 32 {
|
||||
return
|
||||
}
|
||||
|
@ -465,10 +485,10 @@ pub fn (m &map) keys() []string {
|
|||
mut keys := []string{ len:m.len }
|
||||
mut j := 0
|
||||
for i := u32(0); i < m.key_values.len; i++ {
|
||||
if m.key_values.keys[i].str == 0 {
|
||||
if unsafe {m.key_values.keys[i]}.str == 0 {
|
||||
continue
|
||||
}
|
||||
keys[j] = m.key_values.keys[i].clone()
|
||||
keys[j] = unsafe {m.key_values.keys[i]}.clone()
|
||||
j++
|
||||
}
|
||||
return keys
|
||||
|
@ -502,22 +522,30 @@ pub fn (m map) clone() map {
|
|||
extra_metas: m.extra_metas
|
||||
len: m.len
|
||||
}
|
||||
unsafe {
|
||||
C.memcpy(res.metas, m.metas, metas_size)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
[unsafe_fn]
|
||||
pub fn (m &map) free() {
|
||||
unsafe {
|
||||
free(m.metas)
|
||||
}
|
||||
for i := u32(0); i < m.key_values.len; i++ {
|
||||
if m.key_values.keys[i].str == 0 {
|
||||
if unsafe {m.key_values.keys[i]}.str == 0 {
|
||||
continue
|
||||
}
|
||||
unsafe {
|
||||
m.key_values.keys[i].free()
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
free(m.key_values.keys)
|
||||
free(m.key_values.values)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (m map_string) str() string {
|
||||
if m.len == 0 {
|
||||
|
|
|
@ -72,6 +72,7 @@ pub fn vstrlen(s byteptr) int {
|
|||
|
||||
// Converts a C string to a V string.
|
||||
// String data is reused, not copied.
|
||||
[unsafe_fn]
|
||||
pub fn tos(s byteptr, len int) string {
|
||||
// This should never happen.
|
||||
if s == 0 {
|
||||
|
@ -136,7 +137,9 @@ pub fn (a string) clone() string {
|
|||
for i in 0..a.len {
|
||||
b.str[i] = a.str[i]
|
||||
}
|
||||
unsafe {
|
||||
b.str[a.len] = `\0`
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
|
@ -149,11 +152,13 @@ pub fn (s string) cstr() byteptr {
|
|||
|
||||
// cstring_to_vstring creates a copy of cstr and turns it into a v string
|
||||
pub fn cstring_to_vstring(cstr byteptr) string {
|
||||
unsafe {
|
||||
slen := C.strlen(charptr(cstr))
|
||||
mut s := byteptr(memdup(cstr, slen + 1))
|
||||
s[slen] = `\0`
|
||||
return tos(s, slen)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s string) replace_once(rep, with string) string {
|
||||
index := s.index(rep) or {
|
||||
|
@ -193,7 +198,9 @@ pub fn (s string) replace(rep, with string) string {
|
|||
if i == cur_idx {
|
||||
// Reached the location of rep, replace it with "with"
|
||||
for j in 0..with.len {
|
||||
unsafe {
|
||||
b[b_i] = with[j]
|
||||
}
|
||||
b_i++
|
||||
}
|
||||
// Skip the length of rep, since we just replaced it with "with"
|
||||
|
@ -206,13 +213,17 @@ pub fn (s string) replace(rep, with string) string {
|
|||
}
|
||||
else {
|
||||
// Rep doesnt start here, just copy
|
||||
unsafe {
|
||||
b[b_i] = s[i]
|
||||
}
|
||||
b_i++
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
b[new_len] = `\0`
|
||||
return tos(b, new_len)
|
||||
}
|
||||
}
|
||||
|
||||
struct RepIndex {
|
||||
idx int
|
||||
|
@ -292,7 +303,9 @@ pub fn (s string) replace_each(vals []string) string {
|
|||
rep := vals[cur_idx.val_idx]
|
||||
with := vals[cur_idx.val_idx + 1]
|
||||
for j in 0..with.len {
|
||||
unsafe {
|
||||
b[b_i] = with[j]
|
||||
}
|
||||
b_i++
|
||||
}
|
||||
// Skip the length of rep, since we just replaced it with "with"
|
||||
|
@ -305,13 +318,17 @@ pub fn (s string) replace_each(vals []string) string {
|
|||
}
|
||||
else {
|
||||
// Rep doesnt start here, just copy
|
||||
unsafe {
|
||||
b[b_i] = s.str[i]
|
||||
}
|
||||
b_i++
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
b[new_len] = `\0`
|
||||
return tos(b, new_len)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s string) bool() bool {
|
||||
return s == 'true' || s == 't' // TODO t for pg, remove
|
||||
|
@ -411,12 +428,18 @@ fn (s string) add(a string) string {
|
|||
len: new_len
|
||||
}
|
||||
for j in 0..s.len {
|
||||
unsafe {
|
||||
res.str[j] = s.str[j]
|
||||
}
|
||||
}
|
||||
for j in 0..a.len {
|
||||
unsafe {
|
||||
res.str[s.len + j] = a.str[j]
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
res.str[new_len] = `\0` // V strings are not null terminated, but just in case
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -448,10 +471,10 @@ pub fn (s string) split_nth(delim string, nth int) []string {
|
|||
mut start := 0
|
||||
nth_1 := nth - 1
|
||||
for i <= s.len {
|
||||
mut is_delim := s.str[i] == delim.str[0]
|
||||
mut is_delim := unsafe {s.str[i] == delim.str[0]}
|
||||
mut j := 0
|
||||
for is_delim && j < delim.len {
|
||||
is_delim = is_delim && s.str[i + j] == delim.str[j]
|
||||
is_delim = is_delim && unsafe {s.str[i + j] == delim.str[j]}
|
||||
j++
|
||||
}
|
||||
last := i == s.len - 1
|
||||
|
@ -488,8 +511,8 @@ pub fn (s string) split_into_lines() []string {
|
|||
}
|
||||
mut start := 0
|
||||
for i := 0; i < s.len; i++ {
|
||||
is_lf := s.str[i] == `\n`
|
||||
is_crlf := i != s.len - 1 && s.str[i] == `\r` && s.str[i + 1] == `\n`
|
||||
is_lf := unsafe {s.str[i]} == `\n`
|
||||
is_crlf := i != s.len - 1 && unsafe {s.str[i] == `\r` && s.str[i + 1] == `\n`}
|
||||
is_eol := is_lf || is_crlf
|
||||
is_last := if is_crlf {
|
||||
i == s.len - 2
|
||||
|
@ -549,16 +572,19 @@ pub fn (s string) substr(start, end int) string {
|
|||
len: len
|
||||
}
|
||||
for i in 0..len {
|
||||
unsafe {
|
||||
res.str[i] = s.str[start + i]
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
res.str[len] = `\0`
|
||||
}
|
||||
/*
|
||||
res := string {
|
||||
str: s.str + start
|
||||
len: len
|
||||
}
|
||||
*/
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -569,7 +595,7 @@ pub fn (s string) index_old(p string) int {
|
|||
mut i := 0
|
||||
for i < s.len {
|
||||
mut j := 0
|
||||
for j < p.len && s.str[i + j] == p.str[j] {
|
||||
for j < p.len && unsafe {s.str[i + j] == p.str[j]} {
|
||||
j++
|
||||
}
|
||||
if j == p.len {
|
||||
|
@ -587,7 +613,7 @@ pub fn (s string) index(p string) ?int {
|
|||
mut i := 0
|
||||
for i < s.len {
|
||||
mut j := 0
|
||||
for j < p.len && s.str[i + j] == p.str[j] {
|
||||
for j < p.len && unsafe {s.str[i + j] == p.str[j]} {
|
||||
j++
|
||||
}
|
||||
if j == p.len {
|
||||
|
@ -606,20 +632,20 @@ fn (s string) index_kmp(p string) int {
|
|||
mut prefix := []int{len:p.len}
|
||||
mut j := 0
|
||||
for i := 1; i < p.len; i++ {
|
||||
for p.str[j] != p.str[i] && j > 0 {
|
||||
for unsafe {p.str[j] != p.str[i]} && j > 0 {
|
||||
j = prefix[j - 1]
|
||||
}
|
||||
if p.str[j] == p.str[i] {
|
||||
if unsafe {p.str[j] == p.str[i]} {
|
||||
j++
|
||||
}
|
||||
prefix[i] = j
|
||||
}
|
||||
j = 0
|
||||
for i in 0..s.len {
|
||||
for p.str[j] != s.str[i] && j > 0 {
|
||||
for unsafe {p.str[j] != s.str[i]} && j > 0 {
|
||||
j = prefix[j - 1]
|
||||
}
|
||||
if p.str[j] == s.str[i] {
|
||||
if unsafe {p.str[j] == s.str[i]} {
|
||||
j++
|
||||
}
|
||||
if j == p.len {
|
||||
|
@ -646,7 +672,7 @@ pub fn (s string) last_index(p string) ?int {
|
|||
mut i := s.len - p.len
|
||||
for i >= 0 {
|
||||
mut j := 0
|
||||
for j < p.len && s.str[i + j] == p.str[j] {
|
||||
for j < p.len && unsafe {s.str[i + j] == p.str[j]} {
|
||||
j++
|
||||
}
|
||||
if j == p.len {
|
||||
|
@ -672,7 +698,7 @@ pub fn (s string) index_after(p string, start int) int {
|
|||
for i < s.len {
|
||||
mut j := 0
|
||||
mut ii := i
|
||||
for j < p.len && s.str[ii] == p.str[j] {
|
||||
for j < p.len && unsafe {s.str[ii] == p.str[j]} {
|
||||
j++
|
||||
ii++
|
||||
}
|
||||
|
@ -686,7 +712,7 @@ pub fn (s string) index_after(p string, start int) int {
|
|||
|
||||
pub fn (s string) index_byte(c byte) int {
|
||||
for i in 0..s.len {
|
||||
if s.str[i] == c {
|
||||
if unsafe {s.str[i]} == c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
@ -695,7 +721,7 @@ pub fn (s string) index_byte(c byte) int {
|
|||
|
||||
pub fn (s string) last_index_byte(c byte) int {
|
||||
for i := s.len - 1; i >= 0; i-- {
|
||||
if s.str[i] == c {
|
||||
if unsafe {s.str[i] == c} {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
@ -738,7 +764,7 @@ pub fn (s string) starts_with(p string) bool {
|
|||
return false
|
||||
}
|
||||
for i in 0..p.len {
|
||||
if s.str[i] != p.str[i] {
|
||||
if unsafe {s.str[i] != p.str[i]} {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -759,12 +785,14 @@ pub fn (s string) ends_with(p string) bool {
|
|||
|
||||
// TODO only works with ASCII
|
||||
pub fn (s string) to_lower() string {
|
||||
unsafe {
|
||||
mut b := malloc(s.len + 1)
|
||||
for i in 0..s.len {
|
||||
b[i] = byte(C.tolower(s.str[i]))
|
||||
}
|
||||
return tos(b, s.len)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s string) is_lower() bool {
|
||||
for i in 0..s.len {
|
||||
|
@ -776,12 +804,14 @@ pub fn (s string) is_lower() bool {
|
|||
}
|
||||
|
||||
pub fn (s string) to_upper() string {
|
||||
unsafe {
|
||||
mut b := malloc(s.len + 1)
|
||||
for i in 0..s.len {
|
||||
b[i] = byte(C.toupper(s.str[i]))
|
||||
}
|
||||
return tos(b, s.len)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s string) is_upper() bool {
|
||||
for i in 0..s.len {
|
||||
|
@ -996,7 +1026,7 @@ pub fn (s string) ustring() ustring {
|
|||
runes: __new_array(0, s.len, int(sizeof(int)))
|
||||
}
|
||||
for i := 0; i < s.len; i++ {
|
||||
char_len := utf8_char_len(s.str[i])
|
||||
char_len := utf8_char_len(unsafe {s.str[i]})
|
||||
res.runes << i
|
||||
i += char_len - 1
|
||||
res.len++
|
||||
|
@ -1020,7 +1050,7 @@ pub fn (s string) ustring_tmp() ustring {
|
|||
res.runes.len = s.len
|
||||
mut j := 0
|
||||
for i := 0; i < s.len; i++ {
|
||||
char_len := utf8_char_len(s.str[i])
|
||||
char_len := utf8_char_len(unsafe {s.str[i]})
|
||||
res.runes[j] = i
|
||||
j++
|
||||
i += char_len - 1
|
||||
|
@ -1063,14 +1093,14 @@ pub fn (u ustring) add(a ustring) ustring {
|
|||
}
|
||||
mut j := 0
|
||||
for i := 0; i < u.s.len; i++ {
|
||||
char_len := utf8_char_len(u.s.str[i])
|
||||
char_len := utf8_char_len(unsafe {u.s.str[i]})
|
||||
res.runes << j
|
||||
i += char_len - 1
|
||||
j += char_len
|
||||
res.len++
|
||||
}
|
||||
for i := 0; i < a.s.len; i++ {
|
||||
char_len := utf8_char_len(a.s.str[i])
|
||||
char_len := utf8_char_len(unsafe {a.s.str[i]})
|
||||
res.runes << j
|
||||
i += char_len - 1
|
||||
j += char_len
|
||||
|
@ -1157,8 +1187,10 @@ fn (s string) at(idx int) byte {
|
|||
panic('string index out of range: $idx / $s.len')
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
return s.str[idx]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (u ustring) at(idx int) string {
|
||||
$if !no_bounds_checking? {
|
||||
|
@ -1279,18 +1311,24 @@ pub fn (a []string) join(del string) string {
|
|||
// Go thru every string and copy its every char one by one
|
||||
for i, val in a {
|
||||
for j in 0..val.len {
|
||||
unsafe {
|
||||
res.str[idx] = val.str[j]
|
||||
}
|
||||
idx++
|
||||
}
|
||||
// Add del if it's not last
|
||||
if i != a.len - 1 {
|
||||
for k in 0..del.len {
|
||||
unsafe {
|
||||
res.str[idx] = del.str[k]
|
||||
}
|
||||
idx++
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
res.str[res.len] = `\0`
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -1308,8 +1346,10 @@ pub fn (s string) reverse() string {
|
|||
len: s.len
|
||||
}
|
||||
for i := s.len - 1; i >= 0; i-- {
|
||||
unsafe {
|
||||
res.str[s.len - i - 1] = s[i]
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -1362,10 +1402,14 @@ pub fn (s string) repeat(count int) string {
|
|||
mut ret := malloc(s.len * count + 1)
|
||||
for i in 0 .. count {
|
||||
for j in 0 .. s.len {
|
||||
unsafe {
|
||||
ret[i * s.len + j] = s[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
ret[s.len * count] = 0
|
||||
}
|
||||
return string(ret)
|
||||
}
|
||||
|
||||
|
@ -1375,12 +1419,14 @@ pub fn (s string) fields() []string {
|
|||
}
|
||||
|
||||
pub fn (s string) map(func fn(byte) byte) string {
|
||||
unsafe {
|
||||
mut res := malloc(s.len + 1)
|
||||
for i in 0..s.len {
|
||||
res[i] = func(s[i])
|
||||
}
|
||||
return tos(res, s.len)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s string) filter(func fn(b byte) bool) string {
|
||||
mut new_len := 0
|
||||
|
@ -1425,11 +1471,15 @@ pub fn (s string) strip_margin_custom(del byte) string {
|
|||
mut count := 0
|
||||
for i := 0; i < s.len; i++ {
|
||||
if s[i] in [`\n`, `\r`] {
|
||||
unsafe {
|
||||
ret[count] = s[i]
|
||||
}
|
||||
count++
|
||||
// CRLF
|
||||
if s[i] == `\r` && i < s.len - 1 && s[i+1] == `\n` {
|
||||
unsafe {
|
||||
ret[count] = s[i+1]
|
||||
}
|
||||
count++
|
||||
i++
|
||||
}
|
||||
|
@ -1441,10 +1491,14 @@ pub fn (s string) strip_margin_custom(del byte) string {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
unsafe {
|
||||
ret[count] = s[i]
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
ret[count] = 0
|
||||
}
|
||||
return string(ret)
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
|
|||
if len == 0 {
|
||||
return 0
|
||||
}
|
||||
mut p := &key[0]
|
||||
mut p := key
|
||||
mut seed := seed_
|
||||
mut i := len & 63
|
||||
unsafe {
|
||||
|
@ -119,15 +119,21 @@ pub fn wymum(a, b u64) u64 {
|
|||
|
||||
[inline]
|
||||
fn wyr3(p byteptr, k u64) u64 {
|
||||
unsafe {
|
||||
return (u64(p[0])<<16) | (u64(p[k>>1])<<8) | u64(p[k - 1])
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn wyr4(p byteptr) u64 {
|
||||
unsafe {
|
||||
return u32(p[0]) | (u32(p[1])<<u32(8)) | (u32(p[2])<<u32(16)) | (u32(p[3])<<u32(24))
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn wyr8(p byteptr) u64 {
|
||||
unsafe {
|
||||
return u64(p[0]) | (u64(p[1])<<8) | (u64(p[2])<<16) | (u64(p[3])<<24) | (u64(p[4])<<32) | (u64(p[5])<<40) | (u64(p[6])<<48) | (u64(p[7])<<56)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -384,7 +384,7 @@ pub fn remove_tail_zeros(s string) string {
|
|||
mut in_decimal := false
|
||||
mut prev_ch := byte(0)
|
||||
for i < s.len {
|
||||
ch := s.str[i]
|
||||
ch := unsafe {s.str[i]}
|
||||
if ch == `.` {
|
||||
in_decimal = true
|
||||
dot_pos = i
|
||||
|
@ -412,7 +412,7 @@ pub fn remove_tail_zeros(s string) string {
|
|||
} else {
|
||||
tmp = s
|
||||
}
|
||||
if tmp.str[tmp.len-1] == `.` {
|
||||
if unsafe {tmp.str[tmp.len-1]} == `.` {
|
||||
return tmp[..tmp.len-1]
|
||||
}
|
||||
return tmp
|
||||
|
@ -474,7 +474,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
|
||||
// single char, manage it here
|
||||
if ch == `c` && status == .field_char {
|
||||
d1 := *(&byte(pt[p_index]))
|
||||
d1 := unsafe {*(&byte(pt[p_index]))}
|
||||
res.write_b(d1)
|
||||
status = .reset_params
|
||||
p_index++
|
||||
|
@ -484,7 +484,8 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
|
||||
// pointer, manage it here
|
||||
if ch == `p` && status == .field_char {
|
||||
res.write("0x"+ptr_str(pt[p_index]))
|
||||
res.write("0x")
|
||||
res.write(ptr_str(unsafe {pt[p_index]}))
|
||||
status = .reset_params
|
||||
p_index++
|
||||
i++
|
||||
|
@ -525,9 +526,9 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
}
|
||||
// manage "%.*s" precision field
|
||||
else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` {
|
||||
len := *(&int(pt[p_index]))
|
||||
len := unsafe {*(&int(pt[p_index]))}
|
||||
p_index++
|
||||
mut s := *(&string(pt[p_index]))
|
||||
mut s := unsafe {*(&string(pt[p_index]))}
|
||||
s = s[..len]
|
||||
p_index++
|
||||
res.write(s)
|
||||
|
@ -629,11 +630,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
// hh fot 8 bit int
|
||||
`h` {
|
||||
if ch2 == `h` {
|
||||
x := *(&i8(pt[p_index]))
|
||||
x := unsafe {*(&i8(pt[p_index]))}
|
||||
positive = if x >= 0 { true } else { false }
|
||||
d1 = if positive { u64(x) } else { u64(-x) }
|
||||
} else {
|
||||
x := *(&i16(pt[p_index]))
|
||||
x := unsafe {*(&i16(pt[p_index]))}
|
||||
positive = if x >= 0 { true } else { false }
|
||||
d1 = if positive { u64(x) } else { u64(-x) }
|
||||
}
|
||||
|
@ -653,13 +654,13 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
d1 = if positive { u64(x) } else { u64(-x) }
|
||||
}
|
||||
*/
|
||||
x := *(&i64(pt[p_index]))
|
||||
x := unsafe {*(&i64(pt[p_index]))}
|
||||
positive = if x >= 0 { true } else { false }
|
||||
d1 = if positive { u64(x) } else { u64(-x) }
|
||||
}
|
||||
// defualt int
|
||||
// default int
|
||||
else {
|
||||
x := *(&int(pt[p_index]))
|
||||
x := unsafe {*(&int(pt[p_index]))}
|
||||
positive = if x >= 0 { true } else { false }
|
||||
d1 = if positive { u64(x) } else { u64(-x) }
|
||||
}
|
||||
|
@ -685,9 +686,9 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
// hh fot 8 bit unsigned int
|
||||
`h` {
|
||||
if ch2 == `h` {
|
||||
d1 = u64(*(&byte(pt[p_index])))
|
||||
d1 = u64(unsafe {*(&byte(pt[p_index]))})
|
||||
} else {
|
||||
d1 = u64(*(&u16(pt[p_index])))
|
||||
d1 = u64(unsafe {*(&u16(pt[p_index]))})
|
||||
}
|
||||
}
|
||||
// l u64
|
||||
|
@ -701,11 +702,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
d1 = u64(*(&u64(pt[p_index])))
|
||||
}
|
||||
*/
|
||||
d1 = u64(*(&u64(pt[p_index])))
|
||||
d1 = u64(unsafe {*(&u64(pt[p_index]))})
|
||||
}
|
||||
// defualt int
|
||||
else {
|
||||
d1 = u64(*(&u32(pt[p_index])))
|
||||
d1 = u64(unsafe {*(&u32(pt[p_index]))})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,10 +726,10 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
// hh fot 8 bit int
|
||||
`h` {
|
||||
if ch2 == `h` {
|
||||
x := *(&i8(pt[p_index]))
|
||||
x := unsafe {*(&i8(pt[p_index]))}
|
||||
s = x.hex()
|
||||
} else {
|
||||
x := *(&i16(pt[p_index]))
|
||||
x := unsafe {*(&i16(pt[p_index]))}
|
||||
s = x.hex()
|
||||
}
|
||||
}
|
||||
|
@ -745,11 +746,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
s = x.hex()
|
||||
}
|
||||
*/
|
||||
x := *(&i64(pt[p_index]))
|
||||
x := unsafe {*(&i64(pt[p_index]))}
|
||||
s = x.hex()
|
||||
}
|
||||
else {
|
||||
x := *(&int(pt[p_index]))
|
||||
x := unsafe {*(&int(pt[p_index]))}
|
||||
s = x.hex()
|
||||
}
|
||||
}
|
||||
|
@ -767,7 +768,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
|
||||
// float and double
|
||||
if ch in [`f`, `F`] {
|
||||
x := *(&f64(pt[p_index]))
|
||||
x := unsafe {*(&f64(pt[p_index]))}
|
||||
mut positive := x >= f64(0.0)
|
||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
||||
s := format_fl(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
|
||||
|
@ -778,7 +779,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
continue
|
||||
}
|
||||
else if ch in [`e`, `E`] {
|
||||
x := *(&f64(pt[p_index]))
|
||||
x := unsafe {*(&f64(pt[p_index]))}
|
||||
mut positive := x >= f64(0.0)
|
||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
||||
s := format_es(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
|
||||
|
@ -789,7 +790,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
continue
|
||||
}
|
||||
else if ch in [`g`, `G`] {
|
||||
x := *(&f64(pt[p_index]))
|
||||
x := unsafe {*(&f64(pt[p_index]))}
|
||||
mut positive := x >= f64(0.0)
|
||||
mut s := ""
|
||||
tx := fabs(x)
|
||||
|
@ -810,7 +811,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
|
||||
// string
|
||||
else if ch == `s` {
|
||||
s1 := *(&string(pt[p_index]))
|
||||
s1 := unsafe{*(&string(pt[p_index]))}
|
||||
pad_ch = ` `
|
||||
res.write(format_str(s1, {pad_ch: pad_ch, len0: len0, len1: 0, positive: true, sign_flag: false, allign: allign}))
|
||||
status = .reset_params
|
||||
|
|
|
@ -5,10 +5,11 @@ pub fn repeat(c byte, n int) string {
|
|||
if n <= 0 {
|
||||
return ''
|
||||
}
|
||||
mut bytes := &byte(0)
|
||||
unsafe { bytes = malloc(n + 1) }
|
||||
mut bytes := unsafe {malloc(n + 1)}
|
||||
unsafe {
|
||||
C.memset( bytes, c, n )
|
||||
bytes[n] = `0`
|
||||
}
|
||||
return string( bytes, n )
|
||||
}
|
||||
|
||||
|
@ -21,14 +22,17 @@ pub fn repeat_string(s string, n int) string {
|
|||
}
|
||||
slen := s.len
|
||||
blen := slen*n
|
||||
mut bytes := &byte(0)
|
||||
unsafe { bytes = malloc(blen + 1) }
|
||||
mut bytes := unsafe {malloc(blen + 1)}
|
||||
for bi in 0..n {
|
||||
bislen := bi*slen
|
||||
for si in 0..slen {
|
||||
unsafe {
|
||||
bytes[bislen+si] = s[si]
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
bytes[blen] = `0`
|
||||
}
|
||||
return string( bytes, blen )
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue