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