1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//! ASCII string. //! //! This module contains the [`AtomString`](type.AtomString.html), an atom representing standard //! ASCII strings. //! //! Atom strings can only be written once: The `write_atom_body` call expects a CStr from which it can //! copy the data and after that call, the string can't be modified. //! //! An example: //! //! extern crate lv2rs_atom as atom; //! extern crate lv2rs_urid as urid; //! //! use atom::prelude::*; //! use atom::ports::*; //! use urid::{CachedMap, debug::DebugMap}; //! use std::ffi::CStr; //! //! pub struct Plugin { //! in_port: AtomInputPort<AtomString>, //! out_port: AtomOutputPort<AtomString>, //! urids: CachedMap, //! } //! //! impl Plugin { //! /// Simulated `run` method. //! fn run(&mut self) { //! let message: &str = "Hello World!\0"; //! let c_message = CStr::from_bytes_with_nul(message.as_bytes()).unwrap(); //! //! // Writing. //! unsafe { self.out_port.write_atom_body(c_message, &mut self.urids).unwrap() }; //! //! // Reading. //! let string = unsafe { self.in_port.get_atom_body(&mut self.urids) }.unwrap(); //! let str = string.as_cstr().unwrap().to_str().unwrap(); //! assert_eq!("Hello World!", str); //! } //! } //! //! // Getting a debug URID map. //! let mut debug_map = DebugMap::new(); //! let mut urids = unsafe {debug_map.create_cached_map()}; //! //! // Creating the plugin. //! let mut plugin = Plugin { //! in_port: AtomInputPort::new(), //! out_port: AtomOutputPort::new(), //! urids: urids, //! }; //! //! // Creating the atom space. //! let mut atom_space = vec![0u8; 256]; //! let atom = unsafe { (atom_space.as_mut_ptr() as *mut Atom).as_mut() }.unwrap(); //! *(atom.mut_size()) = 256 - 8; //! //! // Connecting the ports. //! plugin.in_port.connect_port(atom as &Atom); //! plugin.out_port.connect_port(atom); //! //! // Calling `run`. //! plugin.run(); use crate::atom::{array::*, *}; use crate::frame::{WritingFrame, WritingFrameExt}; use crate::uris; use std::ffi::CStr; /// ASCII String. /// /// See the [module documentation](index.html) for more information. pub type AtomString = ArrayAtomBody<(), i8>; impl AtomBody for AtomString { type InitializationParameter = CStr; fn get_uri() -> &'static CStr { unsafe { CStr::from_bytes_with_nul_unchecked(uris::STRING_TYPE_URI) } } unsafe fn initialize_body<'a, W>( writer: &mut W, string: &CStr, urids: &mut urid::CachedMap, ) -> Result<(), ()> where W: WritingFrame<'a> + WritingFrameExt<'a, Self>, { Self::__initialize_body(writer, &(), urids)?; writer.write_raw(string.to_bytes())?; // Write the null terminator since `string.to_bytes()` will never contain one. writer.write_sized(&0u8)?; Ok(()) } fn create_ref<'a>(raw_data: &'a [u8]) -> Result<&'a Self, ()> { Self::__create_ref(raw_data) } } impl AtomString { /// Try to wrap the string into a `CStr` reference. /// /// This function returns an error if the internal conversion fails. pub fn as_cstr(&self) -> Result<&CStr, std::ffi::FromBytesWithNulError> { CStr::from_bytes_with_nul(unsafe { std::mem::transmute::<&[i8], &[u8]>(&self.data) }) } }