From 6f0e60d05c3b1361400efba9f529f1afa0619748 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sat, 2 Apr 2022 23:52:07 +0900 Subject: [PATCH 1/5] Add new tags --- src/codec.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index fd17c26..b29d0b6 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -62,11 +62,13 @@ const BIT_BINARY_EXT: u8 = 77; const COMPRESSED_TERM: u8 = 80; const ATOM_CACHE_REF: u8 = 82; const NEW_PID_EXT: u8 = 88; +const NEW_PORT_EXT: u8 = 89; +const NEWER_REFERENCE_EXT: u8 = 90; const SMALL_INTEGER_EXT: u8 = 97; const INTEGER_EXT: u8 = 98; const FLOAT_EXT: u8 = 99; -const ATOM_EXT: u8 = 100; -const REFERENCE_EXT: u8 = 101; +const ATOM_EXT: u8 = 100; // deprecated +const REFERENCE_EXT: u8 = 101; // deprecated const PORT_EXT: u8 = 102; const PID_EXT: u8 = 103; const SMALL_TUPLE_EXT: u8 = 104; @@ -80,11 +82,12 @@ const LARGE_BIG_EXT: u8 = 111; const NEW_FUN_EXT: u8 = 112; const EXPORT_EXT: u8 = 113; const NEW_REFERENCE_EXT: u8 = 114; -const SMALL_ATOM_EXT: u8 = 115; +const SMALL_ATOM_EXT: u8 = 115; // deprecated const MAP_EXT: u8 = 116; const FUN_EXT: u8 = 117; const ATOM_UTF8_EXT: u8 = 118; const SMALL_ATOM_UTF8_EXT: u8 = 119; +const V4_PORT_EXT: u8 = 120; pub struct Decoder { reader: R, From 14bc3eb095456a03728aa6336e5e7db3f3a49bfe Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 3 Apr 2022 08:49:13 +0900 Subject: [PATCH 2/5] Add `NEWER_REFERENCE_EXT` support --- src/codec.rs | 19 +++++++++++++++---- src/lib.rs | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index b29d0b6..a85a0f4 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -145,6 +145,7 @@ impl Decoder { FUN_EXT => self.decode_fun_ext(), ATOM_UTF8_EXT => self.decode_atom_utf8_ext(), SMALL_ATOM_UTF8_EXT => self.decode_small_atom_utf8_ext(), + NEWER_REFERENCE_EXT => self.decode_newer_reference_ext(), _ => Err(DecodeError::UnknownTag { tag }), } } @@ -260,13 +261,23 @@ impl Decoder { Ok(Term::from(Reference { node, id: vec![self.reader.read_u32::()?], - creation: self.reader.read_u8()?, + creation: u32::from(self.reader.read_u8()?), })) } fn decode_new_reference_ext(&mut self) -> DecodeResult { let id_count = self.reader.read_u16::()? as usize; let node = self.decode_term().and_then(aux::term_into_atom)?; - let creation = self.reader.read_u8()?; + let creation = u32::from(self.reader.read_u8()?); + let mut id = Vec::with_capacity(id_count); + for _ in 0..id_count { + id.push(self.reader.read_u32::()?); + } + Ok(Term::from(Reference { node, id, creation })) + } + fn decode_newer_reference_ext(&mut self) -> DecodeResult { + let id_count = self.reader.read_u16::()? as usize; + let node = self.decode_term().and_then(aux::term_into_atom)?; + let creation = self.reader.read_u32::()?; let mut id = Vec::with_capacity(id_count); for _ in 0..id_count { id.push(self.reader.read_u32::()?); @@ -571,13 +582,13 @@ impl Encoder { Ok(()) } fn encode_reference(&mut self, x: &Reference) -> EncodeResult { - self.writer.write_u8(NEW_REFERENCE_EXT)?; + self.writer.write_u8(NEWER_REFERENCE_EXT)?; if x.id.len() > std::u16::MAX as usize { return Err(EncodeError::TooLargeReferenceId(x.clone())); } self.writer.write_u16::(x.id.len() as u16)?; self.encode_atom(&x.node)?; - self.writer.write_u8(x.creation)?; + self.writer.write_u32::(x.creation)?; for n in &x.id { self.writer.write_u32::(*n)?; } diff --git a/src/lib.rs b/src/lib.rs index 934cd8a..2a61945 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -449,7 +449,7 @@ impl<'a> From<(&'a str, u32)> for Port { pub struct Reference { pub node: Atom, pub id: Vec, - pub creation: u8, + pub creation: u32, } impl fmt::Display for Reference { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 8be6d4c7df5b2b0b1dbd8c0b91b1339c37ab2c77 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 3 Apr 2022 08:50:55 +0900 Subject: [PATCH 3/5] Add `NEW_PORT_EXT` support --- src/codec.rs | 20 +++++++++++++++++--- src/lib.rs | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index a85a0f4..f7ffb79 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -127,6 +127,7 @@ impl Decoder { ATOM_EXT => self.decode_atom_ext(), REFERENCE_EXT => self.decode_reference_ext(), PORT_EXT => self.decode_port_ext(), + NEW_PORT_EXT => self.decode_new_port_ext(), PID_EXT => self.decode_pid_ext(), NEW_PID_EXT => self.decode_new_pid_ext(), SMALL_TUPLE_EXT => self.decode_small_tuple_ext(), @@ -253,7 +254,20 @@ impl Decoder { Ok(Term::from(Port { node, id: self.reader.read_u32::()?, - creation: self.reader.read_u8()?, + creation: u32::from(self.reader.read_u8()?), + })) + } + fn decode_new_port_ext(&mut self) -> DecodeResult { + let node: Atom = self.decode_term().and_then(|t| { + t.try_into().map_err(|t| DecodeError::UnexpectedType { + value: t, + expected: "Atom".to_string(), + }) + })?; + Ok(Term::from(Port { + node, + id: self.reader.read_u32::()?, + creation: self.reader.read_u32::()?, })) } fn decode_reference_ext(&mut self) -> DecodeResult { @@ -575,10 +589,10 @@ impl Encoder { Ok(()) } fn encode_port(&mut self, x: &Port) -> EncodeResult { - self.writer.write_u8(PORT_EXT)?; + self.writer.write_u8(NEW_PORT_EXT)?; self.encode_atom(&x.node)?; self.writer.write_u32::(x.id)?; - self.writer.write_u8(x.creation)?; + self.writer.write_u32::(x.creation)?; Ok(()) } fn encode_reference(&mut self, x: &Reference) -> EncodeResult { diff --git a/src/lib.rs b/src/lib.rs index 2a61945..82f96ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -427,7 +427,7 @@ impl<'a> From<(&'a str, u32, u32)> for Pid { pub struct Port { pub node: Atom, pub id: u32, - pub creation: u8, + pub creation: u32, } impl fmt::Display for Port { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From bb48bdc5bbc9623e7f0f4b4133f2280cb7234115 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 3 Apr 2022 08:56:16 +0900 Subject: [PATCH 4/5] Add `V4_PORT_EXT` support --- src/codec.rs | 33 +++++++++++++++++++++++++++------ src/lib.rs | 4 ++-- tests/lib.rs | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index f7ffb79..1d460fb 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -128,6 +128,7 @@ impl Decoder { REFERENCE_EXT => self.decode_reference_ext(), PORT_EXT => self.decode_port_ext(), NEW_PORT_EXT => self.decode_new_port_ext(), + V4_PORT_EXT => self.decode_v4_port_ext(), PID_EXT => self.decode_pid_ext(), NEW_PID_EXT => self.decode_new_pid_ext(), SMALL_TUPLE_EXT => self.decode_small_tuple_ext(), @@ -253,7 +254,7 @@ impl Decoder { })?; Ok(Term::from(Port { node, - id: self.reader.read_u32::()?, + id: u64::from(self.reader.read_u32::()?), creation: u32::from(self.reader.read_u8()?), })) } @@ -266,7 +267,20 @@ impl Decoder { })?; Ok(Term::from(Port { node, - id: self.reader.read_u32::()?, + id: u64::from(self.reader.read_u32::()?), + creation: self.reader.read_u32::()?, + })) + } + fn decode_v4_port_ext(&mut self) -> DecodeResult { + let node: Atom = self.decode_term().and_then(|t| { + t.try_into().map_err(|t| DecodeError::UnexpectedType { + value: t, + expected: "Atom".to_string(), + }) + })?; + Ok(Term::from(Port { + node, + id: self.reader.read_u64::()?, creation: self.reader.read_u32::()?, })) } @@ -589,10 +603,17 @@ impl Encoder { Ok(()) } fn encode_port(&mut self, x: &Port) -> EncodeResult { - self.writer.write_u8(NEW_PORT_EXT)?; - self.encode_atom(&x.node)?; - self.writer.write_u32::(x.id)?; - self.writer.write_u32::(x.creation)?; + if (x.id >> 32) & 0xFFFFFFFF == 0 { + self.writer.write_u8(NEW_PORT_EXT)?; + self.encode_atom(&x.node)?; + self.writer.write_u32::(x.id as u32)?; + self.writer.write_u32::(x.creation)?; + } else { + self.writer.write_u8(V4_PORT_EXT)?; + self.encode_atom(&x.node)?; + self.writer.write_u64::(x.id)?; + self.writer.write_u32::(x.creation)?; + } Ok(()) } fn encode_reference(&mut self, x: &Reference) -> EncodeResult { diff --git a/src/lib.rs b/src/lib.rs index 82f96ff..422676e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -426,7 +426,7 @@ impl<'a> From<(&'a str, u32, u32)> for Pid { #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub struct Port { pub node: Atom, - pub id: u32, + pub id: u64, pub creation: u32, } impl fmt::Display for Port { @@ -438,7 +438,7 @@ impl<'a> From<(&'a str, u32)> for Port { fn from((node, id): (&'a str, u32)) -> Self { Port { node: Atom::from(node), - id, + id: u64::from(id), creation: 0, } } diff --git a/tests/lib.rs b/tests/lib.rs index 3288baf..dec55fa 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -233,7 +233,7 @@ fn reference_test() { // Encode assert_eq!( - vec![131, 114, 0, 1, 100, 0, 3, 102, 111, 111, 0, 0, 0, 0, 123], + vec![131, 90, 0, 1, 100, 0, 3, 102, 111, 111, 0, 0, 0, 0, 0, 0, 0, 123], encode(Term::from(Reference::from(("foo", 123)))) ); } From dc25f68f7a3c6c3c23cd2b24dc3c6a09becf437f Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 3 Apr 2022 08:58:56 +0900 Subject: [PATCH 5/5] Update tests --- tests/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lib.rs b/tests/lib.rs index dec55fa..f2ee51d 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -201,8 +201,8 @@ fn port_test() { // Encode assert_eq!( vec![ - 131, 102, 100, 0, 13, 110, 111, 110, 111, 100, 101, 64, 110, 111, 104, 111, 115, 116, - 0, 0, 1, 110, 0 + 131, 89, 100, 0, 13, 110, 111, 110, 111, 100, 101, 64, 110, 111, 104, 111, 115, 116, 0, + 0, 1, 110, 0, 0, 0, 0 ], encode(Term::from(Port::from(("nonode@nohost", 366)))) );