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