1 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 //! Core Foundation Bundle Type
11
12 use core_foundation_sys::base::kCFAllocatorDefault;
13 pub use core_foundation_sys::bundle::*;
14 use core_foundation_sys::url::kCFURLPOSIXPathStyle;
15 use std::path::PathBuf;
16
17 use base::{CFType, TCFType};
18 use url::CFURL;
19 use dictionary::CFDictionary;
20 use std::os::raw::c_void;
21 use string::CFString;
22
23 declare_TCFType!{
24 /// A Bundle type.
25 CFBundle, CFBundleRef
26 }
27 impl_TCFType!(CFBundle, CFBundleRef, CFBundleGetTypeID);
28
29 impl CFBundle {
new(bundleURL: CFURL) -> Option<CFBundle>30 pub fn new(bundleURL: CFURL) -> Option<CFBundle> {
31 unsafe {
32 let bundle_ref = CFBundleCreate(kCFAllocatorDefault, bundleURL.as_concrete_TypeRef());
33 if bundle_ref.is_null() {
34 None
35 } else {
36 Some(TCFType::wrap_under_create_rule(bundle_ref))
37 }
38 }
39 }
40
bundle_with_identifier(identifier: CFString) -> Option<CFBundle>41 pub fn bundle_with_identifier(identifier: CFString) -> Option<CFBundle> {
42 unsafe {
43 let bundle_ref = CFBundleGetBundleWithIdentifier(identifier.as_concrete_TypeRef());
44 if bundle_ref.is_null() {
45 None
46 } else {
47 Some(TCFType::wrap_under_get_rule(bundle_ref))
48 }
49 }
50 }
51
function_pointer_for_name(&self, function_name: CFString) -> *const c_void52 pub fn function_pointer_for_name(&self, function_name: CFString) -> *const c_void {
53 unsafe {
54 CFBundleGetFunctionPointerForName(self.as_concrete_TypeRef(),
55 function_name.as_concrete_TypeRef())
56 }
57 }
58
main_bundle() -> CFBundle59 pub fn main_bundle() -> CFBundle {
60 unsafe {
61 let bundle_ref = CFBundleGetMainBundle();
62 TCFType::wrap_under_get_rule(bundle_ref)
63 }
64 }
65
info_dictionary(&self) -> CFDictionary<CFString, CFType>66 pub fn info_dictionary(&self) -> CFDictionary<CFString, CFType> {
67 unsafe {
68 let info_dictionary = CFBundleGetInfoDictionary(self.0);
69 TCFType::wrap_under_get_rule(info_dictionary)
70 }
71 }
72
executable_url(&self) -> Option<CFURL>73 pub fn executable_url(&self) -> Option<CFURL> {
74 unsafe {
75 let exe_url = CFBundleCopyExecutableURL(self.0);
76 if exe_url.is_null() {
77 None
78 } else {
79 Some(TCFType::wrap_under_create_rule(exe_url))
80 }
81 }
82 }
83
84 /// Bundle's own location
bundle_url(&self) -> Option<CFURL>85 pub fn bundle_url(&self) -> Option<CFURL> {
86 unsafe {
87 let bundle_url = CFBundleCopyBundleURL(self.0);
88 if bundle_url.is_null() {
89 None
90 } else {
91 Some(TCFType::wrap_under_create_rule(bundle_url))
92 }
93 }
94 }
95
96 /// Bundle's own location
path(&self) -> Option<PathBuf>97 pub fn path(&self) -> Option<PathBuf> {
98 let url = self.bundle_url()?;
99 Some(PathBuf::from(url.get_file_system_path(kCFURLPOSIXPathStyle).to_string()))
100 }
101
private_frameworks_url(&self) -> Option<CFURL>102 pub fn private_frameworks_url(&self) -> Option<CFURL> {
103 unsafe {
104 let fw_url = CFBundleCopyPrivateFrameworksURL(self.0);
105 if fw_url.is_null() {
106 None
107 } else {
108 Some(TCFType::wrap_under_create_rule(fw_url))
109 }
110 }
111 }
112
shared_support_url(&self) -> Option<CFURL>113 pub fn shared_support_url(&self) -> Option<CFURL> {
114 unsafe {
115 let fw_url = CFBundleCopySharedSupportURL(self.0);
116 if fw_url.is_null() {
117 None
118 } else {
119 Some(TCFType::wrap_under_create_rule(fw_url))
120 }
121 }
122 }
123 }
124
125
126 #[test]
safari_executable_url()127 fn safari_executable_url() {
128 use string::CFString;
129 use url::{CFURL, kCFURLPOSIXPathStyle};
130
131 let cfstr_path = CFString::from_static_string("/Applications/Safari.app");
132 let cfurl_path = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true);
133 let cfurl_executable = CFBundle::new(cfurl_path)
134 .expect("Safari not present")
135 .executable_url();
136 assert!(cfurl_executable.is_some());
137 assert_eq!(cfurl_executable
138 .unwrap()
139 .absolute()
140 .get_file_system_path(kCFURLPOSIXPathStyle)
141 .to_string(),
142 "/Applications/Safari.app/Contents/MacOS/Safari");
143 }
144
145 #[test]
safari_private_frameworks_url()146 fn safari_private_frameworks_url() {
147 use string::CFString;
148 use url::{CFURL, kCFURLPOSIXPathStyle};
149
150 let cfstr_path = CFString::from_static_string("/Applications/Safari.app");
151 let cfurl_path = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true);
152 let cfurl_executable = CFBundle::new(cfurl_path)
153 .expect("Safari not present")
154 .private_frameworks_url();
155 assert!(cfurl_executable.is_some());
156 assert_eq!(cfurl_executable
157 .unwrap()
158 .absolute()
159 .get_file_system_path(kCFURLPOSIXPathStyle)
160 .to_string(),
161 "/Applications/Safari.app/Contents/Frameworks");
162 }
163
164 #[test]
non_existant_bundle()165 fn non_existant_bundle() {
166 use string::CFString;
167 use url::{CFURL, kCFURLPOSIXPathStyle};
168
169 let cfstr_path = CFString::from_static_string("/usr/local/foo");
170 let cfurl_path = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true);
171 assert!(CFBundle::new(cfurl_path).is_none());
172 }
173