Skip to content

Commit 6518c5e

Browse files
committed
Pack coils directly into buffer
1 parent d9e60b4 commit 6518c5e

File tree

1 file changed

+31
-32
lines changed

1 file changed

+31
-32
lines changed

src/codec/mod.rs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,9 @@ fn encode_request_pdu(buf: &mut BytesMut, request: &Request<'_>) {
5656
}
5757
WriteMultipleCoils(address, coils) => {
5858
buf.put_u16(*address);
59-
let len = coils.len();
60-
buf.put_u16(u16_len(len));
61-
let packed_coils = pack_coils(coils);
62-
buf.put_u8(u8_len(packed_coils.len()));
63-
buf.put_slice(&packed_coils);
59+
buf.put_u16(u16_len(coils.len()));
60+
buf.put_u8(u8_len(packed_coils_len(coils.len())));
61+
pack_coils(buf, coils);
6462
}
6563
WriteSingleRegister(address, word) => {
6664
buf.put_u16(*address);
@@ -106,11 +104,8 @@ impl From<Response> for Bytes {
106104
data.put_u8(rsp.function_code().value());
107105
match rsp {
108106
ReadCoils(coils) | ReadDiscreteInputs(coils) => {
109-
let packed_coils = pack_coils(&coils);
110-
data.put_u8(u8_len(packed_coils.len()));
111-
for b in packed_coils {
112-
data.put_u8(b);
113-
}
107+
data.put_u8(u8_len(packed_coils_len(coils.len())));
108+
pack_coils(&mut data, &coils);
114109
}
115110
ReadInputRegisters(registers)
116111
| ReadHoldingRegisters(registers)
@@ -132,9 +127,7 @@ impl From<Response> for Bytes {
132127
data.put_u8(2 + u8_len(additional_data.len()));
133128
data.put_u8(server_id);
134129
data.put_u8(if run_indication { 0xFF } else { 0x00 });
135-
for b in additional_data {
136-
data.put_u8(b);
137-
}
130+
data.put_slice(&additional_data);
138131
}
139132
WriteSingleRegister(address, word) => {
140133
data.put_u16(address);
@@ -146,9 +139,7 @@ impl From<Response> for Bytes {
146139
data.put_u16(or_mask);
147140
}
148141
Custom(_, custom_data) => {
149-
for d in custom_data {
150-
data.put_u8(d);
151-
}
142+
data.put_slice(&custom_data);
152143
}
153144
}
154145
data.freeze()
@@ -408,14 +399,16 @@ fn packed_coils_len(bitcount: usize) -> usize {
408399
(bitcount + 7) / 8
409400
}
410401

411-
fn pack_coils(coils: &[Coil]) -> Vec<u8> {
412-
let packed_size = packed_coils_len(coils.len());
413-
let mut res = vec![0; packed_size];
402+
fn pack_coils(buf: &mut BytesMut, coils: &[Coil]) -> usize {
403+
let packed_coils_len = packed_coils_len(coils.len());
404+
let offset = buf.len();
405+
buf.resize(offset + packed_coils_len, 0);
406+
let buf = &mut buf[offset..];
414407
for (i, b) in coils.iter().enumerate() {
415408
let v = u8::from(*b); // 0 or 1
416-
res[i / 8] |= v << (i % 8);
409+
buf[i / 8] |= v << (i % 8);
417410
}
418-
res
411+
packed_coils_len
419412
}
420413

421414
fn unpack_coils(bytes: &[u8], count: u16) -> Vec<Coil> {
@@ -471,7 +464,13 @@ mod tests {
471464

472465
fn request_to_pdu_bytes(request: &Request<'_>) -> Bytes {
473466
let mut buf = BytesMut::new();
474-
super::encode_request_pdu(&mut buf, request);
467+
encode_request_pdu(&mut buf, request);
468+
buf.freeze()
469+
}
470+
471+
fn pack_coils_to_bytes(coils: &[bool]) -> Bytes {
472+
let mut buf = BytesMut::new();
473+
pack_coils(&mut buf, coils);
475474
buf.freeze()
476475
}
477476

@@ -489,16 +488,16 @@ mod tests {
489488

490489
#[test]
491490
fn convert_booleans_to_bytes() {
492-
assert_eq!(pack_coils(&[]), &[]);
493-
assert_eq!(pack_coils(&[true]), &[0b1]);
494-
assert_eq!(pack_coils(&[false]), &[0b0]);
495-
assert_eq!(pack_coils(&[true, false]), &[0b_01]);
496-
assert_eq!(pack_coils(&[false, true]), &[0b_10]);
497-
assert_eq!(pack_coils(&[true, true]), &[0b_11]);
498-
assert_eq!(pack_coils(&[true; 8]), &[0b_1111_1111]);
499-
assert_eq!(pack_coils(&[true; 9]), &[255, 1]);
500-
assert_eq!(pack_coils(&[false; 8]), &[0]);
501-
assert_eq!(pack_coils(&[false; 9]), &[0, 0]);
491+
assert_eq!(&pack_coils_to_bytes(&[])[..], &[]);
492+
assert_eq!(&pack_coils_to_bytes(&[true])[..], &[0b1]);
493+
assert_eq!(&pack_coils_to_bytes(&[false])[..], &[0b0]);
494+
assert_eq!(&pack_coils_to_bytes(&[true, false])[..], &[0b_01]);
495+
assert_eq!(&pack_coils_to_bytes(&[false, true])[..], &[0b_10]);
496+
assert_eq!(&pack_coils_to_bytes(&[true, true])[..], &[0b_11]);
497+
assert_eq!(&pack_coils_to_bytes(&[true; 8])[..], &[0b_1111_1111]);
498+
assert_eq!(&pack_coils_to_bytes(&[true; 9])[..], &[255, 1]);
499+
assert_eq!(&pack_coils_to_bytes(&[false; 8])[..], &[0]);
500+
assert_eq!(&pack_coils_to_bytes(&[false; 9])[..], &[0, 0]);
502501
}
503502

504503
#[test]

0 commit comments

Comments
 (0)