X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Fc_types%2Fmod.rs;h=cd96dffe1969bbe6c845fcfa0ff2ec73e64dff4a;hb=5eebd45b471833805e81ad4c23ec93d7711e0a23;hp=ee7660cd09bc6cb0f11fbaae1922cb466676c88b;hpb=cedd4f5c458f902bd47ec12eb9b5ec0e441d2d66;p=ldk-c-bindings diff --git a/lightning-c-bindings/src/c_types/mod.rs b/lightning-c-bindings/src/c_types/mod.rs index ee7660c..cd96dff 100644 --- a/lightning-c-bindings/src/c_types/mod.rs +++ b/lightning-c-bindings/src/c_types/mod.rs @@ -9,9 +9,23 @@ use bitcoin::secp256k1::key::PublicKey as SecpPublicKey; use bitcoin::secp256k1::key::SecretKey as SecpSecretKey; use bitcoin::secp256k1::Signature as SecpSignature; use bitcoin::secp256k1::Error as SecpError; +use bitcoin::bech32; use std::convert::TryInto; // Bindings need at least rustc 1.34 +/// Integer in the range `0..32` +#[derive(PartialEq, Eq, Copy, Clone)] +#[allow(non_camel_case_types)] +#[repr(C)] +pub struct u5(u8); + +impl From for u5 { + fn from(o: bech32::u5) -> Self { Self(o.to_u8()) } +} +impl Into for u5 { + fn into(self) -> bech32::u5 { bech32::u5::try_from_u8(self.0).expect("u5 objects must be in the range 0..32") } +} + #[derive(Clone)] #[repr(C)] /// Represents a valid secp256k1 public key serialized in "compressed form" as a 33 byte array. @@ -187,9 +201,10 @@ impl Transaction { if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); } ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap() } - pub(crate) fn from_vec(v: Vec) -> Self { - let datalen = v.len(); - let data = Box::into_raw(v.into_boxed_slice()); + pub(crate) fn from_bitcoin(btc: &BitcoinTransaction) -> Self { + let vec = ::bitcoin::consensus::encode::serialize(btc); + let datalen = vec.len(); + let data = Box::into_raw(vec.into_boxed_slice()); Self { data: unsafe { (*data).as_mut_ptr() }, datalen, @@ -295,6 +310,10 @@ pub struct TenBytes { /** The ten bytes */ pub data: [u8; 10], } #[repr(C)] /// A 16-byte byte array. pub struct SixteenBytes { /** The sixteen bytes */ pub data: [u8; 16], } +#[derive(Clone)] +#[repr(C)] +/// A 20-byte byte array. +pub struct TwentyBytes { /** The twenty bytes */ pub data: [u8; 20], } pub(crate) struct VecWriter(pub Vec); impl lightning::util::ser::Writer for VecWriter { @@ -319,18 +338,20 @@ pub(crate) fn deserialize_obj_arg>(s } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Clone)] /// A Rust str object, ie a reference to a UTF8-valid string. /// This is *not* null-terminated so cannot be used directly as a C string! pub struct Str { /// A pointer to the string's bytes, in UTF8 encoding pub chars: *const u8, /// The number of bytes (not characters!) pointed to by `chars` - pub len: usize + pub len: usize, + /// Whether the data pointed to by `chars` should be freed or not. + pub chars_is_owned: bool, } impl Into for &'static str { fn into(self) -> Str { - Str { chars: self.as_ptr(), len: self.len() } + Str { chars: self.as_ptr(), len: self.len(), chars_is_owned: false } } } impl Into<&'static str> for Str { @@ -339,6 +360,23 @@ impl Into<&'static str> for Str { std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap() } } +impl Into for String { + fn into(self) -> Str { + let s = Box::leak(self.into_boxed_str()); + Str { chars: s.as_ptr(), len: s.len(), chars_is_owned: true } + } +} + +impl Drop for Str { + fn drop(&mut self) { + if self.chars_is_owned && self.len != 0 { + let _ = derived::CVec_u8Z { data: self.chars as *mut u8, datalen: self.len }; + } + } +} +#[no_mangle] +/// Frees the data buffer, if chars_is_owned is set and len > 0. +pub extern "C" fn Str_free(_res: Str) { } // Note that the C++ headers memset(0) all the Templ types to avoid deallocation! // Thus, they must gracefully handle being completely null in _free.