gio/auto/resource.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, InputStream, ResourceLookupFlags};
6use glib::translate::*;
7
8glib::wrapper! {
9 /// Applications and libraries often contain binary or textual data that is
10 /// really part of the application, rather than user data. For instance
11 /// [`GtkBuilder`](https://docs.gtk.org/gtk4/class.Builder.html) `.ui` files,
12 /// splashscreen images, [`Menu`][crate::Menu] markup XML, CSS files, icons, etc.
13 /// These are often shipped as files in `$datadir/appname`, or manually
14 /// included as literal strings in the code.
15 ///
16 /// The `GResource` API and the
17 /// [`glib-compile-resources`](glib-compile-resources.html) program provide a
18 /// convenient and efficient alternative to this which has some nice properties.
19 /// You maintain the files as normal files, so it’s easy to edit them, but during
20 /// the build the files are combined into a binary bundle that is linked into the
21 /// executable. This means that loading the resource files are efficient (as they
22 /// are already in memory, shared with other instances) and simple (no need to
23 /// check for things like I/O errors or locate the files in the filesystem). It
24 /// also makes it easier to create relocatable applications.
25 ///
26 /// Resource files can also be marked as compressed. Such files will be included
27 /// in the resource bundle in a compressed form, but will be automatically
28 /// uncompressed when the resource is used. This is very useful e.g. for larger
29 /// text files that are parsed once (or rarely) and then thrown away.
30 ///
31 /// Resource files can also be marked to be preprocessed, by setting the value of the
32 /// `preprocess` attribute to a comma-separated list of preprocessing options.
33 /// The only options currently supported are:
34 ///
35 /// - `xml-stripblanks` which will use the [`xmllint`](man:xmllint(1)) command
36 /// to strip ignorable whitespace from the XML file. For this to work,
37 /// the `XMLLINT` environment variable must be set to the full path to
38 /// the xmllint executable, or xmllint must be in the `PATH`; otherwise
39 /// the preprocessing step is skipped.
40 ///
41 /// - `to-pixdata` (deprecated since gdk-pixbuf 2.32) which will use the
42 /// `gdk-pixbuf-pixdata` command to convert images to the [`GdkPixdata`](https://docs.gtk.org/gdk-pixbuf/class.Pixdata.html)
43 /// format, which allows you to create pixbufs directly using the data inside
44 /// the resource file, rather than an (uncompressed) copy of it. For this, the
45 /// `gdk-pixbuf-pixdata` program must be in the `PATH`, or the
46 /// `GDK_PIXBUF_PIXDATA` environment variable must be set to the full path to
47 /// the `gdk-pixbuf-pixdata` executable; otherwise the resource compiler will
48 /// abort. `to-pixdata` has been deprecated since gdk-pixbuf 2.32, as
49 /// `GResource` supports embedding modern image formats just as well. Instead
50 /// of using it, embed a PNG or SVG file in your `GResource`.
51 ///
52 /// - `json-stripblanks` which will use the
53 /// [`json-glib-format`](man:json-glib-format(1)) command to strip ignorable
54 /// whitespace from the JSON file. For this to work, the `JSON_GLIB_FORMAT`
55 /// environment variable must be set to the full path to the
56 /// `json-glib-format` executable, or it must be in the `PATH`; otherwise the
57 /// preprocessing step is skipped. In addition, at least version 1.6 of
58 /// `json-glib-format` is required.
59 ///
60 /// Resource files will be exported in the `GResource` namespace using the
61 /// combination of the given `prefix` and the filename from the `file` element.
62 /// The `alias` attribute can be used to alter the filename to expose them at a
63 /// different location in the resource namespace. Typically, this is used to
64 /// include files from a different source directory without exposing the source
65 /// directory in the resource namespace, as in the example below.
66 ///
67 /// Resource bundles are created by the
68 /// [`glib-compile-resources`](glib-compile-resources.html) program
69 /// which takes an XML file that describes the bundle, and a set of files that
70 /// the XML references. These are combined into a binary resource bundle.
71 ///
72 /// An example resource description:
73 /// ```xml
74 /// <?xml version="1.0" encoding="UTF-8"?>
75 /// <gresources>
76 /// <gresource prefix="/org/gtk/Example">
77 /// <file>data/splashscreen.png</file>
78 /// <file compressed="true">dialog.ui</file>
79 /// <file preprocess="xml-stripblanks">menumarkup.xml</file>
80 /// <file alias="example.css">data/example.css</file>
81 /// </gresource>
82 /// </gresources>
83 /// ```
84 ///
85 /// This will create a resource bundle with the following files:
86 /// ```text
87 /// /org/gtk/Example/data/splashscreen.png
88 /// /org/gtk/Example/dialog.ui
89 /// /org/gtk/Example/menumarkup.xml
90 /// /org/gtk/Example/example.css
91 /// ```
92 ///
93 /// Note that all resources in the process share the same namespace, so use
94 /// Java-style path prefixes (like in the above example) to avoid conflicts.
95 ///
96 /// You can then use [`glib-compile-resources`](glib-compile-resources.html) to
97 /// compile the XML to a binary bundle that you can load with
98 /// [`load()`][Self::load()]. However, it’s more common to use the
99 /// `--generate-source` and `--generate-header` arguments to create a source file
100 /// and header to link directly into your application.
101 /// This will generate `get_resource()`, `register_resource()` and
102 /// `unregister_resource()` functions, prefixed by the `--c-name` argument passed
103 /// to [`glib-compile-resources`](glib-compile-resources.html). `get_resource()`
104 /// returns the generated `GResource` object. The register and unregister
105 /// functions register the resource so its files can be accessed using
106 /// [`resources_lookup_data()`][crate::resources_lookup_data()].
107 ///
108 /// Once a `GResource` has been created and registered all the data in it can be
109 /// accessed globally in the process by using API calls like
110 /// [`resources_open_stream()`][crate::resources_open_stream()] to stream the data or
111 /// [`resources_lookup_data()`][crate::resources_lookup_data()] to get a direct pointer to the data. You can
112 /// also use URIs like `resource:///org/gtk/Example/data/splashscreen.png` with
113 /// [`File`][crate::File] to access the resource data.
114 ///
115 /// Some higher-level APIs, such as [`GtkApplication`](https://docs.gtk.org/gtk4/class.Application.html),
116 /// will automatically load resources from certain well-known paths in the
117 /// resource namespace as a convenience. See the documentation for those APIs
118 /// for details.
119 ///
120 /// There are two forms of the generated source, the default version uses the
121 /// compiler support for constructor and destructor functions (where available)
122 /// to automatically create and register the `GResource` on startup or library
123 /// load time. If you pass `--manual-register`, two functions to
124 /// register/unregister the resource are created instead. This requires an
125 /// explicit initialization call in your application/library, but it works on all
126 /// platforms, even on the minor ones where constructors are not supported.
127 /// (Constructor support is available for at least Win32, Mac OS and Linux.)
128 ///
129 /// Note that resource data can point directly into the data segment of e.g. a
130 /// library, so if you are unloading libraries during runtime you need to be very
131 /// careful with keeping around pointers to data from a resource, as this goes
132 /// away when the library is unloaded. However, in practice this is not generally
133 /// a problem, since most resource accesses are for your own resources, and
134 /// resource data is often used once, during parsing, and then released.
135 ///
136 /// # Overlays
137 ///
138 /// When debugging a program or testing a change to an installed version, it is
139 /// often useful to be able to replace resources in the program or library,
140 /// without recompiling, for debugging or quick hacking and testing purposes.
141 /// Since GLib 2.50, it is possible to use the `G_RESOURCE_OVERLAYS` environment
142 /// variable to selectively overlay resources with replacements from the
143 /// filesystem. It is a `G_SEARCHPATH_SEPARATOR`-separated list of substitutions
144 /// to perform during resource lookups. It is ignored when running in a setuid
145 /// process.
146 ///
147 /// A substitution has the form
148 ///
149 /// ```text
150 /// /org/gtk/libgtk=/home/desrt/gtk-overlay
151 /// ```
152 ///
153 /// The part before the `=` is the resource subpath for which the overlay
154 /// applies. The part after is a filesystem path which contains files and
155 /// subdirectories as you would like to be loaded as resources with the
156 /// equivalent names.
157 ///
158 /// In the example above, if an application tried to load a resource with the
159 /// resource path `/org/gtk/libgtk/ui/gtkdialog.ui` then `GResource` would check
160 /// the filesystem path `/home/desrt/gtk-overlay/ui/gtkdialog.ui`. If a file was
161 /// found there, it would be used instead. This is an overlay, not an outright
162 /// replacement, which means that if a file is not found at that path, the
163 /// built-in version will be used instead. Whiteouts are not currently
164 /// supported.
165 ///
166 /// Substitutions must start with a slash, and must not contain a trailing slash
167 /// before the `=`. The path after the slash should ideally be absolute, but
168 /// this is not strictly required. It is possible to overlay the location of a
169 /// single resource with an individual file.
170 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
171 pub struct Resource(Shared<ffi::GResource>);
172
173 match fn {
174 ref => |ptr| ffi::g_resource_ref(ptr),
175 unref => |ptr| ffi::g_resource_unref(ptr),
176 type_ => || ffi::g_resource_get_type(),
177 }
178}
179
180impl Resource {
181 /// Returns all the names of children at the specified @path in the resource.
182 ///
183 /// The return result is a `NULL` terminated list of strings which should
184 /// be released with `strfreev()`.
185 ///
186 /// If @path is invalid or does not exist in the [`Resource`][crate::Resource],
187 /// [`ResourceError::NotFound`][crate::ResourceError::NotFound] will be returned.
188 ///
189 /// @lookup_flags controls the behaviour of the lookup.
190 /// ## `path`
191 /// A path name inside the resource
192 /// ## `lookup_flags`
193 /// A [`ResourceLookupFlags`][crate::ResourceLookupFlags]
194 ///
195 /// # Returns
196 ///
197 /// an array of constant strings
198 #[doc(alias = "g_resource_enumerate_children")]
199 pub fn enumerate_children(
200 &self,
201 path: &str,
202 lookup_flags: ResourceLookupFlags,
203 ) -> Result<Vec<glib::GString>, glib::Error> {
204 unsafe {
205 let mut error = std::ptr::null_mut();
206 let ret = ffi::g_resource_enumerate_children(
207 self.to_glib_none().0,
208 path.to_glib_none().0,
209 lookup_flags.into_glib(),
210 &mut error,
211 );
212 if error.is_null() {
213 Ok(FromGlibPtrContainer::from_glib_full(ret))
214 } else {
215 Err(from_glib_full(error))
216 }
217 }
218 }
219
220 /// Looks for a file at the specified @path in the resource and
221 /// if found returns information about it.
222 ///
223 /// @lookup_flags controls the behaviour of the lookup.
224 ///
225 /// The only error this can return is [`ResourceError::NotFound`][crate::ResourceError::NotFound], if @path was
226 /// not found in @self.
227 /// ## `path`
228 /// A path name inside the resource
229 /// ## `lookup_flags`
230 /// A [`ResourceLookupFlags`][crate::ResourceLookupFlags]
231 ///
232 /// # Returns
233 ///
234 /// `TRUE` if the file was found, `FALSE` if there were errors
235 ///
236 /// ## `size`
237 /// a location to place the length of the contents of the file,
238 /// or `NULL` if the length is not needed
239 ///
240 /// ## `flags`
241 /// a location to place the flags about the file,
242 /// or `NULL` if the length is not needed
243 #[doc(alias = "g_resource_get_info")]
244 #[doc(alias = "get_info")]
245 pub fn info(
246 &self,
247 path: &str,
248 lookup_flags: ResourceLookupFlags,
249 ) -> Result<(usize, u32), glib::Error> {
250 unsafe {
251 let mut size = std::mem::MaybeUninit::uninit();
252 let mut flags = std::mem::MaybeUninit::uninit();
253 let mut error = std::ptr::null_mut();
254 let is_ok = ffi::g_resource_get_info(
255 self.to_glib_none().0,
256 path.to_glib_none().0,
257 lookup_flags.into_glib(),
258 size.as_mut_ptr(),
259 flags.as_mut_ptr(),
260 &mut error,
261 );
262 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
263 if error.is_null() {
264 Ok((size.assume_init(), flags.assume_init()))
265 } else {
266 Err(from_glib_full(error))
267 }
268 }
269 }
270
271 /// Returns whether the specified @path in the resource
272 /// has children.
273 /// ## `path`
274 /// A pathname inside the resource
275 ///
276 /// # Returns
277 ///
278 /// [`true`] if @path has children
279 #[cfg(feature = "v2_84")]
280 #[cfg_attr(docsrs, doc(cfg(feature = "v2_84")))]
281 #[doc(alias = "g_resource_has_children")]
282 pub fn has_children(&self, path: &str) -> bool {
283 unsafe {
284 from_glib(ffi::g_resource_has_children(
285 self.to_glib_none().0,
286 path.to_glib_none().0,
287 ))
288 }
289 }
290
291 /// Looks for a file at the specified @path in the resource and
292 /// returns a [`glib::Bytes`][crate::glib::Bytes] that lets you directly access the data in
293 /// memory.
294 ///
295 /// The data is always followed by a zero byte, so you
296 /// can safely use the data as a C string. However, that byte
297 /// is not included in the size of the [`glib::Bytes`][crate::glib::Bytes].
298 ///
299 /// For uncompressed resource files this is a pointer directly into
300 /// the resource bundle, which is typically in some read-only data section
301 /// in the program binary. For compressed files, memory is allocated on
302 /// the heap and the data is automatically uncompressed.
303 ///
304 /// @lookup_flags controls the behaviour of the lookup.
305 ///
306 /// This can return error [`ResourceError::NotFound`][crate::ResourceError::NotFound] if @path was not found in
307 /// @self, or [`ResourceError::Internal`][crate::ResourceError::Internal] if decompression of a compressed
308 /// resource failed.
309 /// ## `path`
310 /// A path name inside the resource
311 /// ## `lookup_flags`
312 /// A [`ResourceLookupFlags`][crate::ResourceLookupFlags]
313 ///
314 /// # Returns
315 ///
316 /// [`glib::Bytes`][crate::glib::Bytes] or `NULL` on error
317 #[doc(alias = "g_resource_lookup_data")]
318 pub fn lookup_data(
319 &self,
320 path: &str,
321 lookup_flags: ResourceLookupFlags,
322 ) -> Result<glib::Bytes, glib::Error> {
323 unsafe {
324 let mut error = std::ptr::null_mut();
325 let ret = ffi::g_resource_lookup_data(
326 self.to_glib_none().0,
327 path.to_glib_none().0,
328 lookup_flags.into_glib(),
329 &mut error,
330 );
331 if error.is_null() {
332 Ok(from_glib_full(ret))
333 } else {
334 Err(from_glib_full(error))
335 }
336 }
337 }
338
339 /// Looks for a file at the specified @path in the resource and
340 /// returns a [`InputStream`][crate::InputStream] that lets you read the data.
341 ///
342 /// @lookup_flags controls the behaviour of the lookup.
343 ///
344 /// The only error this can return is [`ResourceError::NotFound`][crate::ResourceError::NotFound], if @path was
345 /// not found in @self.
346 /// ## `path`
347 /// A path name inside the resource
348 /// ## `lookup_flags`
349 /// A [`ResourceLookupFlags`][crate::ResourceLookupFlags]
350 ///
351 /// # Returns
352 ///
353 /// [`InputStream`][crate::InputStream] or `NULL` on error
354 #[doc(alias = "g_resource_open_stream")]
355 pub fn open_stream(
356 &self,
357 path: &str,
358 lookup_flags: ResourceLookupFlags,
359 ) -> Result<InputStream, glib::Error> {
360 unsafe {
361 let mut error = std::ptr::null_mut();
362 let ret = ffi::g_resource_open_stream(
363 self.to_glib_none().0,
364 path.to_glib_none().0,
365 lookup_flags.into_glib(),
366 &mut error,
367 );
368 if error.is_null() {
369 Ok(from_glib_full(ret))
370 } else {
371 Err(from_glib_full(error))
372 }
373 }
374 }
375
376 /// Loads a binary resource bundle and creates a [`Resource`][crate::Resource]
377 /// representation of it, allowing you to query it for data.
378 ///
379 /// If you want to use this resource in the global resource namespace you need
380 /// to register it with [`resources_register()`][crate::resources_register()].
381 ///
382 /// If @filename is empty or the data in it is corrupt,
383 /// [`ResourceError::Internal`][crate::ResourceError::Internal] will be returned. If @filename doesn’t exist, or
384 /// there is an error in reading it, an error from `GLib::MappedFile::new()`
385 /// will be returned.
386 /// ## `filename`
387 /// the path of a filename to load, in the GLib filename encoding
388 ///
389 /// # Returns
390 ///
391 /// a new [`Resource`][crate::Resource], or `NULL` on error
392 #[doc(alias = "g_resource_load")]
393 pub fn load(filename: impl AsRef<std::path::Path>) -> Result<Resource, glib::Error> {
394 unsafe {
395 let mut error = std::ptr::null_mut();
396 let ret = ffi::g_resource_load(filename.as_ref().to_glib_none().0, &mut error);
397 if error.is_null() {
398 Ok(from_glib_full(ret))
399 } else {
400 Err(from_glib_full(error))
401 }
402 }
403 }
404}