+using namespace std;
+
+size_t CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, string *stringPointer)
+{
+
+ stringPointer->append(receivedBuffer, newMemoryBytes);
+
+ return size * newMemoryBytes;
+
+}
+
+size_t CalDAVSend(char *sendBuffer, size_t size, size_t newMemoryBytes, void *dataStruct){
+
+ struct CalDAVSendData *uploadPtr = (struct CalDAVSendData *)dataStruct;
+
+ if (uploadPtr->sizeleft){
+
+ uploadPtr->sizeleft--;
+ char charSend;
+
+ charSend = (*uploadPtr->readptr)[uploadPtr->seek];
+
+ *sendBuffer = charSend;
+
+ uploadPtr->seek++;
+
+ return 1;
+
+ }
+
+ return 0;
+
+}
+
+CalDAV::CalDAV(){
+
+ // Setup the objects within the CalDAV connection
+ // object.
+
+ connectionHandle = curl_easy_init();
+
+}
+
+CalDAV::~CalDAV(){
+
+ // Destory the objects within the CalDAV connection
+ // object.
+
+ curl_easy_cleanup(connectionHandle);
+ connectionHandle = nullptr;
+
+}
+
+void CalDAV::SetupConnectionData(CalDAVConnectionData *connData){
+
+ // Check if ConnData is a nullptr, return if it is.
+
+ if (connData == nullptr){
+ return;
+ }
+
+ // Set the connection settings to the values from ConnData.
+
+ connectionData = (*connData);
+
+}
+
+CalDAVStatus CalDAV::GetConnectionData(){
+
+ // Get the current connection settings for the CalDAV
+ // connection object and return a CalDAVStatus object.
+
+ CalDAVStatus connectionStatus;
+
+ connectionStatus.hostname = connectionData.hostname;
+ connectionStatus.port = connectionData.port;
+ connectionStatus.username = connectionData.username;
+ connectionStatus.prefix = connectionData.prefix;
+ connectionStatus.useSSL = connectionData.useSSL;
+ connectionStatus.timeout = connectionData.timeout;
+
+ return connectionStatus;
+
+}
+
+CalDAVServerResult CalDAV::Connect(){
+
+ CalDAVServerResult serverResult;
+
+ string serverAddress = "";
+ string serverUserPass = "";
+
+ // Setup the server address.
+
+ serverAddress = BuildServerAddress(&connectionData, "/principals/");
+
+ // Setup the server password.
+
+ serverUserPass += connectionData.username;
+ serverUserPass += ":";
+ serverUserPass += connectionData.password;
+
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, serverAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, serverUserPass.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+ curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, connectionData.timeout);
+ curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive);
+ curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &serverData);
+ curl_easy_setopt(connectionHandle, CURLOPT_WRITEHEADER, &serverHeader);
+
+ // Connect to the CalDAV server.
+
+ serverResult.code = curl_easy_perform(connectionHandle);
+
+ // Process the result received from the server.
+
+ if (serverResult.code != CURLE_OK){
+
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+
+ } else {
+
+ serverResult.result = CALDAVQUERYRESULT_OK;
+
+ }
+
+ // Get the HTTP code.
+
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::GetServerResult(){
+
+ return connectionServerResult;
+
+}
+
+CalDAVServerSupport CalDAV::GetServerSupport(){
+
+ CalDAVServerSupport serverStatus;
+
+ // Setup the server connection.
+
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
+
+ CURLcode serverResult = curl_easy_perform(connectionHandle);
+
+ // Set the results.
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+ return serverStatus;
+ }
+
+ // Check that the server header has data in,
+ // otherwise return an "empty" CalDAVServerSupport.
+
+ if (serverHeader.size() == 0){
+ return serverStatus;
+ }
+
+ // Process each line looking for the first DAV header
+ // line.
+
+ bool newlineMode = true;
+
+ string davLine;
+
+ for (int charSeek = 0; charSeek < serverHeader.size(); charSeek++){
+
+ if (newlineMode == true){
+
+ // Check if we have reached the end of the string.
+
+ if (charSeek >= serverHeader.size()){
+
+ break;
+
+ }
+
+ // Check the first four letters to make sure
+ // they are 'DAV:'.
+
+ string davHeaderCheck = "";
+
+ try {
+ davHeaderCheck = serverHeader.substr(charSeek, 4);
+ }
+
+ catch (out_of_range &oor){
+ break;
+ }
+
+ if (davHeaderCheck == "DAV:"){
+
+ charSeek += 5;
+
+ for (; charSeek < serverHeader.size(); charSeek++){
+
+ if (serverHeader[charSeek] == '\n'){
+
+ break;
+
+ }
+
+ davLine.push_back(serverHeader[charSeek]);
+
+ }
+
+ break;
+
+ }
+
+ newlineMode = false;
+
+ }
+
+ if (serverHeader[charSeek] == '\n'){
+
+ newlineMode = true;
+
+ }
+
+ }
+
+ // Process the DAV line.
+
+ vector<string> davLineData;
+ string davSegmentString;
+
+ for (int charSeek = 0; charSeek < davLine.size(); charSeek++){
+
+ if (davLine[charSeek] == ' '){
+ continue;
+ }
+
+ if (davLine[charSeek] == ','){
+
+ davLineData.push_back(davSegmentString);
+ davSegmentString.clear();
+ continue;
+
+ }
+
+ davSegmentString += davLine[charSeek];
+
+ }
+
+ // Process the DAV values and set each value
+ // to true as required.
+
+ for (int davItemSeek = 0;
+ davItemSeek < davLineData.size();
+ davItemSeek++){
+
+ if (davLineData.at(davItemSeek) == "calendar-access"){
+
+ serverStatus.basicSupport = true;
+
+ }
+
+ }
+
+ // Reset the connection status.
+
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+
+ return serverStatus;
+
+}
+
+string CalDAV::GetUserPrincipal(){
+
+ string currentUserPrincipal = "";
+ string userPrincipalRequest = "";
+ CalDAVSendData userPrincipalSendData;
+
+ userPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propfind xmlns:d=\"DAV:\">\n"
+ " <d:prop>\n"
+ " <d:current-user-principal />\n"
+ " </d:prop>\n"
+ "</d:propfind>";
+
+ userPrincipalSendData.readptr = &userPrincipalRequest;
+ userPrincipalSendData.sizeleft = userPrincipalRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *userPrincipalRequestHeader = NULL;
+
+ userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Depth: 0");
+ userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Prefer: return-minimal");
+ userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, userPrincipalRequestHeader);
+
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &userPrincipalSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverResult = curl_easy_perform(connectionHandle);
+
+ // Set the results.
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+
+ return currentUserPrincipal;
+
+ }
+
+ // Process the User Principal from the ServerData.
+
+ currentUserPrincipal = ProcessXMLUserPrincipal();
+
+ // Reset the changed settings.
+
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return currentUserPrincipal;
+
+}
+
+string CalDAV::GetCalendarHome(string userPrincipalURI){
+
+ string calendarHomeURI = "";
+
+ // Build the Calendar Home URL address.
+
+ string calendarHomeURL = BuildServerAddress(&connectionData, userPrincipalURI);
+
+ // Setup the header request.
+
+ CalDAVSendData calendarHomeSendData;
+
+ string calendarHomeRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:prop>\n"
+ " <c:calendar-home-set />\n"
+ " </d:prop>\n"
+ "</d:propfind>";
+
+ calendarHomeSendData.readptr = &calendarHomeRequest;
+ calendarHomeSendData.sizeleft = calendarHomeRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *calendarRequestHeader = NULL;
+
+ calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Depth: 0");
+ calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Prefer: return-minimal");
+ calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarHomeURL.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarHomeSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverResult = curl_easy_perform(connectionHandle);
+
+ // Set the results.
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+
+ return calendarHomeURI;
+
+ }
+
+ // Process the User Principal from the ServerData.
+
+ calendarHomeURI = ProcessXMLCalendarHome();
+
+ // Reset the changed settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return calendarHomeURI;
+
+}
+
+CalDAVCalendarList CalDAV::GetCalendars(){
+
+ CalDAVCalendarList serverList;
+ CalDAVSendData calendarListSendData;
+
+ // Build the server address.
+
+ string userPrincipalURI = "";
+ userPrincipalURI = GetUserPrincipal();
+
+ if (userPrincipalURI.size() == 0){
+
+ return serverList;
+
+ }
+
+ string calendarHomeURI = "";
+ calendarHomeURI = GetCalendarHome(userPrincipalURI);
+
+ string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURI);
+
+ string calendarListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:prop>\n"
+ " <d:resourcetype />\n"
+ " <d:displayname />\n"
+ " <d:sync-token />\n"
+ " <x0:calendar-color />\n"
+ " <x0:calendar-order />\n"
+ " <cs:getctag />\n"
+ " <c:supported-calendar-component-set />\n"
+ " <c:calendar-description />\n"
+ " </d:prop>\n"
+ "</d:propfind>";
+
+ calendarListSendData.readptr = &calendarListRequest;
+ calendarListSendData.sizeleft = calendarListRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *calendarListRequestHeader = NULL;
+
+ calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Depth: 1");
+ calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Prefer: return-minimal");
+ calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarListRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarListSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverResult = curl_easy_perform(connectionHandle);
+
+ //ServerList = ProcessXMLCalendarList();
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+
+ return serverList;
+
+ }
+
+ // Process the received XML data into a list of calendars
+ // and locations.
+
+ serverList = ProcessXMLCalendarList();
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return serverList;
+
+}
+
+CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF){
+
+ CalDAVEntryList entryList;
+ CalDAVSendData entryListSendData;
+
+ if (calendarHREF->size() == 0){
+
+ return entryList;
+
+ }
+
+ string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
+
+ string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+ /*if (CalendarTag == nullptr){*/
+
+ entryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " <c:calendar-data />\n"
+ " </d:prop>\n"
+ " <c:filter>\n"
+ " <c:comp-filter name=\"VCALENDAR\" />\n"
+ " </c:filter>\n"
+ "</c:calendar-query>";
+
+ /*} else {
+
+ EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:sync-token>";
+ EntryListRequest += *CalendarTag;
+ EntryListRequest += "</d:sync-token>\n"
+ " <d:sync-level>1</d:sync-level>\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " <c:calendar-data />\n"
+ " </d:prop>\n"
+ "</d:sync-collection>";
+
+ }*/
+
+ entryListSendData.readptr = &entryListRequest;
+ entryListSendData.sizeleft = entryListRequest.size();
+
+ struct curl_slist *entryListRequestHeader = NULL;
+
+ entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ /*if (CalendarTag != nullptr){
+
+ EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+ EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ }*/
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverResult = curl_easy_perform(connectionHandle);
+
+ //ServerList = ProcessXMLCalendarList();
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+
+ return entryList;
+
+ }
+
+ // Process the received XML data into a list of calendars
+ // and locations.
+
+ entryList = ProcessXMLEntryList();
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return entryList;
+
+}
+
+CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF, string *calendarTag){
+
+ CalDAVEntryList entryList;
+ CalDAVSendData entryListSendData;
+
+ if (calendarHREF->size() == 0){
+
+ return entryList;
+
+ }
+
+ string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
+
+ // First query: Get the list of contacts that need to be updated.
+
+ string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+ entryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:sync-token>";
+
+ if (calendarTag != nullptr){
+
+ entryListRequest += *calendarTag;
+
+ } else {
+
+ entryListRequest += "";
+
+ }
+
+ entryListRequest += "</d:sync-token>\n"
+ " <d:sync-level>1</d:sync-level>\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " </d:prop>\n"
+ "</d:sync-collection>";
+
+ entryListSendData.readptr = &entryListRequest;
+ entryListSendData.sizeleft = entryListRequest.size();
+
+ struct curl_slist *entryListRequestHeader = NULL;
+
+ entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverResult = curl_easy_perform(connectionHandle);
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+
+ return entryList;
+
+ }
+
+ entryList = ProcessXMLSyncTokenList();
+
+ // Check the last entry matches the HREF and if it
+ // does then delete it.
+
+ if (entryList.href.size() > 0) {
+
+ if (entryList.href.rbegin()->second == *calendarHREF){
+
+ entryList.href.erase((entryList.href.size() - 1));
+ entryList.tag.erase((entryList.href.size() - 1));
+ entryList.data.erase((entryList.href.size() - 1));
+
+ }
+
+ }
+
+ // Build the list into a new list for getting the new
+ // calendar data with.
+
+ entryListRequest.clear();
+
+ entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+ entryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " <c:calendar-data />\n"
+ " </d:prop>\n";
+
+ for (std::map<int,string>::iterator hrefIter = entryList.href.begin();
+ hrefIter != entryList.href.end(); hrefIter++){
+
+ string entryListHREFString = hrefIter->second;
+
+ entryListRequest += " <d:href>";
+ entryListRequest += entryListHREFString;
+ entryListRequest += "</d:href>\n";
+
+ }
+
+ entryListRequest += "</c:calendar-multiget>";
+
+ CalDAVSendData updatedEntryListSendData;
+
+ updatedEntryListSendData.readptr = &entryListRequest;
+ updatedEntryListSendData.sizeleft = entryListRequest.size();
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &updatedEntryListSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Get the updated calendar data.
+
+ serverData.clear();
+ serverHeader.clear();
+ entryList.href.clear();
+ entryList.tag.clear();
+ entryList.data.clear();
+
+ serverResult = curl_easy_perform(connectionHandle);
+
+ // Check the last entry matches the HREF and if it
+ // does then delete it.
+
+ if (serverResult == CURLE_OK){
+ connectionServerResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ connectionServerResult.code = serverResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+
+ if (serverResult != CURLE_OK){
+
+ return entryList;
+
+ }
+
+ entryList = ProcessXMLEntryList();
+
+ // Second query: Get the list of contact data for the contacts that have
+ // beenchanged.
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return entryList;
+
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string calendarName){
+
+ CalDAVServerResult serverResult;
+
+ AddCalendar(&calendarName, nullptr);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string *calendarName, string *calendarShortName){
+
+ CalDAVServerResult serverResult;
+ CalDAVSendData calendarAddSendData;
+
+ // Build the server address.
+
+ string userPrincipalURI = "";
+ userPrincipalURI = GetUserPrincipal();
+
+ if (userPrincipalURI.size() == 0){
+
+ return serverResult;
+
+ }
+
+ string calendarHomeURI = "";
+ calendarHomeURI = GetCalendarHome(userPrincipalURI);
+
+ // Generate the UUID.
+
+ string UUIDValue = "";
+
+ if (calendarShortName == nullptr){
+
+ UUIDValue = GenerateUUID();
+ UUIDValue.erase(UUIDValue.end()-1);
+
+ } else {
+
+ UUIDValue = *calendarShortName;
+
+ }
+
+ string calendarHomeURL = calendarHomeURI;
+ calendarHomeURL.append(UUIDValue);
+ calendarHomeURL.append("/");
+
+ // Build the calendar list address.
+
+ string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURL);
+
+ string calendarAddRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<c:mkcalendar xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:set>\n"
+ " <d:prop>\n"
+ " <d:displayname>";
+ calendarAddRequest += *calendarName;
+ calendarAddRequest += "</d:displayname>\n"
+ " <c:supported-calendar-component-set>\n"
+ " <c:comp name=\"VTODO\"/>\n"
+ " <c:comp name=\"VEVENT\"/>\n"
+ " </c:supported-calendar-component-set>\n"
+ " </d:prop>\n"
+ " </d:set>\n"
+ "</c:mkcalendar>";
+
+ calendarAddSendData.readptr = &calendarAddRequest;
+ calendarAddSendData.sizeleft = calendarAddRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *calendarRequestHeader = NULL;
+
+ //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarAddSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendarProcess(string *calendarHREF,
+ string *calendarName,
+ Colour *calendarColour,
+ string *calendarDescription,
+ int *calendarOrder){
+
+ CalDAVServerResult serverResult;
+ CalDAVSendData calendarEditSendData;
+
+ // Build the server address.
+
+ string userPrincipalURI = "";
+ userPrincipalURI = GetUserPrincipal();
+
+ if (userPrincipalURI.size() == 0){
+
+ return serverResult;
+
+ }
+
+ string calendarHomeURI = "";
+ calendarHomeURI = GetCalendarHome(userPrincipalURI);
+
+ // Generate the UUID.
+
+ string UUIDValue = GenerateUUID();
+ UUIDValue.erase(UUIDValue.end()-1);
+
+ string calendarHomeURL = calendarHomeURI;
+ calendarHomeURL.append(UUIDValue);
+ calendarHomeURL.append("/");
+
+ // Build the calendar list address.
+
+ string calendarEditURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
+
+ string calendarEditRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propertyupdate xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"\n"
+ " xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:set>\n"
+ " <d:prop>\n";
+
+ // Update the calendar name.
+
+ if (calendarName != nullptr){
+
+ calendarEditRequest += "<d:displayname>";
+ calendarEditRequest += (*calendarName);
+ calendarEditRequest += "</d:displayname>\n";
+
+ }
+
+ // Update the calendar colour.
+
+ if (calendarColour != nullptr){
+
+ calendarEditRequest += "<x0:calendar-color>";
+ calendarEditRequest += (*calendarColour);
+ calendarEditRequest += "</x0:calendar-color>\n";
+
+ }
+
+ // Update the calendar description.
+
+ if (calendarDescription != nullptr){
+
+ calendarEditRequest += "<c:calendar-description>";
+ calendarEditRequest += (*calendarDescription);
+ calendarEditRequest += "</c:calendar-description>\n";
+
+ }
+
+ // Update the calendar order.
+
+ if (calendarOrder != nullptr){
+
+ calendarEditRequest += "<x0:calendar-order>";
+ calendarEditRequest += to_string((*calendarOrder));
+ calendarEditRequest += "</x0:calendar-order>\n";
+
+ }
+
+ calendarEditRequest += " </d:prop>\n"
+ " </d:set>\n"
+ "</d:propertyupdate>";
+
+ calendarEditSendData.readptr = &calendarEditRequest;
+ calendarEditSendData.sizeleft = calendarEditRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *calendarRequestHeader = NULL;
+
+ //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarEditURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarEditSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+ string *calendarName,
+ Colour *calendarColour,
+ string *calendarDescription,
+ int *calendarOrder){
+
+ CalDAVServerResult serverResult;
+
+ serverResult = EditCalendarProcess(calendarHREF,
+ calendarName,
+ calendarColour,
+ calendarDescription,
+ calendarOrder);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+ Colour *calendarColour){
+
+ CalDAVServerResult serverResult;
+
+ serverResult = EditCalendarProcess(calendarHREF,
+ nullptr,
+ calendarColour,
+ nullptr,
+ nullptr);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+ string *calendarName){
+
+ CalDAVServerResult serverResult;
+
+ serverResult = EditCalendarProcess(calendarHREF,
+ calendarName,
+ nullptr,
+ nullptr,
+ nullptr);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+ int *calendarOrder){
+
+ CalDAVServerResult serverResult;
+
+ serverResult = EditCalendarProcess(calendarHREF,
+ nullptr,
+ nullptr,
+ nullptr,
+ calendarOrder);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendarDescription(string *calendarHREF,
+ string *calendarDescription){
+
+ CalDAVServerResult serverResult;
+
+ serverResult = EditCalendarProcess(calendarHREF,
+ nullptr,
+ nullptr,
+ calendarDescription,
+ nullptr);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::DeleteCalendar(string *calendarHREF){
+
+ CalDAVServerResult serverResult;
+
+ // Build the server address.
+
+ string userPrincipalURI = "";
+ userPrincipalURI = GetUserPrincipal();
+
+ if (userPrincipalURI.size() == 0){
+
+ return serverResult;
+
+ }
+
+ string calendarHomeURI = "";
+ calendarHomeURI = GetCalendarHome(userPrincipalURI);
+
+ // Generate the UUID.
+
+ string UUIDValue = GenerateUUID();
+ UUIDValue.erase(UUIDValue.end()-1);
+
+ string calendarHomeURL = calendarHomeURI;
+ calendarHomeURL.append(UUIDValue);
+ calendarHomeURL.append("/");
+
+ // Build the calendar list address.
+
+ struct curl_slist *deleteRequestHeader = NULL;
+
+ deleteRequestHeader = curl_slist_append(deleteRequestHeader, "Depth: infinity");
+
+ string calendarDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, deleteRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarDeleteURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+
+ // Delete the calendar.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::GetEntryETag(string *calendarEntryHREF, string *eTagValue){
+
+ CalDAVServerResult serverResult;
+ CalDAVSendData entryETagGetData;
+
+ // Build the server address.
+
+ string userPrincipalURI = "";
+ userPrincipalURI = GetUserPrincipal();
+
+ if (userPrincipalURI.size() == 0){
+
+ return serverResult;
+
+ }
+
+ string calendarHomeURI = "";
+ calendarHomeURI = GetCalendarHome(userPrincipalURI);
+
+ // Split the path and filename.
+
+ string entryURIPath;
+ string entryFilename;
+
+ SplitPathFilename(calendarEntryHREF, &entryURIPath, &entryFilename);
+
+ // Build the request for the server.
+
+ string entryETagRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " </d:prop>\n"
+ " <d:href>";
+ entryETagRequest += (*calendarEntryHREF);
+ entryETagRequest += "</d:href>\n"
+ "</c:calendar-multiget>";
+
+ entryETagGetData.readptr = &entryETagRequest;
+ entryETagGetData.sizeleft = entryETagRequest.size();
+
+ // Build the calendar list address.
+
+ struct curl_slist *getETagRequestHeader = NULL;
+
+ getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Depth: 1");
+ getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Prefer: return-minimal");
+ getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ string getETagURLAddress = BuildServerAddress(&connectionData, entryURIPath);
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, getETagRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, getETagURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryETagGetData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Attempt to get the entity tag.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ if (serverConnectionResult != CURLE_OK){
+ return serverResult;
+ }
+
+ // Get the entity tag from the result.
+
+ *eTagValue = ProcessXMLEntryETag();
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::AddEntry(string *calendarEntryHREF, string *entryData){
+
+ // Add an entry to the calendar collection.
+
+ CalDAVServerResult serverResult;
+ CalDAVSendData entryAddSendData;
+
+ // Build the calendar list address.
+
+ string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
+
+ entryAddSendData.readptr = entryData;
+ entryAddSendData.sizeleft = entryData->size();
+
+ struct curl_slist *calendarRequestHeader = NULL;
+
+ calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditEntry(string *calendarEntryHREF, string *entryData, string *entryETag){
+
+ // Edit an entry in the calendar collection.
+
+ // Add an entry to the calendar collection.
+
+ CalDAVServerResult serverResult;
+ CalDAVSendData entryAddSendData;
+
+ // Build the calendar list address.
+
+ string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
+
+ entryAddSendData.readptr = entryData;
+ entryAddSendData.sizeleft = entryData->size();
+
+ string ifMatchHeader = "If-Match: \"";
+ ifMatchHeader.append(*entryETag);
+ ifMatchHeader.append("\"");
+
+ struct curl_slist *calendarRequestHeader = NULL;
+
+ calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
+ calendarRequestHeader = curl_slist_append(calendarRequestHeader, ifMatchHeader.c_str());
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::DeleteEntry(string *calendarEntryHREF){
+
+ // Delete an entry in the calendar collection.
+
+ CalDAVServerResult serverResult;
+
+ // Build the calendar list address.
+
+ string entryDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
+
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, entryDeleteURLAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+
+ // Delete the calendar.
+
+ serverData.clear();
+ serverHeader.clear();
+
+ CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+
+ if (serverConnectionResult == CURLE_OK){
+ serverResult.result = CALDAVQUERYRESULT_OK;
+ } else {
+ serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ serverResult.code = serverConnectionResult;
+ curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+ // Restore the original settings.
+
+ string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+ curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+ curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return serverResult;
+
+}
+
+bool CalDAVObjectValidSettings(CalDAVConnectionData *connData){
+
+ // Check if the passed CalDAV Connection Data is has
+ // an address set. Return false if nullptr is used.
+
+ if (connData == nullptr){
+
+ return false;
+
+ }
+
+ // Check the server hostname. Return false
+ // if no value has been set.
+
+ if (connData->hostname.size() == 0){
+
+ return false;
+
+ }
+
+ // Check the server port. Return false if
+ // no value has been set or the port number
+ // is less than 1 or higher than 65535.
+
+ if (connData->port < 1 || connData->port > 65535){
+
+ return false;
+
+ }
+
+ // Check the server username. Return false
+ // if no value has been set.
+
+ if (connData->username.size() == 0){
+
+ return false;
+
+ }
+
+ // Check the server password. Return false
+ // if no value has been set.
+
+ if (connData->password.size() == 0){
+
+ return false;
+
+ }
+
+ // Cannot check UseSSL: It is either true
+ // or false.
+
+ // Cannot check Prefix: The prefix may need
+ // to be worked out first.
+
+ // No errors were found whilst checking so
+ // return true.
+
+ return true;
+
+}
+
+string BuildServerAddress(CalDAVConnectionData *connData, string uriAddress){
+
+ string serverAddress;
+
+ // Setup the server address.
+
+ if (connData->useSSL == true){
+ serverAddress += "https://";
+ } else {
+ serverAddress += "http://";
+ }
+
+ serverAddress += connData->hostname;
+
+ // Check if server port is 80, otherwise
+ // specifiy the port number in the address.
+
+ if (connData->port != 80){
+ serverAddress += ":";
+ serverAddress += to_string(connData->port);
+ }
+
+ serverAddress += uriAddress;
+
+ return serverAddress;
+
+}
\ No newline at end of file