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.Loader;
35 private import gtkc.gio;
36 public  import gtkc.giotypes;
37 private import gtkc.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  * Since: 2.32
129  */
130 public class Resource
131 {
132 	/** the main Gtk struct */
133 	protected GResource* gResource;
134 	protected bool ownedRef;
135 
136 	/** Get the main Gtk struct */
137 	public GResource* getResourceStruct()
138 	{
139 		return gResource;
140 	}
141 
142 	/** the main Gtk struct as a void* */
143 	protected void* getStruct()
144 	{
145 		return cast(void*)gResource;
146 	}
147 
148 	/**
149 	 * Sets our main struct and passes it to the parent class.
150 	 */
151 	public this (GResource* gResource, bool ownedRef = false)
152 	{
153 		this.gResource = gResource;
154 		this.ownedRef = ownedRef;
155 	}
156 
157 	~this()
158 	{
159 		if ( Linker.isLoaded(LIBRARY.GIO) && ownedRef )
160 		{
161 			g_resource_unref(gResource);
162 		}
163 	}
164 
165 	/**
166 	 */
167 
168 	/** */
169 	public static GType getType()
170 	{
171 		return g_resource_get_type();
172 	}
173 
174 	/**
175 	 * Creates a GResource from a reference to the binary resource bundle.
176 	 * This will keep a reference to @data while the resource lives, so
177 	 * the data should not be modified or freed.
178 	 *
179 	 * If you want to use this resource in the global resource namespace you need
180 	 * to register it with g_resources_register().
181 	 *
182 	 * Params:
183 	 *     data = A #GBytes
184 	 *
185 	 * Return: a new #GResource, or %NULL on error
186 	 *
187 	 * Since: 2.32
188 	 *
189 	 * Throws: GException on failure.
190 	 * Throws: ConstructionException GTK+ fails to create the object.
191 	 */
192 	public this(Bytes data)
193 	{
194 		GError* err = null;
195 		
196 		auto p = g_resource_new_from_data((data is null) ? null : data.getBytesStruct(), &err);
197 		
198 		if (err !is null)
199 		{
200 			throw new GException( new ErrorG(err) );
201 		}
202 		
203 		if(p is null)
204 		{
205 			throw new ConstructionException("null returned by new_from_data");
206 		}
207 		
208 		this(cast(GResource*) p);
209 	}
210 
211 	/**
212 	 * Registers the resource with the process-global set of resources.
213 	 * Once a resource is registered the files in it can be accessed
214 	 * with the global resource lookup functions like g_resources_lookup_data().
215 	 *
216 	 * Params:
217 	 *     resource = A #GResource
218 	 *
219 	 * Since: 2.32
220 	 */
221 	public static void register(Resource resource)
222 	{
223 		g_resources_register((resource is null) ? null : resource.getResourceStruct());
224 	}
225 
226 	/**
227 	 * Unregisters the resource from the process-global set of resources.
228 	 *
229 	 * Params:
230 	 *     resource = A #GResource
231 	 *
232 	 * Since: 2.32
233 	 */
234 	public static void unregister(Resource resource)
235 	{
236 		g_resources_unregister((resource is null) ? null : resource.getResourceStruct());
237 	}
238 
239 	/**
240 	 * Returns all the names of children at the specified @path in the resource.
241 	 * The return result is a %NULL terminated list of strings which should
242 	 * be released with g_strfreev().
243 	 *
244 	 * If @path is invalid or does not exist in the #GResource,
245 	 * %G_RESOURCE_ERROR_NOT_FOUND will be returned.
246 	 *
247 	 * @lookup_flags controls the behaviour of the lookup.
248 	 *
249 	 * Params:
250 	 *     path = A pathname inside the resource
251 	 *     lookupFlags = A #GResourceLookupFlags
252 	 *
253 	 * Return: an array of constant strings
254 	 *
255 	 * Since: 2.32
256 	 *
257 	 * Throws: GException on failure.
258 	 */
259 	public string[] enumerateChildren(string path, GResourceLookupFlags lookupFlags)
260 	{
261 		GError* err = null;
262 		
263 		auto retStr = g_resource_enumerate_children(gResource, Str.toStringz(path), lookupFlags, &err);
264 		
265 		if (err !is null)
266 		{
267 			throw new GException( new ErrorG(err) );
268 		}
269 		
270 		scope(exit) Str.freeStringArray(retStr);
271 		return Str.toStringArray(retStr);
272 	}
273 
274 	/**
275 	 * Looks for a file at the specified @path in the resource and
276 	 * if found returns information about it.
277 	 *
278 	 * @lookup_flags controls the behaviour of the lookup.
279 	 *
280 	 * Params:
281 	 *     path = A pathname inside the resource
282 	 *     lookupFlags = A #GResourceLookupFlags
283 	 *     size = a location to place the length of the contents of the file,
284 	 *         or %NULL if the length is not needed
285 	 *     flags = a location to place the flags about the file,
286 	 *         or %NULL if the length is not needed
287 	 *
288 	 * Return: %TRUE if the file was found. %FALSE if there were errors
289 	 *
290 	 * Since: 2.32
291 	 *
292 	 * Throws: GException on failure.
293 	 */
294 	public bool getInfo(string path, GResourceLookupFlags lookupFlags, out size_t size, out uint flags)
295 	{
296 		GError* err = null;
297 		
298 		auto p = g_resource_get_info(gResource, Str.toStringz(path), lookupFlags, &size, &flags, &err) != 0;
299 		
300 		if (err !is null)
301 		{
302 			throw new GException( new ErrorG(err) );
303 		}
304 		
305 		return p;
306 	}
307 
308 	/**
309 	 * Looks for a file at the specified @path in the resource and
310 	 * returns a #GBytes that lets you directly access the data in
311 	 * memory.
312 	 *
313 	 * The data is always followed by a zero byte, so you
314 	 * can safely use the data as a C string. However, that byte
315 	 * is not included in the size of the GBytes.
316 	 *
317 	 * For uncompressed resource files this is a pointer directly into
318 	 * the resource bundle, which is typically in some readonly data section
319 	 * in the program binary. For compressed files we allocate memory on
320 	 * the heap and automatically uncompress the data.
321 	 *
322 	 * @lookup_flags controls the behaviour of the lookup.
323 	 *
324 	 * Params:
325 	 *     path = A pathname inside the resource
326 	 *     lookupFlags = A #GResourceLookupFlags
327 	 *
328 	 * Return: #GBytes or %NULL on error.
329 	 *     Free the returned object with g_bytes_unref()
330 	 *
331 	 * Since: 2.32
332 	 *
333 	 * Throws: GException on failure.
334 	 */
335 	public Bytes lookupData(string path, GResourceLookupFlags lookupFlags)
336 	{
337 		GError* err = null;
338 		
339 		auto p = g_resource_lookup_data(gResource, Str.toStringz(path), lookupFlags, &err);
340 		
341 		if (err !is null)
342 		{
343 			throw new GException( new ErrorG(err) );
344 		}
345 		
346 		if(p is null)
347 		{
348 			return null;
349 		}
350 		
351 		return new Bytes(cast(GBytes*) p, true);
352 	}
353 
354 	/**
355 	 * Looks for a file at the specified @path in the resource and
356 	 * returns a #GInputStream that lets you read the data.
357 	 *
358 	 * @lookup_flags controls the behaviour of the lookup.
359 	 *
360 	 * Params:
361 	 *     path = A pathname inside the resource
362 	 *     lookupFlags = A #GResourceLookupFlags
363 	 *
364 	 * Return: #GInputStream or %NULL on error.
365 	 *     Free the returned object with g_object_unref()
366 	 *
367 	 * Since: 2.32
368 	 *
369 	 * Throws: GException on failure.
370 	 */
371 	public InputStream openStream(string path, GResourceLookupFlags lookupFlags)
372 	{
373 		GError* err = null;
374 		
375 		auto p = g_resource_open_stream(gResource, Str.toStringz(path), lookupFlags, &err);
376 		
377 		if (err !is null)
378 		{
379 			throw new GException( new ErrorG(err) );
380 		}
381 		
382 		if(p is null)
383 		{
384 			return null;
385 		}
386 		
387 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p, true);
388 	}
389 
390 	/**
391 	 * Atomically increments the reference count of @resource by one. This
392 	 * function is MT-safe and may be called from any thread.
393 	 *
394 	 * Return: The passed in #GResource
395 	 *
396 	 * Since: 2.32
397 	 */
398 	public Resource doref()
399 	{
400 		auto p = g_resource_ref(gResource);
401 		
402 		if(p is null)
403 		{
404 			return null;
405 		}
406 		
407 		return ObjectG.getDObject!(Resource)(cast(GResource*) p, true);
408 	}
409 
410 	/**
411 	 * Atomically decrements the reference count of @resource by one. If the
412 	 * reference count drops to 0, all memory allocated by the resource is
413 	 * released. This function is MT-safe and may be called from any
414 	 * thread.
415 	 *
416 	 * Since: 2.32
417 	 */
418 	public void unref()
419 	{
420 		g_resource_unref(gResource);
421 	}
422 
423 	/**
424 	 * Loads a binary resource bundle and creates a #GResource representation of it, allowing
425 	 * you to query it for data.
426 	 *
427 	 * If you want to use this resource in the global resource namespace you need
428 	 * to register it with g_resources_register().
429 	 *
430 	 * Params:
431 	 *     filename = the path of a filename to load, in the GLib filename encoding
432 	 *
433 	 * Return: a new #GResource, or %NULL on error
434 	 *
435 	 * Since: 2.32
436 	 *
437 	 * Throws: GException on failure.
438 	 */
439 	public static Resource load(string filename)
440 	{
441 		GError* err = null;
442 		
443 		auto p = g_resource_load(Str.toStringz(filename), &err);
444 		
445 		if (err !is null)
446 		{
447 			throw new GException( new ErrorG(err) );
448 		}
449 		
450 		if(p is null)
451 		{
452 			return null;
453 		}
454 		
455 		return ObjectG.getDObject!(Resource)(cast(GResource*) p, true);
456 	}
457 
458 	/**
459 	 * Returns all the names of children at the specified @path in the set of
460 	 * globally registered resources.
461 	 * The return result is a %NULL terminated list of strings which should
462 	 * be released with g_strfreev().
463 	 *
464 	 * @lookup_flags controls the behaviour of the lookup.
465 	 *
466 	 * Params:
467 	 *     path = A pathname inside the resource
468 	 *     lookupFlags = A #GResourceLookupFlags
469 	 *
470 	 * Return: an array of constant strings
471 	 *
472 	 * Since: 2.32
473 	 *
474 	 * Throws: GException on failure.
475 	 */
476 	public static string[] resourcesEnumerateChildren(string path, GResourceLookupFlags lookupFlags)
477 	{
478 		GError* err = null;
479 		
480 		auto retStr = g_resources_enumerate_children(Str.toStringz(path), lookupFlags, &err);
481 		
482 		if (err !is null)
483 		{
484 			throw new GException( new ErrorG(err) );
485 		}
486 		
487 		scope(exit) Str.freeStringArray(retStr);
488 		return Str.toStringArray(retStr);
489 	}
490 
491 	/**
492 	 * Looks for a file at the specified @path in the set of
493 	 * globally registered resources and if found returns information about it.
494 	 *
495 	 * @lookup_flags controls the behaviour of the lookup.
496 	 *
497 	 * Params:
498 	 *     path = A pathname inside the resource
499 	 *     lookupFlags = A #GResourceLookupFlags
500 	 *     size = a location to place the length of the contents of the file,
501 	 *         or %NULL if the length is not needed
502 	 *     flags = a location to place the flags about the file,
503 	 *         or %NULL if the length is not needed
504 	 *
505 	 * Return: %TRUE if the file was found. %FALSE if there were errors
506 	 *
507 	 * Since: 2.32
508 	 *
509 	 * Throws: GException on failure.
510 	 */
511 	public static bool resourcesGetInfo(string path, GResourceLookupFlags lookupFlags, out size_t size, out uint flags)
512 	{
513 		GError* err = null;
514 		
515 		auto p = g_resources_get_info(Str.toStringz(path), lookupFlags, &size, &flags, &err) != 0;
516 		
517 		if (err !is null)
518 		{
519 			throw new GException( new ErrorG(err) );
520 		}
521 		
522 		return p;
523 	}
524 
525 	/**
526 	 * Looks for a file at the specified @path in the set of
527 	 * globally registered resources and returns a #GBytes that
528 	 * lets you directly access the data in memory.
529 	 *
530 	 * The data is always followed by a zero byte, so you
531 	 * can safely use the data as a C string. However, that byte
532 	 * is not included in the size of the GBytes.
533 	 *
534 	 * For uncompressed resource files this is a pointer directly into
535 	 * the resource bundle, which is typically in some readonly data section
536 	 * in the program binary. For compressed files we allocate memory on
537 	 * the heap and automatically uncompress the data.
538 	 *
539 	 * @lookup_flags controls the behaviour of the lookup.
540 	 *
541 	 * Params:
542 	 *     path = A pathname inside the resource
543 	 *     lookupFlags = A #GResourceLookupFlags
544 	 *
545 	 * Return: #GBytes or %NULL on error.
546 	 *     Free the returned object with g_bytes_unref()
547 	 *
548 	 * Since: 2.32
549 	 *
550 	 * Throws: GException on failure.
551 	 */
552 	public static Bytes resourcesLookupData(string path, GResourceLookupFlags lookupFlags)
553 	{
554 		GError* err = null;
555 		
556 		auto p = g_resources_lookup_data(Str.toStringz(path), lookupFlags, &err);
557 		
558 		if (err !is null)
559 		{
560 			throw new GException( new ErrorG(err) );
561 		}
562 		
563 		if(p is null)
564 		{
565 			return null;
566 		}
567 		
568 		return new Bytes(cast(GBytes*) p, true);
569 	}
570 
571 	/**
572 	 * Looks for a file at the specified @path in the set of
573 	 * globally registered resources and returns a #GInputStream
574 	 * that lets you read the data.
575 	 *
576 	 * @lookup_flags controls the behaviour of the lookup.
577 	 *
578 	 * Params:
579 	 *     path = A pathname inside the resource
580 	 *     lookupFlags = A #GResourceLookupFlags
581 	 *
582 	 * Return: #GInputStream or %NULL on error.
583 	 *     Free the returned object with g_object_unref()
584 	 *
585 	 * Since: 2.32
586 	 *
587 	 * Throws: GException on failure.
588 	 */
589 	public static InputStream resourcesOpenStream(string path, GResourceLookupFlags lookupFlags)
590 	{
591 		GError* err = null;
592 		
593 		auto p = g_resources_open_stream(Str.toStringz(path), lookupFlags, &err);
594 		
595 		if (err !is null)
596 		{
597 			throw new GException( new ErrorG(err) );
598 		}
599 		
600 		if(p is null)
601 		{
602 			return null;
603 		}
604 		
605 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p, true);
606 	}
607 }