Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  contentserializer.c

  Sprache: C
 

#include <stdlib.h>

#include <gtk/gtk.h>

typedef gboolean (* ValueCompareFunc) (GValue *v1, GValue *v2);

typedef struct {
  GOutputStream *ostream;
  GInputStream *istream;
  const char *mime_type;
  GValue value;
  ValueCompareFunc compare;
  gboolean done;
} TestData;

static gboolean
compare_string_values (GValue *v1, GValue *v2)
{
  return G_VALUE_TYPE (v1) == G_TYPE_STRING &&
         G_VALUE_TYPE (v2) == G_TYPE_STRING &&
         strcmp (g_value_get_string (v1), g_value_get_string (v2)) == 0;
}

static gboolean
compare_rgba_values (GValue *v1, GValue *v2)
{
  return G_VALUE_TYPE (v1) == GDK_TYPE_RGBA &&
         G_VALUE_TYPE (v2) == GDK_TYPE_RGBA &&
         gdk_rgba_equal ((GdkRGBA *)g_value_get_boxed (v1),
                         (GdkRGBA *)g_value_get_boxed (v2));
}

static gboolean
textures_equal (GdkTexture *t1,  GdkTexture *t2)
{
  guchar *d1, *d2;
  int width, height;
  gboolean ret;

  width = gdk_texture_get_width (t1);
  height = gdk_texture_get_height (t1);

  if (width != gdk_texture_get_width (t2))
    return FALSE;
  if (height != gdk_texture_get_height (t2))
    return FALSE;

  d1 = g_malloc (width * height * 4);
  d2 = g_malloc (width * height * 4);

  gdk_texture_download (t1, d1, width * 4);
  gdk_texture_download (t2, d2, width * 4);

  ret = memcmp (d1, d2, width * height * 4) == 0;

  if (!ret)
    {
      gdk_texture_save_to_png (t1, "texture1.png");
      gdk_texture_save_to_png (t2, "texture2.png");
    }
  g_free (d1);
  g_free (d2);

  return ret;
}

static gboolean
compare_texture_values (GValue *v1, GValue *v2)
{
  return G_VALUE_TYPE (v1) == GDK_TYPE_TEXTURE &&
         G_VALUE_TYPE (v2) == GDK_TYPE_TEXTURE &&
         textures_equal ((GdkTexture *)g_value_get_object (v1),
                         (GdkTexture *)g_value_get_object (v2));
}

static gboolean
compare_file_values (GValue *v1, GValue *v2)
{
  return G_VALUE_TYPE (v1) == G_TYPE_FILE &&
         G_VALUE_TYPE (v2) == G_TYPE_FILE &&
         g_file_equal ((GFile *)g_value_get_object (v1),
                       (GFile *)g_value_get_object (v2));
}

static gboolean
compare_file_list_values (GValue *v1, GValue *v2)
{
  GSList *s1, *s2, *l1, *l2;

  if (G_VALUE_TYPE (v1) != GDK_TYPE_FILE_LIST ||
      G_VALUE_TYPE (v2) != GDK_TYPE_FILE_LIST)
    return FALSE;

  s1 = g_value_get_boxed (v1);
  s2 = g_value_get_boxed (v2);

  if (g_slist_length (s1) != g_slist_length (s2))
    return FALSE;

  for (l1 = s1, l2 = s2; l1 != NULL; l1 = l1->next, l2 = l2->next)
    {
      GFile *f1 = l1->data;
      GFile *f2 = l2->data;
      if (!g_file_equal (f1, f2))
        return FALSE;
    }

  return TRUE;
}

static void
deserialize_done (GObject      *source,
                  GAsyncResult *result,
                  gpointer      user_data)
{
  GError *error = NULL;
  gboolean res;
  TestData *data = user_data;
  GValue value = G_VALUE_INIT;

  g_value_init (&value, G_VALUE_TYPE (&data->value));

  res = gdk_content_deserialize_finish (result, &value, &error);
  g_assert_true (res);
  g_assert_no_error (error);

  g_assert_true (data->compare (&data->value, &value));

  g_value_unset (&value);

  data->done = TRUE;
  g_main_context_wakeup (NULL);
}

