Skip to content

Commit 7fd1b16

Browse files
authored
builtin: add a string.u8_array() method (#20736)
1 parent e6570dd commit 7fd1b16

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

vlib/builtin/string.v

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,59 @@ pub fn (s string) u8() u8 {
613613
return u8(strconv.common_parse_uint(s, 0, 8, false, false) or { 0 })
614614
}
615615

616+
// u8_array returns the value of the hex/bin string as u8 array.
617+
// hex string example: `'0x11223344ee'.u8_array() == [u8(0x11),0x22,0x33,0x44,0xee]`.
618+
// bin string example: `'0b1101_1101'.u8_array() == [u8(0xdd)]`.
619+
// underscore in the string will be stripped.
620+
pub fn (s string) u8_array() []u8 {
621+
// strip underscore in the string
622+
mut tmps := s.replace('_', '')
623+
if tmps.len == 0 {
624+
return []u8{}
625+
}
626+
tmps = tmps.to_lower()
627+
if tmps.starts_with('0x') {
628+
tmps = tmps[2..]
629+
if tmps.len == 0 {
630+
return []u8{}
631+
}
632+
// make sure every digit is valid hex digit
633+
if !tmps.contains_only('0123456789abcdef') {
634+
return []u8{}
635+
}
636+
// make sure tmps has even hex digits
637+
if tmps.len % 2 == 1 {
638+
tmps = '0' + tmps
639+
}
640+
641+
mut ret := []u8{len: tmps.len / 2}
642+
for i in 0 .. ret.len {
643+
ret[i] = u8(tmps[2 * i..2 * i + 2].parse_uint(16, 8) or { 0 })
644+
}
645+
return ret
646+
} else if tmps.starts_with('0b') {
647+
tmps = tmps[2..]
648+
if tmps.len == 0 {
649+
return []u8{}
650+
}
651+
// make sure every digit is valid binary digit
652+
if !tmps.contains_only('01') {
653+
return []u8{}
654+
}
655+
// make sure tmps has multiple of 8 binary digits
656+
if tmps.len % 8 != 0 {
657+
tmps = '0'.repeat(8 - tmps.len % 8) + tmps
658+
}
659+
660+
mut ret := []u8{len: tmps.len / 8}
661+
for i in 0 .. ret.len {
662+
ret[i] = u8(tmps[8 * i..8 * i + 8].parse_uint(2, 8) or { 0 })
663+
}
664+
return ret
665+
}
666+
return []u8{}
667+
}
668+
616669
// u16 returns the value of the string as u16 `'1'.u16() == u16(1)`.
617670
@[inline]
618671
pub fn (s string) u16() u16 {

vlib/builtin/string_test.v

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,52 @@ fn test_to_num() {
811811
assert big.i64() == 93993993939322
812812
}
813813

814+
fn test_to_u8_array() {
815+
// empty string
816+
assert ''.u8_array() == []
817+
assert '0x'.u8_array() == []
818+
assert '0X'.u8_array() == []
819+
assert '0b'.u8_array() == []
820+
assert '0B'.u8_array() == []
821+
// invalid digit
822+
assert '-123'.u8_array() == []
823+
assert '1_2xt'.u8_array() == []
824+
assert 'd1_2xt'.u8_array() == []
825+
826+
// ---------------------------------
827+
// hex test
828+
// invalid hex digit
829+
assert '0X-123'.u8_array() == []
830+
assert '0O12'.u8_array() == []
831+
// odd number of digits
832+
assert '0x1'.u8_array() == [u8(0x01)]
833+
assert '0x123'.u8_array() == [u8(0x01), 0x23]
834+
assert '0x1_23'.u8_array() == [u8(0x01), 0x23]
835+
836+
// long digits
837+
long_u8 := [u8(0x00), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
838+
0xdd, 0xee, 0xff]
839+
assert '0x00112233445566778899aabbccddeeff'.u8_array() == long_u8
840+
assert '0x00_112_2334455667788_99aabbccddeeff'.u8_array() == long_u8
841+
assert '0x00112233445566778899AABBCCDDEEFF'.u8_array() == long_u8
842+
assert '0x001_12233445566778899A_ABBCCDDEEFF'.u8_array() == long_u8
843+
844+
// ---------------------------------
845+
// bin test
846+
// invalid bin digit
847+
assert '0b-123'.u8_array() == []
848+
assert '0B12'.u8_array() == []
849+
// not enough length
850+
assert '0b0'.u8_array() == [u8(0x00)]
851+
assert '0b1'.u8_array() == [u8(0x01)]
852+
assert '0b101'.u8_array() == [u8(0x05)]
853+
assert '0b0101'.u8_array() == [u8(0x05)]
854+
// long digits
855+
assert '0b0101_0101'.u8_array() == [u8(0x55)]
856+
assert '0b0101010110101010'.u8_array() == [u8(0x55), 0xaa]
857+
assert '0b0101010110101010_0101010110101010'.u8_array() == [u8(0x55), 0xaa, 0x55, 0xaa]
858+
}
859+
814860
fn test_inter_format_string() {
815861
float_num := 1.52345
816862
float_num_string := '-${float_num:.3f}-'

0 commit comments

Comments
 (0)