1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#[macro_export]
macro_rules! ber_choice {
($rs_type:ident, [$($opts:tt)*], $asn1_type:expr, $($args:tt)*) => (
asn1_info!($rs_type, [$($opts)*], $asn1_type);
ber_choice_serialize!($rs_type, $($args)*);
ber_choice_deserialize!($rs_type, $($args)*);
);
($rs_type:ident, $asn1_type:expr, $($args:tt)*) => (
asn1_info!($rs_type, $asn1_type);
ber_choice_serialize!($rs_type, $($args)*);
ber_choice_deserialize!($rs_type, $($args)*);
);
}
#[macro_export]
macro_rules! ber_choice_serialize {
(_ { $rs_type:ident $this:ident $e:ident $writer:ident [$($items:ident, $tags:expr,)*] }
[$($opts:tt)*] $item:ident, $inner:ty; $($args:tt)*) => (
let tag = Some(asn1_spec_tag!([$($opts)*]));
ber_choice_serialize!(_ { $rs_type $this $e $writer [$($items, $tags,)* $item, tag,] } $($args)*)
);
(_ { $rs_type:ident $this:ident $e:ident $writer:ident [$($items:ident, $tags:expr,)*] }
$item:ident, $inner:ty; $($args:tt)*) => (
let tag: Option<$crate::tag::Tag> = None;
ber_choice_serialize!(_ { $rs_type $this $e $writer [$($items, $tags,)* $item, tag,] } $($args)*)
);
(_ { $rs_type:ident $this:ident $e:ident $writer:ident [$($items:ident, $tags:expr,)*] }) => (
match *$this {
$( $rs_type::$items(ref item) => {
if let Some(tag) = $tags {
let mut bytes = Vec::new();
try!(item.serialize_enc($e, &mut bytes));
try!(tag.write_tag($writer));
let len: $crate::tag::Len = Some(bytes.len() as $crate::tag::LenNum).into();
try!(len.write_len($writer));
try!($writer.write_all(&mut bytes));
} else {
try!(item.serialize_enc($e, $writer));
}
} ),*
};
);
($rs_type:ident, $($args:tt)*) => (
impl $crate::BerSerialize for $rs_type {
fn serialize_value<E: $crate::BerEncRules, W: std::io::Write>
(&self, e: E, writer: &mut W) -> Result<(), $crate::err::EncodeError> {
ber_choice_serialize!(_ { $rs_type self e writer [] } $($args)*);
Ok(())
}
}
);
}
#[macro_export]
macro_rules! ber_choice_deserialize {
(_ { $rs_type:ident $e:ident $reader:ident $tag:ident $len:ident [$($tags:expr, $funcs:expr,)*] }
[$($opts:tt)*] $item:ident, $inner:ty; $($args:tt)*) => (
let tag = asn1_spec_tag!([$($opts)*]);
let func = |reader| Ok($rs_type::$item(
try!($crate::BerDeserialize::deserialize_enc($e, reader))
));
ber_choice_deserialize!(_ { $rs_type $e $reader $tag $len [$($tags, $funcs,)* tag, func,] } $($args)*)
);
(_ { $rs_type:ident $e:ident $reader:ident $tag:ident $len:ident [$($tags:expr, $funcs:expr,)*] }
$item:ident, $inner:ty; $($args:tt)*) => (
let tag = <$inner as $crate::Asn1Info>::asn1_tag().unwrap();
let func = |reader| Ok($rs_type::$item(
try!($crate::BerDeserialize::deserialize_with_tag($e, reader, $tag, $len))
));
ber_choice_deserialize!(_ { $rs_type $e $reader $tag $len [$($tags, $funcs,)* tag, func,] } $($args)*)
);
(_ { $rs_type:ident $e:ident $reader:ident $tag:ident $len:ident [$($tags:expr, $funcs:expr,)*] }) => (
return match $tag {
$( tag @ $crate::tag::Tag { .. } if tag == $tags => $funcs($reader) ),*,
_ => unimplemented!(),
};
);
($rs_type:ident, $($args:tt)*) => (
impl $crate::BerDeserialize for $rs_type {
fn deserialize_with_tag<E: $crate::BerEncRules, I: Iterator<Item=std::io::Result<u8>>>
(e: E, reader: &mut I, tag: $crate::tag::Tag, len: $crate::tag::Len)
-> Result<Self, $crate::err::DecodeError> {
ber_choice_deserialize!(_ { $rs_type e reader tag len [] } $($args)*);
}
}
);
}