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