diff options
Diffstat (limited to 'comm/mailnews/mime/src/MimeHeaderParser.cpp')
-rw-r--r-- | comm/mailnews/mime/src/MimeHeaderParser.cpp | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/comm/mailnews/mime/src/MimeHeaderParser.cpp b/comm/mailnews/mime/src/MimeHeaderParser.cpp new file mode 100644 index 0000000000..cc489e2ec5 --- /dev/null +++ b/comm/mailnews/mime/src/MimeHeaderParser.cpp @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "mozilla/mailnews/MimeHeaderParser.h" +#include "mozilla/DebugOnly.h" +#include "nsMemory.h" +#include "nsCOMPtr.h" +#include "nsIMsgHeaderParser.h" +#include "mozilla/Components.h" + +namespace mozilla { +namespace mailnews { + +void detail::DoConversion(const nsTArray<nsString>& aUTF16Array, + nsTArray<nsCString>& aUTF8Array) { + uint32_t count = aUTF16Array.Length(); + aUTF8Array.SetLength(count); + for (uint32_t i = 0; i < count; ++i) + CopyUTF16toUTF8(aUTF16Array[i], aUTF8Array[i]); +} + +void MakeMimeAddress(const nsACString& aName, const nsACString& aEmail, + nsACString& full) { + nsAutoString utf16Address; + MakeMimeAddress(NS_ConvertUTF8toUTF16(aName), NS_ConvertUTF8toUTF16(aEmail), + utf16Address); + + CopyUTF16toUTF8(utf16Address, full); +} + +void MakeMimeAddress(const nsAString& aName, const nsAString& aEmail, + nsAString& full) { + nsCOMPtr<nsIMsgHeaderParser> headerParser( + components::HeaderParser::Service()); + + nsCOMPtr<msgIAddressObject> address; + headerParser->MakeMailboxObject(aName, aEmail, getter_AddRefs(address)); + nsTArray<RefPtr<msgIAddressObject>> addresses; + addresses.AppendElement(address); + headerParser->MakeMimeHeader(addresses, full); +} + +void MakeDisplayAddress(const nsAString& aName, const nsAString& aEmail, + nsAString& full) { + nsCOMPtr<nsIMsgHeaderParser> headerParser( + components::HeaderParser::Service()); + + nsCOMPtr<msgIAddressObject> object; + headerParser->MakeMailboxObject(aName, aEmail, getter_AddRefs(object)); + object->ToString(full); +} + +void RemoveDuplicateAddresses(const nsACString& aHeader, + const nsACString& aOtherEmails, + nsACString& result) { + nsCOMPtr<nsIMsgHeaderParser> headerParser( + components::HeaderParser::Service()); + + headerParser->RemoveDuplicateAddresses(aHeader, aOtherEmails, result); +} + +///////////////////////////////////////////// +// These are the core shim methods we need // +///////////////////////////////////////////// + +nsCOMArray<msgIAddressObject> DecodedHeader(const nsAString& aHeader) { + nsCOMArray<msgIAddressObject> retval; + if (aHeader.IsEmpty()) { + return retval; + } + nsCOMPtr<nsIMsgHeaderParser> headerParser( + components::HeaderParser::Service()); + NS_ENSURE_TRUE(headerParser, retval); + nsTArray<RefPtr<msgIAddressObject>> addresses; + nsresult rv = headerParser->ParseDecodedHeader(aHeader, false, addresses); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Javascript jsmime returned an error!"); + if (NS_SUCCEEDED(rv) && addresses.Length() > 0) { + retval.SetCapacity(addresses.Length()); + for (auto& addr : addresses) { + retval.AppendElement(addr); + } + } + return retval; +} + +nsCOMArray<msgIAddressObject> EncodedHeader(const nsACString& aHeader, + const char* aCharset) { + nsCOMArray<msgIAddressObject> retval; + if (aHeader.IsEmpty()) { + return retval; + } + nsCOMPtr<nsIMsgHeaderParser> headerParser( + components::HeaderParser::Service()); + NS_ENSURE_TRUE(headerParser, retval); + nsTArray<RefPtr<msgIAddressObject>> addresses; + nsresult rv = + headerParser->ParseEncodedHeader(aHeader, aCharset, false, addresses); + MOZ_ASSERT(NS_SUCCEEDED(rv), "This should never fail!"); + if (NS_SUCCEEDED(rv) && addresses.Length() > 0) { + retval.SetCapacity(addresses.Length()); + for (auto& addr : addresses) { + retval.AppendElement(addr); + } + } + return retval; +} + +nsCOMArray<msgIAddressObject> EncodedHeaderW(const nsAString& aHeader) { + nsCOMArray<msgIAddressObject> retval; + if (aHeader.IsEmpty()) { + return retval; + } + nsCOMPtr<nsIMsgHeaderParser> headerParser( + components::HeaderParser::Service()); + NS_ENSURE_TRUE(headerParser, retval); + nsTArray<RefPtr<msgIAddressObject>> addresses; + nsresult rv = headerParser->ParseEncodedHeaderW(aHeader, addresses); + MOZ_ASSERT(NS_SUCCEEDED(rv), "This should never fail!"); + if (NS_SUCCEEDED(rv) && addresses.Length() > 0) { + retval.SetCapacity(addresses.Length()); + for (auto& addr : addresses) { + retval.AppendElement(addr); + } + } + return retval; +} + +void ExtractAllAddresses(const nsCOMArray<msgIAddressObject>& aHeader, + nsTArray<nsString>& names, + nsTArray<nsString>& emails) { + uint32_t count = aHeader.Length(); + + // Prefill arrays before we start + names.SetLength(count); + emails.SetLength(count); + + for (uint32_t i = 0; i < count; i++) { + aHeader[i]->GetName(names[i]); + aHeader[i]->GetEmail(emails[i]); + } + + if (count == 1 && names[0].IsEmpty() && emails[0].IsEmpty()) { + names.Clear(); + emails.Clear(); + } +} + +void ExtractDisplayAddresses(const nsCOMArray<msgIAddressObject>& aHeader, + nsTArray<nsString>& displayAddrs) { + uint32_t count = aHeader.Length(); + + displayAddrs.SetLength(count); + for (uint32_t i = 0; i < count; i++) aHeader[i]->ToString(displayAddrs[i]); + + if (count == 1 && displayAddrs[0].IsEmpty()) displayAddrs.Clear(); +} + +///////////////////////////////////////////////// +// All of these are based on the above methods // +///////////////////////////////////////////////// + +void ExtractEmails(const nsCOMArray<msgIAddressObject>& aHeader, + nsTArray<nsString>& emails) { + nsTArray<nsString> names; + ExtractAllAddresses(aHeader, names, emails); +} + +void ExtractEmail(const nsCOMArray<msgIAddressObject>& aHeader, + nsACString& email) { + AutoTArray<nsString, 1> names; + AutoTArray<nsString, 1> emails; + ExtractAllAddresses(aHeader, names, emails); + + if (emails.Length() > 0) + CopyUTF16toUTF8(emails[0], email); + else + email.Truncate(); +} + +void ExtractFirstAddress(const nsCOMArray<msgIAddressObject>& aHeader, + nsACString& name, nsACString& email) { + AutoTArray<nsString, 1> names, emails; + ExtractAllAddresses(aHeader, names, emails); + if (names.Length() > 0) { + CopyUTF16toUTF8(names[0], name); + CopyUTF16toUTF8(emails[0], email); + } else { + name.Truncate(); + email.Truncate(); + } +} + +void ExtractFirstAddress(const nsCOMArray<msgIAddressObject>& aHeader, + nsAString& name, nsACString& email) { + AutoTArray<nsString, 1> names, emails; + ExtractAllAddresses(aHeader, names, emails); + if (names.Length() > 0) { + name = names[0]; + CopyUTF16toUTF8(emails[0], email); + } else { + name.Truncate(); + email.Truncate(); + } +} + +void ExtractName(const nsCOMArray<msgIAddressObject>& aHeader, + nsACString& name) { + nsCString email; + ExtractFirstAddress(aHeader, name, email); + if (name.IsEmpty()) name = email; +} + +void ExtractName(const nsCOMArray<msgIAddressObject>& aHeader, + nsAString& name) { + AutoTArray<nsString, 1> names; + AutoTArray<nsString, 1> emails; + ExtractAllAddresses(aHeader, names, emails); + if (names.Length() > 0) { + if (names[0].IsEmpty()) + name = emails[0]; + else + name = names[0]; + } else { + name.Truncate(); + } +} + +} // namespace mailnews +} // namespace mozilla |