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