sml_wbxml.c
/*
* libsyncml - A syncml protocol implementation
* Copyright (C) 2005 Armin Bauer <armin.bauer@opensync.org>
* Copyright (C) 2007-2009 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 <libsyncml/syncml.h>
#include <libsyncml/syncml_internals.h>
#include <libsyncml/sml_elements_internals.h>
#include <libsyncml/sml_command_internals.h>
#include <libsyncml/sml_session_internals.h>
#include "libsyncml/sml_error_internals.h"
#ifdef ENABLE_WBXML
#include "sml_xml_assm.h"
#include "sml_xml_assm_internals.h"
#include "sml_xml_parse.h"
#include "sml_xml_parse_internals.h"
#include "sml_wbxml.h"
#include "sml_wbxml_internals.h"
SmlBool smlWbxmlConvertTo(WBXMLConvXML2WBXMLParams *params, const char *input, char **output, size_t *outputLen, SmlError** error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, params, input, output, outputLen, error);
smlAssert(input);
smlAssert(strlen(input));
smlAssert(output);
smlAssert(outputLen);
WBXMLError wberror;
wberror = wbxml_conv_xml2wbxml((WB_UTINY*)input, (WB_UTINY**)output, (WB_ULONG*)outputLen, params);
if (wberror != WBXML_OK)
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlErrorSet(error, SML_ERROR_GENERIC, (char *)wbxml_errors_string(wberror));
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlBool smlWbxmlConvertFrom(WBXMLConvWBXML2XMLParams *params, const char *input, size_t inputLen, char **output, size_t *outputLen, SmlError** error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p)", __func__, params, input, inputLen, output, outputLen, error);
WBXMLError wberror;
smlTrace(TRACE_INTERNAL, "WBXML2 VERSION: %s", WBXML_LIB_VERSION);
wberror = wbxml_conv_wbxml2xml_withlen((WB_UTINY*)input, inputLen, (WB_UTINY**)output, (WB_ULONG*)outputLen, params);
if (wberror != WBXML_OK)
goto error;
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
smlErrorSet(error, SML_ERROR_GENERIC, (char *)wbxml_errors_string(wberror));
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
static SmlBool smlWbxmlParserStart(SmlXmlParser *parser, const char *data, unsigned int size, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, parser, data, size, error);
CHECK_ERROR_REF
smlAssert(parser);
smlAssert(data);
smlAssert(size);
char *bin = smlPrintBinary(data, size);
smlTrace(TRACE_INTERNAL, "Wbxml input: %s", bin);
smlSafeCFree(&bin);
smlLog("received-%i.wbxml", data, size);
/* Ignorable whitespaces must be preserved because sometimes
* a buggy mobile does not the its data objects correctly
* encapsulated into CDATA.
*/
char *buffer = NULL;
size_t buffer_size = 0;
WBXMLConvWBXML2XMLParams params = {WBXML_ENCODER_XML_GEN_COMPACT, WBXML_LANG_UNKNOWN, 0, TRUE};
if (!smlWbxmlConvertFrom(&params, data, size, &buffer, &buffer_size, error))
goto error;
smlTrace(TRACE_INTERNAL, "converted XML message: %s", buffer);
if (!smlXmlParserStart(parser, buffer, buffer_size, error))
goto error;
smlSafeCFree(&buffer);
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
if (buffer)
smlSafeCFree(&buffer);
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
SmlXmlParser *smlWbxmlParserNew(SmlParserFunctions *functions, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, functions, error);
CHECK_ERROR_REF
smlAssert(functions);
SmlXmlParser *parser = smlXmlParserNew(functions, error);
if (!parser)
goto error;
functions->start = (SmlParserStartFunction)smlWbxmlParserStart;
smlTrace(TRACE_EXIT, "%s: %p", __func__, parser);
return parser;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return NULL;
}
SmlBool smlWbxmlAssemblerRun(SmlXmlAssembler *assm, char **data, unsigned int *size, SmlBool *end, SmlBool final, unsigned int maxsize, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %i, %i, %p)", __func__, assm, data, size, end, final, maxsize, error);
CHECK_ERROR_REF
smlAssert(assm);
smlAssert(data);
smlAssert(size);
char *buffer = NULL;
unsigned int buffer_size = 0;
if (!smlXmlAssemblerRun(assm, &buffer, &buffer_size, end, final, 0, error))
goto error;
WBXMLConvXML2WBXMLParams params = {WBXML_VERSION_12, FALSE, FALSE, FALSE};
const char *opt = smlAssemblerGetOption(assm->assembler, "USE_STRTABLE");
if (opt && atoi(opt))
params.use_strtbl = TRUE;
if (!smlWbxmlConvertTo(&params, buffer, data, size, error))
goto error;
smlSafeCFree(&buffer);
char *hex = smlPrintHex(*data, *size);
smlTrace(TRACE_INTERNAL, "Wbxml assembled: %s", hex);
smlSafeCFree(&hex);
smlLog("sent-%i.wbxml", *data, *size);
smlTrace(TRACE_EXIT, "%s", __func__);
return TRUE;
error:
if (buffer)
smlSafeCFree(&buffer);
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return FALSE;
}
unsigned int smlWbxmlAssemblerCheckSize(SmlXmlAssembler *assm, SmlBool headeronly, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, assm, headeronly, error);
CHECK_ERROR_REF
smlAssert(assm);
unsigned int size = 0;
char *data = NULL;
char *buffer = NULL;
unsigned int buffer_size = 0;
if (!smlXmlAssemblerRunFull(assm, &buffer, &buffer_size, NULL, TRUE, FALSE, 0, error))
goto error;
WBXMLConvXML2WBXMLParams params = {WBXML_VERSION_12, FALSE, FALSE, FALSE};
const char *opt = smlAssemblerGetOption(assm->assembler, "USE_STRTABLE");
if (opt && atoi(opt))
params.use_strtbl = TRUE;
if (!smlWbxmlConvertTo(&params, buffer, &data, &size, error))
goto error_free_buffer;
smlSafeCFree(&data);
smlSafeCFree(&buffer);
smlTrace(TRACE_EXIT, "%s: %i", __func__, size);
return size;
error_free_buffer:
smlSafeCFree(&buffer);
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return 0;
}
SmlXmlAssembler *smlWbxmlAssemblerNew(SmlAssembler *assembler, SmlAssemblerFunctions *functions, SmlError **error)
{
smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assembler, functions, error);
CHECK_ERROR_REF
SmlXmlAssembler *assm = smlXmlAssemblerNew(assembler, functions, error);
if (!assm)
goto error;
functions->run = (SmlAssemblerRunFunction)smlWbxmlAssemblerRun;
functions->check_size = (SmlAssemblerCheckFunction)smlWbxmlAssemblerCheckSize;
smlTrace(TRACE_EXIT, "%s: %p", __func__, assm);
return assm;
error:
smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
return NULL;
}
#endif
smlXmlParserStart
SmlBool smlXmlParserStart(SmlXmlParser *parser, const char *data, unsigned int size, SmlError **error)
Start the parsing.
Definition: sml_xml_parse.c:1915
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
SmlAssembler
Definition: sml_parse_internals.h:33
smlPrintHex
char * smlPrintHex(const char *data, int len)
Used for printing binary data in just hex.
Definition: sml_support.c:271
SmlAssemblerFunctions
Definition: sml_parse.h:67
SmlXmlParser
Definition: sml_xml_parse_internals.h:47
smlPrintBinary
char * smlPrintBinary(const char *data, int len)
Used for printing binary data.
Definition: sml_support.c:252
SmlXmlAssembler
Definition: sml_xml_assm_internals.h:68
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
smlErrorSet
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.
Definition: sml_error.c:355
SmlParserFunctions
Definition: sml_parse.h:41
SmlError
Represent an error.
Definition: sml_error_internals.h:29