mirror of
https://github.com/vlang/v.git
synced 2025-09-14 23:12:33 +03:00
80 lines
1.8 KiB
V
80 lines
1.8 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
|
|
|
|
const max_choices_size = 255
|
|
const default_choices_size = 64
|
|
|
|
// ASN.1 CHOICE
|
|
//
|
|
// Choice is an ASN.1 Element
|
|
pub struct Choice {
|
|
mut:
|
|
size int = default_choices_size
|
|
choosen Element
|
|
choices []Element
|
|
}
|
|
|
|
// new creates a new choice element. It accepts el as a choosen element
|
|
// and choices as a source of possible choices list.
|
|
pub fn Choice.new(el Element, choices []Element) !Choice {
|
|
c := Choice{
|
|
choosen: el
|
|
choices: choices
|
|
}
|
|
c.check()!
|
|
return c
|
|
}
|
|
|
|
// set_size sets the maximal this choices size
|
|
pub fn (mut c Choice) set_size(size int) ! {
|
|
if size > max_choices_size {
|
|
return error('Your size exceed max_choices_size')
|
|
}
|
|
c.size = size
|
|
c.check()!
|
|
}
|
|
|
|
// choose chooses some element for as a choosen element for the choice c.
|
|
pub fn (mut c Choice) choose(some Element) ! {
|
|
mut within := false
|
|
for el in c.choices {
|
|
if el.equal(some) {
|
|
within = true
|
|
}
|
|
}
|
|
if within {
|
|
c.choosen = some
|
|
return
|
|
}
|
|
return error('element not within choices')
|
|
}
|
|
|
|
fn (c Choice) check() ! {
|
|
if c.choices.len == 0 {
|
|
return error('bad choices list')
|
|
}
|
|
if c.choices.len > c.size {
|
|
return error('Your choices list exceed size')
|
|
}
|
|
// check the choosen element is within choices
|
|
filtered := c.choices.filter(it.equal(c.choosen))
|
|
// nothing found, so..its bad choice
|
|
if filtered.len == 0 {
|
|
return error('choosen element not within choices list')
|
|
}
|
|
if filtered.len > 1 {
|
|
return error('multiples element within choices matching with choosen element')
|
|
}
|
|
}
|
|
|
|
// tag returns the tag of choice element.
|
|
pub fn (c Choice) tag() Tag {
|
|
return c.choosen.tag()
|
|
}
|
|
|
|
// payload returns the payload of choice element.
|
|
pub fn (c Choice) payload() ![]u8 {
|
|
return c.choosen.payload()!
|
|
}
|