// vcard34conv-v4conv.cpp - vCard34Conv Object vCard4 conversion subroutines.
//
// (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 "vcard34conv.h"
#include "vcard.h"
#include "../version.h"
#include "../common/textprocessing.h"
#include
#include
#include
#include
bool vCard34Conv::ConvertToV4(wxString *wxSData, vCard *vCardOut){
// Convert a vCard 3.0 format into the vCard 4.0 format.
std::map ContactFileLines;
std::map ContactFileProcessed;
std::map ContactFileProcessedWorking;
std::map::iterator striter;
std::map::iterator iterbool;
std::map::iterator iterboolsub;
wxString ContactLineRec;
// Process the received data.
wxStringTokenizer wSTContactFileLines(*wxSData, wxT("\r\n"));
int ContactLineSeek = 0;
while (wSTContactFileLines.HasMoreTokens() == TRUE){
ContactLineRec = wSTContactFileLines.GetNextToken();
ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLineRec));
ContactFileProcessed.insert(std::make_pair(ContactLineSeek, FALSE));
ContactLineSeek++;
}
bool QuoteMode = FALSE;
bool PropertyFind = TRUE;
bool ExtraLineSeek = TRUE;
bool ExtraLineSeekSub = TRUE;
bool FNFirst = FALSE;
bool NicknameFirst = FALSE;
bool TitleFirst = FALSE;
bool OrganisationFirst = FALSE;
bool NoteFirst = FALSE;
bool PhotoFirst = FALSE;
bool FoundData = FALSE;
wxString wxSProperty;
wxString wxSPropertyVCARD4;
wxString wxSPropertySeg1;
wxString wxSPropertySeg2;
wxString wxSPropertyNextLine;
wxString ContactLine;
wxString ContactLineSub;
wxString PropertyName;
wxString PropertyValue;
wxString PropertyDataStr;
size_t ContactLineLen = 0;
size_t ContactLineSubLen = 0;
int QuoteBreakPoint = 0;
size_t intPrevValueSub = 0;
std::map PropertyData;
std::map PropertyLock;
std::map TempPropertyData;
std::map TempPropertyLock;
std::map TempSplitPoints;
std::map TempSplitLength;
std::map::iterator SLiter;
wxString PropertFindSub;
wxString wxSPropertySub;
wxString wxSPropertySeg1Sub;
wxString wxSPropertySeg2Sub;
wxString wxSPropertyValues;
wxString wxSPropertyData;
wxString wxSPropertyNameConv;
wxString wxSPropertyXVCard4Value;
wxString ItemProcString;
bool XVCard4Value = FALSE;
bool VCard3Value = FALSE;
wxString strVer;
// Setup the version string.
strVer.Append(wxT("-//Xestia//Address Book Version "));
strVer.Append(wxT(XSDAB_VERSION));
strVer.Append(wxT("//KW"));
vCardOut->AddRaw(wxT("BEGIN"), wxT("VCARD"));
vCardOut->AddRaw(wxT("VERSION"), wxT("4.0"));
vCardOut->AddRaw(wxT("PRODID"), strVer);
// FN
// NICKNAME
// TITLE
// ORG
// NOTE
// PHOTO
// Process the properties which have X-FIRST.
// Clone the ContactFileProcessed into ContactFileProcessedWorking.
ContactFileProcessedWorking.insert(ContactFileProcessed.begin(), ContactFileProcessed.end());
for (std::map::iterator iter = ContactFileLines.begin();
iter != ContactFileLines.end(); ++iter){
ExtraLineSeek = TRUE;
iterbool = ContactFileProcessed.find(iter->first);
ContactLine = iter->second;
// Ignore certain variables as they are not needed.
if (ContactLine == wxT("BEGIN:VCARD") ||
ContactLine == wxT("END:VCARD") ||
ContactLine.Mid(0, 8) == wxT("VERSION:") ||
ContactLine.Mid(0, 7) == wxT("PRODID:") ||
ContactLine.Mid(0, 5) == wxT("X-AIM") ||
ContactLine.Mid(0, 5) == wxT("X-MSN") ||
ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
ContactLine.Mid(0, 4) == wxT("REV:")){
iterbool->second = TRUE;
continue;
}
if (iterbool->second == TRUE){
continue;
}
if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
continue;
}
if (ContactLine.Mid(0, 4) == wxT("item")){
// Line is a itemn... so ignore.
continue;
}
std::map DataLineProcess;
std::map::iterator DLSLiter;
std::map DataLineProcessOriginal;
int DataLineSeek = 0;
int DataLineSeekOrig = 0;
std::map::iterator itersub = iter;
DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterbool->first));
DataLineSeekOrig++;
while (ExtraLineSeek == TRUE){
// Check if there is extra data on the next line
// (indicated by space or tab at the start) and add data.
itersub++;
if (itersub == ContactFileLines.end()){
break;
}
iterboolsub = ContactFileProcessed.find(itersub->first);
if (iterboolsub == ContactFileProcessed.end()){
break;
}
if (iterboolsub->second == TRUE){
continue;
}
wxSPropertyNextLine = itersub->second;
if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
wxSPropertyNextLine.Remove(0, 1);
ContactLine.Append(wxSPropertyNextLine);
DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterboolsub->first));
DataLineSeekOrig++;
} else {
ExtraLineSeek = FALSE;
}
}
ContactLineLen = ContactLine.Len();
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){
wxSProperty.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;
}
}
wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
wxSProperty = wxSPropertySegSplit.GetNextToken();
// Check what type of property it is.
FoundData = FALSE;
if ((wxSProperty == wxT("PHOTO") && PhotoFirst == FALSE) ||
(wxSProperty == wxT("NICKNAME") && NicknameFirst == FALSE) ||
(wxSProperty == wxT("TITLE") && TitleFirst == FALSE) ||
(wxSProperty == wxT("FN") && FNFirst == FALSE) ||
(wxSProperty == wxT("ORG") && OrganisationFirst == FALSE) ||
(wxSProperty == wxT("NOTE") && NoteFirst == FALSE)){
wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
intPrevValueSub = (wxSPropertyVCARD4.Len() + 2);
for (std::map::iterator itersub = ContactFileLines.begin();
itersub != ContactFileLines.end(); ++itersub){
ContactLineSub = itersub->second;
ExtraLineSeekSub = TRUE;
iterboolsub = ContactFileProcessed.find(itersub->first);
// Ignore certain variables as they are not needed.
if (ContactLineSub == wxT("BEGIN:VCARD") ||
ContactLineSub == wxT("END:VCARD") ||
ContactLineSub.Mid(0, 8) == wxT("VERSION:") ||
ContactLineSub.Mid(0, 7) == wxT("PRODID:") ||
ContactLineSub.Mid(0, 5) == wxT("X-AIM") ||
ContactLineSub.Mid(0, 5) == wxT("X-MSN") ||
ContactLineSub.Mid(0, 5) == wxT("X-ICQ") ||
ContactLineSub.Mid(0, 10) == wxT("X-GADUGADU") ||
ContactLineSub.Mid(0, 7) == wxT("X-YAHOO") ||
ContactLineSub.Mid(0, 7) == wxT("X-SKYPE") ||
ContactLineSub.Mid(0, 8) == wxT("X-JABBER") ||
ContactLineSub.Mid(0, 4) == wxT("REV:")){
iterboolsub->second = TRUE;
continue;
}
if (iterboolsub->second == TRUE){
continue;
}
if (ContactLineSub.Mid(0, 1) == wxT(" ") || ContactLineSub.Mid(0, 1) == wxT("\t")){
continue;
}
if (ContactLineSub.Mid(0, 4) == wxT("item")){
// Line is a itemn... so ignore.
continue;
}
DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
DataLineSeek++;
while (ExtraLineSeekSub == TRUE){
if (itersub == ContactFileLines.end()){
ExtraLineSeekSub = FALSE;
continue;
} else {
itersub++;
}
iterboolsub = ContactFileProcessedWorking.find(itersub->first);
wxSPropertyNextLine = itersub->second;
if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
wxSPropertyNextLine.Remove(0, 1);
ContactLineSub.Append(wxSPropertyNextLine);
DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
DataLineSeek++;
} else {
itersub--;
ExtraLineSeekSub = FALSE;
}
}
ContactLineSubLen = ContactLineSub.Len();
PropertyFind = TRUE;
wxSPropertySub.clear();
for (int i = 0; i <= ContactLineSubLen; i++){
if ((ContactLineSub.Mid(i, 1) == wxT(";") || ContactLineSub.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
PropertyFind = FALSE;
} else if (PropertyFind == TRUE){
wxSPropertySub.Append(ContactLineSub.Mid(i, 1));
}
if (ContactLineSub.Mid(i, 1) == wxT("\"")){
if (QuoteMode == TRUE){
QuoteMode = FALSE;
} else {
QuoteMode = TRUE;
}
}
if (ContactLineSub.Mid(i, 1) == wxT(":") && ContactLineSub.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
QuoteBreakPoint = i;
break;
}
}
if (wxSPropertySub != wxSPropertyVCARD4){
wxSPropertySub.clear();
DataLineSeek = 0;
DataLineProcess.clear();
continue;
}
wxSPropertySeg1Sub = ContactLineSub.Mid(0, QuoteBreakPoint);
wxSPropertySeg2Sub = ContactLineSub.Mid((QuoteBreakPoint + 1));
// Split the property name data.
// Strip the X-VCARD4- from the variable.
wxString wxSPropertyChopped = wxSPropertySeg1Sub.Mid(9);
intPrevValueSub = (wxSProperty.Len() + 2);
SplitValuesData(&wxSPropertyChopped, &TempSplitPoints, &TempSplitLength, (int)intPrevValueSub, &TempPropertyData);
// Process the splitted data into temporary property data.
// Look for certain property names and the X-FIRST
// property name.
bool ProcessData = FALSE;
// Check for X-FIRST.
for (std::map::iterator xfiter = TempPropertyData.begin();
xfiter != TempPropertyData.end(); ++xfiter){
PropertyName = xfiter->first;
PropertyValue = xfiter->second;
if (PropertyName == wxT("X-FIRST") && PropertyValue == wxT("TRUE")){
ProcessData = TRUE;
if (wxSProperty == wxT("PHOTO")){ PhotoFirst = TRUE; }
else if (wxSProperty == wxT("NICKNAME")){ NicknameFirst = TRUE; }
else if (wxSProperty == wxT("TITLE")){ TitleFirst = TRUE; }
else if (wxSProperty == wxT("FN")){ FNFirst = TRUE; }
else if (wxSProperty == wxT("ORG")){ OrganisationFirst = TRUE; }
else if (wxSProperty == wxT("NOTE")){ NoteFirst = TRUE; }
break;
}
}
if (ProcessData == FALSE){
DataLineProcess.clear();
DataLineSeek = 0;
TempPropertyData.clear();
} else {
for (std::map::iterator xfiter = TempPropertyData.begin();
xfiter != TempPropertyData.end(); ++xfiter){
PropertyName = xfiter->first;
PropertyValue = xfiter->second;
if (PropertyName == wxT("X-FIRST")){
continue;
}
PropertyData.insert(std::make_pair(PropertyName, PropertyValue));
PropertyLock.insert(std::make_pair(PropertyName, FALSE));
}
// Mark all lines as processed.
for (std::map::iterator dpiter = DataLineProcess.begin();
dpiter != DataLineProcess.end(); ++dpiter){
DLSLiter = ContactFileProcessed.find(dpiter->second);
DLSLiter->second = TRUE;
}
for (std::map::iterator dpoiter = DataLineProcessOriginal.begin();
dpoiter != DataLineProcessOriginal.end(); ++dpoiter){
DLSLiter = ContactFileProcessed.find(dpoiter->second);
DLSLiter->second = TRUE;
}
DataLineProcess.clear();
DataLineProcessOriginal.clear();
DataLineSeek = 0;
DataLineSeekOrig = 0;
TempSplitPoints.clear();
TempSplitLength.clear();
TempPropertyData.clear();
FoundData = TRUE;
break;
}
}
} else {
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1.Clear();
wxSPropertySeg2.Clear();
wxSPropertySeg1Sub.Clear();
wxSPropertySeg2Sub.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
ContactLineSub.clear();
DataLineProcess.clear();
DataLineProcessOriginal.clear();
TempSplitPoints.clear();
TempSplitLength.clear();
wxSPropertyVCARD4.clear();
DataLineSeek = 0;
DataLineSeekOrig = 0;
XVCard4Value = FALSE;
VCard3Value = FALSE;
}
if (FoundData == FALSE){
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1.Clear();
wxSPropertySeg2.Clear();
wxSPropertySeg1Sub.Clear();
wxSPropertySeg2Sub.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
ContactLineSub.clear();
DataLineProcess.clear();
DataLineProcessOriginal.clear();
TempSplitPoints.clear();
TempSplitLength.clear();
wxSPropertyVCARD4.clear();
DataLineSeek = 0;
DataLineSeekOrig = 0;
XVCard4Value = FALSE;
VCard3Value = FALSE;
}
ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
&wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
&wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
wxString FinalPropertyData;
FinalPropertyData.Append(wxSPropertyNameConv);
for (std::map::iterator striter = PropertyData.begin();
striter != PropertyData.end(); ++striter){
FinalPropertyData.Append(wxT(";"));
FinalPropertyData.Append(striter->first);
FinalPropertyData.Append(wxT("="));
FinalPropertyData.Append(striter->second);
}
wxString FinalPropValue;
if (wxSPropertyXVCard4Value.IsEmpty()){
FinalPropValue = wxSPropertyData;
} else {
if (wxSPropertyXVCard4Value != wxSPropertyData){
FinalPropValue = wxSPropertyXVCard4Value;
}
}
if (FinalPropertyData.IsEmpty() && FinalPropValue.IsEmpty()){
continue;
}
vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1.Clear();
wxSPropertySeg2.Clear();
wxSPropertySeg1Sub.Clear();
wxSPropertySeg2Sub.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
ContactLineSub.clear();
DataLineProcess.clear();
DataLineProcessOriginal.clear();
wxSPropertyVCARD4.clear();
DataLineSeek = 0;
DataLineSeekOrig = 0;
XVCard4Value = FALSE;
VCard3Value = FALSE;
}
// Process the non-itemn values.
for (std::map::iterator iter = ContactFileLines.begin();
iter != ContactFileLines.end(); ++iter){
ExtraLineSeek = TRUE;
iterbool = ContactFileProcessed.find(iter->first);
ContactLine = iter->second;
// Ignore certain variables as they are not needed.
if (ContactLine == wxT("BEGIN:VCARD") ||
ContactLine == wxT("END:VCARD") ||
ContactLine.Mid(0, 8) == wxT("VERSION:") ||
ContactLine.Mid(0, 7) == wxT("PRODID:") ||
ContactLine.Mid(0, 5) == wxT("X-AIM") ||
ContactLine.Mid(0, 5) == wxT("X-MSN") ||
ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
ContactLine.Mid(0, 4) == wxT("REV:")){
iterbool->second = TRUE;
continue;
}
if (iterbool->second == TRUE){
continue;
}
if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
continue;
}
if (ContactLine.Mid(0, 4) == wxT("item")){
// Line is a itemn... so ignore.
continue;
}
std::map::iterator itersub = iter;
while (ExtraLineSeek == TRUE){
// Check if there is extra data on the next line
// (indicated by space or tab at the start) and add data.
if (itersub == ContactFileLines.end()){
ExtraLineSeekSub = FALSE;
continue;
}
else {
itersub++;
}
iterboolsub = ContactFileProcessedWorking.find(itersub->first);
if (iterboolsub == ContactFileProcessedWorking.end()){
break;
}
if (iterboolsub->second == TRUE){
continue;
}
if (itersub == ContactFileLines.end()){
break;
}
wxSPropertyNextLine = itersub->second;
if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
wxSPropertyNextLine.Remove(0, 1);
ContactLine.Append(wxSPropertyNextLine);
iterboolsub->second = TRUE;
} else {
ExtraLineSeek = FALSE;
}
}
ContactLineLen = ContactLine.Len();
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){
wxSProperty.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;
}
}
wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
wxSProperty = wxSPropertySegSplit.GetNextToken();
std::map DataLineProcess;
std::map::iterator DLSLiter;
// Look for the X-VCARD4-(variablename) equivilant.
wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
// Sort out remainder of the types.
ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
&wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
&wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
wxString FinalPropertyData;
FinalPropertyData.Append(wxSPropertyNameConv);
for (std::map::iterator striter = PropertyData.begin();
striter != PropertyData.end(); ++striter){
FinalPropertyData.Append(wxT(";"));
FinalPropertyData.Append(striter->first);
FinalPropertyData.Append(wxT("="));
FinalPropertyData.Append(striter->second);
}
wxString FinalPropValue;
if (wxSPropertyXVCard4Value.IsEmpty()){
FinalPropValue = wxSPropertyData;
} else {
if (wxSPropertyXVCard4Value != wxSPropertyData){
FinalPropValue = wxSPropertyXVCard4Value;
}
}
vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1.Clear();
wxSPropertySeg2.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
XVCard4Value = FALSE;
VCard3Value = FALSE;
}
size_t ItemStringSeekLen = 0;
std::map NumberedName;
std::map NumberedData;
std::map NumberedPropValues;
std::map NumberedPropOldValue;
std::map UnNumberedName;
std::map UnNumberedData;
std::map UnNumberedPropValues;
std::map UnNumberedPropOldValue;
// Part 1: Get the itemn number.
std::map::iterator iterboolsecsub;
std::map::iterator itersub;
std::map TempData;
PropertyData.clear();
PropertyLock.clear();
wxString ItemString;
wxString ItemStringSeek;
wxString ItemPropName;
ContactLineSeek = 0;
ContactLineSub.clear();
ExtraLineSeekSub = 0;
wxString wxSPropertyNextLineSub;
ContactLineSubLen = 0;
int ItemIndex = 0;
PropertFindSub.clear();
wxSPropertySub.clear();
wxSPropertySeg1Sub.clear();
wxSPropertySeg2Sub.clear();
wxSPropertyValues.clear();
wxSPropertyData.clear();
wxSPropertyNameConv.clear();
wxSPropertyXVCard4Value.clear();
ItemProcString.clear();
XVCard4Value = FALSE;
VCard3Value = FALSE;
std::map ItemMapIndex;
// Look for item in the initial line, process into a proper line then
// look for other lines with the same item association.
for (std::map::iterator iter = ContactFileLines.begin();
iter != ContactFileLines.end(); ++iter){
ExtraLineSeek = TRUE;
iterbool = ContactFileProcessed.find(iter->first);
if (iterbool->second == TRUE){
continue;
}
ContactLine = iter->second;
if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
continue;
}
if (ContactLine.Mid(0, 4) != wxT("item")){
continue;
}
// Get Item data.
std::map::iterator itersub = iter;
while (ExtraLineSeek == TRUE){
// Check if there is extra data on the next line
// (indicated by space or tab at the start) and add data.
itersub++;
iterboolsub = ContactFileProcessed.find(itersub->first);
if (iterboolsub == ContactFileProcessed.end()){
break;
}
if (iterboolsub->second == TRUE){
continue;
}
if (itersub == ContactFileLines.end()){
break;
}
wxSPropertyNextLine = itersub->second;
if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
wxSPropertyNextLine.Remove(0, 1);
ContactLine.Append(wxSPropertyNextLine);
iterboolsub->second = TRUE;
} else {
ExtraLineSeek = FALSE;
}
}
ContactLineLen = ContactLine.Len();
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){
wxSProperty.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;
}
}
wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
// Go through the lines and collect the lines like itemn.
std::map *ItemListData;
ItemListData = new std::map;
wxStringTokenizer ItemData(wxSPropertySeg1, wxT("."));
ItemString = ItemData.GetNextToken();
ItemStringSeek = wxT("item") + ItemString.Mid(4);
wxStringTokenizer ItemPropSplit(ItemData.GetNextToken(), wxT(";"));
ItemPropName = ItemPropSplit.GetNextToken();
ItemStringSeekLen = ItemStringSeek.Len();
ItemIndex = 0;
for (std::map::iterator itersec = ContactFileLines.begin();
itersec != ContactFileLines.end(); ++itersec){
ExtraLineSeek = TRUE;
iterboolsub = ContactFileProcessed.find(itersec->first);
if (iterboolsub->second == TRUE){
continue;
}
ContactLineSub = itersec->second;
wxStringTokenizer ItemProcData(ContactLineSub, wxT("."));
ItemProcString = ItemData.GetNextToken();
if (ItemStringSeek != ContactLineSub.Mid(0, ItemStringSeekLen)){
continue;
}
ItemIndex++;
ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
iterboolsub->second = TRUE;
}
ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
ItemMapIndex.insert(std::make_pair(ItemStringSeek, ItemListData));
}
// Process each itemn set.
for (std::map::iterator iter = ItemMapIndex.begin();
iter != ItemMapIndex.end(); ++iter){
std::map *ItemDataPtr;
ItemDataPtr = (std::map*)iter->second;
for (std::map::iterator itersub = ItemDataPtr->begin();
itersub != ItemDataPtr->end(); ++itersub){
ContactLine = itersub->second;
ContactLineLen = ContactLine.Len();
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){
wxSProperty.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;
}
}
wxSPropertySeg1Sub = ContactLine.Mid(0, QuoteBreakPoint);
wxSPropertySeg2Sub = ContactLine.Mid((QuoteBreakPoint + 1));
wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1Sub, wxT(";"));
wxSProperty = wxSPropertySegSplit.GetNextToken();
// Sort out remainder of the types.
// Skip certain X-* IM variables as they are processed via
// IMPP.
if (wxSProperty == wxT("X-AIM") || wxSProperty == wxT("X-MSN") ||
wxSProperty == wxT("X-ICQ") || wxSProperty == wxT("X-GADUGADU") ||
wxSProperty == wxT("X-YAHOO") || wxSProperty == wxT("X-SKYPE") ||
wxSProperty == wxT("X-JABBER")){
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1.Clear();
wxSPropertySeg2.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
XVCard4Value = FALSE;
VCard3Value = FALSE;
continue;
}
ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1Sub, &wxSPropertySeg2Sub,
&wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
&wxSPropertyNameConv, &PropertyData, &PropertyLock, TRUE, &VCard3Value, &XVCard4Value);
}
if (wxSPropertyNameConv.IsEmpty()){
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1.Clear();
wxSPropertySeg2.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
XVCard4Value = FALSE;
VCard3Value = FALSE;
continue;
}
wxString FinalPropertyData;
FinalPropertyData.Append(wxSPropertyNameConv);
for (std::map::iterator striter = PropertyData.begin();
striter != PropertyData.end(); ++striter){
FinalPropertyData.Append(wxT(";"));
FinalPropertyData.Append(striter->first);
FinalPropertyData.Append(wxT("="));
FinalPropertyData.Append(striter->second);
}
wxString FinalPropValue;
if (wxSPropertyXVCard4Value.IsEmpty()){
FinalPropValue = wxSPropertyData;
} else {
if (wxSPropertyXVCard4Value != wxSPropertyData){
FinalPropValue = wxSPropertyData;
} else {
FinalPropValue = wxSPropertyXVCard4Value;
}
}
vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
wxSProperty.clear();
wxSPropertySub.Clear();
wxSPropertySeg1Sub.Clear();
wxSPropertySeg2Sub.Clear();
wxSPropertyValues.Clear();
wxSPropertyData.Clear();
wxSPropertyXVCard4Value.Clear();
wxSPropertyNameConv.Clear();
FinalPropertyData.clear();
FinalPropValue.clear();
PropertyData.clear();
PropertyLock.clear();
ContactLine.clear();
XVCard4Value = FALSE;
VCard3Value = FALSE;
TempData.clear();
}
// Delete data.
std::map *ItemEraseData;
for (std::map::iterator iter = ItemMapIndex.begin();
iter != ItemMapIndex.end(); ++iter){
ItemEraseData = (std::map*)iter->second;
delete ItemEraseData;
ItemEraseData = NULL;
}
ItemMapIndex.clear();
vCardOut->AddRaw(wxT("END"), wxT("VCARD"));
return TRUE;
}