Tony Asleson
2014-04-08 21:50:34 UTC
Will be useful to C plug-in writers.
Signed-off-by: Tony Asleson <***@redhat.com>
---
.../libstoragemgmt/libstoragemgmt_plug_interface.h | 16 ++++
src/Makefile.am | 3 +-
src/lsm_plugin_ipc.cpp | 89 +++++++++++++++++++++-
src/util/qparams.h | 26 ++-----
test/tester.c | 37 +++++++++
5 files changed, 146 insertions(+), 25 deletions(-)
diff --git a/include/libstoragemgmt/libstoragemgmt_plug_interface.h b/include/libstoragemgmt/libstoragemgmt_plug_interface.h
index 28ae176..af212d2 100644
--- a/include/libstoragemgmt/libstoragemgmt_plug_interface.h
+++ b/include/libstoragemgmt/libstoragemgmt_plug_interface.h
@@ -1251,6 +1251,22 @@ lsm_storage_capabilities LSM_DLL_EXPORT *lsm_capability_record_alloc(char const
*/
lsm_optional_data LSM_DLL_EXPORT *lsm_optional_data_record_alloc(void);
+
+/**
+ * Convenience function for plug-in writer.
+ * Note: Make sure to free returned items to prevent memory leaks.
+ * @param[in] uri
+ * @param[out] scheme
+ * @param[out] user
+ * @param[out] server
+ * @param[out] port
+ * @param[out] query_params
+ * @return LSM_ERR_OK on successful parse, else error reason.
+ */
+int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme, char **user,
+ char **server, int *port, char **path,
+ lsm_optional_data **query_params);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 0cb17a2..0c10a68 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,8 @@ libstoragemgmt_la_LIBADD=$(LIBXML_LIBS) $(YAJL_LIBS) $(LIBGLIB_LIBS)
libstoragemgmt_la_LDFLAGS=
libstoragemgmt_la_SOURCES=lsm_mgmt.cpp lsm_datatypes.hpp lsm_datatypes.cpp \
lsm_convert.hpp lsm_convert.cpp lsm_ipc.hpp lsm_ipc.cpp \
- lsm_plugin_ipc.hpp lsm_plugin_ipc.cpp
+ lsm_plugin_ipc.hpp lsm_plugin_ipc.cpp util/qparams.c \
+ util/qparams.h
DEPS = $(top_builddir)/src/libstoragemgmt.la
diff --git a/src/lsm_plugin_ipc.cpp b/src/lsm_plugin_ipc.cpp
index 9dd2359..86cb7f8 100644
--- a/src/lsm_plugin_ipc.cpp
+++ b/src/lsm_plugin_ipc.cpp
@@ -28,13 +28,14 @@
#include "libstoragemgmt/libstoragemgmt_fs.h"
#include "libstoragemgmt/libstoragemgmt_snapshot.h"
#include "libstoragemgmt/libstoragemgmt_nfsexport.h"
-#include <libstoragemgmt/libstoragemgmt_plug_interface.h>
-#include <libstoragemgmt/libstoragemgmt_volumes.h>
-#include <libstoragemgmt/libstoragemgmt_pool.h>
-#include <libstoragemgmt/libstoragemgmt_initiators.h>
+#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
+#include "libstoragemgmt/libstoragemgmt_volumes.h"
+#include "libstoragemgmt/libstoragemgmt_pool.h"
+#include "libstoragemgmt/libstoragemgmt_initiators.h"
#include <errno.h>
#include <string.h>
#include <libxml/uri.h>
+#include "util/qparams.h"
#include <syslog.h>
//Forward decl.
@@ -2505,3 +2506,83 @@ int lsm_plugin_error_log( lsm_plugin_ptr plug, lsm_error_ptr error)
return LSM_ERR_OK;
}
+
+
+#define STR_D(c, s) \
+do { \
+ if(s) { \
+ (c) = strdup(s); \
+ if( !c ) {\
+ rc = LSM_ERR_NO_MEMORY; \
+ goto bail; \
+ } \
+ } \
+} while(0)\
+
+int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme, char **user,
+ char **server, int *port, char **path,
+ lsm_optional_data **query_params)
+{
+ int rc = LSM_ERR_INVALID_URI;
+ xmlURIPtr u = NULL;
+
+ if( uri && strlen(uri) > 0 ) {
+ *scheme = NULL;
+ *user = NULL;
+ *server = NULL;
+ *port = -1;
+ *path = NULL;
+ *query_params = NULL;
+
+ u = xmlParseURI(uri);
+ if( u ) {
+ STR_D(*scheme, u->scheme);
+ STR_D(*user, u->user);
+ STR_D(*server, u->server);
+ STR_D(*path, u->path);
+ *port = u->port;
+
+ *query_params = lsm_optional_data_record_alloc();
+ if( *query_params ) {
+ int i;
+ struct qparam_set *qp = NULL;
+ qp = qparam_query_parse(u->query_raw);
+
+ for( i = 0; i < qp->n; ++i ) {
+ rc = lsm_optional_data_string_set(*query_params,
+ qp->p[i].name,
+ qp->p[i].value);
+ if( LSM_ERR_OK != rc ) {
+ goto bail;
+ }
+ }
+ } else {
+ rc = LSM_ERR_NO_MEMORY;
+ goto bail;
+ }
+
+ rc = LSM_ERR_OK;
+ }
+
+ bail:
+ if( rc != LSM_ERR_OK ){
+ free(*scheme);
+ *scheme = NULL;
+ free(*user);
+ *user = NULL;
+ free(*server);
+ *server = NULL;
+ *port = -1;
+ free(*path);
+ *path = NULL;
+ lsm_optional_data_record_free(*query_params);
+ *query_params = NULL;
+ }
+
+ if( u ) {
+ xmlFreeURI(u);
+ u = NULL;
+ }
+ }
+ return rc;
+}
\ No newline at end of file
diff --git a/src/util/qparams.h b/src/util/qparams.h
index 9009560..ca5ddb4 100644
--- a/src/util/qparams.h
+++ b/src/util/qparams.h
@@ -31,21 +31,7 @@
extern "C" {
#endif
-#if defined _WIN32 || defined __CYGWIN__
- #define QPARAM_DLL_IMPORT __declspec(dllimport)
- #define QPARAM_DLL_EXPORT __declspec(dllexport)
- #define QPARAM_DLL_LOCAL
-#else
- #if __GNUC__ >= 4
- #define QPARAM_DLL_IMPORT __attribute__ ((visibility ("default")))
- #define QPARAM_DLL_EXPORT __attribute__ ((visibility ("default")))
- #define QPARAM_DLL_LOCAL __attribute__ ((visibility ("hidden")))
- #else
- #define QPARAM_DLL_IMPORT
- #define QPARAM_DLL_EXPORT
- #define QPARAM_DLL_LOCAL
- #endif
-#endif
+#include "libstoragemgmt/libstoragemgmt_common.h"
/**
* * ATTRIBUTE_SENTINEL:
@@ -80,20 +66,20 @@ struct qparam_set {
};
/* New parameter set. */
-QPARAM_DLL_LOCAL struct qparam_set *new_qparam_set (int init_alloc, ...)
+LSM_DLL_LOCAL struct qparam_set *new_qparam_set (int init_alloc, ...)
ATTRIBUTE_SENTINEL;
/* Appending parameters. */
-QPARAM_DLL_LOCAL int append_qparams (struct qparam_set *ps, ...)
+LSM_DLL_LOCAL int append_qparams (struct qparam_set *ps, ...)
ATTRIBUTE_SENTINEL;
-QPARAM_DLL_LOCAL int append_qparam (struct qparam_set *ps,
+LSM_DLL_LOCAL int append_qparam (struct qparam_set *ps,
const char *name, const char *value);
/* Parse a query string into a parameter set. */
-QPARAM_DLL_LOCAL struct qparam_set *qparam_query_parse (const char *query);
+LSM_DLL_LOCAL struct qparam_set *qparam_query_parse (const char *query);
-QPARAM_DLL_LOCAL void free_qparam_set (struct qparam_set *ps);
+LSM_DLL_LOCAL void free_qparam_set (struct qparam_set *ps);
#ifdef __cplusplus
}
diff --git a/test/tester.c b/test/tester.c
index b577b23..f1288c3 100644
--- a/test/tester.c
+++ b/test/tester.c
@@ -2610,6 +2610,42 @@ START_TEST(test_pool_create)
}
END_TEST
+START_TEST(test_uri_parse)
+{
+ const char uri_g[] = "sim://***@host:123/path/?namespace=root/uber";
+ char *scheme = NULL;
+ char *user = NULL;
+ char *server = NULL;
+ char *path = NULL;
+ int port = 0;
+ lsm_optional_data *qp = NULL;
+ int rc = lsm_uri_parse(uri_g, &scheme, &user, &server, &port, &path, &qp);
+
+ fail_unless(LSM_ERR_OK == rc, "lsm_uri_parse %d", rc);
+
+ if( LSM_ERR_OK == rc ) {
+ fail_unless(strcmp(scheme, "sim") == 0, "%s", scheme);
+ fail_unless(strcmp(user, "user") == 0, "%s", user);
+ fail_unless(strcmp(server, "host") == 0, "%s", server);
+ fail_unless(strcmp(path, "/path/") == 0, "%s", path);
+ fail_unless(port == 123, "%d", port);
+
+ fail_unless(qp != NULL);
+ if( qp ) {
+ fail_unless(strcmp("root/uber",
+ lsm_optional_data_string_get(qp, "namespace")) == 0,
+ "%s", lsm_optional_data_string_get(qp, "namespace"));
+ }
+
+ free(scheme);
+ free(user);
+ free(server);
+ free(path);
+ lsm_optional_data_record_free(qp);
+ }
+}
+END_TEST
+
Suite * lsm_suite(void)
{
Suite *s = suite_create("libStorageMgmt");
@@ -2620,6 +2656,7 @@ Suite * lsm_suite(void)
tcase_add_test(basic, test_pool_delete);
tcase_add_test(basic, test_pool_create);
+ tcase_add_test(basic, test_uri_parse);
tcase_add_test(basic, test_error_reporting);
tcase_add_test(basic, test_capability);
Signed-off-by: Tony Asleson <***@redhat.com>
---
.../libstoragemgmt/libstoragemgmt_plug_interface.h | 16 ++++
src/Makefile.am | 3 +-
src/lsm_plugin_ipc.cpp | 89 +++++++++++++++++++++-
src/util/qparams.h | 26 ++-----
test/tester.c | 37 +++++++++
5 files changed, 146 insertions(+), 25 deletions(-)
diff --git a/include/libstoragemgmt/libstoragemgmt_plug_interface.h b/include/libstoragemgmt/libstoragemgmt_plug_interface.h
index 28ae176..af212d2 100644
--- a/include/libstoragemgmt/libstoragemgmt_plug_interface.h
+++ b/include/libstoragemgmt/libstoragemgmt_plug_interface.h
@@ -1251,6 +1251,22 @@ lsm_storage_capabilities LSM_DLL_EXPORT *lsm_capability_record_alloc(char const
*/
lsm_optional_data LSM_DLL_EXPORT *lsm_optional_data_record_alloc(void);
+
+/**
+ * Convenience function for plug-in writer.
+ * Note: Make sure to free returned items to prevent memory leaks.
+ * @param[in] uri
+ * @param[out] scheme
+ * @param[out] user
+ * @param[out] server
+ * @param[out] port
+ * @param[out] query_params
+ * @return LSM_ERR_OK on successful parse, else error reason.
+ */
+int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme, char **user,
+ char **server, int *port, char **path,
+ lsm_optional_data **query_params);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 0cb17a2..0c10a68 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,8 @@ libstoragemgmt_la_LIBADD=$(LIBXML_LIBS) $(YAJL_LIBS) $(LIBGLIB_LIBS)
libstoragemgmt_la_LDFLAGS=
libstoragemgmt_la_SOURCES=lsm_mgmt.cpp lsm_datatypes.hpp lsm_datatypes.cpp \
lsm_convert.hpp lsm_convert.cpp lsm_ipc.hpp lsm_ipc.cpp \
- lsm_plugin_ipc.hpp lsm_plugin_ipc.cpp
+ lsm_plugin_ipc.hpp lsm_plugin_ipc.cpp util/qparams.c \
+ util/qparams.h
DEPS = $(top_builddir)/src/libstoragemgmt.la
diff --git a/src/lsm_plugin_ipc.cpp b/src/lsm_plugin_ipc.cpp
index 9dd2359..86cb7f8 100644
--- a/src/lsm_plugin_ipc.cpp
+++ b/src/lsm_plugin_ipc.cpp
@@ -28,13 +28,14 @@
#include "libstoragemgmt/libstoragemgmt_fs.h"
#include "libstoragemgmt/libstoragemgmt_snapshot.h"
#include "libstoragemgmt/libstoragemgmt_nfsexport.h"
-#include <libstoragemgmt/libstoragemgmt_plug_interface.h>
-#include <libstoragemgmt/libstoragemgmt_volumes.h>
-#include <libstoragemgmt/libstoragemgmt_pool.h>
-#include <libstoragemgmt/libstoragemgmt_initiators.h>
+#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
+#include "libstoragemgmt/libstoragemgmt_volumes.h"
+#include "libstoragemgmt/libstoragemgmt_pool.h"
+#include "libstoragemgmt/libstoragemgmt_initiators.h"
#include <errno.h>
#include <string.h>
#include <libxml/uri.h>
+#include "util/qparams.h"
#include <syslog.h>
//Forward decl.
@@ -2505,3 +2506,83 @@ int lsm_plugin_error_log( lsm_plugin_ptr plug, lsm_error_ptr error)
return LSM_ERR_OK;
}
+
+
+#define STR_D(c, s) \
+do { \
+ if(s) { \
+ (c) = strdup(s); \
+ if( !c ) {\
+ rc = LSM_ERR_NO_MEMORY; \
+ goto bail; \
+ } \
+ } \
+} while(0)\
+
+int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme, char **user,
+ char **server, int *port, char **path,
+ lsm_optional_data **query_params)
+{
+ int rc = LSM_ERR_INVALID_URI;
+ xmlURIPtr u = NULL;
+
+ if( uri && strlen(uri) > 0 ) {
+ *scheme = NULL;
+ *user = NULL;
+ *server = NULL;
+ *port = -1;
+ *path = NULL;
+ *query_params = NULL;
+
+ u = xmlParseURI(uri);
+ if( u ) {
+ STR_D(*scheme, u->scheme);
+ STR_D(*user, u->user);
+ STR_D(*server, u->server);
+ STR_D(*path, u->path);
+ *port = u->port;
+
+ *query_params = lsm_optional_data_record_alloc();
+ if( *query_params ) {
+ int i;
+ struct qparam_set *qp = NULL;
+ qp = qparam_query_parse(u->query_raw);
+
+ for( i = 0; i < qp->n; ++i ) {
+ rc = lsm_optional_data_string_set(*query_params,
+ qp->p[i].name,
+ qp->p[i].value);
+ if( LSM_ERR_OK != rc ) {
+ goto bail;
+ }
+ }
+ } else {
+ rc = LSM_ERR_NO_MEMORY;
+ goto bail;
+ }
+
+ rc = LSM_ERR_OK;
+ }
+
+ bail:
+ if( rc != LSM_ERR_OK ){
+ free(*scheme);
+ *scheme = NULL;
+ free(*user);
+ *user = NULL;
+ free(*server);
+ *server = NULL;
+ *port = -1;
+ free(*path);
+ *path = NULL;
+ lsm_optional_data_record_free(*query_params);
+ *query_params = NULL;
+ }
+
+ if( u ) {
+ xmlFreeURI(u);
+ u = NULL;
+ }
+ }
+ return rc;
+}
\ No newline at end of file
diff --git a/src/util/qparams.h b/src/util/qparams.h
index 9009560..ca5ddb4 100644
--- a/src/util/qparams.h
+++ b/src/util/qparams.h
@@ -31,21 +31,7 @@
extern "C" {
#endif
-#if defined _WIN32 || defined __CYGWIN__
- #define QPARAM_DLL_IMPORT __declspec(dllimport)
- #define QPARAM_DLL_EXPORT __declspec(dllexport)
- #define QPARAM_DLL_LOCAL
-#else
- #if __GNUC__ >= 4
- #define QPARAM_DLL_IMPORT __attribute__ ((visibility ("default")))
- #define QPARAM_DLL_EXPORT __attribute__ ((visibility ("default")))
- #define QPARAM_DLL_LOCAL __attribute__ ((visibility ("hidden")))
- #else
- #define QPARAM_DLL_IMPORT
- #define QPARAM_DLL_EXPORT
- #define QPARAM_DLL_LOCAL
- #endif
-#endif
+#include "libstoragemgmt/libstoragemgmt_common.h"
/**
* * ATTRIBUTE_SENTINEL:
@@ -80,20 +66,20 @@ struct qparam_set {
};
/* New parameter set. */
-QPARAM_DLL_LOCAL struct qparam_set *new_qparam_set (int init_alloc, ...)
+LSM_DLL_LOCAL struct qparam_set *new_qparam_set (int init_alloc, ...)
ATTRIBUTE_SENTINEL;
/* Appending parameters. */
-QPARAM_DLL_LOCAL int append_qparams (struct qparam_set *ps, ...)
+LSM_DLL_LOCAL int append_qparams (struct qparam_set *ps, ...)
ATTRIBUTE_SENTINEL;
-QPARAM_DLL_LOCAL int append_qparam (struct qparam_set *ps,
+LSM_DLL_LOCAL int append_qparam (struct qparam_set *ps,
const char *name, const char *value);
/* Parse a query string into a parameter set. */
-QPARAM_DLL_LOCAL struct qparam_set *qparam_query_parse (const char *query);
+LSM_DLL_LOCAL struct qparam_set *qparam_query_parse (const char *query);
-QPARAM_DLL_LOCAL void free_qparam_set (struct qparam_set *ps);
+LSM_DLL_LOCAL void free_qparam_set (struct qparam_set *ps);
#ifdef __cplusplus
}
diff --git a/test/tester.c b/test/tester.c
index b577b23..f1288c3 100644
--- a/test/tester.c
+++ b/test/tester.c
@@ -2610,6 +2610,42 @@ START_TEST(test_pool_create)
}
END_TEST
+START_TEST(test_uri_parse)
+{
+ const char uri_g[] = "sim://***@host:123/path/?namespace=root/uber";
+ char *scheme = NULL;
+ char *user = NULL;
+ char *server = NULL;
+ char *path = NULL;
+ int port = 0;
+ lsm_optional_data *qp = NULL;
+ int rc = lsm_uri_parse(uri_g, &scheme, &user, &server, &port, &path, &qp);
+
+ fail_unless(LSM_ERR_OK == rc, "lsm_uri_parse %d", rc);
+
+ if( LSM_ERR_OK == rc ) {
+ fail_unless(strcmp(scheme, "sim") == 0, "%s", scheme);
+ fail_unless(strcmp(user, "user") == 0, "%s", user);
+ fail_unless(strcmp(server, "host") == 0, "%s", server);
+ fail_unless(strcmp(path, "/path/") == 0, "%s", path);
+ fail_unless(port == 123, "%d", port);
+
+ fail_unless(qp != NULL);
+ if( qp ) {
+ fail_unless(strcmp("root/uber",
+ lsm_optional_data_string_get(qp, "namespace")) == 0,
+ "%s", lsm_optional_data_string_get(qp, "namespace"));
+ }
+
+ free(scheme);
+ free(user);
+ free(server);
+ free(path);
+ lsm_optional_data_record_free(qp);
+ }
+}
+END_TEST
+
Suite * lsm_suite(void)
{
Suite *s = suite_create("libStorageMgmt");
@@ -2620,6 +2656,7 @@ Suite * lsm_suite(void)
tcase_add_test(basic, test_pool_delete);
tcase_add_test(basic, test_pool_create);
+ tcase_add_test(basic, test_uri_parse);
tcase_add_test(basic, test_error_reporting);
tcase_add_test(basic, test_capability);
--
1.8.2.1
1.8.2.1