mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
urllib: rem underscore methods from; add strings index_bytes
This commit is contained in:
parent
f3abb9e682
commit
f8fefd5a60
@ -508,6 +508,24 @@ pub fn (s string) index_after(p string, start int) int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (s string) index_byte(c byte) int {
|
||||||
|
for i:=0; i<s.len; i++ {
|
||||||
|
if s[i] == c {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (s string) last_index_byte(c byte) int {
|
||||||
|
for i:=s.len-1; i>=0; i-- {
|
||||||
|
if s[i] == c {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
// counts occurrences of substr in s
|
// counts occurrences of substr in s
|
||||||
pub fn (s string) count(substr string) int {
|
pub fn (s string) count(substr string) int {
|
||||||
if s.len == 0 || substr.len == 0 {
|
if s.len == 0 || substr.len == 0 {
|
||||||
|
@ -26,7 +26,8 @@ mut:
|
|||||||
tmp []byte
|
tmp []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _new_cbc(b AesCipher, iv []byte) AesCbc {
|
// internal
|
||||||
|
fn new_aes_cbc(b AesCipher, iv []byte) AesCbc {
|
||||||
return AesCbc{
|
return AesCbc{
|
||||||
b: b,
|
b: b,
|
||||||
block_size: b.block_size(),
|
block_size: b.block_size(),
|
||||||
@ -42,7 +43,7 @@ pub fn new_cbc(b AesCipher, iv []byte) AesCbc {
|
|||||||
if iv.len != b.block_size() {
|
if iv.len != b.block_size() {
|
||||||
panic('crypto.cipher.new_cbc_encrypter: IV length must equal block size')
|
panic('crypto.cipher.new_cbc_encrypter: IV length must equal block size')
|
||||||
}
|
}
|
||||||
return _new_cbc(b, iv)
|
return new_aes_cbc(b, iv)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (x &AesCbc) block_size() int { return x.block_size }
|
pub fn (x &AesCbc) block_size() int { return x.block_size }
|
||||||
|
@ -26,22 +26,22 @@ pub fn read(bytes_needed int) ?[]byte {
|
|||||||
if bytes_needed > ReadBatchSize {
|
if bytes_needed > ReadBatchSize {
|
||||||
no_batches := int(math.floor(f64(bytes_needed/ReadBatchSize)))
|
no_batches := int(math.floor(f64(bytes_needed/ReadBatchSize)))
|
||||||
for i:=0; i<no_batches; i++ {
|
for i:=0; i<no_batches; i++ {
|
||||||
if _getrandom(ReadBatchSize, buffer+bytes_read) == -1 {
|
if getrandom(ReadBatchSize, buffer+bytes_read) == -1 {
|
||||||
return ReadError
|
return ReadError
|
||||||
}
|
}
|
||||||
bytes_read += ReadBatchSize
|
bytes_read += ReadBatchSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _getrandom(bytes_needed-bytes_read, buffer+bytes_read) == -1 {
|
if getrandom(bytes_needed-bytes_read, buffer+bytes_read) == -1 {
|
||||||
return ReadError
|
return ReadError
|
||||||
}
|
}
|
||||||
|
|
||||||
return c_array_to_bytes_tmp(bytes_needed, buffer)
|
return c_array_to_bytes_tmp(bytes_needed, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _getrandom(bytes_needed int, buffer voidptr) int {
|
fn getrandom(bytes_needed int, buffer voidptr) int {
|
||||||
if bytes_needed > ReadBatchSize {
|
if bytes_needed > ReadBatchSize {
|
||||||
panic('_getrandom() dont request more thane $ReadBatchSize bytes at once.')
|
panic('getrandom() dont request more thane $ReadBatchSize bytes at once.')
|
||||||
}
|
}
|
||||||
return C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0)
|
return C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0)
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,8 @@ fn (d mut Digest) reset() {
|
|||||||
d.len = 0
|
d.len = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _new(hash crypto.Hash) &Digest {
|
// internal
|
||||||
|
fn new_digest(hash crypto.Hash) &Digest {
|
||||||
mut d := &Digest{function: hash}
|
mut d := &Digest{function: hash}
|
||||||
d.reset()
|
d.reset()
|
||||||
return d
|
return d
|
||||||
@ -128,22 +129,22 @@ fn _new(hash crypto.Hash) &Digest {
|
|||||||
|
|
||||||
// new returns a new Digest (implementing hash.Hash) computing the SHA-512 checksum.
|
// new returns a new Digest (implementing hash.Hash) computing the SHA-512 checksum.
|
||||||
pub fn new() &Digest {
|
pub fn new() &Digest {
|
||||||
return _new(crypto.Hash.SHA512)
|
return new_digest(crypto.Hash.SHA512)
|
||||||
}
|
}
|
||||||
|
|
||||||
// new512_224 returns a new Digest (implementing hash.Hash) computing the SHA-512/224 checksum.
|
// new512_224 returns a new Digest (implementing hash.Hash) computing the SHA-512/224 checksum.
|
||||||
fn new512_224() &Digest {
|
fn new512_224() &Digest {
|
||||||
return _new(crypto.Hash.SHA512_224)
|
return new_digest(crypto.Hash.SHA512_224)
|
||||||
}
|
}
|
||||||
|
|
||||||
// new512_256 returns a new Digest (implementing hash.Hash) computing the SHA-512/256 checksum.
|
// new512_256 returns a new Digest (implementing hash.Hash) computing the SHA-512/256 checksum.
|
||||||
fn new512_256() &Digest {
|
fn new512_256() &Digest {
|
||||||
return _new(crypto.Hash.SHA512_256)
|
return new_digest(crypto.Hash.SHA512_256)
|
||||||
}
|
}
|
||||||
|
|
||||||
// new384 returns a new Digest (implementing hash.Hash) computing the SHA-384 checksum.
|
// new384 returns a new Digest (implementing hash.Hash) computing the SHA-384 checksum.
|
||||||
fn new384() &Digest {
|
fn new384() &Digest {
|
||||||
return _new(crypto.Hash.SHA384)
|
return new_digest(crypto.Hash.SHA384)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (d mut Digest) write(p_ []byte) ?int {
|
fn (d mut Digest) write(p_ []byte) ?int {
|
||||||
@ -245,14 +246,14 @@ fn (d mut Digest) checksum() []byte {
|
|||||||
|
|
||||||
// sum512 returns the SHA512 checksum of the data.
|
// sum512 returns the SHA512 checksum of the data.
|
||||||
pub fn sum512(data []byte) []byte {
|
pub fn sum512(data []byte) []byte {
|
||||||
mut d := _new(crypto.Hash.SHA512)
|
mut d := new_digest(crypto.Hash.SHA512)
|
||||||
d.write(data)
|
d.write(data)
|
||||||
return d.checksum()
|
return d.checksum()
|
||||||
}
|
}
|
||||||
|
|
||||||
// sum384 returns the SHA384 checksum of the data.
|
// sum384 returns the SHA384 checksum of the data.
|
||||||
pub fn sum384(data []byte) []byte {
|
pub fn sum384(data []byte) []byte {
|
||||||
mut d := _new(crypto.Hash.SHA384)
|
mut d := new_digest(crypto.Hash.SHA384)
|
||||||
d.write(data)
|
d.write(data)
|
||||||
sum := d.checksum()
|
sum := d.checksum()
|
||||||
mut sum384 := [byte(0)].repeat(Size384)
|
mut sum384 := [byte(0)].repeat(Size384)
|
||||||
@ -262,7 +263,7 @@ pub fn sum384(data []byte) []byte {
|
|||||||
|
|
||||||
// sum512_224 returns the Sum512/224 checksum of the data.
|
// sum512_224 returns the Sum512/224 checksum of the data.
|
||||||
pub fn sum512_224(data []byte) []byte {
|
pub fn sum512_224(data []byte) []byte {
|
||||||
mut d := _new(crypto.Hash.SHA512_224)
|
mut d := new_digest(crypto.Hash.SHA512_224)
|
||||||
d.write(data)
|
d.write(data)
|
||||||
sum := d.checksum()
|
sum := d.checksum()
|
||||||
mut sum224 := [byte(0)].repeat(Size224)
|
mut sum224 := [byte(0)].repeat(Size224)
|
||||||
@ -272,7 +273,7 @@ pub fn sum512_224(data []byte) []byte {
|
|||||||
|
|
||||||
// Sum512_256 returns the Sum512/256 checksum of the data.
|
// Sum512_256 returns the Sum512/256 checksum of the data.
|
||||||
pub fn sum512_256(data []byte) []byte {
|
pub fn sum512_256(data []byte) []byte {
|
||||||
mut d := _new(crypto.Hash.SHA512_256)
|
mut d := new_digest(crypto.Hash.SHA512_256)
|
||||||
d.write(data)
|
d.write(data)
|
||||||
sum := d.checksum()
|
sum := d.checksum()
|
||||||
mut sum256 := [byte(0)].repeat(Size256)
|
mut sum256 := [byte(0)].repeat(Size256)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// it deviates for compatibility reasons.
|
// it deviates for compatibility reasons.
|
||||||
|
|
||||||
// Based off: https://github.com/golang/go/blob/master/src/net/url/url.go
|
// Based off: https://github.com/golang/go/blob/master/src/net/url/url.go
|
||||||
// Last commit: https://github.com/golang/go/commit/61bb56ad63992a3199acc55b2537c8355ef887b6
|
// Last commit: https://github.com/golang/go/commit/fe2ed5054176935d4adcf13e891715ccf2ee3cce
|
||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
@ -267,7 +267,7 @@ fn escape(s string, mode EncodingMode) string {
|
|||||||
return string(t)
|
return string(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctab := '0123456789ABCDEF'
|
upperhex := '0123456789ABCDEF'
|
||||||
mut j := 0
|
mut j := 0
|
||||||
for i := 0; i < s.len; i++ {
|
for i := 0; i < s.len; i++ {
|
||||||
c1 := s[i]
|
c1 := s[i]
|
||||||
@ -276,8 +276,8 @@ fn escape(s string, mode EncodingMode) string {
|
|||||||
j++
|
j++
|
||||||
} else if should_escape(c1, mode) {
|
} else if should_escape(c1, mode) {
|
||||||
t[j] = `%`
|
t[j] = `%`
|
||||||
t[j+1] = ctab[c1>>4]
|
t[j+1] = upperhex[c1>>4]
|
||||||
t[j+2] = ctab[c1&15]
|
t[j+2] = upperhex[c1&15]
|
||||||
j += 3
|
j += 3
|
||||||
} else {
|
} else {
|
||||||
t[j] = s[i]
|
t[j] = s[i]
|
||||||
@ -404,18 +404,18 @@ fn get_scheme(rawurl string) ?string {
|
|||||||
return split[0]
|
return split[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe s is of the form t c u.
|
// split slices s into two substrings separated by the first occurence of
|
||||||
// If so, return t, c u (or t, u if cutc == true).
|
// sep. If cutc is true then sep is included with the second substring.
|
||||||
// If not, return s, ''.
|
// If sep does not occur in s then s and the empty string is returned.
|
||||||
fn split(s string, c string, cutc bool) []string {
|
fn split(s string, sep byte, cutc bool) (string, string) {
|
||||||
i := s.index(c)
|
i := s.index_byte(sep)
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
return [s, '']
|
return s, ''
|
||||||
}
|
}
|
||||||
if cutc {
|
if cutc {
|
||||||
return [s.left(i), s.right(i+c.len)]
|
return s.left(i), s.right(i+1)
|
||||||
}
|
}
|
||||||
return [s.left(i), s.right(i)]
|
return s.left(i), s.right(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse parses rawurl into a URL structure.
|
// parse parses rawurl into a URL structure.
|
||||||
@ -426,10 +426,8 @@ fn split(s string, c string, cutc bool) []string {
|
|||||||
// error, due to parsing ambiguities.
|
// error, due to parsing ambiguities.
|
||||||
pub fn parse(rawurl string) ?URL {
|
pub fn parse(rawurl string) ?URL {
|
||||||
// Cut off #frag
|
// Cut off #frag
|
||||||
p := split(rawurl, '#', true)
|
u, frag := split(rawurl, `#`, true)
|
||||||
u := p[0]
|
mut url := parse_url(u, false) or {
|
||||||
frag := p[1]
|
|
||||||
mut url := _parse(u, false) or {
|
|
||||||
return error(error_msg(err_msg_parse, u))
|
return error(error_msg(err_msg_parse, u))
|
||||||
}
|
}
|
||||||
if frag == '' {
|
if frag == '' {
|
||||||
@ -448,14 +446,14 @@ pub fn parse(rawurl string) ?URL {
|
|||||||
// The string rawurl is assumed not to have a #fragment suffix.
|
// The string rawurl is assumed not to have a #fragment suffix.
|
||||||
// (Web browsers strip #fragment before sending the URL to a web server.)
|
// (Web browsers strip #fragment before sending the URL to a web server.)
|
||||||
fn parse_request_uri(rawurl string) ?URL {
|
fn parse_request_uri(rawurl string) ?URL {
|
||||||
return _parse(rawurl, true)
|
return parse_url(rawurl, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// _parse parses a URL from a string in one of two contexts. If
|
// parse_url parses a URL from a string in one of two contexts. If
|
||||||
// via_request is true, the URL is assumed to have arrived via an HTTP request,
|
// via_request is true, the URL is assumed to have arrived via an HTTP request,
|
||||||
// in which case only absolute URLs or path-absolute relative URLs are allowed.
|
// in which case only absolute URLs or path-absolute relative URLs are allowed.
|
||||||
// If via_request is false, all forms of relative URLs are allowed.
|
// If via_request is false, all forms of relative URLs are allowed.
|
||||||
fn _parse(rawurl string, via_request bool) ?URL {
|
fn parse_url(rawurl string, via_request bool) ?URL {
|
||||||
if string_contains_ctl_byte(rawurl) {
|
if string_contains_ctl_byte(rawurl) {
|
||||||
return error(error_msg('invalid control character in URL', rawurl))
|
return error(error_msg('invalid control character in URL', rawurl))
|
||||||
}
|
}
|
||||||
@ -480,13 +478,13 @@ fn _parse(rawurl string, via_request bool) ?URL {
|
|||||||
url.scheme = url.scheme.to_lower()
|
url.scheme = url.scheme.to_lower()
|
||||||
|
|
||||||
// if rest.ends_with('?') && strings.count(rest, '?') == 1 {
|
// if rest.ends_with('?') && strings.count(rest, '?') == 1 {
|
||||||
if rest.ends_with('?') && !rest.trim_right('?').contains('?') {
|
if rest.ends_with('?') && !rest.left(1).contains('?') {
|
||||||
url.force_query = true
|
url.force_query = true
|
||||||
rest = rest.left(rest.len-1)
|
rest = rest.left(rest.len-1)
|
||||||
} else {
|
} else {
|
||||||
parts := split(rest, '?', true)
|
r, raw_query := split(rest, `?`, true)
|
||||||
rest = parts[0]
|
rest = r
|
||||||
url.raw_query = parts[1]
|
url.raw_query = raw_query
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rest.starts_with('/') {
|
if !rest.starts_with('/') {
|
||||||
@ -514,9 +512,8 @@ fn _parse(rawurl string, via_request bool) ?URL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//') {
|
if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//') {
|
||||||
parts := split(rest.right(2), '/', false)
|
authority, r := split(rest.right(2), `/`, false)
|
||||||
authority := parts[0]
|
rest = r
|
||||||
rest = parts[1]
|
|
||||||
a := parse_authority(authority) or {
|
a := parse_authority(authority) or {
|
||||||
return error(err)
|
return error(err)
|
||||||
}
|
}
|
||||||
@ -567,9 +564,7 @@ fn parse_authority(authority string) ?ParseAuthorityRes {
|
|||||||
userinfo = u
|
userinfo = u
|
||||||
user = user(userinfo)
|
user = user(userinfo)
|
||||||
} else {
|
} else {
|
||||||
parts := split(userinfo, ':', true)
|
mut username, mut password := split(userinfo, `:`, true)
|
||||||
mut username := parts[0]
|
|
||||||
mut password := parts[1]
|
|
||||||
u := unescape(username, .encode_user_password) or {
|
u := unescape(username, .encode_user_password) or {
|
||||||
return error(err)
|
return error(err)
|
||||||
}
|
}
|
||||||
@ -777,8 +772,8 @@ pub fn (u &URL) str() string {
|
|||||||
// it would be mistaken for a scheme name. Such a segment must be
|
// it would be mistaken for a scheme name. Such a segment must be
|
||||||
// preceded by a dot-segment (e.g., './this:that') to make a relative-
|
// preceded by a dot-segment (e.g., './this:that') to make a relative-
|
||||||
// path reference.
|
// path reference.
|
||||||
i := path.index(':')
|
i := path.index_byte(`:`)
|
||||||
if i > -1 && path.left(i).index('/') == -1 {
|
if i > -1 && path.left(i).index_byte(`/`) == -1 {
|
||||||
buf.write('./')
|
buf.write('./')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -812,7 +807,7 @@ pub fn (u &URL) str() string {
|
|||||||
// interpreted as a key set to an empty value.
|
// interpreted as a key set to an empty value.
|
||||||
pub fn parse_query(query string) ?Values {
|
pub fn parse_query(query string) ?Values {
|
||||||
mut m := new_values()
|
mut m := new_values()
|
||||||
_ = _parse_query(mut m, query) or {
|
_ = parse_query_values(mut m, query) or {
|
||||||
return error(err)
|
return error(err)
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
@ -822,11 +817,11 @@ pub fn parse_query(query string) ?Values {
|
|||||||
// but any errors will be silent
|
// but any errors will be silent
|
||||||
fn parse_query_silent(query string) Values {
|
fn parse_query_silent(query string) Values {
|
||||||
mut m := new_values()
|
mut m := new_values()
|
||||||
_ = _parse_query(mut m, query)
|
_ = parse_query_values(mut m, query)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _parse_query(m mut Values, query string) ?bool {
|
fn parse_query_values(m mut Values, query string) ?bool {
|
||||||
mut had_error := false
|
mut had_error := false
|
||||||
mut q := query
|
mut q := query
|
||||||
for q != '' {
|
for q != '' {
|
||||||
@ -1016,25 +1011,25 @@ pub fn (u &URL) request_uri() string {
|
|||||||
// If the result is enclosed in square brackets, as literal IPv6 addresses are,
|
// If the result is enclosed in square brackets, as literal IPv6 addresses are,
|
||||||
// the square brackets are removed from the result.
|
// the square brackets are removed from the result.
|
||||||
pub fn (u &URL) hostname() string {
|
pub fn (u &URL) hostname() string {
|
||||||
host_port := split_host_port(u.host)
|
host, _ := split_host_port(u.host)
|
||||||
return host_port[0]
|
return host
|
||||||
}
|
}
|
||||||
|
|
||||||
// port returns the port part of u.host, without the leading colon.
|
// port returns the port part of u.host, without the leading colon.
|
||||||
// If u.host doesn't contain a port, port returns an empty string.
|
// If u.host doesn't contain a port, port returns an empty string.
|
||||||
pub fn (u &URL) port() string {
|
pub fn (u &URL) port() string {
|
||||||
host_port := split_host_port(u.host)
|
_, port := split_host_port(u.host)
|
||||||
return host_port[1]
|
return port
|
||||||
}
|
}
|
||||||
|
|
||||||
// split_host_port separates host and port. If the port is not valid, it returns
|
// split_host_port separates host and port. If the port is not valid, it returns
|
||||||
// the entire input as host, and it doesn't check the validity of the host.
|
// the entire input as host, and it doesn't check the validity of the host.
|
||||||
// Per RFC 3986, it requires ports to be numeric.
|
// Per RFC 3986, it requires ports to be numeric.
|
||||||
fn split_host_port(hostport string) []string {
|
fn split_host_port(hostport string) (string, string) {
|
||||||
mut host := hostport
|
mut host := hostport
|
||||||
mut port := ''
|
mut port := ''
|
||||||
|
|
||||||
colon := host.last_index(':')
|
colon := host.last_index_byte(`:`)
|
||||||
if colon != -1 && valid_optional_port(host.right(colon)) {
|
if colon != -1 && valid_optional_port(host.right(colon)) {
|
||||||
port = host.right(colon+1)
|
port = host.right(colon+1)
|
||||||
host = host.left(colon)
|
host = host.left(colon)
|
||||||
@ -1044,7 +1039,7 @@ fn split_host_port(hostport string) []string {
|
|||||||
host = host.substr(1, host.len-1)
|
host = host.substr(1, host.len-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return [host, port]
|
return host, port
|
||||||
}
|
}
|
||||||
|
|
||||||
// valid_userinfo reports whether s is a valid userinfo string per RFC 3986
|
// valid_userinfo reports whether s is a valid userinfo string per RFC 3986
|
||||||
|
@ -4,16 +4,12 @@
|
|||||||
|
|
||||||
module urllib
|
module urllib
|
||||||
|
|
||||||
struct ValueStruct {
|
struct Value {
|
||||||
pub:
|
pub:
|
||||||
mut:
|
mut:
|
||||||
data []string
|
data []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// using this instead of just ValueStruct
|
|
||||||
// because of unknown map initializer bug
|
|
||||||
type Value ValueStruct
|
|
||||||
|
|
||||||
struct Values {
|
struct Values {
|
||||||
pub:
|
pub:
|
||||||
mut:
|
mut:
|
||||||
@ -41,7 +37,7 @@ pub fn (v &Value) all() []string {
|
|||||||
// get gets the first value associated with the given key.
|
// get gets the first value associated with the given key.
|
||||||
// If there are no values associated with the key, get returns
|
// If there are no values associated with the key, get returns
|
||||||
// a empty string.
|
// a empty string.
|
||||||
pub fn (v Values) get(key string) string {
|
pub fn (v &Values) get(key string) string {
|
||||||
if v.data.size == 0 {
|
if v.data.size == 0 {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@ -55,7 +51,7 @@ pub fn (v Values) get(key string) string {
|
|||||||
// get_all gets the all the values associated with the given key.
|
// get_all gets the all the values associated with the given key.
|
||||||
// If there are no values associated with the key, get returns
|
// If there are no values associated with the key, get returns
|
||||||
// a empty []string.
|
// a empty []string.
|
||||||
pub fn (v Values) get_all(key string) []string {
|
pub fn (v &Values) get_all(key string) []string {
|
||||||
if v.data.size == 0 {
|
if v.data.size == 0 {
|
||||||
return []string
|
return []string
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user