static void
serialize_done (GObject      *source,
                GAsyncResult *result,
                gpointer      user_data)
{
  GError *error = NULL;
  gboolean res;
  TestData *data = user_data;
  gpointer serialized_data;
  gsize serialized_len;

  res = gdk_content_serialize_finish (result, &error);
  g_assert_true (res);
  g_assert_no_error (error);

  serialized_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->ostream));
  serialized_len = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->ostream));
  data->istream = g_memory_input_stream_new_from_data (serialized_data, serialized_len, NULL);

  gdk_content_deserialize_async (data->istream,
                                 data->mime_type,
                                 G_VALUE_TYPE (&data->value),
                                 G_PRIORITY_DEFAULT,
                                 NULL,
                                 deserialize_done,
                                 data);
}

static void
test_content_roundtrip (const GValue     *value,
                        const char       *mime_type,
                        ValueCompareFunc  compare)
{
  TestData data = { 0, };

  data.ostream = g_memory_output_stream_new_resizable ();
  data.mime_type = mime_type;
  g_value_init (&data.value, G_VALUE_TYPE (value));
  g_value_copy (value, &data.value);
  data.compare = compare;
  data.done = FALSE;

  gdk_content_serialize_async (data.ostream,
                               data.mime_type,
                               &data.value,
                               G_PRIORITY_DEFAULT,
                               NULL,
                               serialize_done,
                               &data);

  while (!data.done)
    g_main_context_iteration (NULL, TRUE);

  g_object_unref (data.ostream);
  g_object_unref (data.istream);
  g_value_unset (&data.value);
}

static void
test_content_text_plain_utf8 (void)
{
  GValue value = G_VALUE_INIT;

  g_value_init (&value, G_TYPE_STRING);
  g_value_set_static_string (&value, "ABCDEF12345");
  test_content_roundtrip (&value, "text/plain;charset=utf-8", compare_string_values);
  g_value_unset (&value);
}

static void
test_content_text_plain (void)
{
  GValue value = G_VALUE_INIT;

  g_value_init (&value, G_TYPE_STRING);
  g_value_set_static_string (&value, "ABCDEF12345");
  test_content_roundtrip (&value, "text/plain", compare_string_values);
  g_value_unset (&value);
}

static void
test_content_color (void)
{
  GdkRGBA color;
  GValue value = G_VALUE_INIT;

  gdk_rgba_parse (&color, "magenta");
  g_value_init (&value, GDK_TYPE_RGBA);
  g_value_set_boxed (&value, &color);
  test_content_roundtrip (&value, "application/x-color", compare_rgba_values);
  g_value_unset (&value);
}

static void
test_content_texture (gconstpointer data)
{
  const char *mimetype = data;
  GValue value = G_VALUE_INIT;
  char *path;
  GFile *file;
  GdkTexture *texture;
  GError *error = NULL;

  path = g_test_build_filename (G_TEST_DIST, "image-data""image.png", NULL);
  file = g_file_new_for_path (path);
  texture = gdk_texture_new_from_file (file, &error);
  g_assert_no_error (error);
  g_object_unref (file);
  g_free (path);

  g_value_init (&value, GDK_TYPE_TEXTURE);
  g_value_set_object (&value, texture);
  test_content_roundtrip (&value, mimetype, compare_texture_values);
  g_value_unset (&value);
  g_object_unref (texture);
}

static void
test_content_file (void)
{
  GFile *file;
  GValue value = G_VALUE_INIT;

  file = g_file_new_for_path ("/etc/passwd");
  g_value_init (&value, G_TYPE_FILE);
  g_value_set_object (&value, file);
  test_content_roundtrip (&value, "text/uri-list", compare_file_values);
  g_value_unset (&value);
  g_object_unref (file);
}

