postgres_extension/
rust_utils.rs1
2use std::cmp;
3use std::fmt;
4use std::io;
5use std::io::{Error,ErrorKind,Result};
6use std::mem;
7
8use crate::utils::memutils;
9use std::alloc::{GlobalAlloc, Layout};
10
11
12pub trait Write {
14 fn write(&mut self, buf: &[u8]) -> Result<usize>;
15 fn flush(&mut self) -> Result<()>;
16 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
17 while !buf.is_empty() {
18 match self.write(buf) {
19 Ok(0) => return Err(Error::new(ErrorKind::WriteZero,
20 "failed to write whole buffer")),
21 Ok(n) => buf = &buf[n..],
22 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
23 Err(e) => return Err(e),
24 }
25 }
26 Ok(())
27 }
28 fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> {
29 struct Adaptor<'a, T: ?Sized + 'a> {
32 inner: &'a mut T,
33 error: Result<()>,
34 }
35
36 impl<'a, T: Write + ?Sized> fmt::Write for Adaptor<'a, T> {
37 fn write_str(&mut self, s: &str) -> fmt::Result {
38 match self.inner.write_all(s.as_bytes()) {
39 Ok(()) => Ok(()),
40 Err(e) => {
41 self.error = Err(e);
42 Err(fmt::Error)
43 }
44 }
45 }
46 }
47
48 let mut output = Adaptor { inner: self, error: Ok(()) };
49 match fmt::write(&mut output, fmt) {
50 Ok(()) => Ok(()),
51 Err(..) => {
52 if output.error.is_err() {
54 output.error
55 } else {
56 Err(Error::new(ErrorKind::Other, "formatter error"))
57 }
58 }
59 }
60 }
61 fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
62}
63
64impl<'a> Write for &'a mut [i8] {
65 #[inline]
66 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
67 let amt = cmp::min(data.len(), self.len());
68 let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
69 let a_u8 = unsafe { &mut *(a as *mut [i8] as *mut [u8]) };
70 a_u8.copy_from_slice(&data[..amt]);
71 *self = b;
72 Ok(amt)
73 }
74
75 #[inline]
76 fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
77 if self.write(data)? == data.len() {
78 Ok(())
79 } else {
80 Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"))
81 }
82 }
83
84 #[inline]
85 fn flush(&mut self) -> io::Result<()> { Ok(()) }
86}
87
88pub struct PostgresAllocator;
90unsafe impl GlobalAlloc for PostgresAllocator {
91 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
92 return memutils::c::MemoryContextAlloc(
93 memutils::CurrentMemoryContext, layout.size());
94 }
95 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
96 memutils::c::pfree(ptr);
97 }
98}
99