sml_parse.c
/*
* libsyncml - A syncml protocol implementation
* Copyright (C) 2005 Armin Bauer <armin.bauer@opensync.org>
* Copyright (C) 2008 Michael Bell <michael.bell@opensync.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.1 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
*
*/
#include "syncml.h"
#include "syncml_internals.h"
#include "sml_error_internals.h"
#include "sml_parse_internals.h"
#include "sml_command_internals.h"
#include "sml_elements_internals.h"
#include "sml_notification_internals.h"
#include "parser/sml_xml_assm.h"
#include "parser/sml_xml_parse.h"
#include "parser/sml_wbxml.h"
SmlParser *smlParserNew(SmlMimeType type, unsigned int limit, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%i, %i, %p)", __func__, type, limit, error);
CHECK_ERROR_REF
SmlParser *parser = smlTryMalloc0(sizeof(SmlParser), error);
if (!parser)
goto error;
parser->type = type;
parser->limit = limit;
switch (type) {
case SML_MIMETYPE_XML:
if (!(parser->parser_userdata = smlXmlParserNew(&(parser->functions), error)))
goto error_free_parser;
break;
case SML_MIMETYPE_SAN:
/* SANs will be converted to normal SyncML 1.1 notifications */
if (!(parser->parser_userdata = smlXmlParserNew(&(parser->functions), error)))
goto error_free_parser;
break;
case SML_MIMETYPE_WBXML:
#ifdef ENABLE_WBXML
if (!(parser->parser_userdata = smlWbxmlParserNew(&(parser->functions), error)))
goto error_free_parser;
break;
#else
smlErrorSet(error, SML_ERROR_GENERIC, "Wbxml not enabled in this build");
goto error_free_parser;
#endif
default:
smlErrorSet(error, SML_ERROR_GENERIC, "Unknown parser type");
goto error_free_parser;
}
smlTrace(TRACE_EXIT, "%s: %p", __func__, parser);
return parser;
error_free_parser:
smlSafeFree((gpointer *)&parser);
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return NULL;
}
void smlParserSetManager(SmlParser *parser, SmlManager *manager)
{
smlAssert(parser);
smlAssert(manager);
parser->manager = manager;
}
void smlParserFree(SmlParser *parser)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, parser);
smlAssert(parser);
if (parser->functions.free)
parser->functions.free(parser->parser_userdata);
smlSafeFree((gpointer *)&parser);
smlTrace(TRACE_EXIT, "%s", __func__);
}
SmlBool smlParserStart(SmlParser *parser, const char *data, unsigned int size, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, parser, data, size, error);
CHECK_ERROR_REF
smlAssert(parser);
smlAssert(data);
smlAssert(size);
smlAssert(parser->functions.start);
smlAssertMsg(parser->type != SML_MIMETYPE_SAN || parser->manager,
SML_ASSERT_MSG_SAN_PARSE_REQUIRES_MANAGER);
if (parser->limit && size > parser->limit) {
smlErrorSet(error, SML_ERROR_GENERIC, "Input data too large");
goto error;
}
if (parser->type == SML_MIMETYPE_SAN) {
/* convert OMA DS 1.2 SAN into an SyncML 1.1 notification */
smlTrace(TRACE_INTERNAL, "%s - detected an OMA DS 1.2 SAN", __func__);
/* parse the SAN */
SmlNotification *san = smlNotificationParse(data, size, error);
if (!san)
goto error;
/* fix 1.2 SAN for use with SyncML 1.1 */
smlNotificationSetManager(san, parser->manager);
san->type = SML_MIMETYPE_XML;
san->sessionType = SML_SESSION_TYPE_CLIENT;
san->target = smlLocationNew("/", NULL, error);
if (!san->target)
goto error;
/* assemble a SyncML 1.1 notification */
char *xmlData = NULL;
unsigned int xmlSize = 0;
if (!smlNotificationAssemble11(san, &xmlData, &xmlSize, SML_VERSION_12, error))
{
smlNotificationFree(san);
goto error;
}
smlTrace(TRACE_INTERNAL,
"%s - converted OMA DS 1.2 SAN to SyncML 1.1 server alerted sync - %s",
__func__, VA_STRING(xmlData));
/* cleanup notification */
smlNotificationFree(san);
san = NULL;
/* run the parser on the converted SAN */
if (!parser->functions.start(parser->parser_userdata, xmlData, xmlSize, error)) {
smlSafeCFree(&xmlData);
goto error;
}
smlSafeCFree(&xmlData);
} else {
/* run the parser directly on the data */
if (!parser->functions.start(parser->parser_userdata, data, size, error))
goto error;
}
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlBool smlParserGetHeader(SmlParser *parser, SmlHeader **header, SmlCred **cred, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, header, cred, error);
CHECK_ERROR_REF
smlAssert(parser);
smlAssert(header);
smlAssert(cred);
smlAssert(parser->functions.get_header);
if (!parser->functions.get_header(parser->parser_userdata, header, cred, error))
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlParserResult smlParserGetCommand(SmlParser *parser, SmlCommand **cmd, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
CHECK_ERROR_REF
smlAssert(parser);
smlAssert(cmd);
smlAssert(parser->functions.get_cmd);
SmlParserResult result = SML_PARSER_RESULT_ERROR;
if (!(result = parser->functions.get_cmd(parser->parser_userdata, cmd, error)))
goto error;
smlTrace(TRACE_EXIT, "%s: %i", __func__, result);
return result;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return SML_PARSER_RESULT_ERROR;
}
SmlBool smlParserGetStatus(SmlParser *parser, SmlStatus **status, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, status, error);
CHECK_ERROR_REF
smlAssert(parser);
smlAssert(status);
smlAssert(parser->functions.get_status);
if (!parser->functions.get_status(parser->parser_userdata, status, error))
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlBool smlParserEnd(SmlParser *parser, SmlBool *final, SmlBool *end, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, parser, final, end, error);
CHECK_ERROR_REF
smlAssert(parser);
smlAssert(parser->functions.end);
if (!parser->functions.end(parser->parser_userdata, final, end, error))
goto error;
smlTrace(TRACE_INTERNAL, "%s: Final %i, End %i", __func__, final ? *final : -1, end ? *end : -1);
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlAssembler *smlAssemblerNew(SmlMimeType type, unsigned int limit, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%i, %i, %p)", __func__, type, limit, error);
CHECK_ERROR_REF
SmlAssembler *assm = smlTryMalloc0(sizeof(SmlAssembler), error);
if (!assm)
goto error;
assm->type = type;
assm->remoteMaxMsgSize = limit;
assm->empty = TRUE;
assm->remoteMaxObjSize = 0;
switch (type) {
case SML_MIMETYPE_XML:
if (!(assm->assm_userdata = smlXmlAssemblerNew(assm, &(assm->functions), error)))
goto error_free_assm;
break;
case SML_MIMETYPE_WBXML:
#ifdef ENABLE_WBXML
if (!(assm->assm_userdata = smlWbxmlAssemblerNew(assm, &(assm->functions), error)))
goto error_free_assm;
break;
#else
smlErrorSet(error, SML_ERROR_GENERIC, "Wbxml not enabled in this build");
goto error_free_assm;
#endif
default:
smlErrorSet(error, SML_ERROR_GENERIC, "Unknown assembler type");
goto error_free_assm;
}
assm->options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
smlTrace(TRACE_EXIT, "%s: %p", __func__, assm);
return assm;
error_free_assm:
smlSafeFree((gpointer *)&assm);
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return NULL;
}
void smlAssemblerFree(SmlAssembler *assm)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
smlAssert(assm);
if (assm->functions.free)
assm->functions.free(assm->assm_userdata);
g_hash_table_destroy(assm->options);
smlSafeFree((gpointer *)&assm);
smlTrace(TRACE_EXIT, "%s", __func__);
}
SmlBool smlAssemblerStart(SmlAssembler *assm, SmlSession *session, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assm, session, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(session);
smlAssert(assm->functions.start);
if (!assm->functions.start(assm->assm_userdata, session, error))
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlBool smlAssemblerRun(SmlAssembler *assm, char **data, unsigned int *size, SmlBool *end, SmlBool final, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %i, %p)", __func__, assm, data, size, end, final, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(data);
smlAssert(size);
smlAssert(assm->functions.run);
if (!assm->functions.run(assm->assm_userdata, data, size, end, final, smlAssemblerGetRemoteMaxMsgSize(assm), error))
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
unsigned int smlAssemblerCheckSize(SmlAssembler *assm, SmlBool headeronly, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, assm, headeronly, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(assm->functions.check_size);
unsigned int size = 0;
if (!(size = assm->functions.check_size(assm->assm_userdata, headeronly, error)))
goto error;
smlTrace(TRACE_EXIT, "%s: %i", __func__, size);
return size;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return 0;
}
unsigned int smlAssemblerFlush(SmlAssembler *assm)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
smlAssert(assm);
smlAssert(assm->functions.flush);
unsigned int ret = assm->functions.flush(assm->assm_userdata);
assm->empty = TRUE;
smlTrace(TRACE_EXIT, "%s: %i", __func__, ret);
return ret;
}
void smlAssemblerRestoreCommands(SmlAssembler *assm)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
smlAssert(assm);
smlAssert(assm->functions.restore_cmds);
assm->functions.restore_cmds(assm->assm_userdata);
assm->empty = FALSE;
smlTrace(TRACE_EXIT, "%s", __func__);
}
SmlBool smlAssemblerGetSpace(SmlAssembler *assm, int *space, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, assm, space, parent, cmd, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(space);
smlAssert(cmd);
smlAssert(assm->functions.start_cmd);
smlAssert(assm->functions.rem_cmd);
smlAssert(cmd->type == SML_COMMAND_TYPE_ADD || cmd->type == SML_COMMAND_TYPE_REPLACE);
unsigned int parentID = 0;
int limit = smlAssemblerGetRemoteMaxMsgSize(assm);
if (!limit) {
*space = -1;
smlTrace(TRACE_EXIT, "%s: No limit", __func__);
return TRUE;
}
/* Add the command */
if (parent) {
if (!parent->cmdID) {
smlErrorSet(error, SML_ERROR_GENERIC, "Parent has to be added before");
goto error;
}
parentID = parent->cmdID;
}
/* disable the items */
if (cmd->private.change.items)
{
guint i;
for (i=0; i < g_list_length(cmd->private.change.items); i++)
{
SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
item->disabled = TRUE;
}
}
SmlBool noCmdID = FALSE;
if (!cmd->cmdID) {
noCmdID = TRUE;
/* FIXME: This code does not support more
* FIXME: than 99.999 commands in one session. */
cmd->cmdID = 10000;
}
if (!assm->functions.start_cmd(assm->assm_userdata, parentID, cmd, error))
goto error_enable_item;
/* Now check the size */
int size = 0;
if (!(size = smlAssemblerCheckSize(assm, FALSE, error)))
goto error_remove;
if (limit <= size)
*space = 0;
else
*space = limit - size - 10;
/* Remove the command again */
if (!assm->functions.rem_cmd(assm->assm_userdata, parentID, error))
goto error_remove;
/* enable the items again */
if (cmd->private.change.items)
{
guint i;
for (i=0; i < g_list_length(cmd->private.change.items); i++)
{
SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
item->disabled = FALSE;
}
}
if (noCmdID)
cmd->cmdID = 0;
smlTrace(TRACE_EXIT, "%s: %i", __func__, *space);
return TRUE;
error_remove:
assm->functions.rem_cmd(assm->assm_userdata, parentID, NULL);
error_enable_item:
if (cmd->private.change.items)
{
guint i;
for (i=0; i < g_list_length(cmd->private.change.items); i++)
{
SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
item->disabled = FALSE;
}
}
if (noCmdID)
cmd->cmdID = 0;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlAssemblerResult smlAssemblerStartCommand(SmlAssembler *assm, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, assm, parent, cmd, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(cmd);
smlAssert(assm->functions.start_cmd);
smlAssert(assm->functions.rem_cmd);
unsigned int parentID = 0;
/* Add the command */
if (parent) {
if (!parent->cmdID) {
smlErrorSet(error, SML_ERROR_GENERIC, "Parent has to be added before");
goto error;
}
parentID = parent->cmdID;
}
if (!assm->functions.start_cmd(assm->assm_userdata, parentID, cmd, error))
goto error;
/* Lets see if the new buffer is small enough */
int limit = smlAssemblerGetRemoteMaxMsgSize(assm);
if (limit) {
/* Now check the size */
int size = 0;
if (!(size = smlAssemblerCheckSize(assm, FALSE, error)))
goto error;
if (size > limit) {
/* The status does not fit. Remove it again */
if (!assm->functions.rem_cmd(assm->assm_userdata, parentID, error))
goto error;
smlTrace(TRACE_EXIT, "%s: Mismatch", __func__);
return SML_ASSEMBLER_RESULT_MISMATCH;
}
smlTrace(TRACE_INTERNAL, "%s: size %i, limit %i", __func__, size, limit);
}
if (cmd->cmdID)
assm->empty = FALSE;
smlTrace(TRACE_EXIT, "%s", __func__);
return SML_ASSEMBLER_RESULT_OK;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return SML_ASSEMBLER_RESULT_ERROR;
}
SmlBool smlAssemblerEndCommand(SmlAssembler *assm, SmlCommand *parent, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assm, parent, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(assm->functions.end_cmd);
unsigned int parentID = 0;
/* Add the command */
if (parent) {
if (!parent->cmdID) {
smlErrorSet(error, SML_ERROR_GENERIC, "Parent has to be added before");
goto error;
}
parentID = parent->cmdID;
}
/* End the command */
if (!assm->functions.end_cmd(assm->assm_userdata, parentID, error))
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlBool smlAssemblerAddHeader(SmlAssembler *assm, SmlSession *session, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assm, session, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(session);
smlAssert(assm->functions.add_header);
/* Add the command */
if (!assm->functions.add_header(assm->assm_userdata, session, error))
goto error;
/* Now check the size */
unsigned int size = 0;
if (!(size = smlAssemblerCheckSize(assm, TRUE, error)))
goto error;
/* Lets see if the new buffer is small enough */
if (smlAssemblerGetRemoteMaxMsgSize(assm) && size > smlAssemblerGetRemoteMaxMsgSize(assm)) {
smlErrorSet(error, SML_ERROR_GENERIC, "Limit to small. Unable to fit a the header");
goto error;
}
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlAssemblerResult smlAssemblerReserveStatus(SmlAssembler *assm, unsigned int cmdRef, unsigned int msgRef, unsigned int cmdID, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %i, %i, %i, %p)", __func__, assm, cmdRef, msgRef, cmdID, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(assm->functions.reserve_status);
/* Reserve the status */
if (!assm->functions.reserve_status(assm->assm_userdata, cmdRef, msgRef, cmdID, error))
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlAssemblerResult smlAssemblerAddStatusFull(SmlAssembler *assm, SmlStatus *status, SmlBool force, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, assm, status, force, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(status);
smlAssert(assm->functions.add_status);
smlAssert(assm->functions.rem_status);
/* Add the status */
if (!assm->functions.add_status(assm->assm_userdata, status, error))
goto error;
if (!force) {
/* Lets see if the new buffer is small enough */
int limit = smlAssemblerGetRemoteMaxMsgSize(assm);
if (limit) {
/* Now check the size */
int size = 0;
if (!(size = smlAssemblerCheckSize(assm, FALSE, error)))
goto error;
if (size > limit) {
/* The status does not fit. Remove it again */
if (!assm->functions.rem_status(assm->assm_userdata, error))
goto error;
smlTrace(TRACE_EXIT, "%s: Mismatch", __func__);
return SML_ASSEMBLER_RESULT_MISMATCH;
}
}
}
/*if (status->cmdRef != 0)
assm->empty = FALSE;*/
smlTrace(TRACE_EXIT, "%s", __func__);
return SML_ASSEMBLER_RESULT_OK;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return SML_ASSEMBLER_RESULT_ERROR;
}
SmlAssemblerResult smlAssemblerAddStatus(SmlAssembler *assm, SmlStatus *status, SmlError **error)
{
CHECK_ERROR_REF
return smlAssemblerAddStatusFull(assm, status, FALSE, error);
}
void smlAssemblerSetOption(SmlAssembler *assm, const char *optionname, const char *value)
{
smlTrace(TRACE_ENTRY, "%s(%p, %s, %s)", __func__, assm, VA_STRING(optionname), VA_STRING(value));
smlAssert(assm);
smlAssert(optionname);
g_hash_table_replace(assm->options, g_strdup(optionname), g_strdup(value));
smlTrace(TRACE_EXIT, "%s", __func__);
}
const char *smlAssemblerGetOption(SmlAssembler *assm, const char *optionname)
{
smlTrace(TRACE_ENTRY, "%s(%p, %s)", __func__, assm, VA_STRING(optionname));
smlAssert(assm);
smlAssert(optionname);
const char *ret = g_hash_table_lookup(assm->options, optionname);
smlTrace(TRACE_EXIT, "%s: %s", __func__, VA_STRING(ret));
return ret;
}
/* FIXME: DEPRECATED */
unsigned int smlAssemblerGetLimit(SmlAssembler *assm)
{
return smlAssemblerGetRemoteMaxMsgSize(assm);
}
unsigned int smlAssemblerGetRemoteMaxMsgSize(SmlAssembler *assm)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
smlAssert(assm);
smlTrace(TRACE_EXIT, "%s: %i", __func__, assm->remoteMaxMsgSize);
return assm->remoteMaxMsgSize;
}
/* FIXME: DEPRECATED */
void smlAssemblerSetRequestedLimit(SmlAssembler *assm, unsigned int limit)
{
smlAssemblerSetRemoteMaxMsgSize(assm, limit);
}
/* FIXME: DEPRECATED */
void smlAssemblerSetLimit(SmlAssembler *assm, unsigned int limit)
{
smlAssemblerSetRemoteMaxMsgSize(assm, limit);
}
unsigned int smlAssemblerSetRemoteMaxMsgSize(SmlAssembler *assm, unsigned int limit)
{
smlTrace(TRACE_ENTRY, "%s(%p, %i)", __func__, assm, limit);
smlAssert(assm);
if (limit == 0)
{
/* Reset MaxMsgSize to unused state */
assm->remoteMaxMsgSize = limit;
} else {
if (limit < assm->remoteMaxMsgSize || assm->remoteMaxMsgSize == 0)
{
/* There is a real new limit. */
assm->remoteMaxMsgSize = limit;
} else {
smlTrace(TRACE_INTERNAL,
"%s: using old limit (%d) because of large new limit (%d).",
__func__, assm->remoteMaxMsgSize, limit);
}
}
smlTrace(TRACE_EXIT, "%s - %d", __func__, assm->remoteMaxMsgSize);
return assm->remoteMaxMsgSize;
}
/* FIXME: DEPRECATED */
int smlAssemblerGetSendingMaxObjSize(SmlAssembler *assm)
{
return smlAssemblerGetRemoteMaxObjSize(assm);
}
/* FIXME: DEPRECATED */
int smlAssemblerGetRequestedMaxObjSize(SmlAssembler *assm)
{
return smlAssemblerGetRemoteMaxObjSize(assm);
}
unsigned int smlAssemblerGetRemoteMaxObjSize(SmlAssembler *assm)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
smlAssert(assm);
smlTrace(TRACE_EXIT, "%s: %i", __func__, assm->remoteMaxObjSize);
return assm->remoteMaxObjSize;
}
/* FIXME: DEPRECATED */
void smlAssemblerSetRequestedMaxObjSize(SmlAssembler *assm, int limit)
{
smlAssemblerSetRemoteMaxObjSize(assm, limit);
}
/* FIXME: DEPRECATED */
void smlAssemblerSetSendingMaxObjSize(SmlAssembler *assm, int limit)
{
smlAssemblerSetRemoteMaxObjSize(assm, limit);
}
unsigned int smlAssemblerSetRemoteMaxObjSize(SmlAssembler *assm, unsigned int limit)
{
smlTrace(TRACE_ENTRY, "%s(%p, %i)", __func__, assm, limit);
smlAssert(assm);
if (limit == 0)
{
/* Reset MaxObjSize to unused state */
assm->remoteMaxObjSize = limit;
} else {
if (limit < assm->remoteMaxObjSize || assm->remoteMaxObjSize == 0)
{
/* There is a real new limit. */
assm->remoteMaxObjSize = limit;
} else {
smlTrace(TRACE_INTERNAL,
"%s: using old limit (%d) because of large new limit (%d).",
__func__, assm->remoteMaxObjSize, limit);
}
}
smlTrace(TRACE_EXIT, "%s - %d", __func__, assm->remoteMaxObjSize);
return assm->remoteMaxObjSize;
}
SmlBool smlAssemblerIsEmpty(SmlAssembler *assm)
{
smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
smlAssert(assm);
SmlBool ret = assm->empty;
smlTrace(TRACE_EXIT, "%s: %i", __func__, ret);
return ret;
}
SmlBool smlAssemblerIsStatusMissing(SmlAssembler *assm)
{
smlAssert(assm);
smlAssert(assm->functions.missing_status);
SmlBool ret = assm->functions.missing_status(assm->assm_userdata);
return ret;
}
SmlBool smlAssemblerGetNextCmdRef(SmlAssembler *assm, unsigned int *cmdRef, unsigned int *msgRef)
{
smlAssert(assm);
smlAssert(cmdRef);
smlAssert(msgRef);
smlAssert(assm->functions.next_cmdref);
return assm->functions.next_cmdref(assm->assm_userdata, cmdRef, msgRef);
}
smlAssemblerSetOption
void smlAssemblerSetOption(SmlAssembler *assm, const char *optionname, const char *value)
Sets a option on the assembler.
Definition: sml_parse.c:896
smlAssemblerAddHeader
SmlBool smlAssemblerAddHeader(SmlAssembler *assm, SmlSession *session, SmlError **error)
Assembles the header.
Definition: sml_parse.c:762
SmlNotification
Definition: sml_notification_internals.h:33
SmlCred
Definition: sml_elements_internals.h:87
smlErrorPrint
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
Definition: sml_error.c:299
smlAssemblerGetOption
const char * smlAssemblerGetOption(SmlAssembler *assm, const char *optionname)
Gets a option from the assembler.
Definition: sml_parse.c:914
smlParserGetHeader
SmlBool smlParserGetHeader(SmlParser *parser, SmlHeader **header, SmlCred **cred, SmlError **error)
Parses the SyncHdr.
Definition: sml_parse.c:216
SmlError::type
SmlErrorType type
Definition: sml_error_internals.h:31
smlParserFree
void smlParserFree(SmlParser *parser)
Frees a parser.
Definition: sml_parse.c:108
SmlAssembler
Definition: sml_parse_internals.h:33
smlAssemblerStartCommand
SmlAssemblerResult smlAssemblerStartCommand(SmlAssembler *assm, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
Starts a parent command.
Definition: sml_parse.c:659
smlAssemblerAddStatusFull
SmlAssemblerResult smlAssemblerAddStatusFull(SmlAssembler *assm, SmlStatus *status, SmlBool force, SmlError **error)
Assembles a status.
Definition: sml_parse.c:839
SmlManager
Definition: sml_manager_internals.h:35
SmlStatus
Definition: sml_command_internals.h:94
SmlHeader
Definition: sml_elements_internals.h:73
SmlParser
Definition: sml_parse_internals.h:25
smlAssemblerReserveStatus
SmlAssemblerResult smlAssemblerReserveStatus(SmlAssembler *assm, unsigned int cmdRef, unsigned int msgRef, unsigned int cmdID, SmlError **error)
Reserves a place for a status with this assembler.
Definition: sml_parse.c:806
smlParserEnd
SmlBool smlParserEnd(SmlParser *parser, SmlBool *final, SmlBool *end, SmlError **error)
Ends the parsing.
Definition: sml_parse.c:314
SmlItem
Definition: sml_elements_internals.h:46
smlAssemblerRun
SmlBool smlAssemblerRun(SmlAssembler *assm, char **data, unsigned int *size, SmlBool *end, SmlBool final, SmlError **error)
Assembles the complete message and returns the result.
Definition: sml_parse.c:456
smlAssemblerFlush
unsigned int smlAssemblerFlush(SmlAssembler *assm)
Flushes the already parsed commands.
Definition: sml_parse.c:514
smlAssemblerStart
SmlBool smlAssemblerStart(SmlAssembler *assm, SmlSession *session, SmlError **error)
Starts a new message.
Definition: sml_parse.c:428
smlAssemblerIsStatusMissing
SmlBool smlAssemblerIsStatusMissing(SmlAssembler *assm)
Checks if there are reserved statuses missing.
Definition: sml_parse.c:1053
SmlSession
Definition: sml_session_internals.h:27
smlParserNew
SmlParser * smlParserNew(SmlMimeType type, unsigned int limit, SmlError **error)
Creates a new parser.
Definition: sml_parse.c:50
SmlCommand
Definition: sml_command_internals.h:73
smlXmlAssemblerNew
SmlXmlAssembler * smlXmlAssemblerNew(SmlAssembler *assembler, SmlAssemblerFunctions *functions, SmlError **error)
Creates a new XML assembler.
Definition: sml_xml_assm.c:1978
smlTrace
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
Definition: sml_support.c:120
smlAssemblerFree
void smlAssemblerFree(SmlAssembler *assm)
Frees a assembler.
Definition: sml_parse.c:402
smlAssemblerEndCommand
SmlBool smlAssemblerEndCommand(SmlAssembler *assm, SmlCommand *parent, SmlError **error)
Ends a parent command.
Definition: sml_parse.c:722
smlParserStart
SmlBool smlParserStart(SmlParser *parser, const char *data, unsigned int size, SmlError **error)
Starts the parser on a given data buffer.
Definition: sml_parse.c:132
smlParserGetStatus
SmlBool smlParserGetStatus(SmlParser *parser, SmlStatus **status, SmlError **error)
Parses the next status.
Definition: sml_parse.c:284
smlAssemblerNew
SmlAssembler * smlAssemblerNew(SmlMimeType type, unsigned int limit, SmlError **error)
Creates a new assembler.
Definition: sml_parse.c:352
smlParserGetCommand
SmlParserResult smlParserGetCommand(SmlParser *parser, SmlCommand **cmd, SmlError **error)
Parses the next command.
Definition: sml_parse.c:250
smlTryMalloc0
void * smlTryMalloc0(long n_bytes, SmlError **error)
Safely mallocs.
Definition: sml_support.c:335
smlAssemblerCheckSize
unsigned int smlAssemblerCheckSize(SmlAssembler *assm, SmlBool headeronly, SmlError **error)
Assembles the complete message and returns the result.
Definition: sml_parse.c:485
smlErrorSet
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.
Definition: sml_error.c:355
smlAssemblerGetSpace
SmlBool smlAssemblerGetSpace(SmlAssembler *assm, int *space, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
Gets the available space in the assembler.
Definition: sml_parse.c:545
SmlError
Represent an error.
Definition: sml_error_internals.h:29