static void
test_content_files (void)
{
  GSList *files;
  GValue value = G_VALUE_INIT;

  files = NULL;
  files = g_slist_append (files, g_file_new_for_path ("/etc/passwd"));
  files = g_slist_append (files, g_file_new_for_path ("/boot/ostree"));

  g_value_init (&value, GDK_TYPE_FILE_LIST);
  g_value_set_boxed (&value, files);
  test_content_roundtrip (&value, "text/uri-list", compare_file_list_values);
  g_value_unset (&value);
  g_slist_free_full (files, g_object_unref);
}

#define MY_TYPE_INT_LIST (my_int_list_get_type ())
GType my_int_list_get_type (void) G_GNUC_CONST;

typedef gpointer MyIntList;

static gpointer
my_int_list_copy (gpointer list)
{
  int size;
  gpointer copy;

  size = *(int *)list;
  copy = g_malloc ((size + 1) * sizeof (int));
  memcpy (copy, list, (size + 1) * sizeof (int));

  return copy;
}

static void
my_int_list_free (gpointer list)
{
  g_free (list);
}

G_DEFINE_BOXED_TYPE (MyIntList, my_int_list, my_int_list_copy, my_int_list_free)

static void
int_list_serializer_finish (GObject      *source,
                            GAsyncResult *result,
                            gpointer      serializer)
{
  GOutputStream *stream = G_OUTPUT_STREAM (source);
  GError *error = NULL;

  if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
    gdk_content_serializer_return_error (serializer, error);
  else
    gdk_content_serializer_return_success (serializer);
}

static void
int_list_serializer (GdkContentSerializer *serializer)
{
  GString *str;
  const GValue *value;
  int *data;

  str = g_string_new (NULL);
  value = gdk_content_serializer_get_value (serializer);

  data = g_value_get_boxed (value);
  for (int i = 0; i < data[0] + 1; i++)
    {
      if (i > 0)
        g_string_append_c (str, ' ');
      g_string_append_printf (str, "%d", data[i]);
    }

  g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
                                   str->str,
                                   str->len,
                                   gdk_content_serializer_get_priority (serializer),
                                   gdk_content_serializer_get_cancellable (serializer),
                                   int_list_serializer_finish,
                                   serializer);
  gdk_content_serializer_set_task_data (serializer, g_string_free (str, FALSE), g_free);
}

static void
int_list_deserializer_finish (GObject      *source,
                              GAsyncResult *result,
                              gpointer      deserializer)
{
  GOutputStream *stream = G_OUTPUT_STREAM (source);
  GError *error = NULL;
  gssize written;
  GValue *value;
  char *str;
  char **strv;
  int size;
  int *data;

  written = g_output_stream_splice_finish (stream, result, &error);
  if (written < 0)
    {
      gdk_content_deserializer_return_error (deserializer, error);
      return;
    }

  /* write terminating NULL */
  if (g_output_stream_write (stream, ""1, NULL, &error) < 0 ||
      !g_output_stream_close (stream, NULL, &error))
    {
      gdk_content_deserializer_return_error (deserializer, error);
      return;
    }

  str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
  strv = g_strsplit (str, " ", -1);
  size = atoi (strv[0]);
  if (size + 1 != g_strv_length (strv))
    {
      g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Int list corrupt");
      gdk_content_deserializer_return_error (deserializer, error);
      g_free (str);
      g_strfreev (strv);
      return;
    }

  data = g_malloc ((size + 1) * sizeof (int));
  for (int i = 0; i < size + 1; i++)
    data[i] = atoi (strv[i]);
  g_free (str);
  g_strfreev (strv);

  value = gdk_content_deserializer_get_value (deserializer);
  g_value_take_boxed (value, data);

  gdk_content_deserializer_return_success (deserializer);
}

static void
int_list_deserializer (GdkContentDeserializer *deserializer)
{
  GOutputStream *output;

  output = g_memory_output_stream_new_resizable ();

  g_output_stream_splice_async (output,
                                gdk_content_deserializer_get_input_stream (deserializer),
                                G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
                                gdk_content_deserializer_get_priority (deserializer),
                                gdk_content_deserializer_get_cancellable (deserializer),
                                int_list_deserializer_finish,
                                deserializer);
  g_object_unref (output);
}

