summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjell.ahlstedt@bredband.net>2014-11-14 12:54:13 +0100
committerKjell Ahlstedt <kjell.ahlstedt@bredband.net>2014-11-14 12:54:13 +0100
commit05cc3d31e9b0bd17af43629452b955d0fece0ddf (patch)
treedae56e47d7e5daa36c35b08c082691583c213bd1
parent8cd77c559fba8a894392db612280af35639e9457 (diff)
downloadglibmm-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.ccg51
-rw-r--r--gio/src/resource.hg186
-rw-r--r--glib/src/bytes.hg4
-rw-r--r--tools/m4/convert_gio.m45
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()')