Skip to content

Atom soundness and usability fixes #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 53 commits into from
Nov 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
f2d048d
wip
prokopyl Aug 6, 2021
def17b7
Even more wip
prokopyl Aug 7, 2021
555b0cd
Even more wip again
prokopyl Aug 7, 2021
9be9190
Fix things, break even more
prokopyl Aug 8, 2021
465b42e
Fix more things
prokopyl Aug 8, 2021
a9fdce1
Fixed almost everything
prokopyl Aug 8, 2021
46700ab
Add VecSpace
prokopyl Aug 8, 2021
e6c1d2f
Fix almost everything
prokopyl Aug 8, 2021
9aa2e59
It builds!
prokopyl Aug 17, 2021
e586f7e
Some refactorings
prokopyl Aug 17, 2021
d3ff4c2
Some more refactorings
prokopyl Aug 18, 2021
f3cfba6
Wip fix
prokopyl Aug 18, 2021
fe681ce
Some fixes
prokopyl Aug 19, 2021
52b5e9d
Fix all tests
prokopyl Sep 4, 2021
9685125
Move atoms to separate atoms subdir
prokopyl Sep 4, 2021
322d981
Fix build
prokopyl Sep 4, 2021
7b337e6
Move extensions to allocator to own trait
prokopyl Sep 5, 2021
e6872e9
Remove "boxed" space helper
prokopyl Sep 5, 2021
bcf823e
Introduce SpaceReader to cleanup clunky methods on Space struct
prokopyl Sep 6, 2021
861309c
Various fixes and improvements
prokopyl Sep 7, 2021
d9d0aa5
Remove type param on space reader
prokopyl Sep 7, 2021
b18fd1d
Remove default type param on Space type
prokopyl Sep 7, 2021
0808a05
Add lots of docs
prokopyl Sep 8, 2021
86b4368
Some more tests and fixes
prokopyl Sep 8, 2021
a877cf0
WIP
prokopyl Sep 9, 2021
0164748
WIP: replace lifetimes in Atom trait with GAT workaround
prokopyl Sep 9, 2021
655c6a8
More WIP
prokopyl Sep 10, 2021
393adb6
More WIP 2
prokopyl Sep 10, 2021
f5034ec
Fixed everything
prokopyl Sep 11, 2021
acfc0d5
Remove unnecessary Atom::read lifetimes
prokopyl Sep 11, 2021
cfe1b8b
Remove more unnecessary lifetimes
prokopyl Sep 11, 2021
e97652d
Replace Option with Result in many atom read/write operation
prokopyl Sep 12, 2021
5d326b8
Doc & test fixes
prokopyl Sep 12, 2021
2f93848
Change Sequence to hold its unit in a generic type rather than having…
prokopyl Sep 12, 2021
54b4a6f
Split Atom error type
prokopyl Sep 21, 2021
2e862a4
Properly split alignment errors
prokopyl Sep 23, 2021
7e876fe
Some more docs and some fewer errors
prokopyl Sep 23, 2021
39f2e04
Remove some unneeded methods
prokopyl Sep 25, 2021
165d609
Remove some more unneeded methods, add some docs and rename SpaceAllo…
prokopyl Sep 25, 2021
62c92f1
Various module refactorings
prokopyl Sep 25, 2021
7f9a985
Remove unsafe copy/clone impl on UnidentifiedAtom
prokopyl Sep 26, 2021
57ed9d4
Add some more docs
prokopyl Sep 26, 2021
ea33828
Write more docs
prokopyl Sep 27, 2021
44033c9
Rename AtomSpaceWriter to AtomWriter, and add more docs
prokopyl Sep 29, 2021
f421ff5
Implemented proper error messages for AtomError
prokopyl Sep 29, 2021
d72c4ea
Some clippy fixes
prokopyl Sep 29, 2021
e5224d5
Fix tests, add more docs
prokopyl Oct 1, 2021
886f1bd
Finished all clippy-required docs!
prokopyl Oct 1, 2021
23f761a
Rename VecSpace to AlignedVec, docs fixes and cleanup, better depende…
prokopyl Nov 27, 2021
8b2a458
Fix clippy doc
prokopyl Nov 27, 2021
f13768c
Add AlignedVec into_vec and from_vec
prokopyl Nov 28, 2021
c590de8
More docs! (and other fixes)
prokopyl Nov 28, 2021
8eb5f65
Fix some missing docs.
prokopyl Nov 28, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion atom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ maintenance = { status = "passively-maintained" }
[dependencies]
lv2-sys = "2.0.0"
lv2-units = "0.1.3"
urid = "0.1.0"
urid = { version = "0.1.0", default-features = false }

[dependencies.lv2-core]
version = "3.0.0"
optional = true
default-features = false

[dev-dependencies]
lv2-urid = "2.1.0"
Expand Down
51 changes: 51 additions & 0 deletions atom/src/atoms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
pub mod chunk;
pub mod object;
pub mod scalar;
pub mod sequence;
pub mod string;
pub mod tuple;
pub mod vector;

use urid::*;