static gboolean
compare_int_list_values (GValue *v1, GValue *v2)
{
  int *d1, *d2;

  if (G_VALUE_TYPE (v1) != MY_TYPE_INT_LIST ||
      G_VALUE_TYPE (v2) != MY_TYPE_INT_LIST)
    return FALSE;

  d1 = g_value_get_boxed (v1);
  d2 = g_value_get_boxed (v2);

  if (d1[0] != d2[0])
    return FALSE;

  return memcmp (d1, d2, (d1[0] + 1) * sizeof (int)) == 0;
}

static void
test_custom_format (void)
{
  int *data;
  GValue value = G_VALUE_INIT;

  gdk_content_register_serializer (MY_TYPE_INT_LIST,
                                   "application/x-int-list",
                                   int_list_serializer,
                                   NULL, NULL);
  gdk_content_register_deserializer ("application/x-int-list",
                                     MY_TYPE_INT_LIST,
                                     int_list_deserializer,
                                     NULL, NULL);

  data = g_malloc (3 * sizeof (int));
  data[0] = 2;
  data[1] = 3;
  data[2] = 5;

  g_value_init (&value, MY_TYPE_INT_LIST);
  g_value_set_boxed (&value, data);
  test_content_roundtrip (&value, "application/x-int-list", compare_int_list_values);
  g_value_unset (&value);
  g_free (data);
}

static void
test_serialize_union_string (void)
{
  GdkContentFormatsBuilder *builder;
  GdkContentFormats *formats, *result;
  const char * expected[] = {
    "text/plain;charset=utf-8",
    "text/plain",
    NULL,
  };
  const char * const * mime_types;

  builder = gdk_content_formats_builder_new ();
  gdk_content_formats_builder_add_gtype (builder, G_TYPE_STRING);
  formats = gdk_content_formats_builder_free_to_formats (builder);

  result = gdk_content_formats_union_serialize_mime_types (formats);
  mime_types = gdk_content_formats_get_mime_types (result, NULL);

  g_assert_cmpstrv (mime_types, expected);
}

static void
test_deserialize_union_string (void)
{
  GdkContentFormatsBuilder *builder;
  GdkContentFormats *formats, *result;
  const char * expected[] = {
    "text/plain;charset=utf-8",
    "text/plain",
    NULL,
  };
  const char * const * mime_types;

  builder = gdk_content_formats_builder_new ();
  gdk_content_formats_builder_add_gtype (builder, G_TYPE_STRING);
  formats = gdk_content_formats_builder_free_to_formats (builder);

  result = gdk_content_formats_union_deserialize_mime_types (formats);
  mime_types = gdk_content_formats_get_mime_types (result, NULL);

  g_assert_cmpstrv (mime_types, expected);
}

static void
test_serialize_union_textbuffer (void)
{
  GdkContentFormatsBuilder *builder;
  GdkContentFormats *formats, *result;
  const char * expected[] = {
    "text/plain;charset=utf-8",
    "text/plain",
    NULL,
  };
  const char * const * mime_types;
  GtkTextBuffer *b = gtk_text_buffer_new (NULL); // Just to register serializers

  builder = gdk_content_formats_builder_new ();
  gdk_content_formats_builder_add_gtype (builder, GTK_TYPE_TEXT_BUFFER);
  formats = gdk_content_formats_builder_free_to_formats (builder);

  result = gdk_content_formats_union_serialize_mime_types (formats);
  mime_types = gdk_content_formats_get_mime_types (result, NULL);

  g_assert_cmpstrv (mime_types, expected);

  g_object_unref (b);
}

