v/vlib/x/encoding/asn1/util.v

118 lines
2.2 KiB
V

// Copyright (c) 2022, 2024 blackshirt. All rights reserved.
// Use of this source code is governed by a MIT License
// that can be found in the LICENSE file.
module asn1
// ASN.1 Utility function
// read_bytes was safe version of bytes slicing, `src[pos..pos+size]`
fn read_bytes(src []u8, pos int, size int) ![]u8 {
if src.len < 1 || pos > src.len || size > src.len {
return error(' pos=${pos} or size=${size} bigger than len=${src.len}')
}
if pos + size > src.len {
return error('pos + size maybe getting overflow')
}
ret := src[pos..pos + size]
return ret
}
fn read_byte(src []u8, loc int) !(u8, int) {
if src.len == 0 || loc + 1 > src.len {
return error('invalid loc or len')
}
mut pos := loc
result := src[pos]
pos += 1
return result, pos
}
fn read_digit(src []u8, loc int) !(u8, int) {
val, pos := read_byte(src, loc)!
// check its a digit, '0'-'9',
// aka, 0x30 s/d 0x39 in hex, or 48-57 in dec
if !val.is_digit() {
return error('not digit byte')
}
digit := val - u8(0x30) // get the digit value
return digit, pos
}
fn read_2_digits(src []u8, loc int) !(u8, int) {
if loc >= src.len || src.len < 2 + loc {
return error('not enough bytes')
}
mut val, mut pos := read_digit(src, loc)!
first := val * 10
if pos < src.len {
val, pos = read_digit(src, pos)!
}
return first + val, pos
}
fn read_4_digits(src []u8, loc int) !(u16, int) {
if loc >= src.len || src.len < 4 + loc {
return error('not enough bytes')
}
mut val, mut pos := read_digit(src, loc)!
first := u16(val) * 1000
if pos < src.len {
val, pos = read_digit(src, pos)!
}
second := u16(val) * 100
if pos < src.len {
val, pos = read_digit(src, pos)!
}
third := u16(val) * 10
if pos < src.len {
val, pos = read_digit(src, pos)!
}
fourth := u16(val)
result := first + second + third + fourth
return result, pos
}
fn validate_date(year u16, month u8, day u8) bool {
if year < 0 {
return false
}
if day < 1 {
return false
}
mut dim := month
match month {
1, 3, 5, 7, 8, 10, 12 {
dim = 31
}
4, 6, 9, 11 {
dim = 30
}
2 {
// kabisat
if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 {
dim = 29
} else {
dim = 28
}
}
else {
return false
}
}
if day > dim {
return false
}
return true
}