1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gio.Resource;
26 
27 private import gio.InputStream;
28 private import glib.Bytes;
29 private import glib.ConstructionException;
30 private import glib.ErrorG;
31 private import glib.GException;
32 private import glib.Str;
33 private import gobject.ObjectG;
34 private import gtkc.gio;
35 public  import gtkc.giotypes;
36 private import gtkd.Loader;
37 
38 
39 /**
40  * Applications and libraries often contain binary or textual data that is
41  * really part of the application, rather than user data. For instance
42  * #GtkBuilder .ui files, splashscreen images, GMenu markup XML, CSS files,
43  * icons, etc. These are often shipped as files in `$datadir/appname`, or
44  * manually included as literal strings in the code.
45  * 
46  * The #GResource API and the [glib-compile-resources][glib-compile-resources] program
47  * provide a convenient and efficient alternative to this which has some nice properties. You
48  * maintain the files as normal files, so its easy to edit them, but during the build the files
49  * are combined into a binary bundle that is linked into the executable. This means that loading
50  * the resource files are efficient (as they are already in memory, shared with other instances) and
51  * simple (no need to check for things like I/O errors or locate the files in the filesystem). It
52  * also makes it easier to create relocatable applications.
53  * 
54  * Resource files can also be marked as compressed. Such files will be included in the resource bundle
55  * in a compressed form, but will be automatically uncompressed when the resource is used. This
56  * is very useful e.g. for larger text files that are parsed once (or rarely) and then thrown away.
57  * 
58  * Resource files can also be marked to be preprocessed, by setting the value of the
59  * `preprocess` attribute to a comma-separated list of preprocessing options.
60  * The only options currently supported are:
61  * 
62  * `xml-stripblanks` which will use the xmllint command
63  * to strip ignorable whitespace from the XML file. For this to work,
64  * the `XMLLINT` environment variable must be set to the full path to
65  * the xmllint executable, or xmllint must be in the `PATH`; otherwise
66  * the preprocessing step is skipped.
67  * 
68  * `to-pixdata` which will use the gdk-pixbuf-pixdata command to convert
69  * images to the GdkPixdata format, which allows you to create pixbufs directly using the data inside
70  * the resource file, rather than an (uncompressed) copy if it. For this, the gdk-pixbuf-pixdata
71  * program must be in the PATH, or the `GDK_PIXBUF_PIXDATA` environment variable must be
72  * set to the full path to the gdk-pixbuf-pixdata executable; otherwise the resource compiler will
73  * abort.
74  * 
75  * Resource bundles are created by the [glib-compile-resources][glib-compile-resources] program
76  * which takes an XML file that describes the bundle, and a set of files that the XML references. These
77  * are combined into a binary resource bundle.
78  * 
79  * An example resource description:
80  * |[
81  * <?xml version="1.0" encoding="UTF-8"?>
82  * <gresources>
83  * <gresource prefix="/org/gtk/Example">
84  * <file>data/splashscreen.png</file>
85  * <file compressed="true">dialog.ui</file>
86  * <file preprocess="xml-stripblanks">menumarkup.xml</file>
87  * </gresource>
88  * </gresources>
89  * ]|
90  * 
91  * This will create a resource bundle with the following files:
92  * |[
93  * /org/gtk/Example/data/splashscreen.png
94  * /org/gtk/Example/dialog.ui
95  * /org/gtk/Example/menumarkup.xml
96  * ]|
97  * 
98  * Note that all resources in the process share the same namespace, so use Java-style
99  * path prefixes (like in the above example) to avoid conflicts.
100  * 
101  * You can then use [glib-compile-resources][glib-compile-resources] to compile the XML to a
102  * binary bundle that you can load with g_resource_load(). However, its more common to use the --generate-source and
103  * --generate-header arguments to create a source file and header to link directly into your application.
104  * This will generate `get_resource()`, `register_resource()` and
105  * `unregister_resource()` functions, prefixed by the `--c-name` argument passed
106  * to [glib-compile-resources][glib-compile-resources]. `get_resource()` returns
107  * the generated #GResource object. The register and unregister functions
108  * register the resource so its files can be accessed using
109  * g_resources_lookup_data().
110  * 
111  * Once a #GResource has been created and registered all the data in it can be accessed globally in the process by
112  * using API calls like g_resources_open_stream() to stream the data or g_resources_lookup_data() to get a direct pointer
113  * to the data. You can also use URIs like "resource:///org/gtk/Example/data/splashscreen.png" with #GFile to access
114  * the resource data.
115  * 
116  * There are two forms of the generated source, the default version uses the compiler support for constructor
117  * and destructor functions (where available) to automatically create and register the #GResource on startup
118  * or library load time. If you pass --manual-register two functions to register/unregister the resource is instead
119  * created. This requires an explicit initialization call in your application/library, but it works on all platforms,
120  * even on the minor ones where this is not available. (Constructor support is available for at least Win32, Mac OS and Linux.)
121  * 
122  * Note that resource data can point directly into the data segment of e.g. a library, so if you are unloading libraries
123  * during runtime you need to be very careful with keeping around pointers to data from a resource, as this goes away
124  * when the library is unloaded. However, in practice this is not generally a problem, since most resource accesses
125  * is for your own resources, and resource data is often used once, during parsing, and then released.
126  * 
127  * When debugging a program or testing a change to an installed version, it is often useful to be able to
128  * replace resources in the program or library, without recompiling, for debugging or quick hacking and testing
129  * purposes.
130  * 
131  * Since GLib 2.50, it is possible to use the `G_RESOURCE_OVERLAYS` environment variable to selectively overlay
132  * resources with replacements from the filesystem.  It is a colon-separated list of substitutions to perform
133  * during resource lookups.
134  * 
135  * A substitution has the form
136  * 
137  * |[
138  * /org/gtk/libgtk=/home/desrt/gtk-overlay
139  * ]|
140  * 
141  * The part before the `=` is the resource subpath for which the overlay applies.  The part after is a
142  * filesystem path which contains files and subdirectories as you would like to be loaded as resources with the
143  * equivalent names.
144  * 
145  * In the example above, if an application tried to load a resource with the resource path
146  * `/org/gtk/libgtk/ui/gtkdialog.ui` then GResource would check the filesystem path
147  * `/home/desrt/gtk-overlay/ui/gtkdialog.ui`.  If a file was found there, it would be used instead.  This is an
148  * overlay, not an outright replacement, which means that if a file is not found at that path, the built-in
149  * version will be used instead.  Whiteouts are not currently supported.
150  * 
151  * Substitutions must start with a slash, and must not contain a trailing slash before the '='.  The path after
152  * the slash should ideally be absolute, but this is not strictly required.  It is possible to overlay the
153  * location of a single resource with an individual file.
154  *
155  * Since: 2.32
156  */
157 public class Resource
158 {
159 	/** the main Gtk struct */
160 	protected GResource* gResource;
161 	protected bool ownedRef;
162 
163 	/** Get the main Gtk struct */
164 	public GResource* getResourceStruct(bool transferOwnership = false)
165 	{
166 		if (transferOwnership)
167 			ownedRef = false;
168 		return gResource;
169 	}
170 
171 	/** the main Gtk struct as a void* */
172 	protected void* getStruct()
173 	{
174 		return cast(void*)gResource;
175 	}
176 
177 	/**
178 	 * Sets our main struct and passes it to the parent class.
179 	 */
180 	public this (GResource* gResource, bool ownedRef = false)
181 	{
182 		this.gResource = gResource;
183 		this.ownedRef = ownedRef;
184 	}
185 
186 	~this ()
187 	{
188 		if (  Linker.isLoaded(LIBRARY_GIO) && ownedRef )
189 			g_resource_unref(gResource);
190 	}
191 
192 
193 	/** */
194 	public static GType getType()
195 	{
196 		return g_resource_get_type();
197 	}
198 
199 	/**
200 	 * Creates a GResource from a reference to the binary resource bundle.
201 	 * This will keep a reference to @data while the resource lives, so
202 	 * the data should not be modified or freed.
203 	 *
204 	 * If you want to use this resource in the global resource namespace you need
205 	 * to register it with g_resources_register().
206 	 *
207 	 * Params:
208 	 *     data = A #GBytes
209 	 *
210 	 * Returns: a new #GResource, or %NULL on error
211 	 *
212 	 * Since: 2.32
213 	 *
214 	 * Throws: GException on failure.
215 	 * Throws: ConstructionException GTK+ fails to create the object.
216 	 */
217 	public this(Bytes data)
218 	{
219 		GError* err = null;
220 		
221 		auto p = g_resource_new_from_data((data is null) ? null : data.getBytesStruct(), &err);
222 		
223 		if (err !is null)
224 		{
225 			throw new GException( new ErrorG(err) );
226 		}
227 		
228 		if(p is null)
229 		{
230 			throw new ConstructionException("null returned by new_from_data");
231 		}
232 		
233 		this(cast(GResource*) p);
234 	}
235 
236 	/**
237 	 * Registers the resource with the process-global set of resources.
238 	 * Once a resource is registered the files in it can be accessed
239 	 * with the global resource lookup functions like g_resources_lookup_data().
240 	 *
241 	 * Params:
242 	 *     resource = A #GResource
243 	 *
244 	 * Since: 2.32
245 	 */
246 	public static void register(Resource resource)
247 	{
248 		g_resources_register((resource is null) ? null : resource.getResourceStruct());
249 	}
250 
251 	/**
252 	 * Unregisters the resource from the process-global set of resources.
253 	 *
254 	 * Params:
255 	 *     resource = A #GResource
256 	 *
257 	 * Since: 2.32
258 	 */
259 	public static void unregister(Resource resource)
260 	{
261 		g_resources_unregister((resource is null) ? null : resource.getResourceStruct());
262 	}
263 
264 	/**
265 	 * Returns all the names of children at the specified @path in the resource.
266 	 * The return result is a %NULL terminated list of strings which should
267 	 * be released with g_strfreev().
268 	 *
269 	 * If @path is invalid or does not exist in the #GResource,
270 	 * %G_RESOURCE_ERROR_NOT_FOUND will be returned.
271 	 *
272 	 * @lookup_flags controls the behaviour of the lookup.
273 	 *
274 	 * Params:
275 	 *     path = A pathname inside the resource
276 	 *     lookupFlags = A #GResourceLookupFlags
277 	 *
278 	 * Returns: an array of constant strings
279 	 *
280 	 * Since: 2.32
281 	 *
282 	 * Throws: GException on failure.
283 	 */
284 	public string[] enumerateChildren(string path, GResourceLookupFlags lookupFlags)
285 	{
286 		GError* err = null;
287 		
288 		auto retStr = g_resource_enumerate_children(gResource, Str.toStringz(path), lookupFlags, &err);
289 		
290 		if (err !is null)
291 		{
292 			throw new GException( new ErrorG(err) );
293 		}
294 		
295 		scope(exit) Str.freeStringArray(retStr);
296 		return Str.toStringArray(retStr);
297 	}
298 
299 	/**
300 	 * Looks for a file at the specified @path in the resource and
301 	 * if found returns information about it.
302 	 *
303 	 * @lookup_flags controls the behaviour of the lookup.
304 	 *
305 	 * Params:
306 	 *     path = A pathname inside the resource
307 	 *     lookupFlags = A #GResourceLookupFlags
308 	 *     size = a location to place the length of the contents of the file,
309 	 *         or %NULL if the length is not needed
310 	 *     flags = a location to place the flags about the file,
311 	 *         or %NULL if the length is not needed
312 	 *
313 	 * Returns: %TRUE if the file was found. %FALSE if there were errors
314 	 *
315 	 * Since: 2.32
316 	 *
317 	 * Throws: GException on failure.
318 	 */
319 	public bool getInfo(string path, GResourceLookupFlags lookupFlags, out size_t size, out uint flags)
320 	{
321 		GError* err = null;
322 		
323 		auto p = g_resource_get_info(gResource, Str.toStringz(path), lookupFlags, &size, &flags, &err) != 0;
324 		
325 		if (err !is null)
326 		{
327 			throw new GException( new ErrorG(err) );
328 		}
329 		
330 		return p;
331 	}
332 
333 	/**
334 	 * Looks for a file at the specified @path in the resource and
335 	 * returns a #GBytes that lets you directly access the data in
336 	 * memory.
337 	 *
338 	 * The data is always followed by a zero byte, so you
339 	 * can safely use the data as a C string. However, that byte
340 	 * is not included in the size of the GBytes.
341 	 *
342 	 * For uncompressed resource files this is a pointer directly into
343 	 * the resource bundle, which is typically in some readonly data section
344 	 * in the program binary. For compressed files we allocate memory on
345 	 * the heap and automatically uncompress the data.
346 	 *
347 	 * @lookup_flags controls the behaviour of the lookup.
348 	 *
349 	 * Params:
350 	 *     path = A pathname inside the resource
351 	 *     lookupFlags = A #GResourceLookupFlags
352 	 *
353 	 * Returns: #GBytes or %NULL on error.
354 	 *     Free the returned object with g_bytes_unref()
355 	 *
356 	 * Since: 2.32
357 	 *
358 	 * Throws: GException on failure.
359 	 */
360 	public Bytes lookupData(string path, GResourceLookupFlags lookupFlags)
361 	{
362 		GError* err = null;
363 		
364 		auto p = g_resource_lookup_data(gResource, Str.toStringz(path), lookupFlags, &err);
365 		
366 		if (err !is null)
367 		{
368 			throw new GException( new ErrorG(err) );
369 		}
370 		
371 		if(p is null)
372 		{
373 			return null;
374 		}
375 		
376 		return new Bytes(cast(GBytes*) p, true);
377 	}
378 
379 	/**
380 	 * Looks for a file at the specified @path in the resource and
381 	 * returns a #GInputStream that lets you read the data.
382 	 *
383 	 * @lookup_flags controls the behaviour of the lookup.
384 	 *
385 	 * Params:
386 	 *     path = A pathname inside the resource
387 	 *     lookupFlags = A #GResourceLookupFlags
388 	 *
389 	 * Returns: #GInputStream or %NULL on error.
390 	 *     Free the returned object with g_object_unref()
391 	 *
392 	 * Since: 2.32
393 	 *
394 	 * Throws: GException on failure.
395 	 */
396 	public InputStream openStream(string path, GResourceLookupFlags lookupFlags)
397 	{
398 		GError* err = null;
399 		
400 		auto p = g_resource_open_stream(gResource, Str.toStringz(path), lookupFlags, &err);
401 		
402 		if (err !is null)
403 		{
404 			throw new GException( new ErrorG(err) );
405 		}
406 		
407 		if(p is null)
408 		{
409 			return null;
410 		}
411 		
412 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p, true);
413 	}
414 
415 	/**
416 	 * Atomically increments the reference count of @resource by one. This
417 	 * function is MT-safe and may be called from any thread.
418 	 *
419 	 * Returns: The passed in #GResource
420 	 *
421 	 * Since: 2.32
422 	 */
423 	public Resource doref()
424 	{
425 		auto p = g_resource_ref(gResource);
426 		
427 		if(p is null)
428 		{
429 			return null;
430 		}
431 		
432 		return ObjectG.getDObject!(Resource)(cast(GResource*) p, true);
433 	}
434 
435 	/**
436 	 * Atomically decrements the reference count of @resource by one. If the
437 	 * reference count drops to 0, all memory allocated by the resource is
438 	 * released. This function is MT-safe and may be called from any
439 	 * thread.
440 	 *
441 	 * Since: 2.32
442 	 */
443 	public void unref()
444 	{
445 		g_resource_unref(gResource);
446 	}
447 
448 	/**
449 	 * Loads a binary resource bundle and creates a #GResource representation of it, allowing
450 	 * you to query it for data.
451 	 *
452 	 * If you want to use this resource in the global resource namespace you need
453 	 * to register it with g_resources_register().
454 	 *
455 	 * Params:
456 	 *     filename = the path of a filename to load, in the GLib filename encoding
457 	 *
458 	 * Returns: a new #GResource, or %NULL on error
459 	 *
460 	 * Since: 2.32
461 	 *
462 	 * Throws: GException on failure.
463 	 */
464 	public static Resource load(string filename)
465 	{
466 		GError* err = null;
467 		
468 		auto p = g_resource_load(Str.toStringz(filename), &err);
469 		
470 		if (err !is null)
471 		{
472 			throw new GException( new ErrorG(err) );
473 		}
474 		
475 		if(p is null)
476 		{
477 			return null;
478 		}
479 		
480 		return ObjectG.getDObject!(Resource)(cast(GResource*) p, true);
481 	}
482 
483 	/**
484 	 * Returns all the names of children at the specified @path in the set of
485 	 * globally registered resources.
486 	 * The return result is a %NULL terminated list of strings which should
487 	 * be released with g_strfreev().
488 	 *
489 	 * @lookup_flags controls the behaviour of the lookup.
490 	 *
491 	 * Params:
492 	 *     path = A pathname inside the resource
493 	 *     lookupFlags = A #GResourceLookupFlags
494 	 *
495 	 * Returns: an array of constant strings
496 	 *
497 	 * Since: 2.32
498 	 *
499 	 * Throws: GException on failure.
500 	 */
501 	public static string[] resourcesEnumerateChildren(string path, GResourceLookupFlags lookupFlags)
502 	{
503 		GError* err = null;
504 		
505 		auto retStr = g_resources_enumerate_children(Str.toStringz(path), lookupFlags, &err);
506 		
507 		if (err !is null)
508 		{
509 			throw new GException( new ErrorG(err) );
510 		}
511 		
512 		scope(exit) Str.freeStringArray(retStr);
513 		return Str.toStringArray(retStr);
514 	}
515 
516 	/**
517 	 * Looks for a file at the specified @path in the set of
518 	 * globally registered resources and if found returns information about it.
519 	 *
520 	 * @lookup_flags controls the behaviour of the lookup.
521 	 *
522 	 * Params:
523 	 *     path = A pathname inside the resource
524 	 *     lookupFlags = A #GResourceLookupFlags
525 	 *     size = a location to place the length of the contents of the file,
526 	 *         or %NULL if the length is not needed
527 	 *     flags = a location to place the flags about the file,
528 	 *         or %NULL if the length is not needed
529 	 *
530 	 * Returns: %TRUE if the file was found. %FALSE if there were errors
531 	 *
532 	 * Since: 2.32
533 	 *
534 	 * Throws: GException on failure.
535 	 */
536 	public static bool resourcesGetInfo(string path, GResourceLookupFlags lookupFlags, out size_t size, out uint flags)
537 	{
538 		GError* err = null;
539 		
540 		auto p = g_resources_get_info(Str.toStringz(path), lookupFlags, &size, &flags, &err) != 0;
541 		
542 		if (err !is null)
543 		{
544 			throw new GException( new ErrorG(err) );
545 		}
546 		
547 		return p;
548 	}
549 
550 	/**
551 	 * Looks for a file at the specified @path in the set of
552 	 * globally registered resources and returns a #GBytes that
553 	 * lets you directly access the data in memory.
554 	 *
555 	 * The data is always followed by a zero byte, so you
556 	 * can safely use the data as a C string. However, that byte
557 	 * is not included in the size of the GBytes.
558 	 *
559 	 * For uncompressed resource files this is a pointer directly into
560 	 * the resource bundle, which is typically in some readonly data section
561 	 * in the program binary. For compressed files we allocate memory on
562 	 * the heap and automatically uncompress the data.
563 	 *
564 	 * @lookup_flags controls the behaviour of the lookup.
565 	 *
566 	 * Params:
567 	 *     path = A pathname inside the resource
568 	 *     lookupFlags = A #GResourceLookupFlags
569 	 *
570 	 * Returns: #GBytes or %NULL on error.
571 	 *     Free the returned object with g_bytes_unref()
572 	 *
573 	 * Since: 2.32
574 	 *
575 	 * Throws: GException on failure.
576 	 */
577 	public static Bytes resourcesLookupData(string path, GResourceLookupFlags lookupFlags)
578 	{
579 		GError* err = null;
580 		
581 		auto p = g_resources_lookup_data(Str.toStringz(path), lookupFlags, &err);
582 		
583 		if (err !is null)
584 		{
585 			throw new GException( new ErrorG(err) );
586 		}
587 		
588 		if(p is null)
589 		{
590 			return null;
591 		}
592 		
593 		return new Bytes(cast(GBytes*) p, true);
594 	}
595 
596 	/**
597 	 * Looks for a file at the specified @path in the set of
598 	 * globally registered resources and returns a #GInputStream
599 	 * that lets you read the data.
600 	 *
601 	 * @lookup_flags controls the behaviour of the lookup.
602 	 *
603 	 * Params:
604 	 *     path = A pathname inside the resource
605 	 *     lookupFlags = A #GResourceLookupFlags
606 	 *
607 	 * Returns: #GInputStream or %NULL on error.
608 	 *     Free the returned object with g_object_unref()
609 	 *
610 	 * Since: 2.32
611 	 *
612 	 * Throws: GException on failure.
613 	 */
614 	public static InputStream resourcesOpenStream(string path, GResourceLookupFlags lookupFlags)
615 	{
616 		GError* err = null;
617 		
618 		auto p = g_resources_open_stream(Str.toStringz(path), lookupFlags, &err);
619 		
620 		if (err !is null)
621 		{
622 			throw new GException( new ErrorG(err) );
623 		}
624 		
625 		if(p is null)
626 		{
627 			return null;
628 		}
629 		
630 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p, true);
631 	}
632 }