amqpr_codec/frame/content_header/
encoder.rs1use bytes::{BigEndian, BufMut};
2
3use super::{ContentHeaderPayload, Properties};
4use args::{AmqpString, FieldArgument};
5
6use std::collections::HashMap;
7
8const MIN_PAYLOAD_SIZE: usize = 14;
9
10pub fn encode_payload(payload: ContentHeaderPayload) -> Vec<u8> {
11 debug!("Start encoging conent header");
12
13 let mut dst = Vec::with_capacity(MIN_PAYLOAD_SIZE);
14
15 dst.put_u16::<BigEndian>(payload.class_id);
16 debug!("class : {}", payload.class_id);
17
18 dst.put_u16::<BigEndian>(0);
20
21 dst.put_u64::<BigEndian>(payload.body_size);
22 debug!("body size : {}", payload.body_size);
23
24 let property_flags = property_flags(&payload.properties);
26 dst.put_u16::<BigEndian>(property_flags);
27 debug!("property flags : {}", property_flags);
28
29 if property_flags != 0b_0000_0000_0000_0001 {
31 property_list(&payload.properties, &mut dst);
32 }
33
34 dst
35}
36
37
38fn property_flags(ps: &Properties) -> u16 {
39 0b_____1000000000000000 * ps.content_type.is_some() as u16 +
40 0b_0100000000000000 * ps.content_encoding.is_some() as u16 +
41 0b_0010000000000000 * ps.headers.is_some() as u16 +
42 0b_0001000000000000 * ps.delivery_mode.is_some() as u16 +
43 0b_0000100000000000 * ps.priority.is_some() as u16 +
44 0b_0000010000000000 * ps.correlation_id.is_some() as u16 +
45 0b_0000001000000000 * ps.reply_to.is_some() as u16 +
46 0b_0000000100000000 * ps.expiration.is_some() as u16 +
47 0b_0000000010000000 * ps.message_id.is_some() as u16 +
48 0b_0000000001000000 * ps.timestamp.is_some() as u16 +
49 0b_0000000000100000 * ps.type_.is_some() as u16 +
50 0b_0000000000010000 * ps.user_id.is_some() as u16 +
51 0b_0000000000001000 * ps.app_id.is_some() as u16 +
52
53 0b_0000_0000_0000_0001
55}
56
57
58fn property_list(ps: &Properties, dst: &mut Vec<u8>) {
59 if let Some(ref s) = ps.content_type {
60 encode_short_str(s, dst);
61 }
62
63 if let Some(ref s) = ps.content_encoding {
64 encode_short_str(s, dst);
65 }
66
67 if let Some(ref f) = ps.headers {
68 encode_field_table(f, dst);
69 }
70
71 if let Some(ref o) = ps.delivery_mode {
72 dst.put_u8(*o);
73 }
74
75 if let Some(ref o) = ps.priority {
76 dst.put_u8(*o);
77 }
78
79 if let Some(ref s) = ps.correlation_id {
80 encode_short_str(s, dst);
81 }
82
83 if let Some(ref s) = ps.reply_to {
84 encode_short_str(s, dst);
85 }
86
87 if let Some(ref s) = ps.expiration {
88 encode_short_str(s, dst);
89 }
90
91 if let Some(ref s) = ps.message_id {
92 encode_short_str(s, dst);
93 }
94
95 if let Some(ref t) = ps.timestamp {
96 dst.put_i64::<BigEndian>(*t);
97 }
98
99 if let Some(ref s) = ps.type_ {
100 encode_short_str(s, dst);
101 }
102
103 if let Some(ref s) = ps.user_id {
104 encode_short_str(s, dst);
105 }
106
107 if let Some(ref s) = ps.app_id {
108 encode_short_str(s, dst);
109 }
110}
111
112
113fn encode_short_str(s: &AmqpString, dst: &mut Vec<u8>) {
114 dst.put_u8(s.len() as u8);
115 dst.put(s.as_bytes());
116}
117
118fn encode_field_table(f: &HashMap<AmqpString, FieldArgument>, dst: &mut Vec<u8>) {
119 ::frame::method::encoder::encode_field_table_0(f, dst);
120}