0bd976bac8f1e47ee75ad5995a0bf123ce8f01dd
[ldk-c-bindings] / lightning-c-bindings / src / c_types / mod.rs
1 //! This module contains standard C-mapped types for types not in the original crate.
2
3 /// Auto-generated C-mapped types for templated containers
4 pub mod derived;
5
6 use bitcoin::Transaction as BitcoinTransaction;
7 use bitcoin::hashes::Hash;
8 use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
9 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
10 use bitcoin::secp256k1::Signature as SecpSignature;
11 use bitcoin::secp256k1::Error as SecpError;
12 use bitcoin::secp256k1::recovery::RecoveryId;
13 use bitcoin::secp256k1::recovery::RecoverableSignature as SecpRecoverableSignature;
14 use bitcoin::bech32;
15
16 use core::convert::TryInto; // Bindings need at least rustc 1.34
17 use core::ffi::c_void;
18
19 #[cfg(feature = "std")]
20 pub(crate) use std::io::{self, Cursor, Read};
21 #[cfg(feature = "no-std")]
22 pub(crate) use core2::io::{self, Cursor, Read};
23 #[cfg(feature = "no-std")]
24 use alloc::{boxed::Box, vec::Vec, string::String};
25
26 #[repr(C)]
27 /// A dummy struct of which an instance must never exist.
28 /// This corresponds to the Rust type `Infallible`, or, in unstable rust, `!`
29 pub struct NotConstructable {
30         _priv_thing: core::convert::Infallible,
31 }
32 impl From<core::convert::Infallible> for NotConstructable {
33         fn from(_: core::convert::Infallible) -> Self { unreachable!(); }
34 }
35
36 /// Integer in the range `0..32`
37 #[derive(PartialEq, Eq, Copy, Clone)]
38 #[allow(non_camel_case_types)]
39 #[repr(C)]
40 pub struct u5(u8);
41
42 impl From<bech32::u5> for u5 {
43         fn from(o: bech32::u5) -> Self { Self(o.to_u8()) }
44 }
45 impl Into<bech32::u5> for u5 {
46         fn into(self) -> bech32::u5 { bech32::u5::try_from_u8(self.0).expect("u5 objects must be in the range 0..32") }
47 }
48
49 #[derive(Clone)]
50 #[repr(C)]
51 /// Represents a valid secp256k1 public key serialized in "compressed form" as a 33 byte array.
52 pub struct PublicKey {
53         /// The bytes of the public key
54         pub compressed_form: [u8; 33],
55 }
56 impl PublicKey {
57         pub(crate) fn from_rust(pk: &SecpPublicKey) -> Self {
58                 Self {
59                         compressed_form: pk.serialize(),
60                 }
61         }
62         pub(crate) fn into_rust(&self) -> SecpPublicKey {
63                 SecpPublicKey::from_slice(&self.compressed_form).unwrap()
64         }
65         pub(crate) fn is_null(&self) -> bool { self.compressed_form[..] == [0; 33][..] }
66         pub(crate) fn null() -> Self { Self { compressed_form: [0; 33] } }
67 }
68
69 #[repr(C)]
70 /// Represents a valid secp256k1 secret key serialized as a 32 byte array.
71 pub struct SecretKey {
72         /// The bytes of the secret key
73         pub bytes: [u8; 32],
74 }
75 impl SecretKey {
76         // from_rust isn't implemented for a ref since we just return byte array refs directly
77         pub(crate) fn from_rust(sk: SecpSecretKey) -> Self {
78                 let mut bytes = [0; 32];
79                 bytes.copy_from_slice(&sk[..]);
80                 Self { bytes }
81         }
82         pub(crate) fn into_rust(&self) -> SecpSecretKey {
83                 SecpSecretKey::from_slice(&self.bytes).unwrap()
84         }
85 }
86
87 #[repr(C)]
88 #[derive(Clone)]
89 /// Represents a secp256k1 signature serialized as two 32-byte numbers
90 pub struct Signature {
91         /// The bytes of the signature in "compact" form
92         pub compact_form: [u8; 64],
93 }
94 impl Signature {
95         pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
96                 Self {
97                         compact_form: pk.serialize_compact(),
98                 }
99         }
100         pub(crate) fn into_rust(&self) -> SecpSignature {
101                 SecpSignature::from_compact(&self.compact_form).unwrap()
102         }
103         // The following are used for Option<Signature> which we support, but don't use anymore
104         #[allow(unused)] pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
105         #[allow(unused)] pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
106 }
107
108 #[repr(C)]
109 #[derive(Clone)]
110 /// Represents a secp256k1 signature serialized as two 32-byte numbers as well as a tag which
111 /// allows recovering the exact public key which created the signature given the message.
112 pub struct RecoverableSignature {
113         /// The bytes of the signature in "compact" form plus a "Recovery ID" which allows for
114         /// recovery.
115         pub serialized_form: [u8; 68],
116 }
117 impl RecoverableSignature {
118         pub(crate) fn from_rust(pk: &SecpRecoverableSignature) -> Self {
119                 let (id, compact_form) = pk.serialize_compact();
120                 let mut serialized_form = [0; 68];
121                 serialized_form[0..64].copy_from_slice(&compact_form[..]);
122                 serialized_form[64..].copy_from_slice(&id.to_i32().to_le_bytes());
123                 Self { serialized_form }
124         }
125         pub(crate) fn into_rust(&self) -> SecpRecoverableSignature {
126                 let mut id = [0; 4];
127                 id.copy_from_slice(&self.serialized_form[64..]);
128                 SecpRecoverableSignature::from_compact(&self.serialized_form[0..64],
129                                 RecoveryId::from_i32(i32::from_le_bytes(id)).expect("Invalid Recovery ID"))
130                         .unwrap()
131         }
132 }
133
134 #[repr(C)]
135 #[derive(Copy, Clone)]
136 /// Represents an error returned from libsecp256k1 during validation of some secp256k1 data
137 pub enum Secp256k1Error {
138         /// Signature failed verification
139         IncorrectSignature,
140         /// Badly sized message ("messages" are actually fixed-sized digests; see the MESSAGE_SIZE constant)
141         InvalidMessage,
142         /// Bad public key
143         InvalidPublicKey,
144         /// Bad signature
145         InvalidSignature,
146         /// Bad secret key
147         InvalidSecretKey,
148         /// Bad recovery id
149         InvalidRecoveryId,
150         /// Invalid tweak for add_assign or mul_assign
151         InvalidTweak,
152         /// tweak_add_check failed on an xonly public key
153         TweakCheckFailed,
154         /// Didn't pass enough memory to context creation with preallocated memory
155         NotEnoughMemory,
156 }
157 impl Secp256k1Error {
158         pub(crate) fn from_rust(err: SecpError) -> Self {
159                 match err {
160                         SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
161                         SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
162                         SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
163                         SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
164                         SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
165                         SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
166                         SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
167                         SecpError::TweakCheckFailed => Secp256k1Error::TweakCheckFailed,
168                         SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
169                 }
170         }
171 }
172
173 #[repr(C)]
174 #[allow(missing_docs)] // If there's no docs upstream, that's good enough for us
175 #[derive(Clone, Copy, PartialEq)]
176 /// Represents an IO Error. Note that some information is lost in the conversion from Rust.
177 pub enum IOError {
178         NotFound,
179         PermissionDenied,
180         ConnectionRefused,
181         ConnectionReset,
182         ConnectionAborted,
183         NotConnected,
184         AddrInUse,
185         AddrNotAvailable,
186         BrokenPipe,
187         AlreadyExists,
188         WouldBlock,
189         InvalidInput,
190         InvalidData,
191         TimedOut,
192         WriteZero,
193         Interrupted,
194         Other,
195         UnexpectedEof,
196 }
197 #[cfg(feature = "std")]
198 impl IOError {
199         pub(crate) fn from_rust(err: std::io::Error) -> Self {
200                 match err.kind() {
201                         std::io::ErrorKind::NotFound => IOError::NotFound,
202                         std::io::ErrorKind::PermissionDenied => IOError::PermissionDenied,
203                         std::io::ErrorKind::ConnectionRefused => IOError::ConnectionRefused,
204                         std::io::ErrorKind::ConnectionReset => IOError::ConnectionReset,
205                         std::io::ErrorKind::ConnectionAborted => IOError::ConnectionAborted,
206                         std::io::ErrorKind::NotConnected => IOError::NotConnected,
207                         std::io::ErrorKind::AddrInUse => IOError::AddrInUse,
208                         std::io::ErrorKind::AddrNotAvailable => IOError::AddrNotAvailable,
209                         std::io::ErrorKind::BrokenPipe => IOError::BrokenPipe,
210                         std::io::ErrorKind::AlreadyExists => IOError::AlreadyExists,
211                         std::io::ErrorKind::WouldBlock => IOError::WouldBlock,
212                         std::io::ErrorKind::InvalidInput => IOError::InvalidInput,
213                         std::io::ErrorKind::InvalidData => IOError::InvalidData,
214                         std::io::ErrorKind::TimedOut => IOError::TimedOut,
215                         std::io::ErrorKind::WriteZero => IOError::WriteZero,
216                         std::io::ErrorKind::Interrupted => IOError::Interrupted,
217                         std::io::ErrorKind::Other => IOError::Other,
218                         std::io::ErrorKind::UnexpectedEof => IOError::UnexpectedEof,
219                         _ => IOError::Other,
220                 }
221         }
222         pub(crate) fn to_rust(&self) -> std::io::Error {
223                 std::io::Error::new(match self {
224                         IOError::NotFound => std::io::ErrorKind::NotFound,
225                         IOError::PermissionDenied => std::io::ErrorKind::PermissionDenied,
226                         IOError::ConnectionRefused => std::io::ErrorKind::ConnectionRefused,
227                         IOError::ConnectionReset => std::io::ErrorKind::ConnectionReset,
228                         IOError::ConnectionAborted => std::io::ErrorKind::ConnectionAborted,
229                         IOError::NotConnected => std::io::ErrorKind::NotConnected,
230                         IOError::AddrInUse => std::io::ErrorKind::AddrInUse,
231                         IOError::AddrNotAvailable => std::io::ErrorKind::AddrNotAvailable,
232                         IOError::BrokenPipe => std::io::ErrorKind::BrokenPipe,
233                         IOError::AlreadyExists => std::io::ErrorKind::AlreadyExists,
234                         IOError::WouldBlock => std::io::ErrorKind::WouldBlock,
235                         IOError::InvalidInput => std::io::ErrorKind::InvalidInput,
236                         IOError::InvalidData => std::io::ErrorKind::InvalidData,
237                         IOError::TimedOut => std::io::ErrorKind::TimedOut,
238                         IOError::WriteZero => std::io::ErrorKind::WriteZero,
239                         IOError::Interrupted => std::io::ErrorKind::Interrupted,
240                         IOError::Other => std::io::ErrorKind::Other,
241                         IOError::UnexpectedEof => std::io::ErrorKind::UnexpectedEof,
242                 }, "")
243         }
244 }
245
246 #[repr(C)]
247 /// A serialized transaction, in (pointer, length) form.
248 ///
249 /// This type optionally owns its own memory, and thus the semantics around access change based on
250 /// the `data_is_owned` flag. If `data_is_owned` is set, you must call `Transaction_free` to free
251 /// the underlying buffer before the object goes out of scope. If `data_is_owned` is not set, any
252 /// access to the buffer after the scope in which the object was provided to you is invalid. eg,
253 /// access after you return from the call in which a `!data_is_owned` `Transaction` is provided to
254 /// you would be invalid.
255 ///
256 /// Note that, while it may change in the future, because transactions on the Rust side are stored
257 /// in a deserialized form, all `Transaction`s generated on the Rust side will have `data_is_owned`
258 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
259 /// `data_is_owned` either set or unset at your discretion.
260 pub struct Transaction {
261         /// The serialized transaction data.
262         ///
263         /// This is non-const for your convenience, an object passed to Rust is never written to.
264         pub data: *mut u8,
265         /// The length of the serialized transaction
266         pub datalen: usize,
267         /// Whether the data pointed to by `data` should be freed or not.
268         pub data_is_owned: bool,
269 }
270 impl Transaction {
271         fn from_vec(vec: Vec<u8>) -> Self {
272                 let datalen = vec.len();
273                 let data = Box::into_raw(vec.into_boxed_slice());
274                 Self {
275                         data: unsafe { (*data).as_mut_ptr() },
276                         datalen,
277                         data_is_owned: true,
278                 }
279         }
280         pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
281                 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
282                 ::bitcoin::consensus::encode::deserialize(unsafe { core::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
283         }
284         pub(crate) fn from_bitcoin(btc: &BitcoinTransaction) -> Self {
285                 let vec = ::bitcoin::consensus::encode::serialize(btc);
286                 Self::from_vec(vec)
287         }
288 }
289 impl Drop for Transaction {
290         fn drop(&mut self) {
291                 if self.data_is_owned && self.datalen != 0 {
292                         let _ = derived::CVec_u8Z { data: self.data as *mut u8, datalen: self.datalen };
293                 }
294         }
295 }
296 impl Clone for Transaction {
297         fn clone(&self) -> Self {
298                 let sl = unsafe { core::slice::from_raw_parts(self.data, self.datalen) };
299                 let mut v = Vec::new();
300                 v.extend_from_slice(&sl);
301                 Self::from_vec(v)
302         }
303 }
304 #[no_mangle]
305 /// Frees the data buffer, if data_is_owned is set and datalen > 0.
306 pub extern "C" fn Transaction_free(_res: Transaction) { }
307
308 pub(crate) fn bitcoin_to_C_outpoint(outpoint: ::bitcoin::blockdata::transaction::OutPoint) -> crate::lightning::chain::transaction::OutPoint {
309         crate::lightning::chain::transaction::OutPoint_new(ThirtyTwoBytes { data: outpoint.txid.into_inner() }, outpoint.vout.try_into().unwrap())
310 }
311 pub(crate) fn C_to_bitcoin_outpoint(outpoint: crate::lightning::chain::transaction::OutPoint) -> ::bitcoin::blockdata::transaction::OutPoint {
312         unsafe {
313                 ::bitcoin::blockdata::transaction::OutPoint {
314                         txid: (*outpoint.inner).txid, vout: (*outpoint.inner).index as u32
315                 }
316         }
317 }
318
319 #[repr(C)]
320 #[derive(Clone)]
321 /// A transaction output including a scriptPubKey and value.
322 /// This type *does* own its own memory, so must be free'd appropriately.
323 pub struct TxOut {
324         /// The script_pubkey in this output
325         pub script_pubkey: derived::CVec_u8Z,
326         /// The value, in satoshis, of this output
327         pub value: u64,
328 }
329
330 impl TxOut {
331         pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
332                 ::bitcoin::blockdata::transaction::TxOut {
333                         script_pubkey: self.script_pubkey.into_rust().into(),
334                         value: self.value,
335                 }
336         }
337         pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
338                 Self {
339                         script_pubkey: derived::CVec_u8Z::from(txout.script_pubkey.into_bytes()),
340                         value: txout.value
341                 }
342         }
343 }
344
345 #[no_mangle]
346 /// Convenience function for constructing a new TxOut
347 pub extern "C" fn TxOut_new(script_pubkey: derived::CVec_u8Z, value: u64) -> TxOut {
348         TxOut { script_pubkey, value }
349 }
350 #[no_mangle]
351 /// Frees the data pointed to by script_pubkey.
352 pub extern "C" fn TxOut_free(_res: TxOut) { }
353 #[no_mangle]
354 /// Creates a new TxOut which has the same data as `orig` but with a new script buffer.
355 pub extern "C" fn TxOut_clone(orig: &TxOut) -> TxOut { orig.clone() }
356
357 #[repr(C)]
358 /// A "slice" referencing some byte array. This is simply a length-tagged pointer which does not
359 /// own the memory pointed to by data.
360 pub struct u8slice {
361         /// A pointer to the byte buffer
362         pub data: *const u8,
363         /// The number of bytes pointed to by `data`.
364         pub datalen: usize
365 }
366 impl u8slice {
367         pub(crate) fn from_slice(s: &[u8]) -> Self {
368                 Self {
369                         data: s.as_ptr(),
370                         datalen: s.len(),
371                 }
372         }
373         pub(crate) fn to_slice(&self) -> &[u8] {
374                 if self.datalen == 0 { return &[]; }
375                 unsafe { core::slice::from_raw_parts(self.data, self.datalen) }
376         }
377         pub(crate) fn to_reader<'a>(&'a self) -> Cursor<&'a [u8]> {
378                 let sl = self.to_slice();
379                 Cursor::new(sl)
380         }
381         pub(crate) fn from_vec(v: &derived::CVec_u8Z) -> u8slice {
382                 Self::from_slice(v.as_slice())
383         }
384 }
385 pub(crate) fn reader_to_vec<R: Read>(r: &mut R) -> derived::CVec_u8Z {
386         let mut res = Vec::new();
387         r.read_to_end(&mut res).unwrap();
388         derived::CVec_u8Z::from(res)
389 }
390
391 #[repr(C)]
392 #[derive(Copy, Clone)]
393 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
394 /// look up the corresponding function in rust-lightning's docs.
395 pub struct ThirtyTwoBytes {
396         /// The thirty-two bytes
397         pub data: [u8; 32],
398 }
399 impl ThirtyTwoBytes {
400         pub(crate) fn null() -> Self {
401                 Self { data: [0; 32] }
402         }
403 }
404
405 #[repr(C)]
406 /// A 3-byte byte array.
407 pub struct ThreeBytes { /** The three bytes */ pub data: [u8; 3], }
408 #[derive(Clone)]
409 #[repr(C)]
410 /// A 4-byte byte array.
411 pub struct FourBytes { /** The four bytes */ pub data: [u8; 4], }
412 #[derive(Clone)]
413 #[repr(C)]
414 /// A 12-byte byte array.
415 pub struct TwelveBytes { /** The twelve bytes */ pub data: [u8; 12], }
416 #[derive(Clone)]
417 #[repr(C)]
418 /// A 16-byte byte array.
419 pub struct SixteenBytes { /** The sixteen bytes */ pub data: [u8; 16], }
420 #[derive(Clone)]
421 #[repr(C)]
422 /// A 20-byte byte array.
423 pub struct TwentyBytes { /** The twenty bytes */ pub data: [u8; 20], }
424
425 pub(crate) struct VecWriter(pub Vec<u8>);
426 impl lightning::util::ser::Writer for VecWriter {
427         fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {
428                 self.0.extend_from_slice(buf);
429                 Ok(())
430         }
431 }
432 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
433         let mut out = VecWriter(Vec::new());
434         i.write(&mut out).unwrap();
435         derived::CVec_u8Z::from(out.0)
436 }
437 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
438         I::read(&mut s.to_slice())
439 }
440 pub(crate) fn maybe_deserialize_obj<I: lightning::util::ser::MaybeReadable>(s: u8slice) -> Result<Option<I>, lightning::ln::msgs::DecodeError> {
441         I::read(&mut s.to_slice())
442 }
443 pub(crate) fn deserialize_obj_arg<A, I: lightning::util::ser::ReadableArgs<A>>(s: u8slice, args: A) -> Result<I, lightning::ln::msgs::DecodeError> {
444         I::read(&mut s.to_slice(), args)
445 }
446
447 #[repr(C)]
448 /// A Rust str object, ie a reference to a UTF8-valid string.
449 /// This is *not* null-terminated so cannot be used directly as a C string!
450 pub struct Str {
451         /// A pointer to the string's bytes, in UTF8 encoding
452         pub chars: *const u8,
453         /// The number of bytes (not characters!) pointed to by `chars`
454         pub len: usize,
455         /// Whether the data pointed to by `chars` should be freed or not.
456         pub chars_is_owned: bool,
457 }
458 impl Into<Str> for &'static str {
459         fn into(self) -> Str {
460                 Str { chars: self.as_ptr(), len: self.len(), chars_is_owned: false }
461         }
462 }
463 impl Into<Str> for &mut &'static str {
464         fn into(self) -> Str {
465                 let us: &'static str = *self;
466                 us.into()
467         }
468 }
469
470 impl Str {
471         pub(crate) fn into_str(&self) -> &'static str {
472                 if self.len == 0 { return ""; }
473                 core::str::from_utf8(unsafe { core::slice::from_raw_parts(self.chars, self.len) }).unwrap()
474         }
475         pub(crate) fn into_string(mut self) -> String {
476                 let bytes = if self.len == 0 {
477                         Vec::new()
478                 } else if self.chars_is_owned {
479                         let ret = unsafe {
480                                 Box::from_raw(core::slice::from_raw_parts_mut(unsafe { self.chars as *mut u8 }, self.len))
481                         }.into();
482                         self.chars_is_owned = false;
483                         ret
484                 } else {
485                         let mut ret = Vec::with_capacity(self.len);
486                         ret.extend_from_slice(unsafe { core::slice::from_raw_parts(self.chars, self.len) });
487                         ret
488                 };
489                 String::from_utf8(bytes).unwrap()
490         }
491 }
492 impl Into<Str> for String {
493         fn into(self) -> Str {
494                 let s = Box::leak(self.into_boxed_str());
495                 Str { chars: s.as_ptr(), len: s.len(), chars_is_owned: true }
496         }
497 }
498 impl Clone for Str {
499         fn clone(&self) -> Self {
500                 self.into_str().clone().into()
501         }
502 }
503
504 impl Drop for Str {
505         fn drop(&mut self) {
506                 if self.chars_is_owned && self.len != 0 {
507                         let _ = derived::CVec_u8Z { data: self.chars as *mut u8, datalen: self.len };
508                 }
509         }
510 }
511 #[no_mangle]
512 /// Frees the data buffer, if chars_is_owned is set and len > 0.
513 pub extern "C" fn Str_free(_res: Str) { }
514
515 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
516 // Thus, they must gracefully handle being completely null in _free.
517
518 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
519 // everywhere in the containers.
520
521 #[repr(C)]
522 pub(crate) union CResultPtr<O, E> {
523         pub(crate) result: *mut O,
524         pub(crate) err: *mut E,
525 }
526 #[repr(C)]
527 pub(crate) struct CResultTempl<O, E> {
528         pub(crate) contents: CResultPtr<O, E>,
529         pub(crate) result_ok: bool,
530 }
531 impl<O, E> CResultTempl<O, E> {
532         pub(crate) extern "C" fn ok(o: O) -> Self {
533                 CResultTempl {
534                         contents: CResultPtr {
535                                 result: Box::into_raw(Box::new(o)),
536                         },
537                         result_ok: true,
538                 }
539         }
540         pub(crate) extern "C" fn err(e: E) -> Self {
541                 CResultTempl {
542                         contents: CResultPtr {
543                                 err: Box::into_raw(Box::new(e)),
544                         },
545                         result_ok: false,
546                 }
547         }
548 }
549 impl<O, E> Drop for CResultTempl<O, E> {
550         fn drop(&mut self) {
551                 if self.result_ok {
552                         if unsafe { !self.contents.result.is_null() } {
553                                 unsafe { Box::from_raw(self.contents.result) };
554                         }
555                 } else if unsafe { !self.contents.err.is_null() } {
556                         unsafe { Box::from_raw(self.contents.err) };
557                 }
558         }
559 }
560
561 /// Utility to make it easy to set a pointer to null and get its original value in line.
562 pub(crate) trait TakePointer<T> {
563         fn take_ptr(&mut self) -> T;
564 }
565 impl<T> TakePointer<*const T> for *const T {
566         fn take_ptr(&mut self) -> *const T {
567                 let ret = *self;
568                 *self = core::ptr::null();
569                 ret
570         }
571 }
572 impl<T> TakePointer<*mut T> for *mut T {
573         fn take_ptr(&mut self) -> *mut T {
574                 let ret = *self;
575                 *self = core::ptr::null_mut();
576                 ret
577         }
578 }
579
580
581 pub(crate) mod ObjOps {
582         #[cfg(feature = "no-std")]
583         use alloc::boxed::Box;
584
585         #[inline]
586         #[must_use = "returns new dangling pointer"]
587         pub(crate) fn heap_alloc<T>(obj: T) -> *mut T {
588                 let ptr = Box::into_raw(Box::new(obj));
589                 nonnull_ptr_to_inner(ptr)
590         }
591         #[inline]
592         pub(crate) fn nonnull_ptr_to_inner<T>(ptr: *const T) -> *mut T {
593                 if core::mem::size_of::<T>() == 0 {
594                         // We map `None::<T>` as `T { inner: null, .. }` which works great for all
595                         // non-Zero-Sized-Types `T`.
596                         // For ZSTs, we need to differentiate between null implying `None` and null implying
597                         // `Some` with no allocation.
598                         // Thus, for ZSTs, we add one (usually) page here, which should always be aligned.
599                         // Note that this relies on undefined behavior! A pointer to NULL may be valid, but a
600                         // pointer to NULL + 4096 is almost certainly not. That said, Rust's existing use of
601                         // `(*mut T)1` for the pointer we're adding to is also not defined, so we should be
602                         // fine.
603                         // Note that we add 4095 here as at least the Java client assumes that the low bit on
604                         // any heap pointer is 0, which is generally provided by malloc, but which is not true
605                         // for ZSTs "allocated" by `Box::new`.
606                         debug_assert_eq!(ptr as usize, 1);
607                         unsafe { (ptr as *mut T).cast::<u8>().add(4096 - 1).cast::<T>() }
608                 } else {
609                         // In order to get better test coverage, also increment non-ZST pointers with
610                         // --cfg=test_mod_pointers, which is set in genbindings.sh for debug builds.
611                         #[cfg(test_mod_pointers)]
612                         unsafe { (ptr as *mut T).cast::<u8>().add(4096).cast::<T>() }
613                         #[cfg(not(test_mod_pointers))]
614                         unsafe { ptr as *mut T }
615                 }
616         }
617         #[inline]
618         /// Invert nonnull_ptr_to_inner
619         pub(crate) fn untweak_ptr<T>(ptr: *mut T) -> *mut T {
620                 if core::mem::size_of::<T>() == 0 {
621                         unsafe { ptr.cast::<u8>().sub(4096 - 1).cast::<T>() }
622                 } else {
623                         #[cfg(test_mod_pointers)]
624                         unsafe { ptr.cast::<u8>().sub(4096).cast::<T>() }
625                         #[cfg(not(test_mod_pointers))]
626                         ptr
627                 }
628         }
629 }
630
631 #[cfg(test_mod_pointers)]
632 #[no_mangle]
633 /// This function exists for memory safety testing purposes. It should never be used in production
634 /// code
635 pub extern "C" fn __unmangle_inner_ptr(ptr: *const c_void) -> *const c_void {
636         if ptr as usize == 1 {
637                 core::ptr::null()
638         } else {
639                 unsafe { ptr.cast::<u8>().sub(4096).cast::<c_void>() }
640         }
641 }
642
643 pub(crate) struct SmartPtr<T> {
644         ptr: *mut T,
645 }
646 impl<T> SmartPtr<T> {
647         pub(crate) fn from_obj(o: T) -> Self {
648                 Self { ptr: Box::into_raw(Box::new(o)) }
649         }
650         pub(crate) fn null() -> Self {
651                 Self { ptr: core::ptr::null_mut() }
652         }
653 }
654 impl<T> Drop for SmartPtr<T> {
655         fn drop(&mut self) {
656                 if self.ptr != core::ptr::null_mut() {
657                         unsafe { Box::from_raw(self.ptr); }
658                 }
659         }
660 }
661 impl<T> core::ops::Deref for SmartPtr<T> {
662         type Target = *mut T;
663         fn deref(&self) -> &*mut T {
664                 &self.ptr
665         }
666 }