A backend for the p≡p Engine built on Sequoia.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

48 lines
1.4 KiB

12 months ago
  1. //! Buffer management.
  2. //!
  3. //! Some convenience functions to copying data between Rust and C.
  4. //! When moving data to C, we use libc's allocator, which means that
  5. //! the C code can free the memory in the usual way, i.e., using
  6. //! libc's free.
  7. use std::{
  8. ptr::{
  9. copy_nonoverlapping,
  10. },
  11. };
  12. use libc::{
  13. malloc,
  14. c_char,
  15. };
  16. /// Copies a Rust string to a buffer, adding a terminating zero.
  17. pub fn rust_str_to_c_str<S: AsRef<str>>(s: S) -> *mut c_char {
  18. let s = s.as_ref();
  19. let bytes = s.as_bytes();
  20. unsafe {
  21. let buf = malloc(bytes.len() + 1);
  22. copy_nonoverlapping(bytes.as_ptr(), buf as *mut _, bytes.len());
  23. *((buf as *mut u8).add(bytes.len())) = 0; // Terminate.
  24. buf as *mut c_char
  25. }
  26. }
  27. /// Copies a C string to a buffer, adding a terminating zero.
  28. ///
  29. /// Replaces embedded zeros with '_'.
  30. pub fn rust_bytes_to_c_str_lossy<S: AsRef<[u8]>>(s: S) -> *mut c_char {
  31. let bytes = s.as_ref();
  32. unsafe {
  33. let buf = malloc(bytes.len() + 1);
  34. copy_nonoverlapping(bytes.as_ptr(), buf as *mut _, bytes.len());
  35. // Replace embedded zeros.
  36. let bytes_mut = std::slice::from_raw_parts_mut(buf as *mut u8,
  37. bytes.len());
  38. bytes_mut.iter_mut().for_each(|b| if *b == 0 { *b = b'_' });
  39. *((buf as *mut u8).add(bytes.len())) = 0; // Terminate.
  40. buf as *mut c_char
  41. }
  42. }