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 }