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