}
}
+/// Writes out a C-callable concrete Vec<A> struct and utility methods
+pub fn write_vec_block<W: std::io::Write>(w: &mut W, mangled_container: &str, inner_type: &str, clonable: bool) {
+ writeln!(w, "#[repr(C)]").unwrap();
+ writeln!(w, "pub struct {} {{", mangled_container).unwrap();
+ writeln!(w, "\tpub data: *mut {},", inner_type).unwrap();
+ writeln!(w, "\tpub datalen: usize").unwrap();
+ writeln!(w, "}}").unwrap();
+
+ writeln!(w, "impl {} {{", mangled_container).unwrap();
+ writeln!(w, "\t#[allow(unused)] pub(crate) fn into_rust(&mut self) -> Vec<{}> {{", inner_type).unwrap();
+ writeln!(w, "\t\tif self.datalen == 0 {{ return Vec::new(); }}").unwrap();
+ writeln!(w, "\t\tlet ret = unsafe {{ Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }}.into();").unwrap();
+ writeln!(w, "\t\tself.data = std::ptr::null_mut();").unwrap();
+ writeln!(w, "\t\tself.datalen = 0;").unwrap();
+ writeln!(w, "\t\tret").unwrap();
+ writeln!(w, "\t}}").unwrap();
+ writeln!(w, "\t#[allow(unused)] pub(crate) fn as_slice(&self) -> &[{}] {{", inner_type).unwrap();
+ writeln!(w, "\t\tunsafe {{ std::slice::from_raw_parts_mut(self.data, self.datalen) }}").unwrap();
+ writeln!(w, "\t}}").unwrap();
+ writeln!(w, "}}").unwrap();
+
+ writeln!(w, "impl From<Vec<{}>> for {} {{", inner_type, mangled_container).unwrap();
+ writeln!(w, "\tfn from(v: Vec<{}>) -> Self {{", inner_type).unwrap();
+ writeln!(w, "\t\tlet datalen = v.len();").unwrap();
+ writeln!(w, "\t\tlet data = Box::into_raw(v.into_boxed_slice());").unwrap();
+ writeln!(w, "\t\tSelf {{ datalen, data: unsafe {{ (*data).as_mut_ptr() }} }}").unwrap();
+ writeln!(w, "\t}}").unwrap();
+ writeln!(w, "}}").unwrap();
+
+ writeln!(w, "#[no_mangle]").unwrap();
+ writeln!(w, "pub extern \"C\" fn {}_free(_res: {}) {{ }}", mangled_container, mangled_container).unwrap();
+ writeln!(w, "impl Drop for {} {{", mangled_container).unwrap();
+ writeln!(w, "\tfn drop(&mut self) {{").unwrap();
+ writeln!(w, "\t\tif self.datalen == 0 {{ return; }}").unwrap();
+ writeln!(w, "\t\tunsafe {{ Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }};").unwrap();
+ writeln!(w, "\t}}").unwrap();
+ writeln!(w, "}}").unwrap();
+ if clonable {
+ writeln!(w, "impl Clone for {} {{", mangled_container).unwrap();
+ writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
+ writeln!(w, "\t\tlet mut res = Vec::new();").unwrap();
+ writeln!(w, "\t\tif self.datalen == 0 {{ return Self::from(res); }}").unwrap();
+ writeln!(w, "\t\tres.extend_from_slice(unsafe {{ std::slice::from_raw_parts_mut(self.data, self.datalen) }});").unwrap();
+ writeln!(w, "\t\tSelf::from(res)").unwrap();
+ writeln!(w, "\t}}").unwrap();
+ writeln!(w, "}}").unwrap();
+ }
+}
+
/// Prints the docs from a given attribute list unless its tagged no export
pub fn writeln_docs<W: std::io::Write>(w: &mut W, attrs: &[syn::Attribute], prefix: &str) {
for attr in attrs.iter() {
write!(w, "{}", resolved_generic).unwrap();
} else if let Some(c_type) = self.c_type_from_path(&resolved_generic, is_ref, false) {
if self.is_known_container(&resolved_generic, is_ref) {
- if resolved_generic == "Result" {
- let mut inner_args = Vec::new();
- if let syn::PathArguments::AngleBracketed(args) = &p_arg.path.segments.iter().next().unwrap().arguments {
- for arg in args.args.iter() {
- if let syn::GenericArgument::Type(t) = arg { inner_args.push(t) } else { unimplemented!() };
- }
- } else { unimplemented!(); }
- self.write_c_mangled_container_path(w, inner_args, generics, &resolved_generic, is_ref, false, false);
- } else {
- write!(w, "{}::C{}Templ<", Self::container_templ_path(), single_ident_generic_path_to_ident(&p_arg.path).unwrap()).unwrap();
- assert_eq!(p_arg.path.segments.len(), 1);
- if let syn::PathArguments::AngleBracketed(args) = &p_arg.path.segments.iter().next().unwrap().arguments {
- self.write_template_generics(w, &mut args.args.iter().map(|gen|
- if let syn::GenericArgument::Type(t) = gen { t } else { unimplemented!() }),
- generics, is_ref, in_crate);
- } else { unimplemented!(); }
- write!(w, ">").unwrap();
- }
+ assert!(resolved_generic == "Vec" || resolved_generic == "Result");
+ let mut inner_args = Vec::new();
+ if let syn::PathArguments::AngleBracketed(args) = &p_arg.path.segments.iter().next().unwrap().arguments {
+ for arg in args.args.iter() {
+ if let syn::GenericArgument::Type(t) = arg { inner_args.push(t) } else { unimplemented!() };
+ }
+ } else { unimplemented!(); }
+ assert!(self.write_c_mangled_container_path(w, inner_args, generics, &resolved_generic, is_ref, false, false));
} else if resolved_generic == "Option" {
if let syn::PathArguments::AngleBracketed(args) = &p_arg.path.segments.iter().next().unwrap().arguments {
self.write_template_generics(w, &mut args.args.iter().map(|gen|
if is_clonable {
self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
}
+ } else if container_type == "Vec" {
+ let mut a_ty: Vec<u8> = Vec::new();
+ self.write_template_generics(&mut a_ty, &mut args.iter().map(|t| *t), generics, is_ref, true);
+ let ty = String::from_utf8(a_ty).unwrap();
+ let is_clonable = self.is_clonable(&ty);
+ write_vec_block(&mut created_container, &mangled_container, &ty, is_clonable);
+ if is_clonable {
+ self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
+ }
} else {
write!(&mut created_container, "pub type {} = ", mangled_container).unwrap();
write!(&mut created_container, "{}::C{}Templ<", Self::container_templ_path(), container_type).unwrap();
impl Drop for Transaction {
fn drop(&mut self) {
if self.data_is_owned && self.datalen != 0 {
- let _ = CVecTempl { data: self.data as *mut u8, datalen: self.datalen };
+ let _ = derived::CVec_u8Z { data: self.data as *mut u8, datalen: self.datalen };
}
}
}
}
pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
Self {
- script_pubkey: CVecTempl::from(txout.script_pubkey.into_bytes()),
+ script_pubkey: derived::CVec_u8Z::from(txout.script_pubkey.into_bytes()),
value: txout.value
}
}
pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
let mut out = VecWriter(Vec::new());
i.write(&mut out).unwrap();
- CVecTempl::from(out.0)
+ derived::CVec_u8Z::from(out.0)
}
pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
I::read(&mut s.to_slice())
}
}
-#[repr(C)]
-pub struct CVecTempl<T> {
- pub data: *mut T,
- pub datalen: usize
-}
-impl<T> CVecTempl<T> {
- pub(crate) fn into_rust(&mut self) -> Vec<T> {
- if self.datalen == 0 { return Vec::new(); }
- let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into();
- self.data = std::ptr::null_mut();
- self.datalen = 0;
- ret
- }
- pub(crate) fn as_slice(&self) -> &[T] {
- unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }
- }
-}
-impl<T> From<Vec<T>> for CVecTempl<T> {
- fn from(v: Vec<T>) -> Self {
- let datalen = v.len();
- let data = Box::into_raw(v.into_boxed_slice());
- CVecTempl { datalen, data: unsafe { (*data).as_mut_ptr() } }
- }
-}
-pub extern "C" fn CVecTempl_free<T>(_res: CVecTempl<T>) { }
-impl<T> Drop for CVecTempl<T> {
- fn drop(&mut self) {
- if self.datalen == 0 { return; }
- unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) };
- }
-}
-impl<T: Clone> Clone for CVecTempl<T> {
- fn clone(&self) -> Self {
- let mut res = Vec::new();
- if self.datalen == 0 { return Self::from(res); }
- res.extend_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
- Self::from(res)
- }
-}
-
#[repr(C)]
pub struct C2TupleTempl<A, B> {
pub a: A,