///|
/// ASN.1 tag class (X.690 8.1.2.2).
pub(all) enum TagClass {
Universal
Application
ContextSpecific
Private
} derive(Eq, @debug.Debug)
///|
pub fn TagClass::to_bits(self : TagClass) -> Int {
match self {
Universal => 0
Application => 1
ContextSpecific => 2
Private => 3
}
}
///|
pub fn TagClass::from_bits(bits : Int) -> TagClass {
match bits {
0 => Universal
1 => Application
2 => ContextSpecific
_ => Private
}
}
///|
/// An ASN.1 identifier octet(s) decoded into its components.
pub struct BerTag {
class : TagClass
constructed : Bool
number : Int
} derive(Eq, @debug.Debug)
///|
pub fn BerTag::new(
class : TagClass,
constructed : Bool,
number : Int,
) -> BerTag {
{ class, constructed, number }
}
///|
pub fn BerTag::is_constructed(self : BerTag) -> Bool {
self.constructed
}
///|
/// First identifier octet. When `number >= 31` the low five bits are `0b11111`
/// and the full number follows in long form.
pub fn BerTag::first_octet(self : BerTag) -> Int {
let class = self.class.to_bits() << 6
let constructed = if self.constructed { 0x20 } else { 0 }
if self.number < 31 {
class | constructed | self.number
} else {
class | constructed | 0x1F
}
}
///|
pub fn BerTag::to_string(self : BerTag) -> String {
let class = match self.class {
Universal => "universal"
Application => "application"
ContextSpecific => "context"
Private => "private"
}
let kind = if self.constructed { "constructed" } else { "primitive" }
"\{class} \{kind} tag \{self.number}"
}
///|
/// Short helper for constructing universal tags.
pub fn universal_tag(number : Int, constructed : Bool) -> BerTag {
BerTag::new(TagClass::Universal, constructed, number)
}
///|
/// Short helper for constructing context-specific tags.
pub fn context_tag(number : Int, constructed : Bool) -> BerTag {
BerTag::new(TagClass::ContextSpecific, constructed, number)
}
///|
/// Short helper for constructing application tags.
pub fn application_tag(number : Int, constructed : Bool) -> BerTag {
BerTag::new(TagClass::Application, constructed, number)
}
// Universal tag numbers (X.690 8.1.2.4, 8.5-8.23).
///|
let tag_eoc : Int = 0
///|
let tag_boolean : Int = 1
///|
let tag_integer : Int = 2
///|
let tag_bit_string : Int = 3
///|
let tag_octet_string : Int = 4
///|
let tag_null : Int = 5
///|
let tag_oid : Int = 6
///|
let tag_enumerated : Int = 10
///|
let tag_utf8_string : Int = 12
///|
let tag_sequence : Int = 16
///|
let tag_set : Int = 17
///|
let tag_ia5_string : Int = 22