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