mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Added serialization and deserialization for vfs_path_t object
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
e7bb47cc2d
commit
3eafe7308a
@ -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
|
||||
|
||||
|
163
lib/tests/vfs/path_serialize.c
Normal file
163
lib/tests/vfs/path_serialize.c
Normal 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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
165
lib/vfs/path.c
165
lib/vfs/path.c
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user