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