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