diff options
author | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2014-11-14 12:54:13 +0100 |
---|---|---|
committer | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2014-11-14 12:54:13 +0100 |
commit | 05cc3d31e9b0bd17af43629452b955d0fece0ddf (patch) | |
tree | dae56e47d7e5daa36c35b08c082691583c213bd1 | |
parent | 8cd77c559fba8a894392db612280af35639e9457 (diff) | |
download | glibmm-05cc3d31e9b0bd17af43629452b955d0fece0ddf.tar.gz |
Add Gio::Resource
* gio/src/resource.[hg|ccg]: Add class Resource, enum ResourceFlags and
enum ResourceLookupFlags.
* glib/src/bytes.hg: Mention Resource in a comment.
* tools/m4/convert_gio.m4: Add conversions for GResource, GResourceFlags and
GResourceLookupFlags. Bug #739206.
-rw-r--r-- | gio/src/resource.ccg | 51 | ||||
-rw-r--r-- | gio/src/resource.hg | 186 | ||||
-rw-r--r-- | glib/src/bytes.hg | 4 | ||||
-rw-r--r-- | tools/m4/convert_gio.m4 | 5 |
4 files changed, 239 insertions, 7 deletions
diff --git a/gio/src/resource.ccg b/gio/src/resource.ccg index b80d676f..cd5eb8c6 100644 --- a/gio/src/resource.ccg +++ b/gio/src/resource.ccg @@ -1,5 +1,3 @@ -// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- - /* Copyright (C) 2012 The giomm Development Team * * This library is free software; you can redistribute it and/or @@ -21,5 +19,54 @@ namespace Gio { +// Hand-coded because we want ResourceFlags& instead of guint32&. +void Resource::get_info(const Glib::ustring& path, gsize& size, + ResourceFlags& flags, ResourceLookupFlags lookup_flags) const +{ + guint32 file_flags = 0; + GError* gerror = 0; + // Ignore the gboolean return value from g_resource_get_info(). + // gerror is set if and only if the return value is FALSE. + g_resource_get_info(const_cast<GResource*>(gobj()), path.c_str(), + (GResourceLookupFlags)lookup_flags, &size, &file_flags, &gerror); + if (gerror) + ::Glib::Error::throw_exception(gerror); + flags = static_cast<ResourceFlags>(file_flags); +} + +void Resource::get_info(const Glib::ustring& path, ResourceLookupFlags lookup_flags) const +{ + GError* gerror = 0; + g_resource_get_info(const_cast<GResource*>(gobj()), path.c_str(), + (GResourceLookupFlags)lookup_flags, 0, 0, &gerror); + if (gerror) + ::Glib::Error::throw_exception(gerror); +} + +// Hand-coded because we want ResourceFlags& instead of guint32&. +//static +void Resource::get_info_global(const Glib::ustring& path, gsize& size, + ResourceFlags& flags, ResourceLookupFlags lookup_flags) +{ + guint32 file_flags = 0; + GError* gerror = 0; + // Ignore the gboolean return value from g_resources_get_info(). + // gerror is set if and only if the return value is FALSE. + g_resources_get_info(path.c_str(), + (GResourceLookupFlags)lookup_flags, &size, &file_flags, &gerror); + if (gerror) + ::Glib::Error::throw_exception(gerror); + flags = static_cast<ResourceFlags>(file_flags); +} + +//static +void Resource::get_info_global(const Glib::ustring& path, ResourceLookupFlags lookup_flags) +{ + GError* gerror = 0; + g_resources_get_info(path.c_str(), + (GResourceLookupFlags)lookup_flags, 0, 0, &gerror); + if (gerror) + ::Glib::Error::throw_exception(gerror); +} } // namespace Gio diff --git a/gio/src/resource.hg b/gio/src/resource.hg index ad1ddd93..e01d9cf8 100644 --- a/gio/src/resource.hg +++ b/gio/src/resource.hg @@ -1,5 +1,3 @@ -// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- - /* Copyright (C) 2012 The gtkmm Development Team * * This library is free software; you can redistribute it and/or @@ -18,9 +16,19 @@ */ #include <glibmm/error.h> +#include <glibmm/refptr.h> +#include <glibmm/bytes.h> +#include <glibmm/ustring.h> +#include <giomm/inputstream.h> +#include <vector> +#include <string> _DEFS(giomm,gio) +#ifndef DOXYGEN_SHOULD_SKIP_THIS +typedef struct _GResource GResource; +#endif + namespace Gio { @@ -28,4 +36,178 @@ namespace Gio */ _WRAP_GERROR(ResourceError, GResourceError, G_RESOURCE_ERROR, NO_GTYPE) +_WRAP_ENUM(ResourceFlags, GResourceFlags) +_WRAP_ENUM(ResourceLookupFlags, GResourceLookupFlags) + +/** Resource framework. + * + * Applications and libraries often contain binary or textual data that is + * really part of the application, rather than user data. For instance + * Gtk::Builder .ui files, splashscreen images, Gio::Menu markup xml, CSS files, + * icons, etc. These are often shipped as files in `$datadir/appname`, or + * manually included as literal strings in the code. + * + * The Gio::Resource API and the <tt>glib-compile-resources</tt> program + * provide a convenient and efficient alternative to this which has some nice properties. You + * maintain the files as normal files, so its easy to edit them, but during the build the files + * are combined into a binary bundle that is linked into the executable. This means that loading + * the resource files is efficient (as they are already in memory, shared with other instances) and + * simple (no need to check for things like I/O errors or locate the files in the filesystem). It + * also makes it easier to create relocatable applications. + * + * Resource files can also be marked as compressed. Such files will be included in the resource bundle + * in a compressed form, but will be automatically uncompressed when the resource is used. This + * is very useful e.g. for larger text files that are parsed once (or rarely) and then thrown away. + * + * Resource files can also be marked to be preprocessed, by setting the value of the + * `preprocess` attribute to a comma-separated list of preprocessing options. + * The only options currently supported are: + * + * <dl> + * <dt>xml-stripblanks</dt> + * <dd>which will use the <tt>xmllint</tt> command + * to strip ignorable whitespace from the xml file. For this to work, + * the `XMLLINT` environment variable must be set to the full path to + * the <tt>xmllint</tt> executable, or <tt>xmllint</tt> must be in the `PATH`; otherwise + * the preprocessing step is skipped.</dd> + * + * <dt>to-pixdata</dt> + * <dd>which will use the <tt>gdk-pixbuf-pixdata</tt> command to convert + * images to the GdkPixdata format, which allows you to create pixbufs directly using the data inside + * the resource file, rather than an (uncompressed) copy of it. For this, the <tt>gdk-pixbuf-pixdata</tt> + * program must be in the PATH, or the `GDK_PIXBUF_PIXDATA` environment variable must be + * set to the full path to the <tt>gdk-pixbuf-pixdata</tt> executable; otherwise the resource compiler will + * abort.</dd> + * </dl> + * + * Resource bundles are created by the <tt>glib-compile-resources</tt> program + * which takes an xml file that describes the bundle, and a set of files that the xml references. These + * are combined into a binary resource bundle. + * + * An example resource description: + * @code + * <?xml version="1.0" encoding="UTF-8"?> + * <gresources> + * <gresource prefix="/org/gtk/Example"> + * <file>data/splashscreen.png</file> + * <file compressed="true">dialog.ui</file> + * <file preprocess="xml-stripblanks">menumarkup.xml</file> + * </gresource> + * </gresources> + * @endcode + * + * This will create a resource bundle with the following files: + * @code + * /org/gtk/Example/data/splashscreen.png + * /org/gtk/Example/dialog.ui + * /org/gtk/Example/menumarkup.xml + * @endcode + * + * Note that all resources in the process share the same namespace, so use java-style + * path prefixes (like in the above example) to avoid conflicts. + * + * You can then use <tt>glib-compile-resources</tt> to compile the xml to a binary bundle + * that you can load with Gio::Resource::create_from_file(). However, its more common to use the --generate-source and + * --generate-header arguments to create a source file and header to link directly into your application. + * + * Once a Gio::Resource has been created and registered all the data in it can be accessed globally in the process by + * using API calls like Gio::Resource::open_stream_from_global_resources() to stream the data + * or Gio::Resource::lookup_data_in_global_resources() to get a direct pointer + * to the data. You can also use uris like "resource:///org/gtk/Example/data/splashscreen.png" with Gio::File to access + * the resource data. + * + * There are two forms of the generated source, the default version uses the compiler support for constructor + * and destructor functions (where available) to automatically create and register the Gio::Resource on startup + * or library load time. If you pass --manual-register, two functions to register/unregister the resource is instead + * created. This requires an explicit initialization call in your application/library, but it works on all platforms, + * even on the minor ones where this is not available. (Constructor support is available for at least Win32, MacOS and Linux.) + * + * Note that resource data can point directly into the data segment of e.g. a library, so if you are unloading libraries + * during runtime you need to be very careful with keeping around pointers to data from a resource, as this goes away + * when the library is unloaded. However, in practice this is not generally a problem, since most resource accesses + * is for your own resources, and resource data is often used once, during parsing, and then released. + * + * @newin{2,44} + */ +class Resource +{ + _CLASS_OPAQUE_REFCOUNTED(Resource, GResource, NONE, g_resource_ref, g_resource_unref) + _IGNORE(g_resource_ref, g_resource_unref) + +public: + _WRAP_METHOD(static Glib::RefPtr<Resource> create_from_data(const Glib::RefPtr<const Glib::Bytes>& data), g_resource_new_from_data, errthrow) + _WRAP_METHOD(static Glib::RefPtr<Resource> create_from_file(const std::string& filename), g_resource_load, errthrow) + _WRAP_METHOD(Glib::RefPtr<InputStream> open_stream(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const, g_resource_open_stream, errthrow) + _WRAP_METHOD(Glib::RefPtr<const Glib::Bytes> lookup_data(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const, g_resource_lookup_data, errthrow) + +#m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)') + _WRAP_METHOD(std::vector<Glib::ustring> enumerate_children(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const, g_resource_enumerate_children, errthrow) + + /** Looks for a file at the specified @a path in the resource and + * if found returns information about it. + * + * @a lookup_flags controls the behaviour of the lookup. + * + * @newin{2,44} + * + * @param path A pathname inside the resource. + * @param[out] size A location to place the length of the contents of the file. + * @param[out] flags A location to place the flags about the file. + * @param lookup_flags A ResourceLookupFlags. + * @throw Gio::ResourceError if the file was not found. + */ + void get_info(const Glib::ustring& path, gsize& size, ResourceFlags& flags, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const; + _IGNORE(g_resource_get_info) + + /** Looks for a file at the specified @a path in the resource. + * + * @a lookup_flags controls the behaviour of the lookup. + * + * @newin{2,44} + * + * @param path A pathname inside the resource. + * @param lookup_flags A ResourceLookupFlags. + * @throw Gio::ResourceError if the file was not found. + */ + void get_info(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const; + + // 'register' is a keyword. Can't be the name of a method. + _WRAP_METHOD(void register_global(), g_resources_register) + _WRAP_METHOD(void unregister_global(), g_resources_unregister) + _WRAP_METHOD(static Glib::RefPtr<InputStream> open_stream_global(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE), g_resources_open_stream, errthrow) + _WRAP_METHOD(static Glib::RefPtr<const Glib::Bytes> lookup_data_global(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE), g_resources_lookup_data, errthrow) + _WRAP_METHOD(static std::vector<Glib::ustring> enumerate_children_global(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE), g_resources_enumerate_children, errthrow) + + /** Looks for a file at the specified @a path in the set of + * globally registered resources and if found returns information about it. + * + * @a lookup_flags controls the behaviour of the lookup. + * + * @newin{2,44} + * + * @param path A pathname inside the resource. + * @param[out] size A location to place the length of the contents of the file. + * @param[out] flags A location to place the flags about the file. + * @param lookup_flags A ResourceLookupFlags. + * @throw Gio::ResourceError if the file was not found. + */ + static void get_info_global(const Glib::ustring& path, gsize& size, ResourceFlags& flags, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE); + _IGNORE(g_resources_get_info) + + /** Looks for a file at the specified @a path in the set of + * globally registered resources. + * + * @a lookup_flags controls the behaviour of the lookup. + * + * @newin{2,44} + * + * @param path A pathname inside the resource. + * @param lookup_flags A ResourceLookupFlags. + * @throw Gio::ResourceError if the file was not found. + */ + static void get_info_global(const Glib::ustring& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE); + + _IGNORE(g_static_resource_init, g_static_resource_fini, g_static_resource_get_resource)dnl//Used only by the glib-compile-resources command +}; + } // namespace Gio diff --git a/glib/src/bytes.hg b/glib/src/bytes.hg index 255c6689..31f1fc9f 100644 --- a/glib/src/bytes.hg +++ b/glib/src/bytes.hg @@ -30,11 +30,9 @@ typedef struct _GBytes GBytes; namespace Glib { - - //Note: The documentation is a reduced version of the C documentation, //because this class is only really useful with other C types that we don't bother to wrap. -//We only wrap it because it is used in the InputStream API. +//We only wrap it because it is used in the InputStream, OutputStream and Resource APIs. /** A simple refcounted data type representing an immutable byte sequence * from an unspecified origin. diff --git a/tools/m4/convert_gio.m4 b/tools/m4/convert_gio.m4 index 58d2a652..3d170668 100644 --- a/tools/m4/convert_gio.m4 +++ b/tools/m4/convert_gio.m4 @@ -35,6 +35,8 @@ _CONV_ENUM(G,MountUnmountFlags) _CONV_ENUM(G,OutputStreamSpliceFlags) _CONV_ENUM(G,PasswordSave) _CONV_ENUM(G,ResolverRecordType) +_CONV_ENUM(G,ResourceFlags) +_CONV_ENUM(G,ResourceLookupFlags) _CONV_ENUM(G,SettingsBindFlags) _CONV_ENUM(G,SocketClientEvent) _CONV_ENUM(G,SocketFamily) @@ -252,6 +254,9 @@ _CONVERSION(`GProxy*',`Glib::RefPtr<Proxy>',`Glib::wrap($3)') _CONVERSION(`const Glib::RefPtr<const ProxyAddress>&',`GProxyAddress*',__CONVERT_CONST_REFPTR_TO_P) +#Resource +_CONVERSION(`GResource*',`Glib::RefPtr<Resource>',`Glib::wrap($3)') + #Settings _CONVERSION(`GSettings*',`Glib::RefPtr<Settings>',`Glib::wrap($3)') _CONVERSION(`const Glib::StringArrayHandle&',`const gchar*-const*',`($3).data()') |