+ 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);