diff options
author | Omer Katz <omer.drow@gmail.com> | 2019-02-26 20:03:48 +0200 |
---|---|---|
committer | Omer Katz <omer.drow@gmail.com> | 2019-03-03 23:51:12 +0200 |
commit | ac2a6a61cc02778b03c96396a6f7b7e3fac1a0fd (patch) | |
tree | 2056be1293058bd7551df40359b2cc55077a63c6 | |
parent | dfc336d2db69f0e4e8aeda00650c1c5e23b9f93c (diff) | |
download | py-amqp-ac2a6a61cc02778b03c96396a6f7b7e3fac1a0fd.tar.gz |
An incomplete implementation of loads() in rust.
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | Cargo.lock | 257 | ||||
-rw-r--r-- | Cargo.toml | 12 | ||||
-rw-r--r-- | amqp/serialization.py | 11 | ||||
-rw-r--r-- | src/lib.rs | 118 |
5 files changed, 404 insertions, 1 deletions
@@ -25,3 +25,10 @@ Documentation/ .pytest_cache/ coverage.xml htmlcov/ + +# Generated by Cargo +# will have compiled files and executables +/target/ + +# These are backup files generated by rustfmt +**/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8368ba7 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,257 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "amqp-serialization" +version = "0.1.0" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pyo3 0.6.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byteorder" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ctor" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ghost" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "inventory" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ctor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ghost 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "inventory-impl 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "inventory-impl" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.49" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "mashup" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mashup-impl" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro-hack" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pyo3" +version = "0.6.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "inventory 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pyo3cls 0.6.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pyo3-derive-backend" +version = "0.6.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pyo3cls" +version = "0.6.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "pyo3-derive-backend 0.6.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "spin" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "0.15.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" +"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum ctor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9a43db2bba5cafdc6aa068c892a518e477ee0df3705e53ec70247a9ff93546d5" +"checksum ghost 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5297b71943dc9fea26a3241b178c140ee215798b7f79f7773fd61683e25bca74" +"checksum inventory 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21df85981fe094480bc2267723d3dc0fd1ae0d1f136affc659b7398be615d922" +"checksum inventory-impl 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a877ae8bce77402d5e9ed870730939e097aad827b2a932b361958fa9d6e75aa" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e" +"checksum mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2d82b34c7fb11bb41719465c060589e291d505ca4735ea30016a91f6fc79c3b" +"checksum mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "aa607bfb674b4efb310512527d64266b065de3f894fc52f84efcbf7eaa5965fb" +"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" +"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" +"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" +"checksum pyo3 0.6.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "00d5a665157dd1b4b2a6cf851f29fad4e78b6525c028edeebb036368136dabb3" +"checksum pyo3-derive-backend 0.6.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "de5efe5e5c51c44eab434a517f9258c5e67ad8bd95f6cc9e92b71b80d5003349" +"checksum pyo3cls 0.6.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "152892bb1ada7e21a5c37d6bbd345067222e777513e417c883e80775e1473d39" +"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" +"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" +"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b1ac6af --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "amqp-serialization" +version = "0.1.0" +authors = ["Omer Katz <omer.drow@gmail.com>"] + +[lib] +name = "amqp_serialization" +crate-type = ["cdylib"] + +[dependencies] +pyo3 = { version = "0.6.0-alpha.4", features = ["extension-module"] } +byteorder = "1.3.1" diff --git a/amqp/serialization.py b/amqp/serialization.py index 758a3c0..6992716 100644 --- a/amqp/serialization.py +++ b/amqp/serialization.py @@ -161,11 +161,20 @@ def loads(format, buf, offset=0, array = A timestamp = T """ + format = pstr_t(format) + + try: + import amqp_serialization + except ImportError: + pass + else: + buf = str_to_bytes(buf) + return amqp_serialization.loads(format, buf, offset) + bitcount = bits = 0 values = [] append = values.append - format = pstr_t(format) for p in format: if p == 'b': diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..25ad696 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,118 @@ +extern crate byteorder; +extern crate pyo3; + +use byteorder::{BigEndian, ReadBytesExt}; +use pyo3::prelude::*; +use pyo3::types::*; +use pyo3::wrap_pyfunction; +use pyo3::{IntoPy, Py}; + +#[pyfunction] +fn loads(py: Python, format: String, buf: &PyBytes, offset: usize) -> PyResult<Py<PyTuple>> { + let mut bitcount = 0; + let mut bits = 0; + let mut current_offset = offset; + let values = PyList::empty(py); + let buf = buf.as_bytes(); + + for p in format.chars() { + match p { + 'b' => { + if bitcount == 0 { + bits = buf.get(current_offset..current_offset + 1).unwrap()[0]; + } + + bitcount = 8; + values.append((bits & 1) == 1)?; + bits >>= 1; + bitcount -= 1; + current_offset += 1; + } + 'o' => { + bitcount = 0; + bits = 0; + values.append((&buf[current_offset..]).read_u8().unwrap())?; + current_offset += 1; + } + 'B' => { + bitcount = 0; + bits = 0; + values.append((&buf[current_offset..]).read_u16::<BigEndian>().unwrap())?; + current_offset += 2; + } + 'l' => { + bitcount = 0; + bits = 0; + values.append((&buf[current_offset..]).read_u32::<BigEndian>().unwrap())?; + current_offset += 4; + } + 'L' => { + bitcount = 0; + bits = 0; + values.append((&buf[current_offset..]).read_u64::<BigEndian>().unwrap())?; + current_offset += 8; + } + 'f' => { + bitcount = 0; + bits = 0; + values.append((&buf[current_offset..]).read_f32::<BigEndian>().unwrap())?; + current_offset += 4; + } + 's' => { + // TODO: Handle Unicode + bitcount = 0; + bits = 0; + let slen = (&buf[current_offset..]).read_u8().unwrap() as usize; + current_offset += 1; + if current_offset + slen > buf.len() { + values.append(std::str::from_utf8(&buf[current_offset..]).unwrap())?; + } else { + values.append( + std::str::from_utf8(&buf[current_offset..current_offset + slen]).unwrap(), + )?; + } + current_offset += slen; + } + 'S' => { + // TODO: Handle Unicode + bitcount = 0; + bits = 0; + let slen = (&buf[current_offset..]).read_u32::<BigEndian>().unwrap() as usize; + current_offset += 4; + if current_offset + slen > buf.len() { + values.append(std::str::from_utf8(&buf[current_offset..]).unwrap())?; + } else { + values.append( + std::str::from_utf8(&buf[current_offset..current_offset + slen]).unwrap(), + )?; + } + current_offset += slen; + } + 'x' => { + let blen = (&buf[current_offset..]).read_u32::<BigEndian>().unwrap() as usize; + current_offset += 4; + if current_offset + blen > buf.len() { + values.append(&buf[current_offset..])?; + } else { + values.append(&buf[current_offset..current_offset + blen])?; + } + current_offset += blen; + } + // TODO: Handle complex objects + _ => { + // TODO: Once the exception type moves to rust, rewrite this + // Or find out how to use the import_exception! macro + let pycode = &format!("from amqp.exceptions import FrameSyntaxError;raise FrameSyntaxError('Table type {} not handled by amqp.')", p); + py.run(pycode, None, None)?; + } + } + } + Ok((values, current_offset).into_py(py)) +} + +#[pymodule] +fn amqp_serialization(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_wrapped(wrap_pyfunction!(loads))?; + + Ok(()) +} |