Commit cab85835 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#3963] Basic xml formatin an parsing with unit tests

parent 77b689ef
#include "InstantMessaging.h"
#include "expat.h"
namespace sfl
{
static inline char* duplicateString (char dst[], const char src[], size_t len)
{
memcpy (dst, src, len);
dst[len] = 0;
return dst;
}
static void XMLCALL startElementCallback (void *userData, const char *name, const char **atts)
{
std::cout << "startElement " << name << std::endl;
int *depthPtr = (int *) userData;
char attribute[50];
char value[50];
const char **att;
const char **val;
for (att = atts; *att; att += 2) {
const char **val = att+1;
duplicateString (attribute, *att, strlen (*att));
std::cout << "att: " << attribute << std::endl;
duplicateString (value, *val, strlen (*val));
std::cout << "val: " << value << std::endl;
}
*depthPtr += 1;
}
static void XMLCALL endElementCallback (void *userData, const char *name)
{
// std::cout << "endElement " << name << std::endl;
int *depthPtr = (int *) userData;
*depthPtr -= 1;
}
InstantMessaging::InstantMessaging()
: imFiles ()
, messageMaxSize (MAXIMUM_MESSAGE_LENGTH) {}
......@@ -175,4 +221,36 @@ std::vector<std::string> InstantMessaging::split_message (const std::string& tex
return messages;
}
std::string InstantMessaging::generateXmlUriList (UriList& list)
{
std::string xmlbuffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xmlbuffer.append ("<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">");
xmlbuffer.append ("<list>");
xmlbuffer.append ("<entry uri=\"sip:al@example.com\" cp:copyControl=\"to\" />");
xmlbuffer.append ("<entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" />");
xmlbuffer.append ("</list>");
xmlbuffer.append ("</resource-lists>");
return xmlbuffer;
}
InstantMessaging::UriList InstantMessaging::parseXmlUriList (std::string& urilist)
{
InstantMessaging::UriList list;
XML_Parser parser = XML_ParserCreate (NULL);
int depth = 0;
XML_SetUserData (parser, &depth);
XML_SetElementHandler (parser, startElementCallback, endElementCallback);
if (XML_Parse (parser, urilist.c_str(), urilist.size(), 1) == XML_STATUS_ERROR) {
std::cout << "Error: " << XML_ErrorString (XML_GetErrorCode (parser))
<< " at line " << XML_GetCurrentLineNumber (parser) << std::endl;
}
return list;
}
}
......@@ -12,6 +12,8 @@
#include "call.h"
#include "sip/sipcall.h"
#include <map>
#define EMPTY_MESSAGE pj_str((char*)"")
#define STR_TEXT pj_str((char*)"text")
#define STR_PLAIN pj_str((char*)"plain")
......@@ -27,7 +29,12 @@ namespace sfl
class InstantMessaging
{
public:
typedef std::map <std::string, std::string> UriEntry;
typedef std::map <std::string, UriEntry> UriList;
/*
* Class constructor
*/
......@@ -114,6 +121,26 @@ class InstantMessaging
*/
pj_status_t notify (CallID& id);
/**
* Generate Xml participant list for multi recipient based on RFC Draft 5365
*
* @param A UriList of UriEntry
*
* @return A string containing the full XML formated information to be included in the
* sip instant message.
*/
std::string generateXmlUriList(UriList& list);
/**
* Parse the Urilist from a SIP Instant Message provided by a UriList service.
*
* @param A XML formated string as obtained from a SIP instant message.
*
* @return An UriList of UriEntry containing parsed XML information as a map.
*/
UriList parseXmlUriList(std::string& urilist);
private:
/**
......
......@@ -35,6 +35,7 @@
#include "instantmessagingtest.h"
#include "expat.h"
#include <stdio.h>
#define MAXIMUM_SIZE 10
#define DELIMITER_CHAR "\n\n"
......@@ -42,6 +43,7 @@
using std::cout;
using std::endl;
void InstantMessagingTest::setUp()
{
_im = new sfl::InstantMessaging ();
......@@ -141,10 +143,75 @@ void InstantMessagingTest::testSplitMessage ()
CPPUNIT_ASSERT (messages[size- 1] == very_long_message.substr (maxSize * (size-1)));
}
void InstantMessagingTest::testUriListParsing ()
static inline char* dupstr(char dst[], const char src[], size_t len)
{
memcpy(dst, src, len);
dst[len] = 0;
return dst;
}
static void XMLCALL startElementCallback(void *userData, const char *name, const char **atts)
{
std::cout << "startElement " << name << std::endl;
int *nbEntry = (int *)userData;
char attribute[50];
char value[50];
const char **att;
const char **val;
for (att = atts; *att; att += 2) {
const char **val = att+1;
dupstr(attribute, *att, strlen(*att));
std::cout << "att: " << attribute << std::endl;
dupstr(value, *val, strlen(*val));
std::cout << "val: " << value << std::endl;
}
*nbEntry += 1;
}
static void XMLCALL endElementCallback(void *userData, const char *name)
{
XML_Parser parser = XML_ParserCreate(NULL);
// std::cout << "endElement " << name << std::endl;
}
void InstantMessagingTest::testGenerateXmlUriList ()
{
std::cout << std::endl;
sfl::InstantMessaging::UriList list;
std::string buffer = _im->generateXmlUriList(list);
CPPUNIT_ASSERT(buffer.size() != 0);
XML_Parser parser = XML_ParserCreate(NULL);
int nbEntry = 0;
XML_SetUserData(parser, &nbEntry);
XML_SetElementHandler(parser, startElementCallback, endElementCallback);
if (XML_Parse(parser, buffer.c_str(), buffer.size(), 1) == XML_STATUS_ERROR) {
std::cout << "Error: " << XML_ErrorString(XML_GetErrorCode(parser))
<< " at line " << XML_GetCurrentLineNumber(parser) << std::endl;
CPPUNIT_ASSERT(0==1);
}
XML_ParserFree(parser);
CPPUNIT_ASSERT(nbEntry == 4);
CPPUNIT_ASSERT(1==1);
}
void InstantMessagingTest::testXmlUriListParsing ()
{
}
void InstantMessagingTest::tearDown()
......
......@@ -56,7 +56,8 @@ class InstantMessagingTest : public CppUnit::TestCase {
CPPUNIT_TEST (testSaveSingleMessage);
CPPUNIT_TEST (testSaveMultipleMessage);
CPPUNIT_TEST (testSplitMessage);
CPPUNIT_TEST (testUriListParsing);
CPPUNIT_TEST (testGenerateXmlUriList);
CPPUNIT_TEST (testXmlUriListParsing);
CPPUNIT_TEST_SUITE_END();
public:
......@@ -80,7 +81,9 @@ class InstantMessagingTest : public CppUnit::TestCase {
void testSplitMessage ();
void testUriListParsing ();
void testGenerateXmlUriList ();
void testXmlUriListParsing ();
private:
sfl::InstantMessaging *_im;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment