diff --git a/sflphone-common/src/sip/im/InstantMessaging.cpp b/sflphone-common/src/sip/im/InstantMessaging.cpp index d44acfdff140df5b451d8c2f8c6736edfa1690a0..2bab2afbad14c82f04057e2349bf3309a7b9c37c 100644 --- a/sflphone-common/src/sip/im/InstantMessaging.cpp +++ b/sflphone-common/src/sip/im/InstantMessaging.cpp @@ -1,8 +1,54 @@ #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; +} + } diff --git a/sflphone-common/src/sip/im/InstantMessaging.h b/sflphone-common/src/sip/im/InstantMessaging.h index bcc25d85c11dbeb6577ea2d574e99fb7b78bacb1..e9699e1af3f882c88aeaa52b5b77bea7ab11497a 100644 --- a/sflphone-common/src/sip/im/InstantMessaging.h +++ b/sflphone-common/src/sip/im/InstantMessaging.h @@ -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: /** diff --git a/sflphone-common/test/instantmessagingtest.cpp b/sflphone-common/test/instantmessagingtest.cpp index 28b39e7d396d31b8719fbbda45855cb50c28eb4c..a215f83492ee01608251e57349cea5bea8bd71a7 100644 --- a/sflphone-common/test/instantmessagingtest.cpp +++ b/sflphone-common/test/instantmessagingtest.cpp @@ -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() diff --git a/sflphone-common/test/instantmessagingtest.h b/sflphone-common/test/instantmessagingtest.h index c450a07e7c82132af681c4b240a60913498874f0..9194cb3f6b34a4953bd16ff95563dd06ffe7fa44 100644 --- a/sflphone-common/test/instantmessagingtest.h +++ b/sflphone-common/test/instantmessagingtest.h @@ -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;