]> git.proxmox.com Git - rustc.git/blob - vendor/cc-1.0.59/src/com.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / cc-1.0.59 / src / com.rs
1 // Copyright © 2017 winapi-rs developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
4 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
5 // All files in the project carrying such notice may not be copied, modified, or distributed
6 // except according to those terms.
7
8 #![allow(unused)]
9
10 use crate::winapi::CoInitializeEx;
11 use crate::winapi::IUnknown;
12 use crate::winapi::Interface;
13 use crate::winapi::BSTR;
14 use crate::winapi::COINIT_MULTITHREADED;
15 use crate::winapi::{SysFreeString, SysStringLen};
16 use crate::winapi::{HRESULT, S_FALSE, S_OK};
17 use std::ffi::{OsStr, OsString};
18 use std::mem::forget;
19 use std::ops::Deref;
20 use std::os::windows::ffi::{OsStrExt, OsStringExt};
21 use std::ptr::null_mut;
22 use std::slice::from_raw_parts;
23
24 pub fn initialize() -> Result<(), HRESULT> {
25 let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) };
26 if err != S_OK && err != S_FALSE {
27 // S_FALSE just means COM is already initialized
28 return Err(err);
29 }
30 Ok(())
31 }
32
33 pub struct ComPtr<T>(*mut T)
34 where
35 T: Interface;
36 impl<T> ComPtr<T>
37 where
38 T: Interface,
39 {
40 /// Creates a `ComPtr` to wrap a raw pointer.
41 /// It takes ownership over the pointer which means it does __not__ call `AddRef`.
42 /// `T` __must__ be a COM interface that inherits from `IUnknown`.
43 pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {
44 assert!(!ptr.is_null());
45 ComPtr(ptr)
46 }
47 /// Casts up the inheritance chain
48 pub fn up<U>(self) -> ComPtr<U>
49 where
50 T: Deref<Target = U>,
51 U: Interface,
52 {
53 ComPtr(self.into_raw() as *mut U)
54 }
55 /// Extracts the raw pointer.
56 /// You are now responsible for releasing it yourself.
57 pub fn into_raw(self) -> *mut T {
58 let p = self.0;
59 forget(self);
60 p
61 }
62 /// For internal use only.
63 fn as_unknown(&self) -> &IUnknown {
64 unsafe { &*(self.0 as *mut IUnknown) }
65 }
66 /// Performs QueryInterface fun.
67 pub fn cast<U>(&self) -> Result<ComPtr<U>, i32>
68 where
69 U: Interface,
70 {
71 let mut obj = null_mut();
72 let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) };
73 if err < 0 {
74 return Err(err);
75 }
76 Ok(unsafe { ComPtr::from_raw(obj as *mut U) })
77 }
78 }
79 impl<T> Deref for ComPtr<T>
80 where
81 T: Interface,
82 {
83 type Target = T;
84 fn deref(&self) -> &T {
85 unsafe { &*self.0 }
86 }
87 }
88 impl<T> Clone for ComPtr<T>
89 where
90 T: Interface,
91 {
92 fn clone(&self) -> Self {
93 unsafe {
94 self.as_unknown().AddRef();
95 ComPtr::from_raw(self.0)
96 }
97 }
98 }
99 impl<T> Drop for ComPtr<T>
100 where
101 T: Interface,
102 {
103 fn drop(&mut self) {
104 unsafe {
105 self.as_unknown().Release();
106 }
107 }
108 }
109 pub struct BStr(BSTR);
110 impl BStr {
111 pub unsafe fn from_raw(s: BSTR) -> BStr {
112 BStr(s)
113 }
114 pub fn to_osstring(&self) -> OsString {
115 let len = unsafe { SysStringLen(self.0) };
116 let slice = unsafe { from_raw_parts(self.0, len as usize) };
117 OsStringExt::from_wide(slice)
118 }
119 }
120 impl Drop for BStr {
121 fn drop(&mut self) {
122 unsafe { SysFreeString(self.0) };
123 }
124 }
125
126 pub trait ToWide {
127 fn to_wide(&self) -> Vec<u16>;
128 fn to_wide_null(&self) -> Vec<u16>;
129 }
130 impl<T> ToWide for T
131 where
132 T: AsRef<OsStr>,
133 {
134 fn to_wide(&self) -> Vec<u16> {
135 self.as_ref().encode_wide().collect()
136 }
137 fn to_wide_null(&self) -> Vec<u16> {
138 self.as_ref().encode_wide().chain(Some(0)).collect()
139 }
140 }
141 pub trait FromWide
142 where
143 Self: Sized,
144 {
145 fn from_wide(wide: &[u16]) -> Self;
146 fn from_wide_null(wide: &[u16]) -> Self {
147 let len = wide.iter().take_while(|&&c| c != 0).count();
148 Self::from_wide(&wide[..len])
149 }
150 }
151 impl FromWide for OsString {
152 fn from_wide(wide: &[u16]) -> OsString {
153 OsStringExt::from_wide(wide)
154 }
155 }