(root)/
glib-2.79.0/
gio/
tests/
resources.c
       1  /* GLib testing framework examples and tests
       2   *
       3   * Copyright (C) 2011 Red Hat, Inc.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   */
      20  
      21  #include <string.h>
      22  #include <gio/gio.h>
      23  #include <glibconfig.h>
      24  #include "gconstructor.h"
      25  #include "test_resources2.h"
      26  #include "digit_test_resources.h"
      27  
      28  #ifdef _MSC_VER
      29  # define MODULE_FILENAME_PREFIX ""
      30  #else
      31  # define MODULE_FILENAME_PREFIX "lib"
      32  #endif
      33  
      34  static void
      35  test_resource (GResource *resource)
      36  {
      37    GError *error = NULL;
      38    gboolean found, success;
      39    gsize size;
      40    guint32 flags;
      41    GBytes *data;
      42    char **children;
      43    GInputStream *in;
      44    char buffer[128];
      45    const gchar *not_found_paths[] =
      46      {
      47        "/not/there",
      48        "/",
      49        "",
      50      };
      51    gsize i;
      52  
      53    for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
      54      {
      55        found = g_resource_get_info (resource,
      56                                     not_found_paths[i],
      57                                     G_RESOURCE_LOOKUP_FLAGS_NONE,
      58                                     &size, &flags, &error);
      59        g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
      60        g_clear_error (&error);
      61        g_assert_false (found);
      62      }
      63  
      64    found = g_resource_get_info (resource,
      65  			       "/test1.txt",
      66  			       G_RESOURCE_LOOKUP_FLAGS_NONE,
      67  			       &size, &flags, &error);
      68    g_assert_true (found);
      69    g_assert_no_error (error);
      70    g_assert_cmpint (size, ==, 6);
      71    g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
      72  
      73    found = g_resource_get_info (resource,
      74                                 "/empty.txt",
      75                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
      76                                 &size, &flags, &error);
      77    g_assert_true (found);
      78    g_assert_no_error (error);
      79    g_assert_cmpint (size, ==, 0);
      80    g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
      81  
      82    found = g_resource_get_info (resource,
      83  			       "/a_prefix/test2.txt",
      84  			       G_RESOURCE_LOOKUP_FLAGS_NONE,
      85  			       &size, &flags, &error);
      86    g_assert_true (found);
      87    g_assert_no_error (error);
      88    g_assert_cmpint (size, ==, 6);
      89    g_assert_cmpuint (flags, ==, 0);
      90  
      91    found = g_resource_get_info (resource,
      92  			       "/a_prefix/test2-alias.txt",
      93  			       G_RESOURCE_LOOKUP_FLAGS_NONE,
      94  			       &size, &flags, &error);
      95    g_assert_true (found);
      96    g_assert_no_error (error);
      97    g_assert_cmpint (size, ==, 6);
      98    g_assert_cmpuint (flags, ==, 0);
      99  
     100    for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
     101      {
     102        data = g_resource_lookup_data (resource,
     103                                       not_found_paths[i],
     104                                       G_RESOURCE_LOOKUP_FLAGS_NONE,
     105                                       &error);
     106        g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     107        g_clear_error (&error);
     108        g_assert_null (data);
     109      }
     110  
     111    data = g_resource_lookup_data (resource,
     112  				 "/test1.txt",
     113  				 G_RESOURCE_LOOKUP_FLAGS_NONE,
     114  				 &error);
     115    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     116    g_assert_no_error (error);
     117    g_bytes_unref (data);
     118  
     119    data = g_resource_lookup_data (resource,
     120                                   "/empty.txt",
     121                                   G_RESOURCE_LOOKUP_FLAGS_NONE,
     122                                   &error);
     123    g_assert_cmpuint (g_bytes_get_size (data), ==, 0);
     124    g_assert_no_error (error);
     125    g_bytes_unref (data);
     126  
     127    for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
     128      {
     129        in = g_resource_open_stream (resource,
     130                                     not_found_paths[i],
     131                                     G_RESOURCE_LOOKUP_FLAGS_NONE,
     132                                     &error);
     133        g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     134        g_clear_error (&error);
     135        g_assert_null (in);
     136      }
     137  
     138    in = g_resource_open_stream (resource,
     139  			       "/test1.txt",
     140  			       G_RESOURCE_LOOKUP_FLAGS_NONE,
     141  			       &error);
     142    g_assert_nonnull (in);
     143    g_assert_no_error (error);
     144  
     145    success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
     146  				     &size,
     147  				     NULL, &error);
     148    g_assert_true (success);
     149    g_assert_no_error (error);
     150    g_assert_cmpint (size, ==, 6);
     151    buffer[size] = 0;
     152    g_assert_cmpstr (buffer, ==, "test1\n");
     153  
     154    g_input_stream_close (in, NULL, &error);
     155    g_assert_no_error (error);
     156    g_clear_object (&in);
     157  
     158    in = g_resource_open_stream (resource,
     159                                 "/empty.txt",
     160                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
     161                                 &error);
     162    g_assert_no_error (error);
     163    g_assert_nonnull (in);
     164  
     165    success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
     166                                       &size,
     167                                       NULL, &error);
     168    g_assert_no_error (error);
     169    g_assert_true (success);
     170    g_assert_cmpint (size, ==, 0);
     171  
     172    g_input_stream_close (in, NULL, &error);
     173    g_assert_no_error (error);
     174    g_clear_object (&in);
     175  
     176    data = g_resource_lookup_data (resource,
     177  				 "/a_prefix/test2.txt",
     178  				 G_RESOURCE_LOOKUP_FLAGS_NONE,
     179  				 &error);
     180    g_assert_nonnull (data);
     181    g_assert_no_error (error);
     182    size = g_bytes_get_size (data);
     183    g_assert_cmpint (size, ==, 6);
     184    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
     185    g_bytes_unref (data);
     186  
     187    data = g_resource_lookup_data (resource,
     188  				 "/a_prefix/test2-alias.txt",
     189  				 G_RESOURCE_LOOKUP_FLAGS_NONE,
     190  				 &error);
     191    g_assert_nonnull (data);
     192    g_assert_no_error (error);
     193    size = g_bytes_get_size (data);
     194    g_assert_cmpint (size, ==, 6);
     195    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
     196    g_bytes_unref (data);
     197  
     198    for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
     199      {
     200        if (g_str_equal (not_found_paths[i], "/"))
     201          continue;
     202  
     203        children = g_resource_enumerate_children (resource,
     204                                                  not_found_paths[i],
     205                                                  G_RESOURCE_LOOKUP_FLAGS_NONE,
     206                                                  &error);
     207        g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     208        g_clear_error (&error);
     209        g_assert_null (children);
     210      }
     211  
     212    children = g_resource_enumerate_children  (resource,
     213  					     "/a_prefix",
     214  					     G_RESOURCE_LOOKUP_FLAGS_NONE,
     215  					     &error);
     216    g_assert_nonnull (children);
     217    g_assert_no_error (error);
     218    g_assert_cmpint (g_strv_length (children), ==, 2);
     219    g_strfreev (children);
     220  
     221    /* Test the preferred lookup where we have a trailing slash. */
     222    children = g_resource_enumerate_children  (resource,
     223  					     "/a_prefix/",
     224  					     G_RESOURCE_LOOKUP_FLAGS_NONE,
     225  					     &error);
     226    g_assert_nonnull (children);
     227    g_assert_no_error (error);
     228    g_assert_cmpint (g_strv_length (children), ==, 2);
     229    g_strfreev (children);
     230  
     231    /* test with a path > 256 and no trailing slash to test the
     232     * slow path of resources where we allocate a modified path.
     233     */
     234    children = g_resource_enumerate_children  (resource,
     235  					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
     236  					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
     237  					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
     238  					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
     239  					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
     240  					     "/with/no/trailing/slash",
     241  					     G_RESOURCE_LOOKUP_FLAGS_NONE,
     242  					     &error);
     243    g_assert_null (children);
     244    g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     245    g_clear_error (&error);
     246  }
     247  
     248  static void
     249  test_resource_file (void)
     250  {
     251    GResource *resource;
     252    GError *error = NULL;
     253  
     254    resource = g_resource_load ("not-there", &error);
     255    g_assert_null (resource);
     256    g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
     257    g_clear_error (&error);
     258  
     259    resource = g_resource_load (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), &error);
     260    g_assert_nonnull (resource);
     261    g_assert_no_error (error);
     262  
     263    test_resource (resource);
     264    g_resource_unref (resource);
     265  }
     266  
     267  static void
     268  test_resource_file_path (void)
     269  {
     270    static const struct {
     271      const gchar *input;
     272      const gchar *expected;
     273    } test_uris[] = {
     274      { "resource://", "resource:///" },
     275      { "resource:///", "resource:///" },
     276      { "resource://////", "resource:///" },
     277      { "resource:///../../../", "resource:///" },
     278      { "resource:///../../..", "resource:///" },
     279      { "resource://abc", "resource:///abc" },
     280      { "resource:///abc/", "resource:///abc" },
     281      { "resource:/a/b/../c/", "resource:///a/c" },
     282      { "resource://../a/b/../c/../", "resource:///a" },
     283      { "resource://a/b/cc//bb//a///", "resource:///a/b/cc/bb/a" },
     284      { "resource://././././", "resource:///" },
     285      { "resource://././././../", "resource:///" },
     286      { "resource://a/b/c/d.png", "resource:///a/b/c/d.png" },
     287      { "resource://a/b/c/..png", "resource:///a/b/c/..png" },
     288      { "resource://a/b/c/./png", "resource:///a/b/c/png" },
     289    };
     290    guint i;
     291  
     292    for (i = 0; i < G_N_ELEMENTS (test_uris); i++)
     293      {
     294        GFile *file;
     295        gchar *uri;
     296  
     297        file = g_file_new_for_uri (test_uris[i].input);
     298        g_assert_nonnull (file);
     299  
     300        uri = g_file_get_uri (file);
     301        g_assert_nonnull (uri);
     302  
     303        g_assert_cmpstr (uri, ==, test_uris[i].expected);
     304  
     305        g_object_unref (file);
     306        g_free (uri);
     307      }
     308  }
     309  
     310  static void
     311  test_resource_data (void)
     312  {
     313    GResource *resource;
     314    GError *error = NULL;
     315    gboolean loaded_file;
     316    char *content;
     317    gsize content_size;
     318    GBytes *data;
     319  
     320    loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
     321                                       &content, &content_size, NULL);
     322    g_assert_true (loaded_file);
     323  
     324    data = g_bytes_new_take (content, content_size);
     325    resource = g_resource_new_from_data (data, &error);
     326    g_bytes_unref (data);
     327    g_assert_nonnull (resource);
     328    g_assert_no_error (error);
     329  
     330    test_resource (resource);
     331  
     332    g_resource_unref (resource);
     333  }
     334  
     335  static void
     336  test_resource_data_unaligned (void)
     337  {
     338    GResource *resource;
     339    GError *error = NULL;
     340    gboolean loaded_file;
     341    char *content, *content_copy;
     342    gsize content_size;
     343    GBytes *data;
     344  
     345    loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
     346                                       &content, &content_size, NULL);
     347    g_assert_true (loaded_file);
     348  
     349    content_copy = g_new (char, content_size + 1);
     350    memcpy (content_copy + 1, content, content_size);
     351  
     352    data = g_bytes_new_with_free_func (content_copy + 1, content_size,
     353                                       (GDestroyNotify) g_free, content_copy);
     354    g_free (content);
     355    resource = g_resource_new_from_data (data, &error);
     356    g_bytes_unref (data);
     357    g_assert_nonnull (resource);
     358    g_assert_no_error (error);
     359  
     360    test_resource (resource);
     361  
     362    g_resource_unref (resource);
     363  }
     364  
     365  /* Test error handling for corrupt GResource files (specifically, a corrupt
     366   * GVDB header). */
     367  static void
     368  test_resource_data_corrupt (void)
     369  {
     370    /* A GVDB header is 6 guint32s, and requires a magic number in the first two
     371     * guint32s. A set of zero bytes of a greater length is considered corrupt. */
     372    static const guint8 data[sizeof (guint32) * 7] = { 0, };
     373    GBytes *bytes = NULL;
     374    GResource *resource = NULL;
     375    GError *local_error = NULL;
     376  
     377    bytes = g_bytes_new_static (data, sizeof (data));
     378    resource = g_resource_new_from_data (bytes, &local_error);
     379    g_bytes_unref (bytes);
     380    g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
     381    g_assert_null (resource);
     382  
     383    g_clear_error (&local_error);
     384  }
     385  
     386  /* Test handling for empty GResource files. They should also be treated as
     387   * corrupt. */
     388  static void
     389  test_resource_data_empty (void)
     390  {
     391    GBytes *bytes = NULL;
     392    GResource *resource = NULL;
     393    GError *local_error = NULL;
     394  
     395    bytes = g_bytes_new_static (NULL, 0);
     396    resource = g_resource_new_from_data (bytes, &local_error);
     397    g_bytes_unref (bytes);
     398    g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
     399    g_assert_null (resource);
     400  
     401    g_clear_error (&local_error);
     402  }
     403  
     404  static void
     405  test_resource_registered (void)
     406  {
     407    GResource *resource;
     408    GError *error = NULL;
     409    gboolean found, success;
     410    gsize size;
     411    guint32 flags;
     412    GBytes *data;
     413    char **children;
     414    GInputStream *in;
     415    char buffer[128];
     416  
     417    resource = g_resource_load (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), &error);
     418    g_assert_nonnull (resource);
     419    g_assert_no_error (error);
     420  
     421    found = g_resources_get_info ("/test1.txt",
     422  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     423  				&size, &flags, &error);
     424    g_assert_false (found);
     425    g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     426    g_clear_error (&error);
     427  
     428    g_resources_register (resource);
     429  
     430    found = g_resources_get_info ("/test1.txt",
     431  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     432  				&size, &flags, &error);
     433    g_assert_true (found);
     434    g_assert_no_error (error);
     435    g_assert_cmpint (size, ==, 6);
     436    g_assert_cmpint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
     437  
     438    found = g_resources_get_info ("/empty.txt",
     439                                  G_RESOURCE_LOOKUP_FLAGS_NONE,
     440                                  &size, &flags, &error);
     441    g_assert_no_error (error);
     442    g_assert_true (found);
     443    g_assert_cmpint (size, ==, 0);
     444    g_assert_cmpint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
     445  
     446    found = g_resources_get_info ("/a_prefix/test2.txt",
     447  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     448  				&size, &flags, &error);
     449    g_assert_true (found);
     450    g_assert_no_error (error);
     451    g_assert_cmpint (size, ==, 6);
     452    g_assert_cmpint (flags, ==, 0);
     453  
     454    found = g_resources_get_info ("/a_prefix/test2-alias.txt",
     455  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     456  				&size, &flags, &error);
     457    g_assert_true (found);
     458    g_assert_no_error (error);
     459    g_assert_cmpint (size, ==, 6);
     460    g_assert_cmpuint (flags, ==, 0);
     461  
     462    data = g_resources_lookup_data ("/test1.txt",
     463  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     464  				  &error);
     465    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     466    g_assert_no_error (error);
     467    g_bytes_unref (data);
     468  
     469    in = g_resources_open_stream ("/test1.txt",
     470  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     471  				&error);
     472    g_assert_nonnull (in);
     473    g_assert_no_error (error);
     474  
     475    success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
     476  				     &size,
     477  				     NULL, &error);
     478    g_assert_true (success);
     479    g_assert_no_error (error);
     480    g_assert_cmpint (size, ==, 6);
     481    buffer[size] = 0;
     482    g_assert_cmpstr (buffer, ==, "test1\n");
     483  
     484    g_input_stream_close (in, NULL, &error);
     485    g_assert_no_error (error);
     486    g_clear_object (&in);
     487  
     488    data = g_resources_lookup_data ("/empty.txt",
     489                                    G_RESOURCE_LOOKUP_FLAGS_NONE,
     490                                    &error);
     491    g_assert_no_error (error);
     492    g_assert_cmpuint (g_bytes_get_size (data), ==, 0);
     493    g_bytes_unref (data);
     494  
     495    in = g_resources_open_stream ("/empty.txt",
     496                                  G_RESOURCE_LOOKUP_FLAGS_NONE,
     497                                  &error);
     498    g_assert_no_error (error);
     499    g_assert_nonnull (in);
     500  
     501    success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
     502                                       &size,
     503                                       NULL, &error);
     504    g_assert_no_error (error);
     505    g_assert_true (success);
     506    g_assert_cmpint (size, ==, 0);
     507  
     508    g_input_stream_close (in, NULL, &error);
     509    g_assert_no_error (error);
     510    g_clear_object (&in);
     511  
     512    data = g_resources_lookup_data ("/a_prefix/test2.txt",
     513  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     514  				  &error);
     515    g_assert_nonnull (data);
     516    g_assert_no_error (error);
     517    size = g_bytes_get_size (data);
     518    g_assert_cmpint (size, ==, 6);
     519    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
     520    g_bytes_unref (data);
     521  
     522    data = g_resources_lookup_data ("/a_prefix/test2-alias.txt",
     523  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     524  				  &error);
     525    g_assert_nonnull (data);
     526    g_assert_no_error (error);
     527    size = g_bytes_get_size (data);
     528    g_assert_cmpint (size, ==, 6);
     529    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
     530    g_bytes_unref (data);
     531  
     532    children = g_resources_enumerate_children ("/not/here",
     533  					     G_RESOURCE_LOOKUP_FLAGS_NONE,
     534  					     &error);
     535    g_assert_null (children);
     536    g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     537    g_clear_error (&error);
     538  
     539    children = g_resources_enumerate_children ("/a_prefix",
     540  					     G_RESOURCE_LOOKUP_FLAGS_NONE,
     541  					     &error);
     542    g_assert_nonnull (children);
     543    g_assert_no_error (error);
     544    g_assert_cmpint (g_strv_length (children), ==, 2);
     545    g_strfreev (children);
     546  
     547    g_resources_unregister (resource);
     548    g_resource_unref (resource);
     549  
     550    found = g_resources_get_info ("/test1.txt",
     551  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     552  				&size, &flags, &error);
     553    g_assert_false (found);
     554    g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     555    g_clear_error (&error);
     556  }
     557  
     558  static void
     559  test_resource_automatic (void)
     560  {
     561    GError *error = NULL;
     562    gboolean found;
     563    gsize size;
     564    guint32 flags;
     565    GBytes *data;
     566  
     567    found = g_resources_get_info ("/auto_loaded/test1.txt",
     568  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     569  				&size, &flags, &error);
     570    g_assert_true (found);
     571    g_assert_no_error (error);
     572    g_assert_cmpint (size, ==, 6);
     573    g_assert_cmpint (flags, ==, 0);
     574  
     575    data = g_resources_lookup_data ("/auto_loaded/test1.txt",
     576  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     577  				  &error);
     578    g_assert_nonnull (data);
     579    g_assert_no_error (error);
     580    size = g_bytes_get_size (data);
     581    g_assert_cmpint (size, ==, 6);
     582    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     583    g_bytes_unref (data);
     584  }
     585  
     586  static void
     587  test_resource_manual (void)
     588  {
     589    GError *error = NULL;
     590    gboolean found;
     591    gsize size;
     592    guint32 flags;
     593    GBytes *data;
     594  
     595    found = g_resources_get_info ("/manual_loaded/test1.txt",
     596  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     597  				&size, &flags, &error);
     598    g_assert_true (found);
     599    g_assert_no_error (error);
     600    g_assert_cmpint (size, ==, 6);
     601    g_assert_cmpuint (flags, ==, 0);
     602  
     603    data = g_resources_lookup_data ("/manual_loaded/test1.txt",
     604  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     605  				  &error);
     606    g_assert_nonnull (data);
     607    g_assert_no_error (error);
     608    size = g_bytes_get_size (data);
     609    g_assert_cmpint (size, ==, 6);
     610    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     611    g_bytes_unref (data);
     612  }
     613  
     614  static void
     615  test_resource_manual2 (void)
     616  {
     617    GResource *resource;
     618    GBytes *data;
     619    gsize size;
     620    GError *error = NULL;
     621  
     622    resource = _g_test2_get_resource ();
     623  
     624    data = g_resource_lookup_data (resource,
     625                                   "/manual_loaded/test1.txt",
     626  				 G_RESOURCE_LOOKUP_FLAGS_NONE,
     627  				 &error);
     628    g_assert_nonnull (data);
     629    g_assert_no_error (error);
     630    size = g_bytes_get_size (data);
     631    g_assert_cmpint (size, ==, 6);
     632    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     633    g_bytes_unref (data);
     634  
     635    g_resource_unref (resource);
     636  }
     637  
     638  /* Test building resources with external data option,
     639   * where data is linked in as binary instead of compiled in.
     640   * Checks if resources are automatically registered and
     641   * data can be found and read. */
     642  static void
     643  test_resource_binary_linked (void)
     644  {
     645    #ifndef __linux__
     646    g_test_skip ("--external-data test only works on Linux");
     647    return;
     648    #else /* if __linux__ */
     649    GError *error = NULL;
     650    gboolean found;
     651    gsize size;
     652    guint32 flags;
     653    GBytes *data;
     654  
     655    found = g_resources_get_info ("/binary_linked/test1.txt",
     656  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     657  				&size, &flags, &error);
     658    g_assert_true (found);
     659    g_assert_no_error (error);
     660    g_assert_cmpint (size, ==, 6);
     661    g_assert_cmpuint (flags, ==, 0);
     662  
     663    data = g_resources_lookup_data ("/binary_linked/test1.txt",
     664  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     665  				  &error);
     666    g_assert_nonnull (data);
     667    g_assert_no_error (error);
     668    size = g_bytes_get_size (data);
     669    g_assert_cmpint (size, ==, 6);
     670    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     671    g_bytes_unref (data);
     672    #endif /* if __linux__ */
     673  }
     674  
     675  /* Test resource whose xml file starts with more than one digit
     676   * and where no explicit c-name is given
     677   * Checks if resources are successfully registered and
     678   * data can be found and read. */
     679  static void
     680  test_resource_digits (void)
     681  {
     682    GError *error = NULL;
     683    gboolean found;
     684    gsize size;
     685    guint32 flags;
     686    GBytes *data;
     687  
     688    found = g_resources_get_info ("/digit_test/test1.txt",
     689  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     690  				&size, &flags, &error);
     691    g_assert_true (found);
     692    g_assert_no_error (error);
     693    g_assert_cmpint (size, ==, 6);
     694    g_assert_cmpuint (flags, ==, 0);
     695  
     696    data = g_resources_lookup_data ("/digit_test/test1.txt",
     697  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
     698  				  &error);
     699    g_assert_nonnull (data);
     700    g_assert_no_error (error);
     701    size = g_bytes_get_size (data);
     702    g_assert_cmpint (size, ==, 6);
     703    g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     704    g_bytes_unref (data);
     705  }
     706  
     707  static void
     708  test_resource_module (void)
     709  {
     710    GIOModule *module;
     711    gboolean found;
     712    gsize size;
     713    guint32 flags;
     714    GBytes *data;
     715    GError *error;
     716  
     717  #ifdef GLIB_STATIC_COMPILATION
     718    /* The resource module is statically linked with a separate copy
     719     * of a GLib so g_static_resource_init won't work as expected. */
     720    g_test_skip ("Resource modules aren't supported in static builds.");
     721    return;
     722  #endif
     723  
     724    if (g_module_supported ())
     725      {
     726        module = g_io_module_new (g_test_get_filename (G_TEST_BUILT,
     727                                                       MODULE_FILENAME_PREFIX "resourceplugin",
     728                                                       NULL));
     729  
     730        error = NULL;
     731  
     732        found = g_resources_get_info ("/resourceplugin/test1.txt",
     733  				    G_RESOURCE_LOOKUP_FLAGS_NONE,
     734  				    &size, &flags, &error);
     735        g_assert_false (found);
     736        g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     737        g_clear_error (&error);
     738  
     739        g_type_module_use (G_TYPE_MODULE (module));
     740  
     741        found = g_resources_get_info ("/resourceplugin/test1.txt",
     742  				    G_RESOURCE_LOOKUP_FLAGS_NONE,
     743  				    &size, &flags, &error);
     744        g_assert_true (found);
     745        g_assert_no_error (error);
     746        g_assert_cmpint (size, ==, 6);
     747        g_assert_cmpuint (flags, ==, 0);
     748  
     749        data = g_resources_lookup_data ("/resourceplugin/test1.txt",
     750  				      G_RESOURCE_LOOKUP_FLAGS_NONE,
     751  				      &error);
     752        g_assert_nonnull (data);
     753        g_assert_no_error (error);
     754        size = g_bytes_get_size (data);
     755        g_assert_cmpint (size, ==, 6);
     756        g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
     757        g_bytes_unref (data);
     758  
     759        g_type_module_unuse (G_TYPE_MODULE (module));
     760  
     761        found = g_resources_get_info ("/resourceplugin/test1.txt",
     762  				    G_RESOURCE_LOOKUP_FLAGS_NONE,
     763  				    &size, &flags, &error);
     764        g_assert_false (found);
     765        g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
     766        g_clear_error (&error);
     767  
     768        g_clear_object (&module);
     769      }
     770  }
     771  
     772  static void
     773  test_uri_query_info (void)
     774  {
     775    GResource *resource;
     776    GError *error = NULL;
     777    gboolean loaded_file;
     778    char *content;
     779    gsize content_size;
     780    GBytes *data;
     781    GFile *file;
     782    GFileInfo *info;
     783    const char *content_type;
     784    gchar *mime_type = NULL;
     785    const char *fs_type;
     786    gboolean readonly;
     787  
     788    loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
     789                                       &content, &content_size, NULL);
     790    g_assert_true (loaded_file);
     791  
     792    data = g_bytes_new_take (content, content_size);
     793    resource = g_resource_new_from_data (data, &error);
     794    g_bytes_unref (data);
     795    g_assert_nonnull (resource);
     796    g_assert_no_error (error);
     797  
     798    g_resources_register (resource);
     799  
     800    file = g_file_new_for_uri ("resource://" "/a_prefix/test2-alias.txt");
     801    info = g_file_query_info (file, "*", 0, NULL, &error);
     802    g_assert_no_error (error);
     803  
     804    content_type = g_file_info_get_content_type (info);
     805    g_assert_nonnull (content_type);
     806    mime_type = g_content_type_get_mime_type (content_type);
     807    g_assert_nonnull (mime_type);
     808  #ifdef __APPLE__
     809    g_assert_cmpstr (mime_type, ==, "text/*");
     810  #else
     811    g_assert_cmpstr (mime_type, ==, "text/plain");
     812  #endif
     813    g_free (mime_type);
     814  
     815    g_object_unref (info);
     816  
     817    info = g_file_query_filesystem_info (file, "*", NULL, &error);
     818    g_assert_no_error (error);
     819  
     820    fs_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
     821    g_assert_cmpstr (fs_type, ==, "resource");
     822    readonly = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
     823    g_assert_true (readonly);
     824  
     825    g_object_unref (info);
     826  
     827    g_assert_cmpuint  (g_file_hash (file), !=, 0);
     828  
     829    g_object_unref (file);
     830  
     831    g_resources_unregister (resource);
     832    g_resource_unref (resource);
     833  }
     834  
     835  static void
     836  test_uri_file (void)
     837  {
     838    GResource *resource;
     839    GError *error = NULL;
     840    gboolean loaded_file;
     841    char *content;
     842    gsize content_size;
     843    GBytes *data;
     844    GFile *file;
     845    GFileInfo *info;
     846    gchar *name;
     847    GFile *file2, *parent;
     848    GFileEnumerator *enumerator;
     849    gchar *scheme;
     850    GFileAttributeInfoList *attrs;
     851    GInputStream *stream;
     852    gchar buf[1024];
     853    gboolean ret;
     854    gssize skipped;
     855  
     856    loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
     857                                       &content, &content_size, NULL);
     858    g_assert_true (loaded_file);
     859  
     860    data = g_bytes_new_take (content, content_size);
     861    resource = g_resource_new_from_data (data, &error);
     862    g_bytes_unref (data);
     863    g_assert_nonnull (resource);
     864    g_assert_no_error (error);
     865  
     866    g_resources_register (resource);
     867  
     868    file = g_file_new_for_uri ("resource://" "/a_prefix/test2-alias.txt");
     869  
     870    g_assert_null (g_file_get_path (file));
     871  
     872    name = g_file_get_parse_name (file);
     873    g_assert_cmpstr (name, ==, "resource:///a_prefix/test2-alias.txt");
     874    g_free (name);
     875  
     876    name = g_file_get_uri (file);
     877    g_assert_cmpstr (name, ==, "resource:///a_prefix/test2-alias.txt");
     878    g_free (name);
     879  
     880    g_assert_false (g_file_is_native (file));
     881    g_assert_false (g_file_has_uri_scheme (file, "http"));
     882    g_assert_true (g_file_has_uri_scheme (file, "resource"));
     883    scheme = g_file_get_uri_scheme (file);
     884    g_assert_cmpstr (scheme, ==, "resource");
     885    g_free (scheme);
     886  
     887    file2 = g_file_dup (file);
     888    g_assert_true (g_file_equal (file, file2));
     889    g_object_unref (file2);
     890  
     891    parent = g_file_get_parent (file);
     892    enumerator = g_file_enumerate_children (parent, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
     893    g_assert_no_error (error);
     894  
     895    file2 = g_file_get_child_for_display_name (parent, "test2-alias.txt", &error);
     896    g_assert_no_error (error);
     897    g_assert_true (g_file_equal (file, file2));
     898    g_object_unref (file2);
     899  
     900    info = g_file_enumerator_next_file (enumerator, NULL, &error);
     901    g_assert_no_error (error);
     902    g_assert_nonnull (info);
     903    g_object_unref (info);
     904  
     905    info = g_file_enumerator_next_file (enumerator, NULL, &error);
     906    g_assert_no_error (error);
     907    g_assert_nonnull (info);
     908    g_object_unref (info);
     909  
     910    info = g_file_enumerator_next_file (enumerator, NULL, &error);
     911    g_assert_no_error (error);
     912    g_assert_null (info);
     913  
     914    g_file_enumerator_close (enumerator, NULL, &error);
     915    g_assert_no_error (error);
     916    g_object_unref (enumerator);
     917  
     918    file2 = g_file_new_for_uri ("resource://" "a_prefix/../a_prefix//test2-alias.txt");
     919    g_assert_true (g_file_equal (file, file2));
     920  
     921    g_assert_true (g_file_has_prefix (file, parent));
     922  
     923    name = g_file_get_relative_path (parent, file);
     924    g_assert_cmpstr (name, ==, "test2-alias.txt");
     925    g_free (name);
     926  
     927    g_object_unref (parent);
     928  
     929    attrs = g_file_query_settable_attributes (file, NULL, &error);
     930    g_assert_no_error (error);
     931    g_file_attribute_info_list_unref (attrs);
     932  
     933    attrs = g_file_query_writable_namespaces (file, NULL, &error);
     934    g_assert_no_error (error);
     935    g_file_attribute_info_list_unref (attrs);
     936  
     937    stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
     938    g_assert_no_error (error);
     939    g_assert_cmpint (g_seekable_tell (G_SEEKABLE (stream)), ==, 0);
     940    g_assert_true (g_seekable_can_seek (G_SEEKABLE (G_SEEKABLE (stream))));
     941    ret = g_seekable_seek (G_SEEKABLE (stream), 1, G_SEEK_SET, NULL, &error);
     942    g_assert_true (ret);
     943    g_assert_no_error (error);
     944    skipped = g_input_stream_skip (stream, 1, NULL, &error);
     945    g_assert_cmpint (skipped, ==, 1);
     946    g_assert_no_error (error);
     947  
     948    memset (buf, 0, 1024);
     949    ret = g_input_stream_read_all (stream, &buf, 1024, NULL, NULL, &error);
     950    g_assert_true (ret);
     951    g_assert_no_error (error);
     952    g_assert_cmpstr (buf, ==, "st2\n");
     953    info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (stream),
     954                                           G_FILE_ATTRIBUTE_STANDARD_SIZE,
     955                                           NULL,
     956                                           &error);
     957    g_assert_no_error (error);
     958    g_assert_nonnull (info);
     959    g_assert_cmpint (g_file_info_get_size (info), ==, 6);
     960    g_object_unref (info);
     961  
     962    ret = g_input_stream_close (stream, NULL, &error);
     963    g_assert_true (ret);
     964    g_assert_no_error (error);
     965    g_object_unref (stream);
     966  
     967    g_object_unref (file);
     968    g_object_unref (file2);
     969  
     970    g_resources_unregister (resource);
     971    g_resource_unref (resource);
     972  }
     973  
     974  static void
     975  test_resource_64k (void)
     976  {
     977    GError *error = NULL;
     978    gboolean found;
     979    gsize size;
     980    guint32 flags;
     981    GBytes *data;
     982    gchar **tokens;
     983  
     984    found = g_resources_get_info ("/big_prefix/gresource-big-test.txt",
     985  				G_RESOURCE_LOOKUP_FLAGS_NONE,
     986  				&size, &flags, &error);
     987    g_assert_true (found);
     988    g_assert_no_error (error);
     989  
     990    /* Check size: 100 of all lower case letters + newline char +
     991     *             100 all upper case letters + newline char +
     992     *             100 of all numbers between 0 to 9 + newline char
     993     *             (for 12 iterations)
     994     */
     995  
     996    g_assert_cmpint (size, ==, (26 + 26 + 10) * (100 + 1) * 12);
     997    g_assert_cmpuint (flags, ==, 0);
     998    data = g_resources_lookup_data ("/big_prefix/gresource-big-test.txt",
     999  				  G_RESOURCE_LOOKUP_FLAGS_NONE,
    1000  				  &error);
    1001    g_assert_nonnull (data);
    1002    g_assert_no_error (error);
    1003    size = g_bytes_get_size (data);
    1004  
    1005    g_assert_cmpint (size, ==, (26 + 26 + 10) * (100 + 1) * 12);
    1006    tokens = g_strsplit ((const gchar *) g_bytes_get_data (data, NULL), "\n", -1);
    1007  
    1008    /* check tokens[x] == entry at gresource-big-test.txt's line, where x = line - 1 */
    1009    g_assert_cmpstr (tokens[0], ==, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    1010    g_assert_cmpstr (tokens[27], ==, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
    1011    g_assert_cmpstr (tokens[183], ==, "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777");
    1012    g_assert_cmpstr (tokens[600], ==, "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
    1013    g_assert_cmpstr (tokens[742], ==, "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888");
    1014    g_strfreev (tokens);
    1015    g_bytes_unref (data);
    1016  }
    1017  
    1018  /* Check that g_resources_get_info() respects G_RESOURCE_OVERLAYS */
    1019  static void
    1020  test_overlay (void)
    1021  {
    1022    if (g_test_subprocess ())
    1023      {
    1024         GError *error = NULL;
    1025         gboolean res;
    1026         gsize size;
    1027         char *overlay;
    1028         char *path;
    1029  
    1030         path = g_test_build_filename (G_TEST_DIST, "test1.overlay", NULL);
    1031         overlay = g_strconcat ("/auto_loaded/test1.txt=", path, NULL);
    1032  
    1033         g_setenv ("G_RESOURCE_OVERLAYS", overlay, TRUE);
    1034         res = g_resources_get_info ("/auto_loaded/test1.txt", 0, &size, NULL, &error);
    1035         g_assert_true (res);
    1036         g_assert_no_error (error);
    1037         /* test1.txt is 6 bytes, test1.overlay is 23 */
    1038         g_assert_cmpint (size, ==, 23);
    1039  
    1040         g_free (overlay);
    1041         g_free (path);
    1042  
    1043         return;
    1044      }
    1045    g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR);
    1046    g_test_trap_assert_passed ();
    1047  }
    1048  
    1049  int
    1050  main (int   argc,
    1051        char *argv[])
    1052  {
    1053    g_test_init (&argc, &argv, NULL);
    1054  
    1055    _g_test2_register_resource ();
    1056    _digit_test_register_resource ();
    1057  
    1058    g_test_add_func ("/resource/file", test_resource_file);
    1059    g_test_add_func ("/resource/file-path", test_resource_file_path);
    1060    g_test_add_func ("/resource/data", test_resource_data);
    1061    g_test_add_func ("/resource/data_unaligned", test_resource_data_unaligned);
    1062    g_test_add_func ("/resource/data-corrupt", test_resource_data_corrupt);
    1063    g_test_add_func ("/resource/data-empty", test_resource_data_empty);
    1064    g_test_add_func ("/resource/registered", test_resource_registered);
    1065    g_test_add_func ("/resource/manual", test_resource_manual);
    1066    g_test_add_func ("/resource/manual2", test_resource_manual2);
    1067  #ifdef G_HAS_CONSTRUCTORS
    1068    g_test_add_func ("/resource/automatic", test_resource_automatic);
    1069    /* This only uses automatic resources too, so it tests the constructors and destructors */
    1070    g_test_add_func ("/resource/module", test_resource_module);
    1071    g_test_add_func ("/resource/binary-linked", test_resource_binary_linked);
    1072  #endif
    1073    g_test_add_func ("/resource/uri/query-info", test_uri_query_info);
    1074    g_test_add_func ("/resource/uri/file", test_uri_file);
    1075    g_test_add_func ("/resource/64k", test_resource_64k);
    1076    g_test_add_func ("/resource/overlay", test_overlay);
    1077    g_test_add_func ("/resource/digits", test_resource_digits);
    1078  
    1079    return g_test_run();
    1080  }