stanza: add xmpp_stanza_new_from_string()
This function creates a stanza object from a string. The string must contain a single complete stanza. Multiple stanzas will lead to memory leak and this is not handled in the patch.
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
- xmpp_conn_is_connecting()
|
- xmpp_conn_is_connecting()
|
||||||
- xmpp_conn_is_connected()
|
- xmpp_conn_is_connected()
|
||||||
- xmpp_conn_is_disconnected()
|
- xmpp_conn_is_disconnected()
|
||||||
|
- xmpp_stanza_new_from_string()
|
||||||
- xmpp_stanza_add_child_ex()
|
- xmpp_stanza_add_child_ex()
|
||||||
- xmpp_stanza_get_context()
|
- xmpp_stanza_get_context()
|
||||||
- xmpp_global_timed_handler_add()
|
- xmpp_global_timed_handler_add()
|
||||||
|
|||||||
57
src/stanza.c
57
src/stanza.c
@@ -22,6 +22,7 @@
|
|||||||
#include "strophe.h"
|
#include "strophe.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
/** Create a stanza object.
|
/** Create a stanza object.
|
||||||
* This function allocates and initializes a blank stanza object.
|
* This function allocates and initializes a blank stanza object.
|
||||||
@@ -1461,3 +1462,59 @@ xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx,
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _stub_stream_start(char *name, char **attrs, void *userdata)
|
||||||
|
{
|
||||||
|
UNUSED(name);
|
||||||
|
UNUSED(attrs);
|
||||||
|
UNUSED(userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _stub_stream_end(char *name, void *userdata)
|
||||||
|
{
|
||||||
|
UNUSED(name);
|
||||||
|
UNUSED(userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _stream_stanza(xmpp_stanza_t *stanza, void *userdata)
|
||||||
|
{
|
||||||
|
stanza = xmpp_stanza_clone(stanza);
|
||||||
|
*(xmpp_stanza_t **)userdata = stanza;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a stanza object from the string.
|
||||||
|
* This function allocates and initializes a stanza object which represents
|
||||||
|
* stanza located in the string.
|
||||||
|
* The stanza will have a reference count of one, so the caller does not
|
||||||
|
* need to clone it.
|
||||||
|
*
|
||||||
|
* @param ctx a Strophe context object
|
||||||
|
* @param str stanza in NULL terminated string representation
|
||||||
|
*
|
||||||
|
* @return a stanza object or NULL on an error
|
||||||
|
*
|
||||||
|
* @ingroup Stanza
|
||||||
|
*/
|
||||||
|
xmpp_stanza_t *xmpp_stanza_new_from_string(xmpp_ctx_t *ctx, const char *str)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t *stanza = NULL;
|
||||||
|
parser_t *parser;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
static const char *start = "<stream>";
|
||||||
|
static const char *end = "</stream>";
|
||||||
|
|
||||||
|
parser = parser_new(ctx, _stub_stream_start, _stub_stream_end,
|
||||||
|
_stream_stanza, &stanza);
|
||||||
|
if (parser) {
|
||||||
|
ret = parser_feed(parser, (char *)start, strlen(start)) &&
|
||||||
|
parser_feed(parser, (char *)str, strlen(str)) &&
|
||||||
|
parser_feed(parser, (char *)end, strlen(end));
|
||||||
|
parser_free(parser);
|
||||||
|
if (!ret && stanza) {
|
||||||
|
xmpp_stanza_release(stanza);
|
||||||
|
stanza = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stanza;
|
||||||
|
}
|
||||||
|
|||||||
@@ -330,6 +330,7 @@ void xmpp_register_stanza_handler(conn, stanza, xmlns, type, handler)
|
|||||||
|
|
||||||
/* allocate and initialize a blank stanza */
|
/* allocate and initialize a blank stanza */
|
||||||
xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx);
|
xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx);
|
||||||
|
xmpp_stanza_t *xmpp_stanza_new_from_string(xmpp_ctx_t *ctx, const char *str);
|
||||||
|
|
||||||
/* clone a stanza */
|
/* clone a stanza */
|
||||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza);
|
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define MAGICPTR ((void *)0xfeedbeef)
|
#define MAGICPTR ((void *)0xfeedbeef)
|
||||||
static unsigned long used_blocks = 0;
|
static unsigned long used_blocks = 0;
|
||||||
@@ -31,7 +32,10 @@ static void stanza_free(void *ptr, void *userdata)
|
|||||||
{
|
{
|
||||||
assert(userdata == MAGICPTR);
|
assert(userdata == MAGICPTR);
|
||||||
|
|
||||||
--used_blocks;
|
if (ptr != NULL) {
|
||||||
|
assert(used_blocks > 0);
|
||||||
|
--used_blocks;
|
||||||
|
}
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +43,14 @@ static void *stanza_realloc(void *ptr, size_t size, void *userdata)
|
|||||||
{
|
{
|
||||||
assert(userdata == MAGICPTR);
|
assert(userdata == MAGICPTR);
|
||||||
|
|
||||||
|
if (ptr != NULL && size == 0) {
|
||||||
|
/* equivalent to free(ptr) */
|
||||||
|
assert(used_blocks > 0);
|
||||||
|
--used_blocks;
|
||||||
|
} else if (ptr == NULL) {
|
||||||
|
/* equivalent to malloc(size) */
|
||||||
|
++used_blocks;
|
||||||
|
}
|
||||||
return realloc(ptr, size);
|
return realloc(ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +90,28 @@ static void test_stanza_add_child(xmpp_ctx_t *ctx)
|
|||||||
assert(used_blocks == baseline);
|
assert(used_blocks == baseline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_stanza_from_string(xmpp_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t *stanza;
|
||||||
|
char *buf;
|
||||||
|
size_t buflen;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
static const char *str =
|
||||||
|
"<signcrypt xmlns=\"urn:xmpp:openpgp:0\"><to "
|
||||||
|
"jid=\"user@domain.com\"/><time "
|
||||||
|
"stamp=\"2020-06-03T21:26:24+0200\"/><rpad/><payload><body "
|
||||||
|
"xmlns=\"jabber:client\">Hello World!</body></payload></signcrypt>";
|
||||||
|
|
||||||
|
stanza = xmpp_stanza_new_from_string(ctx, str);
|
||||||
|
assert(stanza != NULL);
|
||||||
|
ret = xmpp_stanza_to_text(stanza, &buf, &buflen);
|
||||||
|
assert(ret == XMPP_EOK);
|
||||||
|
assert(strcmp(buf, str) == 0);
|
||||||
|
xmpp_free(ctx, buf);
|
||||||
|
xmpp_stanza_release(stanza);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx;
|
xmpp_ctx_t *ctx;
|
||||||
@@ -87,6 +121,7 @@ int main()
|
|||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
|
|
||||||
test_stanza_add_child(ctx);
|
test_stanza_add_child(ctx);
|
||||||
|
test_stanza_from_string(ctx);
|
||||||
|
|
||||||
xmpp_ctx_free(ctx);
|
xmpp_ctx_free(ctx);
|
||||||
xmpp_shutdown();
|
xmpp_shutdown();
|
||||||
|
|||||||
Reference in New Issue
Block a user