/// An URID collection of all standard atom types, provided for convenience.
#[derive(Clone)]
pub struct AtomURIDCollection {
pub blank: URID<object::Blank>,
pub double: URID<scalar::Double>,
pub float: URID<scalar::Float>,
pub int: URID<scalar::Int>,
pub long: URID<scalar::Long>,
pub urid: URID<scalar::AtomURID>,
pub bool: URID<scalar::Bool>,
pub vector: URID<vector::Vector>,
pub chunk: URID<chunk::Chunk>,
pub literal: URID<string::Literal>,
pub object: URID<object::Object>,
pub property: URID<object::Property>,
pub string: URID<string::String>,
pub tuple: URID<tuple::Tuple>,
pub sequence: URID<sequence::Sequence>,
}

impl URIDCollection for AtomURIDCollection {
fn from_map<M: Map + ?Sized>(map: &M) -> Option<Self> {
Some(Self {
blank: map.map_type()?,
double: map.map_type()?,
float: map.map_type()?,
int: map.map_type()?,
long: map.map_type()?,
urid: map.map_type()?,
bool: map.map_type()?,
vector: map.map_type()?,
chunk: map.map_type()?,
literal: map.map_type()?,
object: map.map_type()?,
property: map.map_type()?,
string: map.map_type()?,
tuple: map.map_type()?,
sequence: map.map_type()?,
})
}
}
125 changes: 125 additions & 0 deletions atom/src/atoms/chunk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//! An atom containing memory of undefined type.
//!
//! This contents of this atom is considered as a simple blob of data. It used, for example, by the host to transmit the size of a writable atom port. Since it is so simple, it does not need a reading or writing parameter.
//!
//! # Example
//! ```
//! use lv2_core::prelude::*;
//! use lv2_atom::prelude::*;
//!
//! use lv2_atom::space::{AtomSpace, AtomWriter, SpaceWriter};
//!
//! #[derive(PortCollection)]
//! struct MyPorts {
//! input: InputPort<AtomPort>,
//! output: OutputPort<AtomPort>,
//! }
//!
//! fn run(ports: &mut MyPorts, urids: &AtomURIDCollection) {
//! let in_chunk: &AtomSpace = ports.input.read(urids.chunk).unwrap();
//! let mut out_chunk: AtomWriter = ports.output.write(urids.chunk).unwrap();
//!
//! let bytes = in_chunk.as_bytes();
//! out_chunk.write_bytes(bytes).unwrap();
//! }
//! ```
//!
//! # Specification
//!
//! [http://lv2plug.in/ns/ext/atom/atom.html#Chunk](http://lv2plug.in/ns/ext/atom/atom.html#Chunk)
use crate::space::error::{AtomReadError, AtomWriteError};
use crate::space::*;
use crate::AtomWriter;
use crate::{Atom, AtomHandle};
use urid::UriBound;

/// An atom containing an arbitrary byte buffer.
///
/// [See also the module documentation.](index.html)
pub struct Chunk;

unsafe impl UriBound for Chunk {
const URI: &'static [u8] = sys::LV2_ATOM__Chunk;
}

pub struct ChunkReaderHandle;
impl<'a> AtomHandle<'a> for ChunkReaderHandle {
type Handle = &'a AtomSpace;
}

pub struct ChunkWriterHandle;
impl<'a> AtomHandle<'a> for ChunkWriterHandle {
type Handle = AtomWriter<'a>;
}

impl Atom for Chunk {
type ReadHandle = ChunkReaderHandle;
type WriteHandle = ChunkWriterHandle;

#[inline]
unsafe fn read(
body: &AtomSpace,
) -> Result<<Self::ReadHandle as AtomHandle>::Handle, AtomReadError> {
Ok(body)
}

#[inline]
fn write(
frame: AtomWriter,
) -> Result<<Self::WriteHandle as AtomHandle>::Handle, AtomWriteError> {
Ok(frame)
}
}

#[cfg(test)]
mod tests {
use crate::atoms::chunk::*;
use crate::*;

#[test]
fn test_chunk_and_slice_writer() {
const SLICE_LENGTH: usize = 42;

let map = HashURIDMapper::new();
let urids = crate::atoms::AtomURIDCollection::from_map(&map).unwrap();

let mut raw_space = AlignedVec::<AtomHeader>::new_with_capacity(64);
let raw_space = raw_space.as_space_mut();

// writing
{
let mut space = SpaceCursor::new(raw_space.as_bytes_mut());
let mut writer = space.write_atom(urids.chunk).unwrap();
let data = writer.allocate(SLICE_LENGTH).unwrap();

for (i, value) in data.iter_mut().enumerate() {
*value = i as u8;
}

space.write_value(41u8).unwrap();
}

// verifying
{
let atom = unsafe { raw_space.read().next_atom() }.unwrap();
assert_eq!(atom.header().size_of_body(), SLICE_LENGTH);
assert_eq!(atom.header().urid(), urids.chunk.get());

let data = atom.body().as_bytes();
for (i, value) in data.iter().enumerate() {
assert_eq!(*value as usize, i);
}
}

// reading
{
let data =
unsafe { Chunk::read(raw_space.read().next_atom().unwrap().body()) }.unwrap();
assert_eq!(data.bytes_len(), SLICE_LENGTH);

for (i, value) in data.as_bytes().iter().enumerate() {
assert_eq!(*value as usize, i);
}
}
}
}
Loading