// ContactDataObject.cpp - Client Data Object. // // (c) 2012-2015 Xestia Software Development. // // This file is part of Xestia Address Book. // // Xestia Address Book is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by the // Free Software Foundation, version 3 of the license. // // Xestia Address Book is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with Xestia Address Book. If not, see #include "ContactDataObject.h" ContactLoadStatus ContactDataObject::LoadFile(wxString Filename){ if (!wxFileExists(Filename)){ return CONTACTLOAD_FILEMISSING; } wxFile ContactFile; if (!ContactFile.Open(Filename, wxFile::read, wxS_DEFAULT)){ return CONTACTLOAD_FILEERROR; } // Check that the vCard is a valid vCard 4.0 file. vCard vCard4FormatCheck; vCard4FormatCheck.LoadFile(Filename); if (vCard4FormatCheck.Get("VERSION") != wxT("4.0")){ return CONTACTLOAD_FILEINVALIDFORMAT; } // Check that the vCard meets the base specification. if (!vCard4FormatCheck.MeetBaseSpecification()){ return CONTACTLOAD_FILEBASESPECFAIL; } wxStringTokenizer wSTContactFileLines(vCard4FormatCheck.WriteString(), wxT("\r\n")); std::map ContactFileLines; int ContactLineSeek = 0; while (wSTContactFileLines.HasMoreTokens() == TRUE){ wxString ContactLine = wSTContactFileLines.GetNextToken(); ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine)); ContactLineSeek++; } wxString wxSPropertyNextLine; bool ExtraLineSeek = TRUE; bool QuoteMode = FALSE; bool PropertyFind = TRUE; bool KindProcessed = FALSE; bool NameProcessed = FALSE; bool GenderProcessed = FALSE; bool BirthdayProcessed = FALSE; bool AnniversaryProcessed = FALSE; int ContactLineLen = 0; int QuoteBreakPoint = 0; int GroupCount = 0; int FNCount = 0; int NicknameCount = 0; int TimeZoneCount = 0; wxString ContactLine; wxString PropertyLine; wxString PropertySeg1; wxString PropertySeg2; wxString PropertyNextLine; wxString Property; for (std::map::iterator iter = ContactFileLines.begin(); iter != ContactFileLines.end(); ++iter){ ExtraLineSeek = TRUE; QuoteMode = FALSE; PropertyFind = TRUE; ContactLineLen = 0; QuoteBreakPoint = 0; ContactLine.Clear(); PropertyLine.Clear(); PropertySeg1.Clear(); PropertySeg2.Clear(); Property.Clear(); ContactLine = iter->second; while (ExtraLineSeek == TRUE){ // Check if there is extra data on the next line // (indicated by space or tab at the start) and add data. iter++; if (iter == ContactFileLines.end()){ iter--; break; } PropertyNextLine = iter->second; if (PropertyNextLine.Mid(0, 1) == wxT(" ") || PropertyNextLine.Mid(0, 1) == wxT("\t")){ PropertyNextLine.Remove(0, 1); ContactLine.Append(PropertyNextLine); } else { iter--; ExtraLineSeek = FALSE; } } ContactLineLen = ContactLine.Len(); // Make sure we are not in quotation mode. // Make sure colon does not have \ or \\ before it. for (int i = 0; i <= ContactLineLen; i++){ if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){ PropertyFind = FALSE; } else if (PropertyFind == TRUE){ Property.Append(ContactLine.Mid(i, 1)); } if (ContactLine.Mid(i, 1) == wxT("\"")){ if (QuoteMode == TRUE){ QuoteMode = FALSE; } else { QuoteMode = TRUE; } } if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){ QuoteBreakPoint = i; break; } } // Split that line at the point into two variables (ignore the colon). PropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint); PropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1)); if (Property == wxT("KIND") && KindProcessed == FALSE){ ProcessKind(PropertySeg2); } else if (Property == wxT("MEMBER")){ ProcessMember(PropertySeg1, PropertySeg2, &GroupCount); GroupCount++; } else if (Property == wxT("FN")){ ProcessFN(PropertySeg1, PropertySeg2, &FNCount); FNCount++; } else if (Property == wxT("N") && NameProcessed == FALSE){ ProcessN(PropertySeg1, PropertySeg2); NameProcessed = TRUE; } else if (Property == wxT("NICKNAME")){ ProcessNickname(PropertySeg1, PropertySeg2, &NicknameCount); NicknameCount++; } else if (Property == wxT("GENDER") && GenderProcessed == FALSE){ ProcessGender(PropertySeg1, PropertySeg2); GenderProcessed = TRUE; } else if (Property == wxT("BDAY") && BirthdayProcessed == FALSE){ ProcessBirthday(PropertySeg1, PropertySeg2); BirthdayProcessed = TRUE; } else if (Property == wxT("ANNIVERSARY") && AnniversaryProcessed == FALSE){ ProcessAnniversary(PropertySeg1, PropertySeg2); AnniversaryProcessed = TRUE; } else if (Property == wxT("TZ")){ ProcessTimeZone(PropertySeg1, PropertySeg2, &TimeZoneCount); TimeZoneCount++; } } return CONTACTLOAD_OK; } void ContactDataObject::ProcessKind(wxString KindType){ if (KindType == wxT("individual")){ ContactKind = CONTACTKIND_INDIVIDUAL; } else if (KindType == wxT("group")){ ContactKind = CONTACTKIND_GROUP; } else if (KindType == wxT("org")){ ContactKind = CONTACTKIND_ORGANISATION; } else if (KindType == wxT("location")){ ContactKind = CONTACTKIND_LOCATION; } else { ContactKind = CONTACTKIND_NONE; } } void ContactDataObject::ProcessMember(wxString PropertySeg1, wxString PropertySeg2, int *GroupCount){ std::map SplitPoints; std::map SplitLength; int intPrevValue = 8; int intPref = 0; int intType = 0; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 7; wxString PropertyName; wxString PropertyValue; wxString PropertyData; wxString PropertyTokens; std::map::iterator SLiter; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; CaptureString(&PropertyValue, FALSE); if (PropertyName == wxT("ALTID")){ GroupsListAltID.erase(*GroupCount); GroupsListAltID.insert(std::make_pair(*GroupCount, PropertyValue)); } else if (PropertyName == wxT("PID")){ GroupsListPID.erase(*GroupCount); GroupsListPID.insert(std::make_pair(*GroupCount, PropertyValue)); } else if (PropertyName == wxT("PREF")){ int PriorityNumber = 0; bool ValidNumber = TRUE; try{ PriorityNumber = std::stoi(PropertyValue.ToStdString()); } catch(std::invalid_argument &e){ ValidNumber = FALSE; } if (ValidNumber == TRUE){ GroupsListPref.erase(*GroupCount); GroupsListPref.insert(std::make_pair(*GroupCount, PriorityNumber)); } } else if (PropertyName == wxT("MEDIATYPE")){ GroupsListMediaType.erase(*GroupCount); GroupsListMediaType.insert(std::make_pair(*GroupCount, PropertyValue)); } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } GroupsList.insert(std::make_pair(*GroupCount, PropertySeg2)); if (!PropertyTokens.IsEmpty()){ GroupsListTokens.insert(std::make_pair(*GroupCount, PropertyTokens)); } } void ContactDataObject::ProcessFN(wxString PropertySeg1, wxString PropertySeg2, int *FNCount){ std::map SplitPoints; std::map SplitLength; int intPrevValue = 4; int intPref = 0; int intType = 0; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 3; wxString PropertyName; wxString PropertyValue; wxString PropertyData; wxString PropertyTokens; std::map::iterator SLiter; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; CaptureString(&PropertyValue, FALSE); if (PropertyName == wxT("TYPE")){ if (!PropertyValue.IsEmpty() || PropertyValue == wxT("home") || PropertyValue == wxT("work") ){ FullNamesListType.erase(*FNCount); FullNamesListType.insert(std::make_pair(*FNCount, PropertyValue)); } } else if (PropertyName == wxT("LANGUAGE")){ FullNamesListLanguage.erase(*FNCount); FullNamesListLanguage.insert(std::make_pair(*FNCount, PropertyValue)); } else if (PropertyName == wxT("ALTID")){ FullNamesListAltID.erase(*FNCount); FullNamesListAltID.insert(std::make_pair(*FNCount, PropertyValue)); } else if (PropertyName == wxT("PID")){ FullNamesListPID.erase(*FNCount); FullNamesListPID.insert(std::make_pair(*FNCount, PropertyValue)); } else if (PropertyName == wxT("PREF")){ int PriorityNumber = 0; bool ValidNumber = TRUE; try{ PriorityNumber = std::stoi(PropertyValue.ToStdString()); } catch(std::invalid_argument &e){ ValidNumber = FALSE; } if (ValidNumber == TRUE){ FullNamesListPref.erase(*FNCount); FullNamesListPref.insert(std::make_pair(*FNCount, PriorityNumber)); } } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } FullNamesList.insert(std::make_pair(*FNCount, PropertySeg2)); if (!PropertyTokens.IsEmpty()){ FullNamesListTokens.insert(std::make_pair(*FNCount, PropertyTokens)); } } void ContactDataObject::ProcessN(wxString PropertySeg1, wxString PropertySeg2){ std::map SplitPoints; std::map SplitLength; int intPrevValue = 3; int intPref = 0; int intType = 0; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 2; wxString PropertyName; wxString PropertyValue; wxString PropertyData; wxString PropertyTokens; std::map::iterator SLiter; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; CaptureString(&PropertyValue, FALSE); if (PropertyName == wxT("ALTID")){ NameAltID = PropertyValue; } else if (PropertyName == wxT("LANGUAGE")){ NameLanguage = PropertyValue; } else if (PropertyName == wxT("SORT-AS")){ if (PropertyValue.Left(1) == wxT("\"") && PropertyValue.Right(1) == wxT("\"") && PropertyValue.Len() >= 3){ NameDisplayAs = PropertyValue.Mid(1, (PropertyValue.Len() - 2)); } } else if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } // Split the name data. int intSplitSeek = 0; int intSplitsFound = 0; int intSplitSize = 0; int intPropertyLen = PropertySeg2.Len(); std::map NameValues; intPrevValue = 0; for (int i = 0; i <= intPropertyLen; i++){ if (PropertySeg2.Mid(i, 1) == wxT(";") && PropertySeg2.Mid((i - 1), 1) != wxT("\\")){ NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, intSplitSize))); intSplitSeek = i; intSplitSeek++; if (intSplitsFound == 4){ NameValues.insert(std::make_pair(++intSplitsFound, PropertySeg2.Mid(intSplitSeek, wxString::npos))); break; } intSplitSize = 0; continue; } intSplitSize++; } // Split the data into several parts. for (std::map::iterator iter = NameValues.begin(); iter != NameValues.end(); ++iter){ if (iter->first == 1){ // Deal with family name. NameSurname = iter->second; } else if (iter->first == 2){ // Deal with given names. NameForename = iter->second; } else if (iter->first == 3){ // Deal with additional names. NameOtherNames = iter->second; } else if (iter->first == 4){ // Deal with honorifix prefixes and suffixes. NameTitle = iter->second; iter++; if (iter == NameValues.end()){ break; } NameSuffix = iter->second; } } // Add the name token data. if (!PropertyTokens.IsEmpty()){ NameTokens = PropertyTokens; } } void ContactDataObject::ProcessNickname(wxString PropertySeg1, wxString PropertySeg2, int *NicknameCount){ std::map SplitPoints; std::map SplitLength; int intPrevValue = 10; int intPref = 0; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 9; PropertyType PropType; // Look for type before continuing. CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType); intPrevValue = 9; std::map *NicknamesList = NULL; std::map *NicknamesListType = NULL; std::map *NicknamesListLanguage = NULL; std::map *NicknamesListAltID = NULL; std::map *NicknamesListPID = NULL; std::map *NicknamesListTokens = NULL; std::map *NicknamesListPref = NULL; switch(PropType){ case PROPERTY_NONE: NicknamesList = &GeneralNicknamesList; NicknamesListType = &GeneralNicknamesListType; NicknamesListLanguage = &GeneralNicknamesListLanguage; NicknamesListAltID = &GeneralNicknamesListAltID; NicknamesListPID = &GeneralNicknamesListPID; NicknamesListTokens = &GeneralNicknamesListTokens; NicknamesListPref = &GeneralNicknamesListPref; break; case PROPERTY_HOME: NicknamesList = &HomeNicknamesList; NicknamesListType = &HomeNicknamesListType; NicknamesListLanguage = &HomeNicknamesListLanguage; NicknamesListAltID = &HomeNicknamesListAltID; NicknamesListPID = &HomeNicknamesListPID; NicknamesListTokens = &HomeNicknamesListTokens; NicknamesListPref = &HomeNicknamesListPref; break; case PROPERTY_WORK: NicknamesList = &BusinessNicknamesList; NicknamesListType = &BusinessNicknamesListType; NicknamesListLanguage = &BusinessNicknamesListLanguage; NicknamesListAltID = &BusinessNicknamesListAltID; NicknamesListPID = &BusinessNicknamesListPID; NicknamesListTokens = &BusinessNicknamesListTokens; NicknamesListPref = &BusinessNicknamesListPref; break; } std::map::iterator SLiter; wxString PropertyData; wxString PropertyName; wxString PropertyValue; wxString PropertyTokens; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; CaptureString(&PropertyValue, FALSE); if (PropertyName == wxT("ALTID")){ NicknamesListAltID->erase(*NicknameCount); NicknamesListAltID->insert(std::make_pair(*NicknameCount, PropertyValue)); } else if (PropertyName == wxT("PID")){ NicknamesListPID->erase(*NicknameCount); NicknamesListPID->insert(std::make_pair(*NicknameCount, PropertyValue)); } else if (PropertyName == wxT("PREF")){ int PriorityNumber = 0; bool ValidNumber = TRUE; try{ PriorityNumber = std::stoi(PropertyValue.ToStdString()); } catch(std::invalid_argument &e){ ValidNumber = FALSE; } if (ValidNumber == TRUE){ NicknamesListPref->erase(*NicknameCount); NicknamesListPref->insert(std::make_pair(*NicknameCount, PriorityNumber)); } } else if (PropertyName == wxT("LANGUAGE")){ NicknamesListLanguage->erase(*NicknameCount); NicknamesListLanguage->insert(std::make_pair(*NicknameCount, PropertyValue)); } else { // Something else we don't know about so append // to the tokens variable. if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } } NicknamesList->insert(std::make_pair(*NicknameCount, PropertySeg2)); // Add the name token data. if (!PropertyTokens.IsEmpty()){ NicknamesListTokens->insert(std::make_pair(*NicknameCount, PropertyTokens)); } } void ContactDataObject::ProcessGender(wxString PropertySeg1, wxString PropertySeg2){ std::map SplitPoints; std::map SplitLength; std::map::iterator SLiter; wxString PropertyData; wxString PropertyName; wxString PropertyValue; wxString PropertyTokens; bool FirstToken = TRUE; int intPrevValue = 8; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 7; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; // Process properties. size_t intPropertyValueLen = PropertyValue.Len(); if (PropertyValue.Mid((intPropertyValueLen - 1), 1) == wxT("\"")){ PropertyValue.Trim(); PropertyValue.RemoveLast(); } if (PropertyValue.Mid(0, 1) == wxT("\"")){ PropertyValue.Remove(0, 1); } if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } wxStringTokenizer GenderData (PropertySeg2, wxT(";")); wxString GenderComponent; if (GenderData.CountTokens() >= 2){ Gender = GenderData.GetNextToken(); GenderDetails = GenderData.GetString(); CaptureString(&GenderDetails, FALSE); } else { Gender = GenderData.GetNextToken(); } if (!PropertyTokens.IsEmpty()){ GenderTokens = PropertyTokens; } } void ContactDataObject::ProcessBirthday(wxString PropertySeg1, wxString PropertySeg2){ // Process date. Preserve the remainder in the string. std::map SplitPoints; std::map SplitLength; std::map::iterator SLiter; wxString PropertyData; wxString PropertyName; wxString PropertyValue; wxString PropertyTokens; bool BirthdayText = FALSE; int intPrevValue = 6; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 5; // Look for type before continuing. for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && BirthdayText == FALSE){ CaptureString(&PropertySeg2, FALSE); Birthday = PropertySeg2; BirthdayText = TRUE; } } // Setup blank lines for later on. intPrevValue = 5; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; // Process properties. CaptureString(&PropertyValue, FALSE); if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){ PropertyValue.Trim(); PropertyValue.RemoveLast(); } if (PropertyValue.Mid(0, 1) == wxT("\"")){ PropertyValue.Remove(0, 1); } if (PropertyName == wxT("ALTID")){ BirthdayAltID = PropertyValue; } else if (PropertyName == wxT("CALSCALE")){ BirthdayCalScale = PropertyValue; } else if (PropertyName != wxT("VALUE")) { // Something else we don't know about so append // to the tokens variable. if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } } // Add the data to the variables and form. if (BirthdayText == FALSE){ Birthday = PropertySeg2; } if (!PropertyTokens.IsEmpty()){ BirthdayTokens = PropertyTokens; } } void ContactDataObject::ProcessAnniversary(wxString PropertySeg1, wxString PropertySeg2){ // Process date. Preserve the remainder in the string. std::map SplitPoints; std::map SplitLength; std::map::iterator SLiter; wxString PropertyData; wxString PropertyName; wxString PropertyValue; wxString PropertyTokens; bool AnniversaryText = FALSE; int intPrevValue = 13; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 12; // Look for type before continuing. for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; if (PropertyName == wxT("VALUE") && PropertyValue == wxT("text") && AnniversaryText == FALSE){ CaptureString(&PropertySeg2, FALSE); Anniversary = PropertySeg2; AnniversaryText = TRUE; } } // Setup blank lines for later on. intPrevValue = 12; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, SLiter->second); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; // Process properties. CaptureString(&PropertyValue, FALSE); if (PropertyValue.Mid((PropertyValue.Len() - 1), 1) == wxT("\"")){ PropertyValue.Trim(); PropertyValue.RemoveLast(); } if (PropertyValue.Mid(0, 1) == wxT("\"")){ PropertyValue.Remove(0, 1); } if (PropertyName == wxT("ALTID")){ AnniversaryAltID = PropertyValue; } else if (PropertyName == wxT("CALSCALE")){ AnniversaryCalScale = PropertyValue; } else if (PropertyName != wxT("VALUE")) { // Something else we don't know about so append // to the tokens variable. if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty()){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } } // Add the data to the variables and form. if (AnniversaryText == FALSE){ Anniversary = PropertySeg2; } if (!PropertyTokens.IsEmpty()){ AnniversaryTokens = PropertyTokens; } } void ContactDataObject::ProcessTimeZone(wxString PropertySeg1, wxString PropertySeg2, int *TimeZoneCount){ std::map SplitPoints; std::map SplitLength; int intPrevValue = 4; int intPref = 0; SplitValues(&PropertySeg1, &SplitPoints, &SplitLength, intPrevValue); intPrevValue = 3; PropertyType PropType; // Look for type before continuing. CheckType(&PropertySeg1, &SplitPoints, &SplitLength, &intPrevValue, &PropType); intPrevValue = 3; std::map *TZList = NULL; std::map *TZListType = NULL; std::map *TZListMediatype = NULL; std::map *TZListAltID = NULL; std::map *TZListPID = NULL; std::map *TZListTokens = NULL; std::map *TZListPref = NULL; switch(PropType){ case PROPERTY_NONE: TZList = &GeneralTZList; TZListType = &GeneralTZListType; TZListMediatype = &GeneralTZListMediatype; TZListAltID = &GeneralTZListAltID; TZListPID = &GeneralTZListPID; TZListTokens = &GeneralTZListTokens; TZListPref = &GeneralTZListPref; break; case PROPERTY_HOME: TZList = &HomeTZList; TZListType = &HomeTZListType; TZListMediatype = &HomeTZListMediatype; TZListAltID = &HomeTZListAltID; TZListPID = &HomeTZListPID; TZListTokens = &HomeTZListTokens; TZListPref = &HomeTZListPref; break; case PROPERTY_WORK: TZList = &BusinessTZList; TZListType = &BusinessTZListType; TZListMediatype = &BusinessTZListMediatype; TZListAltID = &BusinessTZListAltID; TZListPID = &BusinessTZListPID; TZListTokens = &BusinessTZListTokens; TZListPref = &BusinessTZListPref; break; } std::map::iterator SLiter; wxString PropertyData; wxString PropertyName; wxString PropertyValue; wxString PropertyTokens; bool FirstToken = TRUE; for (std::map::iterator intiter = SplitPoints.begin(); intiter != SplitPoints.end(); ++intiter){ SLiter = SplitLength.find(intiter->first); PropertyData = PropertySeg1.Mid(intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); intPrevValue = intiter->second; CaptureString(&PropertyValue, FALSE); if (PropertyName == wxT("ALTID")){ TZListAltID->erase(*TimeZoneCount); TZListAltID->insert(std::make_pair(*TimeZoneCount, PropertyValue)); } else if (PropertyName == wxT("PID")){ TZListPID->erase(*TimeZoneCount); TZListPID->insert(std::make_pair(*TimeZoneCount, PropertyValue)); } else if (PropertyName == wxT("PREF")){ int PriorityNumber = 0; bool ValidNumber = TRUE; try{ PriorityNumber = std::stoi(PropertyValue.ToStdString()); } catch(std::invalid_argument &e){ ValidNumber = FALSE; } if (ValidNumber == TRUE){ TZListPref->erase(*TimeZoneCount); TZListPref->insert(std::make_pair(*TimeZoneCount, PriorityNumber)); } } else if (PropertyName == wxT("MEDIATYPE")){ TZListMediatype->erase(*TimeZoneCount); TZListMediatype->insert(std::make_pair(*TimeZoneCount, PropertyValue)); } else { // Something else we don't know about so append // to the tokens variable. if (!PropertyName.IsEmpty() && !PropertyValue.IsEmpty() && PropertyName != wxT("TYPE")){ if (FirstToken == TRUE){ PropertyTokens.Append(PropertyName + wxT("=") + PropertyValue); FirstToken = FALSE; } else { PropertyTokens.Append(wxT(";") + PropertyName + wxT("=") + PropertyValue); } } } } TZList->insert(std::make_pair(*TimeZoneCount, PropertySeg2)); // Add the name token data. if (!PropertyTokens.IsEmpty()){ TZListTokens->insert(std::make_pair(*TimeZoneCount, PropertyTokens)); } } void SplitValues(wxString *PropertyLine, std::map *SplitPoints, std::map *SplitLength, int intSize){ size_t intPropertyLen = PropertyLine->Len(); int intSplitsFound = 0; int intSplitSize = 0; int intSplitSeek = 0; for (int i = intSize; i <= intPropertyLen; i++){ intSplitSize++; if (PropertyLine->Mid(i, 1) == wxT(";") && PropertyLine->Mid((i - 1), 1) != wxT("\\")){ if (intSplitsFound == 0){ SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize))); } else { SplitLength->insert(std::make_pair(intSplitsFound, (intSplitSize - 1))); } SplitPoints->insert(std::make_pair(intSplitsFound, (i + 1))); intSplitsFound++; intSplitSeek = i; intSplitSize = 0; } } if (intSplitsFound == 0){ SplitPoints->insert(std::make_pair(intSplitsFound, (8 + 1))); SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize)); } else { SplitPoints->insert(std::make_pair(intSplitsFound, (intSplitSeek + 1))); SplitLength->insert(std::make_pair(intSplitsFound, intSplitSize)); } } void CheckType(wxString *PropertySeg1, std::map *SplitPoints, std::map *SplitLength, int *intPrevValue, PropertyType *PropType){ wxString PropertyData; wxString PropertyName; wxString PropertyValue; std::map::iterator SLiter; for (std::map::iterator intiter = SplitPoints->begin(); intiter != SplitPoints->end(); ++intiter){ SLiter = SplitLength->find(intiter->first); PropertyData = PropertySeg1->Mid(*intPrevValue, (SLiter->second)); wxStringTokenizer PropertyElement (PropertyData, wxT("=")); PropertyName = PropertyElement.GetNextToken(); PropertyValue = PropertyElement.GetNextToken(); *intPrevValue = intiter->second; if (PropertyName == wxT("TYPE")){ if (PropertyValue == wxT("work")){ *PropType = PROPERTY_WORK; } else if (PropertyValue == wxT("home")){ *PropType = PROPERTY_HOME; } else { *PropType = PROPERTY_NONE; } return; } } }