}
+ if (NodeFound == false){
+
+ return UserPrincipalURI;
+
+ }
+
// Look for response.
if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
- NodeFound = MatchXMLName(&NodeSeek, "response");
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "response");
// Look for propstat.
if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
- NodeFound = MatchXMLName(&NodeSeek, "propstat");
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "propstat");
// Look for prop.
if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
- NodeFound = MatchXMLName(&NodeSeek, "prop");
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "prop");
// Look for current-user-principal.
if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
- NodeFound = MatchXMLName(&NodeSeek, "current-user-principal");
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "current-user-principal");
// Look for href.
if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
- NodeFound = MatchXMLName(&NodeSeek, "href");
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "href");
// Get the data from href.
}
-bool CalDAV::MatchXMLName(xmlNodePtr *NodePtr, string NodeName){
+string CalDAV::ProcessXMLCalendarHome(){
+
+ string CalendarHomeURI;
+
+ xmlDocPtr xmlCalDAVDoc;
+ xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
+
+ xmlNodePtr NodeSeek;
+ bool NodeFound = false;
+
+ // Start with the first node, look for multistatus.
+
+ for (NodeSeek = xmlCalDAVDoc->children;
+ NodeSeek != NULL;
+ NodeSeek = NodeSeek->next)
+ {
+
+ if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
+ ){
+
+ NodeFound = true;
+ break;
+
+ }
+
+ }
+
+ if (NodeFound == false){
+
+ return CalendarHomeURI;
+
+ }
+
+ // Look for response.
+
+ if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "response");
+
+ // Look for propstat.
+
+ if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "propstat");
+
+ // Look for prop.
+
+ if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "prop");
+
+ // Look for calendar-home-set.
+
+ if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "calendar-home-set");
+
+ // Look for href.
+
+ if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "href");
+
+ // Get the data from href.
+
+ CalendarHomeURI = FetchXMLData(&NodeSeek);
+
+ xmlFreeDoc(xmlCalDAVDoc);
+
+ return CalendarHomeURI;
+
+}
+
+CalDAVCalendarList CalDAV::ProcessXMLCalendarList(){
+
+ CalDAVCalendarList CalendarList;
+
+ xmlDocPtr xmlCalDAVDoc;
+ xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
+
+ xmlNodePtr NodeSeek = NULL;
+ xmlNodePtr NodeResponse = NULL;
+ xmlNodePtr NodeMatch = NULL;
+ xmlNodePtr NodeData = NULL;
+ bool NodeFound = false;
+ int ResponseCount = 0;
+
+ // Start with the first node, look for multistatus.
+
+ for (NodeSeek = xmlCalDAVDoc->children;
+ NodeSeek != NULL;
+ NodeSeek = NodeSeek->next)
+ {
+
+ if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
+ ){
+
+ NodeResponse = NodeSeek->children;
+ NodeFound = true;
+ break;
+
+ }
+
+ }
+
+ if (NodeFound == false){
+
+ return CalendarList;
+
+ }
+
+ for (NodeResponse = NodeSeek->children;
+ NodeResponse != nullptr;
+ NodeResponse = NodeResponse->next)
+ {
+
+ // Go through each of the responses and find the calendars.
+
+ NodeMatch = xmlCopyNode(NodeResponse, 1);
+
+ if (MatchXMLName(&NodeMatch, "response")){
+\r NodeData = xmlCopyNode(NodeMatch, 1);
+
+ // Check the resource type is a calendar.
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "resourcetype")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "calendar")){ continue; }
+
+ // Get the HREF.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ if (!MatchXMLNameTransverse(&NodeData, "href")){ continue; }
+
+ string HREFAddress = FetchXMLData(&NodeData);
+
+ // Get the calendar name.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "displayname")){ continue; }
+
+ string CalendarName = FetchXMLData(&NodeData);
+
+ // Get the calendar description.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ string CalendarDescription = "";
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "calendar-description")){
+
+ CalendarDescription = FetchXMLData(&NodeData);
+
+ }
+
+ // Get the calendar colour.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ Colour CalendarColour;
+ bool ColourResult = false;
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "calendar-color")){
+
+ string CalendarColourString = "";
+ string CalendarColourHexValue = "";
+ int ColourNumber;
+ bool KeepRunning = true;
+
+ CalendarColourString = FetchXMLData(&NodeData);
+
+ while(KeepRunning == true){
+
+ if (CalendarColourString.substr(0,1) == "#" && CalendarColourString.length() == 9){
+
+ // Get the red colour.
+
+ CalendarColourHexValue = CalendarColourString.substr(1,2);
+ if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; }
+ CalendarColour.red = ColourNumber;
+
+ // Get the green colour.
+
+ CalendarColourHexValue = CalendarColourString.substr(3,2);
+ if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; }
+ CalendarColour.green = ColourNumber;
+
+ // Get the blue colour.
+
+ CalendarColourHexValue = CalendarColourString.substr(5,2);
+ if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; };
+ CalendarColour.blue = ColourNumber;
+
+ // Get the alpha.
+
+ CalendarColourHexValue = CalendarColourString.substr(7,2);
+ if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; };
+ CalendarColour.alpha = ColourNumber;
+
+ ColourResult = true;
+
+ } else {
+
+ ColourResult = false;
+
+ }
+
+ break;
+
+ }
+
+ }
+
+ if (ColourResult == false){
+
+ CalendarColour.red = 0;
+ CalendarColour.blue = 0;
+ CalendarColour.green = 0;
+ CalendarColour.alpha = 0;
+
+ }
+
+ // Get the calendar order.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ int CalendarOrder = 0;
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "calendar-order")){
+
+ string CalendarOrderString = FetchXMLData(&NodeData);
+ if (!HexToInt(&CalendarOrderString, &CalendarOrder)){
+ CalendarOrder = 0;
+ }
+
+ }
+
+ // Get the calendar tag.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ string CalendarTag = "";
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "getctag")){
+
+ CalendarTag = FetchXMLData(&NodeData);
+
+ }
+
+ // Get the calendar tag URL.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ string CalendarTagURL = "";
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "sync-token")){
+
+ CalendarTagURL = FetchXMLData(&NodeData);
+
+ }
+
+ // Insert the calendar information into the
+ // list if all the information is there.
+
+ CalendarList.Name.insert(make_pair(ResponseCount, CalendarName));
+ CalendarList.Description.insert(make_pair(ResponseCount, CalendarDescription));
+ CalendarList.HREF.insert(make_pair(ResponseCount, HREFAddress));
+ CalendarList.CalColour.insert(make_pair(ResponseCount, CalendarColour));
+ CalendarList.Order.insert(make_pair(ResponseCount, CalendarOrder));
+ CalendarList.Tag.insert(make_pair(ResponseCount, CalendarTag));
+ CalendarList.TagURL.insert(make_pair(ResponseCount, CalendarTagURL));
+
+ ResponseCount++;
+
+ }
+
+ }
+
+ xmlFreeDoc(xmlCalDAVDoc);
+
+ return CalendarList;
+
+}
+
+string CalDAV::ProcessXMLEntryETag(){
+
+ string EntryETag;
+
+ xmlDocPtr xmlCalDAVDoc;
+ xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
+
+ xmlNodePtr NodeSeek;
+ bool NodeFound = false;
+
+ // Start with the first node, look for multistatus.
+
+ for (NodeSeek = xmlCalDAVDoc->children;
+ NodeSeek != NULL;
+ NodeSeek = NodeSeek->next)
+ {
+
+ if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
+ ){
+
+ NodeFound = true;
+ break;
+
+ }
+
+ }
+
+ if (NodeFound == false){
+
+ return EntryETag;
+
+ }
+
+ // Look for response.
+
+ if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "response");
+
+ // Look for propstat.
+
+ if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "propstat");
+
+ // Look for prop.
+
+ if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "prop");
+
+ // Look for calendar-home-set.
+
+ if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
+ NodeFound = MatchXMLNameTransverse(&NodeSeek, "getetag");
+
+ // Get the data from href.
+
+ EntryETag = FetchXMLData(&NodeSeek);
+
+ xmlFreeDoc(xmlCalDAVDoc);
+
+ // Check if the entity tag contains quote marks
+ // at the start and end and remove them (if needed).
+
+ if (EntryETag.substr(0,1) == "\"" &&
+ EntryETag.substr(EntryETag.size()-1, 1) == "\"" && EntryETag.size() > 2){
+
+ EntryETag.erase(EntryETag.begin());
+ EntryETag.erase(EntryETag.end()-1);
+
+ }
+
+ return EntryETag;
+
+}
+
+CalDAVEntryList CalDAV::ProcessXMLEntryList(){
+
+ CalDAVEntryList EntryList;
+
+ xmlDocPtr xmlCalDAVDoc;
+ xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
+
+ xmlNodePtr NodeSeek = NULL;
+ xmlNodePtr NodeResponse = NULL;
+ xmlNodePtr NodeMatch = NULL;
+ xmlNodePtr NodeData = NULL;
+ bool NodeFound = false;
+ int ResponseCount = 0;
+
+ // Start with the first node, look for multistatus.
+
+ for (NodeSeek = xmlCalDAVDoc->children;
+ NodeSeek != NULL;
+ NodeSeek = NodeSeek->next)
+ {
+
+ if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
+ ){
+
+ NodeResponse = NodeSeek->children;
+ NodeFound = true;
+ break;
+
+ }
+
+ }
+
+ if (NodeFound == false){
+
+ return EntryList;
+
+ }
+
+ for (NodeResponse = NodeSeek->children;
+ NodeResponse != nullptr;
+ NodeResponse = NodeResponse->next)
+ {
+
+ // Go through each of the responses and find the calendars.
+
+ NodeMatch = xmlCopyNode(NodeResponse, 1);
+
+ if (MatchXMLName(&NodeMatch, "response")){
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ // Get the HREF.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ if (!MatchXMLNameTransverse(&NodeData, "href")){ continue; }
+
+ string HREFAddress = FetchXMLData(&NodeData);
+
+ // Get the calendar data.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ string EntryDescription = "";
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "calendar-data")){
+
+ // Note: libxml2 will strip the CDATA part at the start and
+ // end of each calendar-data section.
+
+ EntryDescription = FetchXMLData(&NodeData);
+
+ }
+
+ // Get the entry entity tag.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ string EntryEntityTag = "";
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "getetag")){
+
+ EntryEntityTag = FetchXMLData(&NodeData);
+
+ }
+
+ // Insert the calendar information into the
+ // list if all the information is there.
+
+ EntryList.HREF.insert(make_pair(ResponseCount, HREFAddress));
+ EntryList.Data.insert(make_pair(ResponseCount, EntryDescription));
+ EntryList.Tag.insert(make_pair(ResponseCount, EntryEntityTag));
+
+ ResponseCount++;
+
+ }
+
+ }
+
+ xmlFreeDoc(xmlCalDAVDoc);
+
+ return EntryList;
+
+}
+
+CalDAVEntryList CalDAV::ProcessXMLSyncTokenList(){
+
+ CalDAVEntryList EntryList;
+
+ xmlDocPtr xmlCalDAVDoc;
+ xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
+
+ xmlNodePtr NodeSeek = NULL;
+ xmlNodePtr NodeResponse = NULL;
+ xmlNodePtr NodeMatch = NULL;
+ xmlNodePtr NodeData = NULL;
+ bool NodeFound = false;
+ int ResponseCount = 0;
+
+ // Start with the first node, look for multistatus.
+
+ for (NodeSeek = xmlCalDAVDoc->children;
+ NodeSeek != NULL;
+ NodeSeek = NodeSeek->next)
+ {
+
+ if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
+ !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
+ ){
+
+ NodeResponse = NodeSeek->children;
+ NodeFound = true;
+ break;
+
+ }
+
+ }
+
+ if (NodeFound == false){
+
+ return EntryList;
+
+ }
+
+ for (NodeResponse = NodeSeek->children;
+ NodeResponse != nullptr;
+ NodeResponse = NodeResponse->next)
+ {
+
+ // Go through each of the responses and find the calendars.
+
+ NodeMatch = xmlCopyNode(NodeResponse, 1);
+
+ if (MatchXMLName(&NodeMatch, "response")){
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ // Get the HREF.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ if (!MatchXMLNameTransverse(&NodeData, "href")){ continue; }
+
+ string HREFAddress = FetchXMLData(&NodeData);
+
+ // Get the entry entity tag.
+
+ NodeData = xmlCopyNode(NodeMatch, 1);
+
+ string EntryEntityTag = "";
+
+ if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
+ if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
+ if (MatchXMLNameTransverse(&NodeData, "getetag")){
+
+ EntryEntityTag = FetchXMLData(&NodeData);
+
+ }
+
+ // Insert the calendar information into the
+ // list if all the information is there.
+
+ EntryList.HREF.insert(make_pair(ResponseCount, HREFAddress));
+ EntryList.Data.insert(make_pair(ResponseCount, ""));
+ EntryList.Tag.insert(make_pair(ResponseCount, EntryEntityTag));
+
+ ResponseCount++;
+
+ }
+
+ }
+
+ xmlFreeDoc(xmlCalDAVDoc);
+
+ return EntryList;
+
+}
+
+bool CalDAV::MatchXMLNameTransverse(xmlNodePtr *NodePtr, string NodeName){
string NodeNameSmallD = "d:" + NodeName;
string NodeNameLargeD = "D:" + NodeName;
}
+bool CalDAV::MatchXMLName(xmlNodePtr *NodePtrOriginal, string NodeName){
+
+ if (NodePtrOriginal == nullptr){
+
+ return false;
+
+ }
+
+ string NodeNameSmallD = "d:" + NodeName;
+ string NodeNameLargeD = "D:" + NodeName;
+
+ xmlNodePtr *NodePtr = NodePtrOriginal;
+
+ if (!xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeName.c_str()) ||
+ !xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeNameSmallD.c_str()) ||
+ !xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeNameLargeD.c_str())
+ ){
+
+ return true;
+
+ } else {
+
+ return false;
+
+ }
+
+ return false;
+
+}
+
string CalDAV::FetchXMLData(xmlNodePtr *NodePtr){
for ((*NodePtr) = (*NodePtr)->children;