static void
test_deserialize_union_textbuffer (void)
{
  GdkContentFormatsBuilder *builder;
  GdkContentFormats *formats, *result;
  const char * expected[] = {
    "text/plain;charset=utf-8",
    "text/plain",
    NULL,
  };
  const char * const * mime_types;
  GtkTextBuffer *b = gtk_text_buffer_new (NULL);

  builder = gdk_content_formats_builder_new ();
  gdk_content_formats_builder_add_gtype (builder, GTK_TYPE_TEXT_BUFFER);
  formats = gdk_content_formats_builder_free_to_formats (builder);

  result = gdk_content_formats_union_deserialize_mime_types (formats);
  mime_types = gdk_content_formats_get_mime_types (result, NULL);

  g_assert_cmpstrv (mime_types, expected);

  g_object_unref (b);
}

static void
my_string_serializer (GdkContentSerializer *serializer)
{
  int *count;
  GOutputStream *stream;
  const GValue *value;
  const char *text;
  gboolean res;
  gsize written;
  GError *error = NULL;

  g_assert_true (gdk_content_serializer_get_gtype (serializer) == G_TYPE_STRING);
  g_assert_cmpstr (gdk_content_serializer_get_mime_type (serializer), ==, "text/plain;charset=utf-8");

  count = gdk_content_serializer_get_user_data (serializer);
  (*count)++;

  stream = gdk_content_serializer_get_output_stream (serializer);
  value = gdk_content_serializer_get_value (serializer);

  text = g_value_get_string (value);
  res = g_output_stream_write_all (stream, text, strlen (text), &written, NULL, &error);
  g_assert_true (res);
  g_assert_no_error (error);

  gdk_content_serializer_return_success (serializer);
}

static void
my_serialize_done (GObject *source,
                   GAsyncResult *result,
                   gpointer data)
{
  gboolean *done = data;
  gboolean res;
  GError *error = NULL;

  res = gdk_content_serialize_finish (result, &error);
  g_assert_true (res);
  g_assert_no_error (error);

  *done = TRUE;

  g_main_context_wakeup (NULL);
}

static int my_serializer_count = 0;

static void
test_override_serializer (void)
{
  GOutputStream *stream;
  GValue value = G_VALUE_INIT;
  gboolean done = FALSE;

  gdk_content_register_serializer (G_TYPE_STRING, "text/plain;charset=utf-8",
                                   my_string_serializer,
                                   &my_serializer_count,
                                   NULL);

  g_value_init (&value, G_TYPE_STRING);
  g_value_set_static_string (&value, "bu ba bla");

  stream = g_memory_output_stream_new_resizable ();

  gdk_content_serialize_async (stream,
                               "text/plain;charset=utf-8",
                               &value,
                               G_PRIORITY_DEFAULT,
                               NULL,
                               my_serialize_done,
                               &done);

  while (!done)
    g_main_context_iteration (NULL, TRUE);

  g_assert_true (my_serializer_count > 0);

  g_object_unref (stream);
  g_value_unset (&value);
}

int
main (int argc, char *argv[])
{
  (g_test_init) (&argc, &argv, NULL);

  gtk_init ();

  g_test_add_func ("/content/text_plain_utf8", test_content_text_plain_utf8);
  g_test_add_func ("/content/text_plain", test_content_text_plain);
  g_test_add_func ("/content/color", test_content_color);
  g_test_add_data_func ("/content/texture/png""image/png", test_content_texture);
  g_test_add_data_func ("/content/texture/tiff""image/tiff", test_content_texture);
  g_test_add_func ("/content/file", test_content_file);
  g_test_add_func ("/content/files", test_content_files);
  g_test_add_func ("/content/custom", test_custom_format);
  g_test_add_func ("/content/serialize/union/string", test_serialize_union_string);
  g_test_add_func ("/content/serialize/union/textbuffer", test_serialize_union_textbuffer);
  g_test_add_func ("/content/deserialize/union/string", test_deserialize_union_string);
  g_test_add_func ("/content/deserialize/union/textbuffer", test_deserialize_union_textbuffer);
  g_test_add_func ("/content/serializer/override", test_override_serializer);

  return g_test_run ();
}

Messung V0.5 in Prozent
C=99 H=90 G=94

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik