/* parses LocalMessageURI * mailbox-message://folder1/folder2#123?header=none or * mailbox-message://folder1/folder2#1234&part=1.2 * * puts folder URI in folderURI (mailbox://folder1/folder2) * message key number in key */ nsresult nsParseLocalMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key) { if(!key) return NS_ERROR_NULL_POINTER; nsCAutoString uriStr(uri); PRInt32 keySeparator = uriStr.FindChar('#'); if(keySeparator != -1) { PRInt32 keyEndSeparator = MsgFindCharInSet(uriStr, "?&", keySeparator); folderURI = StringHead(uriStr, keySeparator); folderURI.Cut(7, 8); // cut out the -message part of mailbox-message: nsCAutoString keyStr; if (keyEndSeparator != -1) keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1)); else keyStr = StringTail(uriStr, uriStr.Length() - (keySeparator + 1)); *key = (PRUint32) ParseUint64Str(keyStr.get()); return NS_OK; } return NS_ERROR_FAILURE; }
/* parses ImapMessageURI */ nsresult nsParseImapMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key, char **part) { if(!key) return NS_ERROR_NULL_POINTER; nsCAutoString uriStr(uri); PRInt32 folderEnd = -1; // imap-message uri's can have imap:// url strings tacked on the end, // e.g., when opening/saving attachments. We don't want to look for '#' // in that part of the uri, if the attachment name contains '#', // so check for that here. if (StringBeginsWith(uriStr, NS_LITERAL_CSTRING("imap-message"))) folderEnd = uriStr.Find("imap://"); PRInt32 keySeparator = MsgRFindChar(uriStr, '#', folderEnd); if(keySeparator != -1) { PRInt32 keyEndSeparator = MsgFindCharInSet(uriStr, "/?&", keySeparator); nsAutoString folderPath; folderURI = StringHead(uriStr, keySeparator); folderURI.Cut(4, 8); // cut out the _message part of imap-message: // folder uri's don't have fully escaped usernames. PRInt32 atPos = folderURI.FindChar('@'); if (atPos != -1) { nsCString unescapedName, escapedName; PRInt32 userNamePos = folderURI.Find("//") + 2; PRUint32 origUserNameLen = atPos - userNamePos; if (NS_SUCCEEDED(MsgUnescapeString(Substring(folderURI, userNamePos, origUserNameLen), 0, unescapedName))) { // Re-escape the username, matching the way we do it in uris, not the // way necko escapes urls. See nsMsgIncomingServer::GetServerURI. MsgEscapeString(unescapedName, nsINetUtil::ESCAPE_XALPHAS, escapedName); folderURI.Replace(userNamePos, origUserNameLen, escapedName); } } nsCAutoString keyStr; if (keyEndSeparator != -1) keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1)); else keyStr = Substring(uriStr, keySeparator + 1); *key = strtoul(keyStr.get(), nsnull, 10); if (part && keyEndSeparator != -1) { PRInt32 partPos = MsgFind(uriStr, "part=", PR_FALSE, keyEndSeparator); if (partPos != -1) { *part = ToNewCString(Substring(uriStr, keyEndSeparator)); } } } return NS_OK; }
/* parses NewsMessageURI */ nsresult nsParseNewsMessageURI(const char* uri, nsCString& group, nsMsgKey *key) { NS_ENSURE_ARG_POINTER(uri); NS_ENSURE_ARG_POINTER(key); nsAutoCString uriStr(uri); int32_t keySeparator = uriStr.FindChar('#'); if(keySeparator != -1) { int32_t keyEndSeparator = MsgFindCharInSet(uriStr, "?&", keySeparator); // Grab between the last '/' and the '#' for the key group = StringHead(uriStr, keySeparator); int32_t groupSeparator = group.RFind("/"); if (groupSeparator == -1) return NS_ERROR_FAILURE; // Our string APIs don't let us unescape into the same buffer from earlier, // so escape into a temporary nsAutoCString unescapedGroup; MsgUnescapeString(Substring(group, groupSeparator + 1), 0, unescapedGroup); group = unescapedGroup; nsAutoCString keyStr; if (keyEndSeparator != -1) keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1)); else keyStr = Substring(uriStr, keySeparator + 1); nsresult errorCode; *key = keyStr.ToInteger(&errorCode); return errorCode; } return NS_ERROR_FAILURE; }
void nsEudoraAddress::AddSingleCard(CAliasEntry *pEntry, nsVoidArray &emailList, nsIAddrDatabase *pDb) { // We always have a nickname and everything else is optional. // Map both home and work related fields to our address card. Eudora // fields that can't be mapped will be left in the 'note' field! nsIMdbRow* newRow = nullptr; pDb->GetNewRow(&newRow); if (!newRow) return; nsCString displayName, name, firstName, lastName; nsCString fax, secondaryFax, phone, mobile, secondaryMobile, webLink; nsCString address, address2, city, state, zip, country; nsCString phoneWK, webLinkWK, title, company; nsCString addressWK, address2WK, cityWK, stateWK, zipWK, countryWK; nsCString primaryLocation, otherPhone, otherWeb; nsCString additionalEmail, stillMoreEmail; nsCString note(pEntry->m_notes); nsString noteUTF16; bool isSecondaryMobileWorkNumber = true; bool isSecondaryFaxWorkNumber = true; if (!note.IsEmpty()) { ExtractNoteField(note, fax, "fax"); ExtractNoteField(note, secondaryFax, "fax2"); ExtractNoteField(note, phone, "phone"); ExtractNoteField(note, mobile, "mobile"); ExtractNoteField(note, secondaryMobile, "mobile2"); ExtractNoteField(note, address, "address"); ExtractNoteField(note, city, "city"); ExtractNoteField(note, state, "state"); ExtractNoteField(note, zip, "zip"); ExtractNoteField(note, country, "country"); ExtractNoteField(note, name, "name"); ExtractNoteField(note, firstName, "first"); ExtractNoteField(note, lastName, "last"); ExtractNoteField(note, webLink, "web"); ExtractNoteField(note, addressWK, "address2"); ExtractNoteField(note, cityWK, "city2"); ExtractNoteField(note, stateWK, "state2"); ExtractNoteField(note, zipWK, "zip2"); ExtractNoteField(note, countryWK, "country2"); ExtractNoteField(note, phoneWK, "phone2"); ExtractNoteField(note, title, "title"); ExtractNoteField(note, company, "company"); ExtractNoteField(note, webLinkWK, "web2"); ExtractNoteField(note, primaryLocation, "primary"); ExtractNoteField(note, additionalEmail, "otheremail"); ExtractNoteField(note, otherPhone, "otherphone"); ExtractNoteField(note, otherWeb, "otherweb"); // Is there any "extra" data that we may want to format nicely and place // in the notes field? if (!additionalEmail.IsEmpty() || !otherPhone.IsEmpty() || !otherWeb.IsEmpty()) { nsCString otherNotes(note); if (!additionalEmail.IsEmpty()) { // Reconstitute line breaks for additional email MsgReplaceSubstring(additionalEmail, "\x03", "\n"); // Try to figure out if there are multiple email addresses in additionalEmail int32_t idx = MsgFindCharInSet(additionalEmail, "\t\r\n,; "); if (idx != -1) { // We found a character that indicates that there's more than one email address here. // Separate out the addresses after the first one. stillMoreEmail = Substring(additionalEmail, idx + 1); stillMoreEmail.Trim(kWhitespace); // Separate out the first address. additionalEmail.SetLength(idx); } // If there were more than one additional email addresses store all the extra // ones in the notes field, labeled nicely. if (!stillMoreEmail.IsEmpty()) FormatExtraDataInNoteField(EUDORAIMPORT_ADDRESS_LABEL_OTHEREMAIL, stillMoreEmail, noteUTF16); } if (!otherPhone.IsEmpty()) { // Reconstitute line breaks for other phone numbers MsgReplaceSubstring(otherPhone, "\x03", "\n"); // Store other phone numbers in the notes field, labeled nicely FormatExtraDataInNoteField(EUDORAIMPORT_ADDRESS_LABEL_OTHERPHONE, otherPhone, noteUTF16); } if (!otherWeb.IsEmpty()) { // Reconstitute line breaks for other web sites MsgReplaceSubstring(otherWeb, "\x03", "\n"); // Store other web sites in the notes field, labeled nicely FormatExtraDataInNoteField(EUDORAIMPORT_ADDRESS_LABEL_OTHERWEB, otherWeb, noteUTF16); } noteUTF16.Append(NS_ConvertASCIItoUTF16(note)); } } CAliasData *pData = emailList.Count() ? (CAliasData *)emailList.ElementAt(0) : nullptr; if (pData && !pData->m_realName.IsEmpty()) displayName = pData->m_realName; else if (!name.IsEmpty()) displayName = name; else displayName = pEntry->m_name; MsgReplaceSubstring(address, "\x03", "\n"); SplitString(address, address2); MsgReplaceSubstring(note, "\x03", "\n"); MsgReplaceSubstring(fax, "\x03", " "); MsgReplaceSubstring(secondaryFax, "\x03", " "); MsgReplaceSubstring(phone, "\x03", " "); MsgReplaceSubstring(name, "\x03", " "); MsgReplaceSubstring(city, "\x03", " "); MsgReplaceSubstring(state, "\x03", " "); MsgReplaceSubstring(zip, "\x03", " "); MsgReplaceSubstring(country, "\x03", " "); MsgReplaceSubstring(addressWK, "\x03", "\n"); SplitString(addressWK, address2WK); MsgReplaceSubstring(phoneWK, "\x03", " "); MsgReplaceSubstring(cityWK, "\x03", " "); MsgReplaceSubstring(stateWK, "\x03", " "); MsgReplaceSubstring(zipWK, "\x03", " "); MsgReplaceSubstring(countryWK, "\x03", " "); MsgReplaceSubstring(title, "\x03", " "); MsgReplaceSubstring(company, "\x03", " "); if (newRow) { nsAutoString uniStr; // Home related fields. ADD_FIELD_TO_DB_ROW(pDb, AddDisplayName, newRow, displayName, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddNickName, newRow, pEntry->m_name, uniStr); if (pData) ADD_FIELD_TO_DB_ROW(pDb, AddPrimaryEmail, newRow, pData->m_email, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddFirstName, newRow, firstName, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddLastName, newRow, lastName, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWebPage2, newRow, webLink, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomePhone, newRow, phone, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomeAddress, newRow, address, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomeAddress2, newRow, address2, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomeCity, newRow, city, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomeZipCode, newRow, zip, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomeState, newRow, state, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddHomeCountry, newRow, country, uniStr); // Work related fields. ADD_FIELD_TO_DB_ROW(pDb, AddJobTitle, newRow, title, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddCompany, newRow, company, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWebPage1, newRow, webLinkWK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkPhone, newRow, phoneWK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkAddress, newRow, addressWK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkAddress2, newRow, address2WK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkCity, newRow, cityWK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkZipCode, newRow, zipWK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkState, newRow, stateWK, uniStr); ADD_FIELD_TO_DB_ROW(pDb, AddWorkCountry, newRow, countryWK, uniStr); if ((primaryLocation.IsEmpty() || primaryLocation.LowerCaseEqualsLiteral("home")) && !mobile.IsEmpty()) { // Primary location field is either specified to be "home" or is not // specified and there is a home mobile number, so use that as the mobile number. ADD_FIELD_TO_DB_ROW(pDb, AddCellularNumber, newRow, mobile, uniStr); isSecondaryMobileWorkNumber = true; } else { // Primary location field is either specified to be "work" or there is no // home mobile number, so use work mobile number. ADD_FIELD_TO_DB_ROW(pDb, AddCellularNumber, newRow, secondaryMobile, uniStr); // Home mobile number (if any) is the secondary mobile number secondaryMobile = mobile; isSecondaryMobileWorkNumber = false; } if ((primaryLocation.IsEmpty() || primaryLocation.LowerCaseEqualsLiteral("home")) && !fax.IsEmpty()) { // Primary location field is either specified to be "home" or is not // specified and there is a home fax number, so use that as the fax number. ADD_FIELD_TO_DB_ROW(pDb, AddFaxNumber, newRow, fax, uniStr); isSecondaryFaxWorkNumber = true; } else { // Primary location field is either specified to be "work" or there is no // home fax number, so use work fax number. ADD_FIELD_TO_DB_ROW(pDb, AddFaxNumber, newRow, secondaryFax, uniStr); // Home fax number (if any) is the secondary fax number secondaryFax = fax; isSecondaryFaxWorkNumber = false; } ADD_FIELD_TO_DB_ROW(pDb, Add2ndEmail, newRow, additionalEmail, uniStr); // Extra info fields int32_t stringID; nsString pFormat; nsString pCustomData; // Add second mobile number, if any, to the Custom 1 field if (!secondaryMobile.IsEmpty()) { stringID = isSecondaryMobileWorkNumber ? EUDORAIMPORT_ADDRESS_LABEL_WORKMOBILE : EUDORAIMPORT_ADDRESS_LABEL_HOMEMOBILE; pFormat.Adopt(nsEudoraStringBundle::GetStringByID(stringID)); pCustomData.Adopt(nsTextFormatter::smprintf(pFormat.get(), NS_ConvertASCIItoUTF16(secondaryMobile).get())); pDb->AddCustom1(newRow, NS_ConvertUTF16toUTF8(pCustomData).get()); } // Add second fax number, if any, to the Custom 2 field if (!secondaryFax.IsEmpty()) { stringID = isSecondaryFaxWorkNumber ? EUDORAIMPORT_ADDRESS_LABEL_WORKFAX : EUDORAIMPORT_ADDRESS_LABEL_HOMEFAX; pFormat.Adopt(nsEudoraStringBundle::GetStringByID(stringID)); pCustomData.Adopt(nsTextFormatter::smprintf(pFormat.get(), NS_ConvertASCIItoUTF16(secondaryFax).get())); pDb->AddCustom2(newRow, NS_ConvertUTF16toUTF8(pCustomData).get()); } // Lastly, note field. pDb->AddNotes(newRow, NS_ConvertUTF16toUTF8(noteUTF16).get()); pDb->AddCardRowToDB(newRow); IMPORT_LOG1("Added card to db: %s\n", displayName.get()); } }