aboutsummaryrefslogtreecommitdiff
path: root/ffi-util
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2016-12-30 18:55:10 -0800
committerJoe Wilm <joe@jwilm.com>2016-12-30 18:55:10 -0800
commita00970c9a83d0a9033e70650beb2f4a924cfe9cc (patch)
tree6d640e6f02f91580dc4b144b1c1697271fa52ae4 /ffi-util
parent44c6171bc0ce461697ef568a0b1134f02cb4c9aa (diff)
downloadalacritty-a00970c9a83d0a9033e70650beb2f4a924cfe9cc.tar.gz
alacritty-a00970c9a83d0a9033e70650beb2f4a924cfe9cc.zip
Add ffi-util crate and use in fontconfig wrapper
This cleans up and fixes the C-type wrapping for fontconfig.
Diffstat (limited to 'ffi-util')
-rw-r--r--ffi-util/Cargo.toml6
-rw-r--r--ffi-util/src/lib.rs102
2 files changed, 108 insertions, 0 deletions
diff --git a/ffi-util/Cargo.toml b/ffi-util/Cargo.toml
new file mode 100644
index 00000000..740a3b95
--- /dev/null
+++ b/ffi-util/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "ffi-util"
+version = "0.1.0"
+authors = ["Joe Wilm <joe@jwilm.com>"]
+
+[dependencies]
diff --git a/ffi-util/src/lib.rs b/ffi-util/src/lib.rs
new file mode 100644
index 00000000..be82e560
--- /dev/null
+++ b/ffi-util/src/lib.rs
@@ -0,0 +1,102 @@
+// Copyright 2011 Google Inc.
+// 2013 Jack Lloyd
+// 2013-2014 Steven Fackler
+//
+// 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 std::cell::UnsafeCell;
+
+/// This is intended to be used as the inner type for `FooRef` types converted from raw C pointers.
+/// It has an `UnsafeCell` internally to inform the compiler about aliasability and doesn't
+/// implement `Copy`, so it can't be dereferenced.
+pub struct Opaque(UnsafeCell<()>);
+
+/// A type implemented by wrappers over foreign types.
+///
+/// This should not be implemented by anything outside of this crate; new methods may be added at
+/// any time.
+pub trait ForeignType: Sized {
+ /// The raw C type.
+ type CType;
+
+ /// The type representing a reference to this type.
+ type Ref: ForeignTypeRef<CType = Self::CType>;
+
+ /// Constructs an instance of this type from its raw type.
+ unsafe fn from_ptr(ptr: *mut Self::CType) -> Self;
+}
+
+/// A trait implemented by types which reference borrowed foreign types.
+///
+/// This should not be implemented by anything outside of this crate; new methods may be added at
+/// any time.
+pub trait ForeignTypeRef: Sized {
+ /// The raw C type.
+ type CType;
+
+ /// Constructs a shared instance of this type from its raw type.
+ unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self {
+ &*(ptr as *mut _)
+ }
+
+ /// Constructs a mutable reference of this type from its raw type.
+ unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self {
+ &mut *(ptr as *mut _)
+ }
+
+ /// Returns a raw pointer to the wrapped value.
+ fn as_ptr(&self) -> *mut Self::CType {
+ self as *const _ as *mut _
+ }
+}
+
+#[macro_export]
+macro_rules! ffi_type {
+ ($n:ident, $r:ident, $c:path, $d:path) => {
+ pub struct $n(*mut $c);
+
+ impl $crate::ForeignType for $n {
+ type CType = $c;
+ type Ref = $r;
+
+ unsafe fn from_ptr(ptr: *mut $c) -> $n {
+ $n(ptr)
+ }
+ }
+
+ impl Drop for $n {
+ fn drop(&mut self) {
+ unsafe { $d(self.0) }
+ }
+ }
+
+ impl ::std::ops::Deref for $n {
+ type Target = $r;
+
+ fn deref(&self) -> &$r {
+ unsafe { $crate::ForeignTypeRef::from_ptr(self.0) }
+ }
+ }
+
+ impl ::std::ops::DerefMut for $n {
+ fn deref_mut(&mut self) -> &mut $r {
+ unsafe { $crate::ForeignTypeRef::from_ptr_mut(self.0) }
+ }
+ }
+
+ pub struct $r($crate::Opaque);
+
+ impl $crate::ForeignTypeRef for $r {
+ type CType = $c;
+ }
+ }
+}