Added serialization and deserialization for vfs_path_t object

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2011-06-07 12:22:31 +03:00
parent e7bb47cc2d
commit 3eafe7308a
4 changed files with 337 additions and 2 deletions

View File

@ -8,10 +8,11 @@ LIBS=@CHECK_LIBS@ \
TESTS = \
current_dir \
vfs_prefix_to_class \
get_vfs_class \
vfs_split \
path_serialize \
vfs_path_string_convert \
vfs_prefix_to_class \
vfs_split \
vfs_s_get_path_mangle
check_PROGRAMS = $(TESTS)
@ -22,6 +23,9 @@ current_dir_SOURCES = \
get_vfs_class_SOURCES = \
get_vfs_class.c
path_serialize_SOURCES = \
path_serialize.c
vfs_split_SOURCES = \
vfs_split.c

View File

@ -0,0 +1,163 @@
/* lib/vfs - vfs_path_t serialize/deserialize functions
Copyright (C) 2011 Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2011
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define TEST_SUITE_NAME "/lib/vfs"
#include <check.h>
#include "lib/global.c"
#ifndef HAVE_CHARSET
#define HAVE_CHARSET 1
#endif
#include "lib/charsets.h"
#include "lib/strutil.h"
#include "lib/vfs/xdirentry.h"
#include "lib/vfs/path.h"
#include "src/vfs/local/local.c"
struct vfs_s_subclass test_subclass1, test_subclass2, test_subclass3;
struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
static void
setup (void)
{
str_init_strings (NULL);
vfs_init ();
init_localfs ();
vfs_setup_work_dir ();
test_subclass1.flags = VFS_S_REMOTE;
vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
vfs_test_ops1.name = "testfs1";
vfs_test_ops1.flags = VFSF_NOLINKS;
vfs_test_ops1.prefix = "test1:";
vfs_register_class (&vfs_test_ops1);
vfs_s_init_class (&vfs_test_ops2, &test_subclass2);
vfs_test_ops2.name = "testfs2";
vfs_test_ops2.prefix = "test2:";
vfs_register_class (&vfs_test_ops2);
vfs_s_init_class (&vfs_test_ops3, &test_subclass3);
vfs_test_ops3.name = "testfs3";
vfs_test_ops3.prefix = "test3:";
vfs_register_class (&vfs_test_ops3);
mc_global.sysconfig_dir = (char *) TEST_SHARE_DIR;
load_codepages_list ();
}
static void
teardown (void)
{
free_codepages_list ();
vfs_shut ();
str_uninit_strings ();
}
/* --------------------------------------------------------------------------------------------- */
#define ETALON_PATH_STR "/local/path/#test1:user:pass@some.host:12345/bla-bla/some/path/#test2:/#enc:KOI8-R/bla-bla/some/path#test3:/111/22/33"
#define ETALON_SERIALIZED_PATH "g14:path-element-0p4:pathv12:/local/path/p10:class-namev7:localfs" \
"g14:path-element-1p4:pathv18:bla-bla/some/path/p10:class-namev7:testfs1p11:raw_url_strv31:test1:user:pass@some.host:12345" \
"g14:path-element-2p4:pathv17:bla-bla/some/pathp10:class-namev7:testfs2p8:encodingv6:KOI8-Rp11:raw_url_strv6:test2:" \
"g14:path-element-3p4:pathv9:111/22/33p10:class-namev7:testfs3p11:raw_url_strv6:test3:"
START_TEST (test_path_serialize_deserialize)
{
vfs_path_t *vpath;
char *serialized_vpath;
GError *error = NULL;
vpath = vfs_path_from_str (ETALON_PATH_STR);
serialized_vpath = vfs_path_serialize (vpath, &error);
vfs_path_free (vpath);
if (serialized_vpath == NULL)
{
fail ("serialized_vpath is NULL!\nError code is '%d'; error message is '%s'", error->code, error->message);
g_clear_error (&error);
return;
}
fail_unless (
strcmp (serialized_vpath, ETALON_SERIALIZED_PATH ) == 0,
"serialized_vpath (%s) doesn't equal to etalon (%s)", serialized_vpath, ETALON_SERIALIZED_PATH
);
vpath = vfs_path_deserialize (serialized_vpath, &error);
g_free (serialized_vpath);
if (vpath == NULL)
{
fail ("vpath is NULL!\nError code is '%d'; error message is '%s'", error->code, error->message);
g_clear_error (&error);
return;
}
serialized_vpath = vfs_path_to_str (vpath);
fail_unless (
strcmp (serialized_vpath, ETALON_PATH_STR) == 0,
"\ndeserialized path (%s)\nnot equal to etalon (%s)", serialized_vpath, ETALON_PATH_STR
);
vfs_path_free(vpath);
g_free(serialized_vpath);
}
END_TEST
/* --------------------------------------------------------------------------------------------- */
int
main (void)
{
int number_failed;
Suite *s = suite_create (TEST_SUITE_NAME);
TCase *tc_core = tcase_create ("Core");
SRunner *sr;
tcase_add_checked_fixture (tc_core, setup, teardown);
/* Add new tests here: *************** */
tcase_add_test (tc_core, test_path_serialize_deserialize);
/* *********************************** */
suite_add_tcase (s, tc_core);
sr = srunner_create (s);
srunner_set_log (sr, "path_serialize.log");
srunner_run_all (sr, CK_NORMAL);
number_failed = srunner_ntests_failed (sr);
srunner_free (sr);
return (number_failed == 0) ? 0 : 1;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -35,6 +35,7 @@
#include "lib/global.h"
#include "lib/strutil.h"
#include "lib/util.h" /* concat_dir_and_file */
#include "lib/serialize.h"
#include "vfs.h"
#include "utilvfs.h"
@ -198,6 +199,33 @@ vfs_get_encoding (const char *path)
}
}
/* --------------------------------------------------------------------------------------------- */
/**
* get VFS class for the given name
*
* @param class_name name of class
*
* @return pointer to class structure or NULL if class not found
*/
static struct vfs_class *
vfs_get_class_by_name (const char *class_name)
{
guint i;
if (class_name == NULL)
return NULL;
for (i = 0; i < vfs__classes_list->len; i++)
{
struct vfs_class *vfs = (struct vfs_class *) g_ptr_array_index (vfs__classes_list, i);
if ((vfs->name != NULL) && (strcmp (vfs->name, class_name) == 0))
return vfs;
}
return NULL;
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
@ -463,3 +491,140 @@ vfs_path_element_need_cleanup_converter (const vfs_path_element_t * element)
}
/* --------------------------------------------------------------------------------------------- */
/**
* Serialize vfs_path_t object to string
*
* @param vpath data for serialization
* @param error contain pointer to object for handle error code and message
*
* @return serialized vpath as newly allocated string
*/
char *
vfs_path_serialize (const vfs_path_t * vpath, GError ** error)
{
mc_config_t *cpath = mc_config_init (NULL);
ssize_t element_index;
char *ret_value;
if ((vpath == NULL) || (vfs_path_elements_count (vpath) == 0))
{
g_set_error (error, MC_ERROR, -1, "vpath object is empty");
return NULL;
}
for (element_index = 0; element_index < vfs_path_elements_count (vpath); element_index++)
{
char *groupname = g_strdup_printf ("path-element-%zd", element_index);
vfs_path_element_t *element = vfs_path_get_by_index (vpath, element_index);
/* convert one element to config group */
mc_config_set_string_raw (cpath, groupname, "path", element->path);
mc_config_set_string_raw (cpath, groupname, "class-name", element->class->name);
mc_config_set_string_raw (cpath, groupname, "encoding", element->encoding);
mc_config_set_string_raw (cpath, groupname, "raw_url_str", element->raw_url_str);
if (element->url != NULL)
{
mc_config_set_bool (cpath, groupname, "has-url", TRUE);
mc_config_set_string_raw (cpath, groupname, "url-user", element->url->user);
mc_config_set_string_raw (cpath, groupname, "url-password", element->url->password);
mc_config_set_string_raw (cpath, groupname, "url-host", element->url->host);
mc_config_set_int (cpath, groupname, "url-port", element->url->port);
mc_config_set_string_raw (cpath, groupname, "url-path", element->url->path);
}
g_free (groupname);
}
ret_value = mc_serialize_config (cpath, error);
mc_config_deinit (cpath);
return ret_value;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Deserialize string to vfs_path_t object
*
* @param data data for serialization
* @param error contain pointer to object for handle error code and message
*
* @return newly allocated vfs_path_t object
*/
vfs_path_t *
vfs_path_deserialize (const char *data, GError ** error)
{
mc_config_t *cpath = mc_deserialize_config (data, error);
size_t element_index = 0;
vfs_path_t *vpath;
if (cpath == NULL)
return NULL;
vpath = vfs_path_new ();
while (TRUE)
{
vfs_path_element_t *element;
char *cfg_value;
char *groupname;
groupname = g_strdup_printf ("path-element-%zd", element_index);
if (!mc_config_has_group (cpath, groupname))
{
g_free (groupname);
break;
}
element = g_new0 (vfs_path_element_t, 1);
element->dir.converter = INVALID_CONV;
cfg_value = mc_config_get_string_raw (cpath, groupname, "class-name", NULL);
element->class = vfs_get_class_by_name (cfg_value);
if (element->class == NULL)
{
g_free (element);
vfs_path_free (vpath);
g_set_error (error, MC_ERROR, -1, "Unable to find VFS class by name '%s'", cfg_value);
g_free (cfg_value);
mc_config_deinit (cpath);
return NULL;
}
g_free (cfg_value);
element->path = mc_config_get_string_raw (cpath, groupname, "path", NULL);
element->encoding = mc_config_get_string_raw (cpath, groupname, "encoding", NULL);
element->raw_url_str = mc_config_get_string_raw (cpath, groupname, "raw_url_str", NULL);
if (mc_config_get_bool (cpath, groupname, "has-url", FALSE))
{
element->url = g_new0 (vfs_url_t, 1);
element->url->user = mc_config_get_string_raw (cpath, groupname, "url-user", NULL);
element->url->password =
mc_config_get_string_raw (cpath, groupname, "url-password", NULL);
element->url->host = mc_config_get_string_raw (cpath, groupname, "url-host", NULL);
element->url->port = mc_config_get_int (cpath, groupname, "url-port", 0);
element->url->path = mc_config_get_string_raw (cpath, groupname, "url-path", NULL);
}
vpath->path = g_list_append (vpath->path, element);
g_free (groupname);
element_index++;
}
mc_config_deinit (cpath);
if (vfs_path_elements_count (vpath) == 0)
{
vfs_path_free (vpath);
g_set_error (error, MC_ERROR, -1, "No any path elements found");
return NULL;
}
return vpath;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -52,6 +52,9 @@ struct vfs_class *vfs_prefix_to_class (const char *prefix);
gboolean vfs_path_element_need_cleanup_converter (const vfs_path_element_t * element);
char *vfs_path_serialize (const vfs_path_t * vpath, GError ** error);
vfs_path_t *vfs_path_deserialize (const char *data, GError ** error);
/*** inline functions ****************************************************************************/
#endif