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