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