summaryrefslogtreecommitdiff
path: root/src/binary
diff options
context:
space:
mode:
Diffstat (limited to 'src/binary')
-rw-r--r--src/binary/mod.rs2
-rw-r--r--src/binary/reverse_appendix.rs35
2 files changed, 37 insertions, 0 deletions
diff --git a/src/binary/mod.rs b/src/binary/mod.rs
new file mode 100644
index 0000000..66f6c30
--- /dev/null
+++ b/src/binary/mod.rs
@@ -0,0 +1,2 @@
+mod reverse_appendix;
+pub use reverse_appendix::*;
diff --git a/src/binary/reverse_appendix.rs b/src/binary/reverse_appendix.rs
new file mode 100644
index 0000000..d131526
--- /dev/null
+++ b/src/binary/reverse_appendix.rs
@@ -0,0 +1,35 @@
+use crate::{Codec, Error};
+
+/// Reverses payload binary data and writes it ass-first past the end of the original data. A
+/// length marker is also prepended to the payload *before reversing* so the decoder knows how long
+/// the payload is.
+pub struct BinaryReverseAppendixCodec;
+
+impl Codec for BinaryReverseAppendixCodec {
+ fn encode(&self, carrier: &[u8], payload: &[u8]) -> Result<Vec<u8>, crate::Error> {
+ let mut encoded = Vec::<u8>::new();
+ encoded.extend(carrier.iter());
+ let payload_len = (payload.len() as u64 + 8).to_le_bytes();
+ encoded.extend(payload_len.iter().chain(payload.iter()).rev());
+ Ok(encoded)
+ }
+
+ fn decode(&self, encoded: &[u8]) -> Result<(Vec<u8>, Vec<u8>), crate::Error> {
+ if encoded.len() < 8 {
+ return Err(Error::DataNotEncoded);
+ }
+
+ let encoded_len = encoded.len();
+ let payload_len = u64::from_le_bytes(encoded.iter().rev().take(8).cloned().collect::<Vec<_>>().try_into().unwrap()) as usize;
+ if encoded_len < payload_len + 8 || payload_len < 8 {
+ return Err(Error::DataNotEncoded);
+ }
+
+ let carrier_len = encoded_len - payload_len;
+
+ let carrier = encoded[..carrier_len].to_vec();
+ let payload = encoded.iter().rev().skip(8).take(payload_len - 8).cloned().collect::<Vec<_>>();
+
+ Ok((carrier, payload))
+ }
+}