1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
// Copyright 2019 Tyler Neely // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // use libc::{self, c_void, size_t}; use std::ops::Deref; use std::slice; use std::str; /// Vector of bytes stored in the database. /// /// This is a `C` allocated byte array and a length value. /// Normal usage would be to utilize the fact it implements `Deref<[u8]>` and use it as /// a slice. pub struct DBVector { base: *mut u8, len: usize, } impl Deref for DBVector { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.base, self.len) } } } impl AsRef<[u8]> for DBVector { fn as_ref(&self) -> &[u8] { // Implement this via Deref so as not to repeat ourselves &*self } } impl Drop for DBVector { fn drop(&mut self) { unsafe { libc::free(self.base as *mut c_void); } } } impl DBVector { /// Used internally to create a DBVector from a `C` memory block /// /// # Unsafe /// Requires that the ponter be allocated by a `malloc` derivative (all C libraries), and /// `val_len` be the length of the C array to be safe (since `sizeof(u8) = 1`). /// /// # Example /// /// ```ignore /// let buf_len: libc::size_t = unsafe { mem::uninitialized() }; /// // Assume the function fills buf_len with the length of the returned array /// let buf: *mut u8 = unsafe { ffi_function_returning_byte_array(&buf_len) }; /// DBVector::from_c(buf, buf_len) /// ``` pub unsafe fn from_c(val: *mut u8, val_len: size_t) -> DBVector { DBVector { base: val, len: val_len as usize, } } /// Convenience function to attempt to reinterperet value as string. /// /// implemented as `str::from_utf8(&self[..])` pub fn to_utf8(&self) -> Option<&str> { str::from_utf8(self.deref()).ok() } }