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
use crate::params;
use crate::params::message;
use crate::signature;
use crate::wire::marshal::base::*;
use crate::wire::marshal::MarshalContext;
use crate::wire::util::*;
pub fn marshal_param(p: ¶ms::Param, ctx: &mut MarshalContext) -> message::Result<()> {
match p {
params::Param::Base(b) => marshal_base_param(&b, ctx),
params::Param::Container(c) => marshal_container_param(&c, ctx),
}
}
fn marshal_array(
array: &[params::Param],
sig: &signature::Type,
ctx: &mut MarshalContext,
) -> message::Result<()> {
ctx.align_to(4);
let len_pos = ctx.buf.len();
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.align_to(sig.get_alignment());
let content_pos = ctx.buf.len();
for p in array {
marshal_param(&p, ctx)?;
}
let len = ctx.buf.len() - content_pos;
insert_u32(
ctx.byteorder,
len as u32,
&mut ctx.buf[len_pos..len_pos + 4],
);
Ok(())
}
fn marshal_struct(params: &[params::Param], ctx: &mut MarshalContext) -> message::Result<()> {
ctx.align_to(8);
for p in params {
marshal_param(&p, ctx)?;
}
Ok(())
}
fn marshal_variant(var: ¶ms::Variant, ctx: &mut MarshalContext) -> message::Result<()> {
let mut sig_str = String::new();
var.sig.to_str(&mut sig_str);
marshal_signature(&sig_str, ctx.buf)?;
marshal_param(&var.value, ctx)?;
Ok(())
}
fn marshal_dict(dict: ¶ms::DictMap, ctx: &mut MarshalContext) -> message::Result<()> {
ctx.align_to(4);
let len_pos = ctx.buf.len();
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.align_to(8);
let content_pos = ctx.buf.len();
for (key, value) in dict {
ctx.align_to(8);
marshal_base_param(&key, ctx)?;
marshal_param(&value, ctx)?;
}
let len = ctx.buf.len() - content_pos;
insert_u32(
ctx.byteorder,
len as u32,
&mut ctx.buf[len_pos..len_pos + 4],
);
Ok(())
}
pub fn marshal_container_param(
p: ¶ms::Container,
ctx: &mut MarshalContext,
) -> message::Result<()> {
match p {
params::Container::Array(params) => {
params::validate_array(¶ms.values, ¶ms.element_sig)?;
marshal_array(¶ms.values, ¶ms.element_sig, ctx)?;
}
params::Container::ArrayRef(params) => {
params::validate_array(¶ms.values, ¶ms.element_sig)?;
marshal_array(¶ms.values, ¶ms.element_sig, ctx)?;
}
params::Container::Struct(params) => {
marshal_struct(params, ctx)?;
}
params::Container::StructRef(params) => {
marshal_struct(params, ctx)?;
}
params::Container::Dict(params) => {
params::validate_dict(¶ms.map, params.key_sig, ¶ms.value_sig)?;
marshal_dict(¶ms.map, ctx)?;
}
params::Container::DictRef(params) => {
params::validate_dict(¶ms.map, params.key_sig, ¶ms.value_sig)?;
marshal_dict(params.map, ctx)?;
}
params::Container::Variant(variant) => {
marshal_variant(variant, ctx)?;
}
}
Ok(())
}