mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 02:32:11 +01:00
Add GMarkupEncoder
An encoder and decoder that uses XML (parseable by GMarkup) as the intermediate representation of its data.
This commit is contained in:
parent
a2ac1d0fd1
commit
a324690d06
@ -389,6 +389,7 @@ libgio_2_0_la_SOURCES = \
|
|||||||
giostream.c \
|
giostream.c \
|
||||||
gkeyfileencoder.c \
|
gkeyfileencoder.c \
|
||||||
gloadableicon.c \
|
gloadableicon.c \
|
||||||
|
gmarkupencoder.c \
|
||||||
gmount.c \
|
gmount.c \
|
||||||
gmemoryinputstream.c \
|
gmemoryinputstream.c \
|
||||||
gmemoryoutputstream.c \
|
gmemoryoutputstream.c \
|
||||||
@ -565,6 +566,7 @@ gio_headers = \
|
|||||||
giostream.h \
|
giostream.h \
|
||||||
gkeyfileencoder.h \
|
gkeyfileencoder.h \
|
||||||
gloadableicon.h \
|
gloadableicon.h \
|
||||||
|
gmarkupencoder.h \
|
||||||
gmount.h \
|
gmount.h \
|
||||||
gmemoryinputstream.h \
|
gmemoryinputstream.h \
|
||||||
gmemoryoutputstream.h \
|
gmemoryoutputstream.h \
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
#include <gio/giostream.h>
|
#include <gio/giostream.h>
|
||||||
#include <gio/gkeyfileencoder.h>
|
#include <gio/gkeyfileencoder.h>
|
||||||
#include <gio/gloadableicon.h>
|
#include <gio/gloadableicon.h>
|
||||||
|
#include <gio/gmarkupencoder.h>
|
||||||
#include <gio/gmemoryinputstream.h>
|
#include <gio/gmemoryinputstream.h>
|
||||||
#include <gio/gmemoryoutputstream.h>
|
#include <gio/gmemoryoutputstream.h>
|
||||||
#include <gio/gmount.h>
|
#include <gio/gmount.h>
|
||||||
|
@ -50,6 +50,7 @@ typedef struct _GEncoder GEncoder;
|
|||||||
typedef struct _GSerializable GSerializable;
|
typedef struct _GSerializable GSerializable;
|
||||||
typedef struct _GBinaryEncoder GBinaryEncoder;
|
typedef struct _GBinaryEncoder GBinaryEncoder;
|
||||||
typedef struct _GKeyfileEncoder GKeyfileEncoder;
|
typedef struct _GKeyfileEncoder GKeyfileEncoder;
|
||||||
|
typedef struct _GMarkupEncoder GMarkupEncoder;
|
||||||
|
|
||||||
typedef struct _GSimpleActionGroup GSimpleActionGroup;
|
typedef struct _GSimpleActionGroup GSimpleActionGroup;
|
||||||
typedef struct _GRemoteActionGroup GRemoteActionGroup;
|
typedef struct _GRemoteActionGroup GRemoteActionGroup;
|
||||||
|
437
gio/gmarkupencoder.c
Normal file
437
gio/gmarkupencoder.c
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
/* GIO - GLib Input, Output and Streaming Library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Emmanuele Bassi <ebassi@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General
|
||||||
|
* Public License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:gmarkupencoder
|
||||||
|
* @Title: GMarkupEncoder
|
||||||
|
* @Short_Description: Encodes and decodes data as markup
|
||||||
|
*
|
||||||
|
* #GMarkupEncoder is a class that allows encoding and decoding data
|
||||||
|
* as an XML subset that can be parsed by #GMarkupParser.
|
||||||
|
*
|
||||||
|
* Note that you can only use #GMarkupEncoder to decode the output
|
||||||
|
* of data encoded by a #GMarkupEncoder.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gmarkupencoder.h"
|
||||||
|
#include "gencoder.h"
|
||||||
|
#include "gioerror.h"
|
||||||
|
#include "glibintl.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct _GMarkupEncoder
|
||||||
|
{
|
||||||
|
GEncoder parent_instance;
|
||||||
|
|
||||||
|
/* parser state */
|
||||||
|
char *cur_key;
|
||||||
|
char *cur_value;
|
||||||
|
char *cur_value_type;
|
||||||
|
|
||||||
|
guint in_entries : 1;
|
||||||
|
guint in_entry : 1;
|
||||||
|
guint in_key : 1;
|
||||||
|
guint in_value : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GMarkupEncoderClass
|
||||||
|
{
|
||||||
|
GEncoderClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GMarkupEncoder, g_markup_encoder, G_TYPE_ENCODER)
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_markup_encoder_start_element (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
const gchar **attribute_names,
|
||||||
|
const gchar **attribute_values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GMarkupEncoder *self = user_data;
|
||||||
|
|
||||||
|
if (strcmp (element_name, "entries") == 0)
|
||||||
|
{
|
||||||
|
if (self->in_entries)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"The 'entries' tag cannot be nested");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (!self->in_entry);
|
||||||
|
g_assert (!self->in_key);
|
||||||
|
g_assert (!self->in_value);
|
||||||
|
self->in_entries = TRUE;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (element_name, "entry") == 0)
|
||||||
|
{
|
||||||
|
if (!self->in_entries)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"The 'entry' tag can only be used inside an 'entries' tag");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (!self->in_entry);
|
||||||
|
g_assert (!self->in_key);
|
||||||
|
g_assert (!self->in_value);
|
||||||
|
self->in_entry = TRUE;
|
||||||
|
|
||||||
|
g_free (self->cur_key);
|
||||||
|
self->cur_key = NULL;
|
||||||
|
g_free (self->cur_value_type);
|
||||||
|
self->cur_value_type = NULL;
|
||||||
|
g_free (self->cur_value);
|
||||||
|
self->cur_value = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (element_name, "key") == 0)
|
||||||
|
{
|
||||||
|
if (!self->in_entry)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"The 'key' tag can only be used inside an 'entry' tag");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (!self->in_value);
|
||||||
|
self->in_key = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (element_name, "value") == 0)
|
||||||
|
{
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
if (!self->in_entry)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"The 'value' tag can only be used inside an 'entry' tag");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = g_markup_collect_attributes (element_name,
|
||||||
|
attribute_names,
|
||||||
|
attribute_values,
|
||||||
|
error,
|
||||||
|
G_MARKUP_COLLECT_STRDUP, "type", &self->cur_value_type,
|
||||||
|
G_MARKUP_COLLECT_INVALID);
|
||||||
|
if (!res)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_assert (!self->in_key);
|
||||||
|
self->in_value = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_markup_encoder_add_current_entry (GMarkupEncoder *self,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GError *internal_error;
|
||||||
|
GVariant *variant;
|
||||||
|
|
||||||
|
if (self->cur_key == NULL)
|
||||||
|
{
|
||||||
|
if (self->cur_value_type != NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"No key defined for entry of type '%s'",
|
||||||
|
self->cur_value_type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"No key defined for entry");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->cur_value_type == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"No value type defined for key '%s'",
|
||||||
|
self->cur_key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->cur_value == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"No value defined for key '%s' of type '%s'",
|
||||||
|
self->cur_key,
|
||||||
|
self->cur_value_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_error = NULL;
|
||||||
|
variant = g_variant_parse (G_VARIANT_TYPE (self->cur_value_type),
|
||||||
|
self->cur_value,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&internal_error);
|
||||||
|
if (internal_error != NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"Unable to parse the entry value: %s",
|
||||||
|
internal_error->message);
|
||||||
|
g_error_free (internal_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_encoder_add_key (G_ENCODER (self), self->cur_key, variant);
|
||||||
|
g_variant_unref (variant);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_markup_encoder_end_element (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GMarkupEncoder *self = user_data;
|
||||||
|
|
||||||
|
if (strcmp (element_name, "entries") == 0)
|
||||||
|
{
|
||||||
|
self->in_entries = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (element_name, "entry") == 0)
|
||||||
|
{
|
||||||
|
g_assert (self->in_entries);
|
||||||
|
self->in_entry = FALSE;
|
||||||
|
|
||||||
|
g_markup_encoder_add_current_entry (self, error);
|
||||||
|
|
||||||
|
g_free (self->cur_key);
|
||||||
|
self->cur_key = NULL;
|
||||||
|
g_free (self->cur_value_type);
|
||||||
|
self->cur_value_type = NULL;
|
||||||
|
g_free (self->cur_value);
|
||||||
|
self->cur_value = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (element_name, "key") == 0)
|
||||||
|
{
|
||||||
|
g_assert (self->in_entries);
|
||||||
|
g_assert (self->in_entry);
|
||||||
|
self->in_key = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (element_name, "value") == 0)
|
||||||
|
{
|
||||||
|
g_assert (self->in_entries);
|
||||||
|
g_assert (self->in_entry);
|
||||||
|
self->in_value = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_set_error (error, G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
||||||
|
"Unknown element '%s' in markup",
|
||||||
|
element_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_markup_encoder_text (GMarkupParseContext *context,
|
||||||
|
const gchar *text,
|
||||||
|
gsize text_len,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GMarkupEncoder *self = user_data;
|
||||||
|
|
||||||
|
if (self->in_key)
|
||||||
|
{
|
||||||
|
g_free (self->cur_key);
|
||||||
|
self->cur_key = g_strndup (text, text_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->in_value)
|
||||||
|
{
|
||||||
|
g_free (self->cur_value);
|
||||||
|
self->cur_value = g_strndup (text, text_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GMarkupParser markup_parser = {
|
||||||
|
/* .start_element = */ g_markup_encoder_start_element,
|
||||||
|
/* .end_element = */ g_markup_encoder_end_element,
|
||||||
|
/* .text = */ g_markup_encoder_text,
|
||||||
|
/* .passthrough = */ NULL,
|
||||||
|
/* .error = */ NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_parser_state (gpointer data)
|
||||||
|
{
|
||||||
|
GMarkupEncoder *self = data;
|
||||||
|
|
||||||
|
g_free (self->cur_key);
|
||||||
|
self->cur_key = NULL;
|
||||||
|
g_free (self->cur_value_type);
|
||||||
|
self->cur_value_type = NULL;
|
||||||
|
g_free (self->cur_value);
|
||||||
|
self->cur_value = NULL;
|
||||||
|
|
||||||
|
self->in_entries = FALSE;
|
||||||
|
self->in_entry = FALSE;
|
||||||
|
self->in_key = FALSE;
|
||||||
|
self->in_value = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
g_markup_encoder_read_from_bytes (GEncoder *encoder,
|
||||||
|
GBytes *buffer,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GMarkupParseContext *context;
|
||||||
|
GError *internal_error = NULL;
|
||||||
|
|
||||||
|
clear_parser_state (encoder);
|
||||||
|
|
||||||
|
context = g_markup_parse_context_new (&markup_parser, 0, encoder, clear_parser_state);
|
||||||
|
|
||||||
|
g_markup_parse_context_parse (context,
|
||||||
|
g_bytes_get_data (buffer, NULL),
|
||||||
|
g_bytes_get_size (buffer),
|
||||||
|
&internal_error);
|
||||||
|
|
||||||
|
g_markup_parse_context_free (context);
|
||||||
|
|
||||||
|
if (internal_error)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"Unable to read markup data: %s",
|
||||||
|
internal_error->message);
|
||||||
|
g_error_free (internal_error);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GBytes *
|
||||||
|
g_markup_encoder_write_to_bytes (GEncoder *encoder,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GVariant *data = g_encoder_close (encoder);
|
||||||
|
GVariant *entry;
|
||||||
|
GVariantIter iter;
|
||||||
|
GString *buffer;
|
||||||
|
gsize len;
|
||||||
|
|
||||||
|
buffer = g_string_sized_new (1024);
|
||||||
|
|
||||||
|
g_string_append (buffer, "<?xml version=\"1.0\"?>\n");
|
||||||
|
g_string_append (buffer, "<entries version=\"1.0\">\n");
|
||||||
|
|
||||||
|
g_variant_iter_init (&iter, data);
|
||||||
|
while ((entry = g_variant_iter_next_value (&iter)) != NULL)
|
||||||
|
{
|
||||||
|
GVariant *key = g_variant_get_child_value (entry, 0);
|
||||||
|
GVariant *tmp = g_variant_get_child_value (entry, 1);
|
||||||
|
GVariant *value;
|
||||||
|
char *value_str;
|
||||||
|
|
||||||
|
g_string_append (buffer, " <entry>\n");
|
||||||
|
|
||||||
|
value = g_variant_get_variant (tmp);
|
||||||
|
value_str = g_variant_print (value, FALSE);
|
||||||
|
|
||||||
|
g_string_append_printf (buffer,
|
||||||
|
" <key>%s</key>\n",
|
||||||
|
g_variant_get_string (key, NULL));
|
||||||
|
|
||||||
|
g_string_append_printf (buffer,
|
||||||
|
" <value type=\"%s\">%s</value>\n",
|
||||||
|
(const char *) g_variant_get_type (value),
|
||||||
|
value_str);
|
||||||
|
|
||||||
|
g_free (value_str);
|
||||||
|
g_variant_unref (value);
|
||||||
|
g_variant_unref (tmp);
|
||||||
|
g_variant_unref (key);
|
||||||
|
|
||||||
|
g_string_append (buffer, " </entry>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_append (buffer, "</entries>");
|
||||||
|
len = buffer->len;
|
||||||
|
|
||||||
|
return g_bytes_new_take (g_string_free (buffer, FALSE), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_markup_encoder_class_init (GMarkupEncoderClass *klass)
|
||||||
|
{
|
||||||
|
GEncoderClass *encoder_class = G_ENCODER_CLASS (klass);
|
||||||
|
|
||||||
|
encoder_class->read_from_bytes = g_markup_encoder_read_from_bytes;
|
||||||
|
encoder_class->write_to_bytes = g_markup_encoder_write_to_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_markup_encoder_init (GMarkupEncoder *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_markup_encoder_new:
|
||||||
|
*
|
||||||
|
* Creates a new #GMarkupEncoder instance.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): the newly created #GMarkupEncoder instance.
|
||||||
|
* Use g_object_unref() when done.
|
||||||
|
*
|
||||||
|
* Since: 2.38
|
||||||
|
*/
|
||||||
|
GEncoder *
|
||||||
|
g_markup_encoder_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (G_TYPE_MARKUP_ENCODER, NULL);
|
||||||
|
}
|
49
gio/gmarkupencoder.h
Normal file
49
gio/gmarkupencoder.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* GIO - GLib Input, Output and Streaming Library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Emmanuele Bassi <ebassi@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General
|
||||||
|
* Public License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __G_MARKUP_ENCODER_H__
|
||||||
|
#define __G_MARKUP_ENCODER_H__
|
||||||
|
|
||||||
|
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
|
||||||
|
#error "Only <gio/gio.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gio/giotypes.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define G_TYPE_MARKUP_ENCODER (g_markup_encoder_get_type ())
|
||||||
|
#define G_MARKUP_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_MARKUP_ENCODER, GMarkupEncoder))
|
||||||
|
#define G_IS_MARKUP_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_MARKUP_ENCODER))
|
||||||
|
#define G_MARKUP_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_MARKUP_ENCODER, GMarkupEncoderClass))
|
||||||
|
#define G_IS_MARKUP_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_MARKUP_ENCODER))
|
||||||
|
#define G_MARKUP_ENCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_MARKUP_ENCODER, GMarkupEncoderClass))
|
||||||
|
|
||||||
|
typedef struct _GMarkupEncoderClass GMarkupEncoderClass;
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_38
|
||||||
|
GType g_markup_encoder_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_38
|
||||||
|
GEncoder * g_markup_encoder_new (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __G_MARKUP_ENCODER_H__ */
|
@ -1,34 +1,35 @@
|
|||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
static void
|
static GBytes *
|
||||||
encoder_binary (void)
|
encode_data (GEncoder *encoder)
|
||||||
{
|
{
|
||||||
GEncoder *encoder = g_binary_encoder_new ();
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GBytes *buffer;
|
GBytes *buffer;
|
||||||
gboolean bool_value;
|
|
||||||
char *str_value;
|
|
||||||
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (encoder), (gpointer *) &encoder);
|
|
||||||
|
|
||||||
g_encoder_add_key_bool (encoder, "BoolValue", TRUE);
|
g_encoder_add_key_bool (encoder, "BoolValue", TRUE);
|
||||||
g_encoder_add_key_string (encoder, "StringValue", "Hello");
|
g_encoder_add_key_string (encoder, "StringValue", "Hello");
|
||||||
|
g_encoder_add_key_double (encoder, "DoubleValue", 3.14159);
|
||||||
|
|
||||||
buffer = g_encoder_write_to_bytes (encoder, &error);
|
buffer = g_encoder_write_to_bytes (encoder, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (buffer != NULL);
|
g_assert (buffer != NULL);
|
||||||
|
|
||||||
g_object_unref (encoder);
|
|
||||||
g_assert (encoder == NULL);
|
|
||||||
|
|
||||||
if (g_test_verbose ())
|
if (g_test_verbose ())
|
||||||
g_print ("*** buffer (len: %d) = ***\n%s\n",
|
g_print ("*** buffer (len: %d) = ***\n%s\n",
|
||||||
(int) g_bytes_get_size (buffer),
|
(int) g_bytes_get_size (buffer),
|
||||||
(const char *) g_bytes_get_data (buffer, NULL));
|
(const char *) g_bytes_get_data (buffer, NULL));
|
||||||
|
|
||||||
encoder = g_binary_encoder_new ();
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (encoder), (gpointer *) &encoder);
|
static void
|
||||||
|
decode_data (GEncoder *encoder,
|
||||||
|
GBytes *buffer)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
gboolean bool_value;
|
||||||
|
char *str_value;
|
||||||
|
double dbl_value;
|
||||||
|
|
||||||
g_encoder_read_from_bytes (encoder, buffer, &error);
|
g_encoder_read_from_bytes (encoder, buffer, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@ -40,45 +41,58 @@ encoder_binary (void)
|
|||||||
g_assert_cmpstr (str_value, ==, "Hello");
|
g_assert_cmpstr (str_value, ==, "Hello");
|
||||||
g_free (str_value);
|
g_free (str_value);
|
||||||
|
|
||||||
g_bytes_unref (buffer);
|
g_encoder_get_key_double (encoder, "DoubleValue", &dbl_value);
|
||||||
|
g_assert_cmpfloat ((float) dbl_value, ==, 3.14159f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
encoder_binary (void)
|
||||||
|
{
|
||||||
|
GEncoder *encoder, *decoder;
|
||||||
|
GBytes *buffer;
|
||||||
|
|
||||||
|
encoder = g_binary_encoder_new ();
|
||||||
|
buffer = encode_data (encoder);
|
||||||
g_object_unref (encoder);
|
g_object_unref (encoder);
|
||||||
g_assert (encoder == NULL);
|
|
||||||
|
decoder = g_binary_encoder_new ();
|
||||||
|
decode_data (decoder, buffer);
|
||||||
|
g_object_unref (decoder);
|
||||||
|
g_bytes_unref (buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encoder_keyfile (void)
|
encoder_keyfile (void)
|
||||||
{
|
{
|
||||||
GEncoder *encoder = g_keyfile_encoder_new ();
|
GEncoder *encoder, *decoder;
|
||||||
GError *error = NULL;
|
|
||||||
GBytes *buffer;
|
GBytes *buffer;
|
||||||
gboolean res;
|
|
||||||
|
|
||||||
g_keyfile_encoder_set_section_name (G_KEYFILE_ENCODER (encoder), "Test");
|
|
||||||
g_encoder_add_key_bool (encoder, "BoolValue", TRUE);
|
|
||||||
|
|
||||||
buffer = g_encoder_write_to_bytes (encoder, &error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
g_assert (buffer != NULL);
|
|
||||||
|
|
||||||
g_object_unref (encoder);
|
|
||||||
|
|
||||||
if (g_test_verbose ())
|
|
||||||
g_print ("*** buffer (len: %d) = ***\n%s",
|
|
||||||
(int) g_bytes_get_size (buffer),
|
|
||||||
(const char *) g_bytes_get_data (buffer, NULL));
|
|
||||||
|
|
||||||
encoder = g_keyfile_encoder_new ();
|
encoder = g_keyfile_encoder_new ();
|
||||||
g_keyfile_encoder_set_section_name (G_KEYFILE_ENCODER (encoder), "Test");
|
g_keyfile_encoder_set_section_name (G_KEYFILE_ENCODER (encoder), "Test");
|
||||||
|
buffer = encode_data (encoder);
|
||||||
g_encoder_read_from_bytes (encoder, buffer, &error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
g_encoder_get_key_bool (encoder, "BoolValue", &res);
|
|
||||||
g_assert (res);
|
|
||||||
|
|
||||||
g_bytes_unref (buffer);
|
|
||||||
g_object_unref (encoder);
|
g_object_unref (encoder);
|
||||||
|
|
||||||
|
decoder = g_keyfile_encoder_new ();
|
||||||
|
g_keyfile_encoder_set_section_name (G_KEYFILE_ENCODER (decoder), "Test");
|
||||||
|
decode_data (decoder, buffer);
|
||||||
|
g_object_unref (decoder);
|
||||||
|
g_bytes_unref (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
encoder_markup (void)
|
||||||
|
{
|
||||||
|
GEncoder *encoder, *decoder;
|
||||||
|
GBytes *buffer;
|
||||||
|
|
||||||
|
encoder = g_markup_encoder_new ();
|
||||||
|
buffer = encode_data (encoder);
|
||||||
|
g_object_unref (encoder);
|
||||||
|
|
||||||
|
decoder = g_markup_encoder_new ();
|
||||||
|
decode_data (decoder, buffer);
|
||||||
|
g_object_unref (decoder);
|
||||||
|
g_bytes_unref (buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -88,6 +102,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
g_test_add_func ("/encoder/binary", encoder_binary);
|
g_test_add_func ("/encoder/binary", encoder_binary);
|
||||||
g_test_add_func ("/encoder/key-file", encoder_keyfile);
|
g_test_add_func ("/encoder/key-file", encoder_keyfile);
|
||||||
|
g_test_add_func ("/encoder/markup", encoder_markup);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user