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}