diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/import/src/nsVCardAddress.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mailnews/import/src/nsVCardAddress.cpp')
-rw-r--r-- | comm/mailnews/import/src/nsVCardAddress.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/comm/mailnews/import/src/nsVCardAddress.cpp b/comm/mailnews/import/src/nsVCardAddress.cpp new file mode 100644 index 0000000000..2ced1d7c0b --- /dev/null +++ b/comm/mailnews/import/src/nsVCardAddress.cpp @@ -0,0 +1,151 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsNativeCharsetUtils.h" +#include "nsNetUtil.h" +#include "nsVCardAddress.h" + +#include "nsIAbCard.h" +#include "nsIAbDirectory.h" +#include "nsIFile.h" +#include "nsIInputStream.h" +#include "nsIUnicharLineInputStream.h" +#include "nsIConverterInputStream.h" +#include "nsIMsgVCardService.h" + +#include "plstr.h" +#include "msgCore.h" +#include "nsMsgUtils.h" + +nsVCardAddress::nsVCardAddress() {} + +nsVCardAddress::~nsVCardAddress() {} + +nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName, + nsIFile* pSrc, + nsIAbDirectory* pDirectory, + nsString& errors, + uint32_t* pProgress) { + // Open the source file for reading, read each line and process it! + nsCOMPtr<nsIInputStream> inputStream; + nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), pSrc); + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Error opening address file for reading\n"); + return rv; + } + + // Open the source file for reading, read each line and process it! + // Here we use this to work out the size of the file, so we can update + // an integer as we go through the file which will update a progress + // bar if required by the caller. + uint64_t bytesLeft = 0; + rv = inputStream->Available(&bytesLeft); + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Error checking address file for size\n"); + inputStream->Close(); + return rv; + } + uint64_t totalBytes = bytesLeft; + + // Try to detect the character set and decode. Only UTF-8 is valid from + // vCard 4.0, but we support older versions, so other charsets are possible. + + nsAutoCString sourceCharset; + rv = MsgDetectCharsetFromFile(pSrc, sourceCharset); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIConverterInputStream> converterStream = + do_CreateInstance("@mozilla.org/intl/converter-input-stream;1"); + NS_ENSURE_TRUE(converterStream, NS_ERROR_FAILURE); + + rv = converterStream->Init( + inputStream, sourceCharset.get(), 8192, + nsIConverterInputStream::DEFAULT_REPLACEMENT_CHARACTER); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIUnicharLineInputStream> lineStream( + do_QueryInterface(converterStream, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIMsgVCardService> vCardService = + do_GetService("@mozilla.org/addressbook/msgvcardservice;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + bool more = true; + nsAutoString record; + while (!(*pAbort) && more && NS_SUCCEEDED(rv)) { + rv = ReadRecord(lineStream, record, &more); + if (NS_SUCCEEDED(rv) && !record.IsEmpty()) { + // Parse the vCard and build an nsIAbCard from it + nsCOMPtr<nsIAbCard> cardFromVCard; + rv = vCardService->VCardToAbCard(record, getter_AddRefs(cardFromVCard)); + NS_ENSURE_SUCCESS(rv, rv); + + nsIAbCard* outCard; + rv = pDirectory->AddCard(cardFromVCard, &outCard); + NS_ENSURE_SUCCESS(rv, rv); + + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Error processing vCard record.\n"); + } + } + if (NS_SUCCEEDED(rv) && pProgress) { + // This won't be totally accurate, but its the best we can do + // considering that converterStream won't give us how many bytes + // are actually left. + bytesLeft -= record.Length(); + *pProgress = totalBytes - bytesLeft; + } + } + inputStream->Close(); + + if (NS_FAILED(rv)) { + IMPORT_LOG0( + "*** Error reading the address book - probably incorrect ending\n"); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult nsVCardAddress::ReadRecord(nsIUnicharLineInputStream* aLineStream, + nsString& aRecord, bool* aMore) { + bool more = true; + nsresult rv; + nsAutoString line; + + aRecord.Truncate(); + + // remove the empty lines. + do { + rv = aLineStream->ReadLine(line, aMore); + } while (line.IsEmpty() && *aMore); + if (!*aMore) return rv; + + // read BEGIN:VCARD + if (!line.LowerCaseEqualsLiteral("begin:vcard")) { + IMPORT_LOG0( + "*** Expected case-insensitive BEGIN:VCARD at start of vCard\n"); + rv = NS_ERROR_FAILURE; + *aMore = more; + return rv; + } + aRecord.Append(line); + + // read until END:VCARD + do { + if (!more) { + IMPORT_LOG0( + "*** Expected case-insensitive END:VCARD at start of vCard\n"); + rv = NS_ERROR_FAILURE; + break; + } + rv = aLineStream->ReadLine(line, &more); + aRecord.AppendLiteral(MSG_LINEBREAK); + aRecord.Append(line); + } while (!line.LowerCaseEqualsLiteral("end:vcard")); + + *aMore = more; + return rv; +} |