mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 09:57:32 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
58
mailnews/import/src/ImportCharSet.cpp
Normal file
58
mailnews/import/src/ImportCharSet.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "ImportCharSet.h"
|
||||
|
||||
char ImportCharSet::m_upperCaseMap[256];
|
||||
char ImportCharSet::m_Ascii[256] = {0}; // the initialiser makes it strong
|
||||
|
||||
class UInitMaps {
|
||||
public:
|
||||
UInitMaps();
|
||||
};
|
||||
|
||||
UInitMaps gInitMaps;
|
||||
|
||||
UInitMaps::UInitMaps()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
ImportCharSet::m_upperCaseMap[i] = i;
|
||||
for (i = 'a'; i <= 'z'; i++)
|
||||
ImportCharSet::m_upperCaseMap[i] = i - 'a' + 'A';
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
ImportCharSet::m_Ascii[i] = 0;
|
||||
|
||||
for (i = ImportCharSet::cUpperAChar; i <= ImportCharSet::cUpperZChar; i++)
|
||||
ImportCharSet::m_Ascii[i] |= (ImportCharSet::cAlphaNumChar | ImportCharSet::cAlphaChar);
|
||||
for (i = ImportCharSet::cLowerAChar; i <= ImportCharSet::cLowerZChar; i++)
|
||||
ImportCharSet::m_Ascii[i] |= (ImportCharSet::cAlphaNumChar | ImportCharSet::cAlphaChar);
|
||||
for (i = ImportCharSet::cZeroChar; i <= ImportCharSet::cNineChar; i++)
|
||||
ImportCharSet::m_Ascii[i] |= (ImportCharSet::cAlphaNumChar | ImportCharSet::cDigitChar);
|
||||
|
||||
ImportCharSet::m_Ascii[ImportCharSet::cTabChar] |= ImportCharSet::cWhiteSpaceChar;
|
||||
ImportCharSet::m_Ascii[ImportCharSet::cCRChar] |= ImportCharSet::cWhiteSpaceChar;
|
||||
ImportCharSet::m_Ascii[ImportCharSet::cLinefeedChar] |= ImportCharSet::cWhiteSpaceChar;
|
||||
ImportCharSet::m_Ascii[ImportCharSet::cSpaceChar] |= ImportCharSet::cWhiteSpaceChar;
|
||||
|
||||
ImportCharSet::m_Ascii[uint8_t('(')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t(')')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('<')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('>')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('@')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t(',')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t(';')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t(':')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('\\')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('"')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('.')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t('[')] |= ImportCharSet::c822SpecialChar;
|
||||
ImportCharSet::m_Ascii[uint8_t(']')] |= ImportCharSet::c822SpecialChar;
|
||||
|
||||
|
||||
}
|
||||
175
mailnews/import/src/ImportCharSet.h
Normal file
175
mailnews/import/src/ImportCharSet.h
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef ImportCharSet_h___
|
||||
#define ImportCharSet_h___
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
|
||||
// Some useful ASCII values
|
||||
// 'A' = 65, 0x41
|
||||
// 'Z' = 90, 0x5a
|
||||
// '_' = 95, 0x5f
|
||||
// 'a' = 97, 0x61
|
||||
// 'z' = 122, 0x7a
|
||||
// '0' = 48, 0x30
|
||||
// '1' = 49, 0x31
|
||||
// '9' = 57, 0x39
|
||||
// ' ' = 32, 0x20
|
||||
// whitespace, 10, 13, 32, 9 (linefeed, cr, space, tab) - 0x0a, 0x0d, 0x20, 0x09
|
||||
// ':' = 58, 0x3a
|
||||
|
||||
|
||||
// a typedef enum would be nicer but some compilers still have trouble with treating
|
||||
// enum's as plain numbers when needed
|
||||
|
||||
class ImportCharSet {
|
||||
public:
|
||||
enum {
|
||||
cTabChar = 9,
|
||||
cLinefeedChar = 10,
|
||||
cCRChar = 13,
|
||||
cSpaceChar = 32,
|
||||
cUpperAChar = 65,
|
||||
cUpperZChar = 90,
|
||||
cUnderscoreChar = 95,
|
||||
cLowerAChar = 97,
|
||||
cLowerZChar = 122,
|
||||
cZeroChar = 48,
|
||||
cNineChar = 57,
|
||||
|
||||
cAlphaNumChar = 1,
|
||||
cAlphaChar = 2,
|
||||
cWhiteSpaceChar = 4,
|
||||
cDigitChar = 8,
|
||||
c822SpecialChar = 16
|
||||
};
|
||||
|
||||
static char m_upperCaseMap[256];
|
||||
static char m_Ascii[256];
|
||||
|
||||
inline static bool IsUSAscii(uint8_t ch) { return (((ch & (uint8_t)0x80) == 0));}
|
||||
inline static bool Is822CtlChar(uint8_t ch) { return (ch < 32);}
|
||||
inline static bool Is822SpecialChar(uint8_t ch) { return ((m_Ascii[ch] & c822SpecialChar) == c822SpecialChar);}
|
||||
inline static bool IsWhiteSpace(uint8_t ch) { return ((m_Ascii[ch] & cWhiteSpaceChar) == cWhiteSpaceChar); }
|
||||
inline static bool IsAlphaNum(uint8_t ch) { return ((m_Ascii[ch] & cAlphaNumChar) == cAlphaNumChar); }
|
||||
inline static bool IsDigit(uint8_t ch) { return ((m_Ascii[ch] & cDigitChar) == cDigitChar); }
|
||||
|
||||
inline static uint8_t ToLower(uint8_t ch) { if ((m_Ascii[ch] & cAlphaChar) == cAlphaChar) { return cLowerAChar + (m_upperCaseMap[ch] - cUpperAChar); } else return ch; }
|
||||
|
||||
inline static long AsciiToLong(const uint8_t * pChar, uint32_t len) {
|
||||
long num = 0;
|
||||
while (len) {
|
||||
if ((m_Ascii[*pChar] & cDigitChar) == 0)
|
||||
return num;
|
||||
num *= 10;
|
||||
num += (*pChar - cZeroChar);
|
||||
len--;
|
||||
pChar++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
inline static void ByteToHex(uint8_t byte, uint8_t * pHex) {
|
||||
uint8_t val = byte;
|
||||
val /= 16;
|
||||
if (val < 10)
|
||||
*pHex = '0' + val;
|
||||
else
|
||||
*pHex = 'A' + (val - 10);
|
||||
pHex++;
|
||||
val = byte;
|
||||
val &= 0x0F;
|
||||
if (val < 10)
|
||||
*pHex = '0' + val;
|
||||
else
|
||||
*pHex = 'A' + (val - 10);
|
||||
}
|
||||
|
||||
inline static void LongToHexBytes(uint32_t type, uint8_t * pStr) {
|
||||
ByteToHex((uint8_t) (type >> 24), pStr);
|
||||
pStr += 2;
|
||||
ByteToHex((uint8_t) ((type >> 16) & 0x0FF), pStr);
|
||||
pStr += 2;
|
||||
ByteToHex((uint8_t) ((type >> 8) & 0x0FF), pStr);
|
||||
pStr += 2;
|
||||
ByteToHex((uint8_t) (type & 0x0FF), pStr);
|
||||
}
|
||||
|
||||
inline static void SkipWhiteSpace(const uint8_t * & pChar, uint32_t & pos, uint32_t max) {
|
||||
while ((pos < max) && (IsWhiteSpace(*pChar))) {
|
||||
pos++; pChar++;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void SkipSpaceTab(const uint8_t * & pChar, uint32_t& pos, uint32_t max) {
|
||||
while ((pos < max) && ((*pChar == (uint8_t)cSpaceChar) || (*pChar == (uint8_t)cTabChar))) {
|
||||
pos++; pChar++;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void SkipTilSpaceTab(const uint8_t * & pChar, uint32_t& pos, uint32_t max) {
|
||||
while ((pos < max) && (*pChar != (uint8_t)cSpaceChar) && (*pChar != (uint8_t)cTabChar)) {
|
||||
pos++;
|
||||
pChar++;
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool StrNICmp(const uint8_t * pChar, const uint8_t * pSrc, uint32_t len) {
|
||||
while (len && (m_upperCaseMap[*pChar] == m_upperCaseMap[*pSrc])) {
|
||||
pChar++; pSrc++; len--;
|
||||
}
|
||||
return len == 0;
|
||||
}
|
||||
|
||||
inline static bool StrNCmp(const uint8_t * pChar, const uint8_t *pSrc, uint32_t len) {
|
||||
while (len && (*pChar == *pSrc)) {
|
||||
pChar++; pSrc++; len--;
|
||||
}
|
||||
return len == 0;
|
||||
}
|
||||
|
||||
inline static int FindChar(const uint8_t * pChar, uint8_t ch, uint32_t max) {
|
||||
uint32_t pos = 0;
|
||||
while ((pos < max) && (*pChar != ch)) {
|
||||
pos++; pChar++;
|
||||
}
|
||||
if (pos < max)
|
||||
return (int) pos;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline static bool NextChar(const uint8_t * & pChar, uint8_t ch, uint32_t& pos, uint32_t max) {
|
||||
if ((pos < max) && (*pChar == ch)) {
|
||||
pos++;
|
||||
pChar++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static int32_t strcmp(const char * pS1, const char * pS2) {
|
||||
while (*pS1 && *pS2 && (*pS1 == *pS2)) {
|
||||
pS1++;
|
||||
pS2++;
|
||||
}
|
||||
return *pS1 - *pS2;
|
||||
}
|
||||
|
||||
inline static int32_t stricmp(const char * pS1, const char * pS2) {
|
||||
while (*pS1 && *pS2 && (m_upperCaseMap[uint8_t(*pS1)] == m_upperCaseMap[uint8_t(*pS2)])) {
|
||||
pS1++;
|
||||
pS2++;
|
||||
}
|
||||
return m_upperCaseMap[uint8_t(*pS1)] - m_upperCaseMap[uint8_t(*pS2)];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* ImportCharSet_h__ */
|
||||
|
||||
22
mailnews/import/src/ImportDebug.h
Normal file
22
mailnews/import/src/ImportDebug.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef ImportDebug_h___
|
||||
#define ImportDebug_h___
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#define IMPORT_DEBUG 1
|
||||
#endif
|
||||
|
||||
// Use MOZ_LOG for logging.
|
||||
#include "mozilla/Logging.h"
|
||||
extern PRLogModuleInfo *IMPORTLOGMODULE; // Logging module
|
||||
|
||||
#define IMPORT_LOG0(x) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (x))
|
||||
#define IMPORT_LOG1(x, y) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (x, y))
|
||||
#define IMPORT_LOG2(x, y, z) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (x, y, z))
|
||||
#define IMPORT_LOG3(a, b, c, d) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (a, b, c, d))
|
||||
|
||||
#endif
|
||||
299
mailnews/import/src/ImportOutFile.cpp
Normal file
299
mailnews/import/src/ImportOutFile.cpp
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "prio.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "ImportOutFile.h"
|
||||
#include "ImportCharSet.h"
|
||||
|
||||
#include "ImportDebug.h"
|
||||
|
||||
/*
|
||||
#ifdef _MAC
|
||||
#define kMacNoCreator '????'
|
||||
#define kMacTextFile 'TEXT'
|
||||
#else
|
||||
#define kMacNoCreator 0
|
||||
#define kMacTextFile 0
|
||||
#endif
|
||||
*/
|
||||
|
||||
ImportOutFile::ImportOutFile()
|
||||
{
|
||||
m_ownsFileAndBuffer = false;
|
||||
m_pos = 0;
|
||||
m_pBuf = nullptr;
|
||||
m_bufSz = 0;
|
||||
m_pTrans = nullptr;
|
||||
m_pTransOut = nullptr;
|
||||
m_pTransBuf = nullptr;
|
||||
}
|
||||
|
||||
ImportOutFile::ImportOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz)
|
||||
{
|
||||
m_pTransBuf = nullptr;
|
||||
m_pTransOut = nullptr;
|
||||
m_pTrans = nullptr;
|
||||
m_ownsFileAndBuffer = false;
|
||||
InitOutFile(pFile, pBuf, sz);
|
||||
}
|
||||
|
||||
ImportOutFile::~ImportOutFile()
|
||||
{
|
||||
if (m_ownsFileAndBuffer)
|
||||
{
|
||||
Flush();
|
||||
delete [] m_pBuf;
|
||||
}
|
||||
|
||||
delete m_pTrans;
|
||||
delete m_pTransOut;
|
||||
delete [] m_pTransBuf;
|
||||
}
|
||||
|
||||
bool ImportOutFile::Set8bitTranslator(nsImportTranslator *pTrans)
|
||||
{
|
||||
if (!Flush())
|
||||
return false;
|
||||
|
||||
m_engaged = false;
|
||||
m_pTrans = pTrans;
|
||||
m_supports8to7 = pTrans->Supports8bitEncoding();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImportOutFile::End8bitTranslation(bool *pEngaged, nsCString& useCharset, nsCString& encoding)
|
||||
{
|
||||
if (!m_pTrans)
|
||||
return false;
|
||||
|
||||
|
||||
bool bResult = Flush();
|
||||
if (m_supports8to7 && m_pTransOut) {
|
||||
if (bResult)
|
||||
bResult = m_pTrans->FinishConvertToFile(m_pTransOut);
|
||||
if (bResult)
|
||||
bResult = Flush();
|
||||
}
|
||||
|
||||
if (m_supports8to7) {
|
||||
m_pTrans->GetCharset(useCharset);
|
||||
m_pTrans->GetEncoding(encoding);
|
||||
}
|
||||
else
|
||||
useCharset.Truncate();
|
||||
*pEngaged = m_engaged;
|
||||
delete m_pTrans;
|
||||
m_pTrans = nullptr;
|
||||
delete m_pTransOut;
|
||||
m_pTransOut = nullptr;
|
||||
delete [] m_pTransBuf;
|
||||
m_pTransBuf = nullptr;
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
bool ImportOutFile::InitOutFile(nsIFile *pFile, uint32_t bufSz)
|
||||
{
|
||||
if (!bufSz)
|
||||
bufSz = 32 * 1024;
|
||||
if (!m_pBuf)
|
||||
m_pBuf = new uint8_t[ bufSz];
|
||||
|
||||
if (!m_outputStream)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = MsgNewBufferedFileOutputStream(getter_AddRefs(m_outputStream),
|
||||
pFile,
|
||||
PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
|
||||
0644);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
IMPORT_LOG0("Couldn't create outfile\n");
|
||||
delete [] m_pBuf;
|
||||
m_pBuf = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_pFile = pFile;
|
||||
m_ownsFileAndBuffer = true;
|
||||
m_pos = 0;
|
||||
m_bufSz = bufSz;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImportOutFile::InitOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz)
|
||||
{
|
||||
m_ownsFileAndBuffer = false;
|
||||
m_pFile = pFile;
|
||||
m_pBuf = pBuf;
|
||||
m_bufSz = sz;
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ImportOutFile::Flush(void)
|
||||
{
|
||||
if (!m_pos)
|
||||
return true;
|
||||
|
||||
uint32_t transLen;
|
||||
bool duddleyDoWrite = false;
|
||||
|
||||
// handle translations if appropriate
|
||||
if (m_pTrans) {
|
||||
if (m_engaged && m_supports8to7) {
|
||||
// Markers can get confused by this crap!!!
|
||||
// TLR: FIXME: Need to update the markers based on
|
||||
// the difference between the translated len and untranslated len
|
||||
|
||||
if (!m_pTrans->ConvertToFile( m_pBuf, m_pos, m_pTransOut, &transLen))
|
||||
return false;
|
||||
if (!m_pTransOut->Flush())
|
||||
return false;
|
||||
// now update our buffer...
|
||||
if (transLen < m_pos) {
|
||||
memcpy(m_pBuf, m_pBuf + transLen, m_pos - transLen);
|
||||
}
|
||||
m_pos -= transLen;
|
||||
}
|
||||
else if (m_engaged) {
|
||||
// does not actually support translation!
|
||||
duddleyDoWrite = true;
|
||||
}
|
||||
else {
|
||||
// should we engage?
|
||||
uint8_t * pChar = m_pBuf;
|
||||
uint32_t len = m_pos;
|
||||
while (len) {
|
||||
if (!ImportCharSet::IsUSAscii(*pChar))
|
||||
break;
|
||||
pChar++;
|
||||
len--;
|
||||
}
|
||||
if (len) {
|
||||
m_engaged = true;
|
||||
if (m_supports8to7) {
|
||||
// allocate our translation output buffer and file...
|
||||
m_pTransBuf = new uint8_t[m_bufSz];
|
||||
m_pTransOut = new ImportOutFile(m_pFile, m_pTransBuf, m_bufSz);
|
||||
return Flush();
|
||||
}
|
||||
else
|
||||
duddleyDoWrite = true;
|
||||
}
|
||||
else {
|
||||
duddleyDoWrite = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
duddleyDoWrite = true;
|
||||
|
||||
if (duddleyDoWrite) {
|
||||
uint32_t written = 0;
|
||||
nsresult rv = m_outputStream->Write((const char *)m_pBuf, (int32_t)m_pos, &written);
|
||||
if (NS_FAILED(rv) || ((uint32_t)written != m_pos))
|
||||
return false;
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImportOutFile::WriteU8NullTerm(const uint8_t * pSrc, bool includeNull)
|
||||
{
|
||||
while (*pSrc) {
|
||||
if (m_pos >= m_bufSz) {
|
||||
if (!Flush())
|
||||
return false;
|
||||
}
|
||||
*(m_pBuf + m_pos) = *pSrc;
|
||||
m_pos++;
|
||||
pSrc++;
|
||||
}
|
||||
if (includeNull) {
|
||||
if (m_pos >= m_bufSz) {
|
||||
if (!Flush())
|
||||
return false;
|
||||
}
|
||||
*(m_pBuf + m_pos) = 0;
|
||||
m_pos++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImportOutFile::SetMarker(int markerID)
|
||||
{
|
||||
if (!Flush()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (markerID < kMaxMarkers) {
|
||||
int64_t pos = 0;
|
||||
if (m_outputStream)
|
||||
{
|
||||
// do we need to flush for the seek to give us the right pos?
|
||||
m_outputStream->Flush();
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsISeekableStream> seekStream = do_QueryInterface(m_outputStream, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
rv = seekStream->Tell(&pos);
|
||||
if (NS_FAILED(rv)) {
|
||||
IMPORT_LOG0("*** Error, Tell failed on output stream\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_markers[markerID] = (uint32_t)pos + m_pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImportOutFile::ClearMarker(int markerID)
|
||||
{
|
||||
if (markerID < kMaxMarkers)
|
||||
m_markers[markerID] = 0;
|
||||
}
|
||||
|
||||
bool ImportOutFile::WriteStrAtMarker(int markerID, const char *pStr)
|
||||
{
|
||||
if (markerID >= kMaxMarkers)
|
||||
return false;
|
||||
|
||||
if (!Flush())
|
||||
return false;
|
||||
int64_t pos;
|
||||
m_outputStream->Flush();
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsISeekableStream> seekStream = do_QueryInterface(m_outputStream, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
rv = seekStream->Tell(&pos);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, (int32_t) m_markers[markerID]);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
uint32_t written;
|
||||
rv = m_outputStream->Write(pStr, strlen(pStr), &written);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, pos);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
94
mailnews/import/src/ImportOutFile.h
Normal file
94
mailnews/import/src/ImportOutFile.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
#ifndef ImportOutFile_h___
|
||||
#define ImportOutFile_h___
|
||||
|
||||
#include "nsImportTranslator.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
#define kMaxMarkers 10
|
||||
|
||||
class ImportOutFile;
|
||||
|
||||
class ImportOutFile {
|
||||
public:
|
||||
ImportOutFile();
|
||||
ImportOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz);
|
||||
~ImportOutFile();
|
||||
|
||||
bool InitOutFile(nsIFile *pFile, uint32_t bufSz = 4096);
|
||||
void InitOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz);
|
||||
inline bool WriteData(const uint8_t * pSrc, uint32_t len);
|
||||
inline bool WriteByte(uint8_t byte);
|
||||
bool WriteStr(const char *pStr) {return WriteU8NullTerm((const uint8_t *) pStr, false); }
|
||||
bool WriteU8NullTerm(const uint8_t * pSrc, bool includeNull);
|
||||
bool WriteEol(void) { return WriteStr("\x0D\x0A"); }
|
||||
bool Done(void) {return Flush();}
|
||||
|
||||
// Marker support
|
||||
bool SetMarker(int markerID);
|
||||
void ClearMarker(int markerID);
|
||||
bool WriteStrAtMarker(int markerID, const char *pStr);
|
||||
|
||||
// 8-bit to 7-bit translation
|
||||
bool Set8bitTranslator(nsImportTranslator *pTrans);
|
||||
bool End8bitTranslation(bool *pEngaged, nsCString& useCharset, nsCString& encoding);
|
||||
|
||||
protected:
|
||||
bool Flush(void);
|
||||
|
||||
protected:
|
||||
nsCOMPtr <nsIFile> m_pFile;
|
||||
nsCOMPtr <nsIOutputStream> m_outputStream;
|
||||
uint8_t * m_pBuf;
|
||||
uint32_t m_bufSz;
|
||||
uint32_t m_pos;
|
||||
bool m_ownsFileAndBuffer;
|
||||
|
||||
// markers
|
||||
uint32_t m_markers[kMaxMarkers];
|
||||
|
||||
// 8 bit to 7 bit translations
|
||||
nsImportTranslator * m_pTrans;
|
||||
bool m_engaged;
|
||||
bool m_supports8to7;
|
||||
ImportOutFile * m_pTransOut;
|
||||
uint8_t * m_pTransBuf;
|
||||
};
|
||||
|
||||
inline bool ImportOutFile::WriteData(const uint8_t * pSrc, uint32_t len) {
|
||||
while ((len + m_pos) > m_bufSz) {
|
||||
if ((m_bufSz - m_pos)) {
|
||||
memcpy(m_pBuf + m_pos, pSrc, m_bufSz - m_pos);
|
||||
len -= (m_bufSz - m_pos);
|
||||
pSrc += (m_bufSz - m_pos);
|
||||
m_pos = m_bufSz;
|
||||
}
|
||||
if (!Flush())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
memcpy(m_pBuf + m_pos, pSrc, len);
|
||||
m_pos += len;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool ImportOutFile::WriteByte(uint8_t byte) {
|
||||
if (m_pos == m_bufSz) {
|
||||
if (!Flush())
|
||||
return false;
|
||||
}
|
||||
*(m_pBuf + m_pos) = byte;
|
||||
m_pos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* ImportOutFile_h__ */
|
||||
|
||||
|
||||
105
mailnews/import/src/ImportTranslate.cpp
Normal file
105
mailnews/import/src/ImportTranslate.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "ImportTranslate.h"
|
||||
|
||||
int ImportTranslate::m_useTranslator = -1;
|
||||
|
||||
|
||||
bool ImportTranslate::ConvertString(const nsCString& inStr, nsCString& outStr, bool mimeHeader)
|
||||
{
|
||||
if (inStr.IsEmpty()) {
|
||||
outStr = inStr;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsImportTranslator *pTrans = GetTranslator();
|
||||
// int maxLen = (int) pTrans->GetMaxBufferSize(inStr.Length());
|
||||
// int hLen = 0;
|
||||
nsCString set;
|
||||
nsCString lang;
|
||||
|
||||
if (mimeHeader) {
|
||||
// add the charset and language
|
||||
pTrans->GetCharset(set);
|
||||
pTrans->GetLanguage(lang);
|
||||
}
|
||||
|
||||
// Unfortunatly, we didn't implement ConvertBuffer for all translators,
|
||||
// just ConvertToFile. This means that this data will not always
|
||||
// be converted to the charset of pTrans. In that case...
|
||||
// We don't always have the data in the same charset as the current
|
||||
// translator...
|
||||
// It is safer to leave the charset and language field blank
|
||||
set.Truncate();
|
||||
lang.Truncate();
|
||||
|
||||
uint8_t * pBuf;
|
||||
/*
|
||||
pBuf = (P_U8) outStr.GetBuffer(maxLen);
|
||||
if (!pBuf) {
|
||||
delete pTrans;
|
||||
return FALSE;
|
||||
}
|
||||
pTrans->ConvertBuffer((PC_U8)(PC_S8)inStr, inStr.GetLength(), pBuf);
|
||||
outStr.ReleaseBuffer();
|
||||
*/
|
||||
outStr = inStr;
|
||||
delete pTrans;
|
||||
|
||||
|
||||
// Now I need to run the string through the mime-header special char
|
||||
// encoder.
|
||||
|
||||
pTrans = new CMHTranslator;
|
||||
pBuf = new uint8_t[pTrans->GetMaxBufferSize(outStr.Length())];
|
||||
pTrans->ConvertBuffer((const uint8_t *)(outStr.get()), outStr.Length(), pBuf);
|
||||
delete pTrans;
|
||||
outStr.Truncate();
|
||||
if (mimeHeader) {
|
||||
outStr = set;
|
||||
outStr += "'";
|
||||
outStr += lang;
|
||||
outStr += "'";
|
||||
}
|
||||
outStr += (const char *)pBuf;
|
||||
delete [] pBuf;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
nsImportTranslator *ImportTranslate::GetTranslator(void)
|
||||
{
|
||||
if (m_useTranslator == -1) {
|
||||
// get the translator to use...
|
||||
// CString trans;
|
||||
// trans.LoadString(IDS_LANGUAGE_TRANSLATION);
|
||||
m_useTranslator = 0;
|
||||
// if (!trans.CompareNoCase("iso-2022-jp"))
|
||||
// gWizData.m_useTranslator = 1;
|
||||
}
|
||||
|
||||
switch(m_useTranslator) {
|
||||
case 0:
|
||||
return new nsImportTranslator;
|
||||
//case 1:
|
||||
// return new CSJis2JisTranslator;
|
||||
default:
|
||||
return new nsImportTranslator;
|
||||
}
|
||||
}
|
||||
|
||||
nsImportTranslator *ImportTranslate::GetMatchingTranslator(const char *pCharSet)
|
||||
{
|
||||
/*
|
||||
CString jp = "iso-2022-jp";
|
||||
if (!jp.CompareNoCase(pCharSet))
|
||||
return new CSJis2JisTranslator;
|
||||
*/
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
23
mailnews/import/src/ImportTranslate.h
Normal file
23
mailnews/import/src/ImportTranslate.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef ImportTranslate_h___
|
||||
#define ImportTranslate_h___
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsImportTranslator.h"
|
||||
|
||||
class ImportTranslate {
|
||||
public:
|
||||
static bool ConvertString(const nsCString& inStr, nsCString& outStr, bool mimeHeader);
|
||||
static nsImportTranslator *GetTranslator(void);
|
||||
static nsImportTranslator *GetMatchingTranslator(const char *pCharSet);
|
||||
|
||||
protected:
|
||||
static int m_useTranslator;
|
||||
};
|
||||
|
||||
|
||||
#endif /* ImportTranslate_h__ */
|
||||
25
mailnews/import/src/moz.build
Normal file
25
mailnews/import/src/moz.build
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
SOURCES += [
|
||||
'ImportCharSet.cpp',
|
||||
'ImportOutFile.cpp',
|
||||
'ImportTranslate.cpp',
|
||||
'nsImportABDescriptor.cpp',
|
||||
'nsImportAddressBooks.cpp',
|
||||
'nsImportEmbeddedImageData.cpp',
|
||||
'nsImportEncodeScan.cpp',
|
||||
'nsImportFieldMap.cpp',
|
||||
'nsImportMail.cpp',
|
||||
'nsImportMailboxDescriptor.cpp',
|
||||
'nsImportMimeEncode.cpp',
|
||||
'nsImportScanFile.cpp',
|
||||
'nsImportService.cpp',
|
||||
'nsImportStringBundle.cpp',
|
||||
'nsImportTranslator.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'import'
|
||||
|
||||
32
mailnews/import/src/nsImportABDescriptor.cpp
Normal file
32
mailnews/import/src/nsImportABDescriptor.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsImportABDescriptor.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_METHOD nsImportABDescriptor::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsImportABDescriptor *it = new nsImportABDescriptor();
|
||||
if (it == nullptr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImportABDescriptor, nsIImportABDescriptor)
|
||||
|
||||
nsImportABDescriptor::nsImportABDescriptor()
|
||||
: mId(0), mRef(0), mSize(0), mImport(true)
|
||||
{
|
||||
}
|
||||
103
mailnews/import/src/nsImportABDescriptor.h
Normal file
103
mailnews/import/src/nsImportABDescriptor.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportABDescriptor_h___
|
||||
#define nsImportABDescriptor_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIImportABDescriptor.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsImportABDescriptor : public nsIImportABDescriptor
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetIdentifier(uint32_t *pIdentifier) override {
|
||||
*pIdentifier = mId;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetIdentifier(uint32_t ident) override {
|
||||
mId = ident;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetRef(uint32_t *pRef) override {
|
||||
*pRef = mRef;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetRef(uint32_t ref) override {
|
||||
mRef = ref;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute unsigned long size; */
|
||||
NS_IMETHOD GetSize(uint32_t *pSize) override {
|
||||
*pSize = mSize;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetSize(uint32_t theSize) override {
|
||||
mSize = theSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute AString displayName; */
|
||||
NS_IMETHOD GetPreferredName(nsAString &aName) override {
|
||||
aName = mDisplayName;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetPreferredName(const nsAString &aName) override {
|
||||
mDisplayName = aName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIFile fileSpec; */
|
||||
NS_IMETHOD GetAbFile(nsIFile **aFile) override {
|
||||
if (!mFile)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return mFile->Clone(aFile);
|
||||
}
|
||||
|
||||
NS_IMETHOD SetAbFile(nsIFile *aFile) override {
|
||||
if (!aFile) {
|
||||
mFile = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return aFile->Clone(getter_AddRefs(mFile));
|
||||
}
|
||||
|
||||
/* attribute boolean import; */
|
||||
NS_IMETHOD GetImport(bool *pImport) override {
|
||||
*pImport = mImport;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetImport(bool doImport) override {
|
||||
mImport = doImport;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsImportABDescriptor();
|
||||
|
||||
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
private:
|
||||
virtual ~nsImportABDescriptor() {}
|
||||
uint32_t mId; // used by creator of the structure
|
||||
uint32_t mRef; // depth in the hierarchy
|
||||
nsString mDisplayName; // name of this mailbox
|
||||
nsCOMPtr<nsIFile> mFile; // source file (if applicable)
|
||||
uint32_t mSize; // size
|
||||
bool mImport; // import it or not?
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
894
mailnews/import/src/nsImportAddressBooks.cpp
Normal file
894
mailnews/import/src/nsImportAddressBooks.cpp
Normal file
|
|
@ -0,0 +1,894 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "prprf.h"
|
||||
#include "plstr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsIImportService.h"
|
||||
#include "nsIImportAddressBooks.h"
|
||||
#include "nsIImportGeneric.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIImportABDescriptor.h"
|
||||
#include "nsIImportFieldMap.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIAddrDatabase.h"
|
||||
#include "nsIAbManager.h"
|
||||
#include "nsIAbLDIFService.h"
|
||||
#include "nsAbBaseCID.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsImportStringBundle.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "msgCore.h"
|
||||
#include "ImportDebug.h"
|
||||
#include "nsIAbMDBDirectory.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsArrayUtils.h"
|
||||
|
||||
static void ImportAddressThread(void *stuff);
|
||||
|
||||
class AddressThreadData;
|
||||
|
||||
class nsImportGenericAddressBooks : public nsIImportGeneric
|
||||
{
|
||||
public:
|
||||
|
||||
nsImportGenericAddressBooks();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
/* nsISupports GetData (in string dataId); */
|
||||
NS_IMETHOD GetData(const char *dataId, nsISupports **_retval) override;
|
||||
|
||||
NS_IMETHOD SetData(const char *dataId, nsISupports *pData) override;
|
||||
|
||||
NS_IMETHOD GetStatus(const char *statusKind, int32_t *_retval) override;
|
||||
|
||||
NS_IMETHOD WantsProgress(bool *_retval) override;
|
||||
|
||||
NS_IMETHOD BeginImport(nsISupportsString *successLog, nsISupportsString *errorLog, bool *_retval) override;
|
||||
|
||||
NS_IMETHOD ContinueImport(bool *_retval) override;
|
||||
|
||||
NS_IMETHOD GetProgress(int32_t *_retval) override;
|
||||
|
||||
NS_IMETHOD CancelImport(void) override;
|
||||
|
||||
private:
|
||||
virtual ~nsImportGenericAddressBooks();
|
||||
void GetDefaultLocation(void);
|
||||
void GetDefaultBooks(void);
|
||||
void GetDefaultFieldMap(void);
|
||||
|
||||
public:
|
||||
static void SetLogs(nsString& success, nsString& error, nsISupportsString *pSuccess, nsISupportsString *pError);
|
||||
static void ReportError(const char16_t *pName, nsString *pStream,
|
||||
nsIStringBundle *aBundle);
|
||||
|
||||
private:
|
||||
nsIImportAddressBooks * m_pInterface;
|
||||
nsCOMPtr<nsIArray> m_Books;
|
||||
nsCOMArray<nsIAddrDatabase> m_DBs;
|
||||
nsCOMPtr <nsIFile> m_pLocation;
|
||||
nsIImportFieldMap * m_pFieldMap;
|
||||
bool m_autoFind;
|
||||
char16_t * m_description;
|
||||
bool m_gotLocation;
|
||||
bool m_found;
|
||||
bool m_userVerify;
|
||||
nsISupportsString * m_pSuccessLog;
|
||||
nsISupportsString * m_pErrorLog;
|
||||
uint32_t m_totalSize;
|
||||
bool m_doImport;
|
||||
AddressThreadData * m_pThreadData;
|
||||
char * m_pDestinationUri;
|
||||
nsCOMPtr<nsIStringBundle> m_stringBundle;
|
||||
};
|
||||
|
||||
class AddressThreadData {
|
||||
public:
|
||||
bool driverAlive;
|
||||
bool threadAlive;
|
||||
bool abort;
|
||||
bool fatalError;
|
||||
uint32_t currentTotal;
|
||||
uint32_t currentSize;
|
||||
nsIArray *books;
|
||||
nsCOMArray<nsIAddrDatabase>* dBs;
|
||||
nsCOMPtr<nsIAbLDIFService> ldifService;
|
||||
nsIImportAddressBooks * addressImport;
|
||||
nsIImportFieldMap * fieldMap;
|
||||
nsISupportsString * successLog;
|
||||
nsISupportsString * errorLog;
|
||||
char * pDestinationUri;
|
||||
nsIStringBundle* stringBundle;
|
||||
|
||||
AddressThreadData();
|
||||
~AddressThreadData();
|
||||
};
|
||||
|
||||
|
||||
nsresult NS_NewGenericAddressBooks(nsIImportGeneric** aImportGeneric)
|
||||
{
|
||||
NS_PRECONDITION(aImportGeneric != nullptr, "null ptr");
|
||||
if (! aImportGeneric)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsImportGenericAddressBooks *pGen = new nsImportGenericAddressBooks();
|
||||
|
||||
if (pGen == nullptr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(pGen);
|
||||
nsresult rv = pGen->QueryInterface(NS_GET_IID(nsIImportGeneric), (void **)aImportGeneric);
|
||||
NS_RELEASE(pGen);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsImportGenericAddressBooks::nsImportGenericAddressBooks()
|
||||
{
|
||||
m_pInterface = nullptr;
|
||||
m_pSuccessLog = nullptr;
|
||||
m_pErrorLog = nullptr;
|
||||
m_totalSize = 0;
|
||||
m_doImport = false;
|
||||
m_pThreadData = nullptr;
|
||||
m_pDestinationUri = nullptr;
|
||||
m_pFieldMap = nullptr;
|
||||
|
||||
m_autoFind = false;
|
||||
m_description = nullptr;
|
||||
m_gotLocation = false;
|
||||
m_found = false;
|
||||
m_userVerify = false;
|
||||
|
||||
nsImportStringBundle::GetStringBundle(IMPORT_MSGS_URL, getter_AddRefs(m_stringBundle));
|
||||
}
|
||||
|
||||
|
||||
nsImportGenericAddressBooks::~nsImportGenericAddressBooks()
|
||||
{
|
||||
if (m_pDestinationUri)
|
||||
NS_Free(m_pDestinationUri);
|
||||
|
||||
if (m_description)
|
||||
NS_Free(m_description);
|
||||
|
||||
NS_IF_RELEASE(m_pFieldMap);
|
||||
NS_IF_RELEASE(m_pInterface);
|
||||
NS_IF_RELEASE(m_pSuccessLog);
|
||||
NS_IF_RELEASE(m_pErrorLog);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImportGenericAddressBooks, nsIImportGeneric)
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::GetData(const char *dataId, nsISupports **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv;
|
||||
*_retval = nullptr;
|
||||
if (!PL_strcasecmp(dataId, "addressInterface")) {
|
||||
*_retval = m_pInterface;
|
||||
NS_IF_ADDREF(m_pInterface);
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "addressLocation")) {
|
||||
if (!m_pLocation)
|
||||
GetDefaultLocation();
|
||||
NS_IF_ADDREF(*_retval = m_pLocation);
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "addressBooks")) {
|
||||
if (!m_pLocation)
|
||||
GetDefaultLocation();
|
||||
if (!m_Books)
|
||||
GetDefaultBooks();
|
||||
*_retval = m_Books;
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "addressDestination")) {
|
||||
if (m_pDestinationUri) {
|
||||
nsCOMPtr<nsISupportsCString> abString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
abString->SetData(nsDependentCString(m_pDestinationUri));
|
||||
NS_IF_ADDREF(*_retval = abString);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "fieldMap")) {
|
||||
if (m_pFieldMap) {
|
||||
*_retval = m_pFieldMap;
|
||||
m_pFieldMap->AddRef();
|
||||
}
|
||||
else {
|
||||
if (m_pInterface && m_pLocation) {
|
||||
bool needsIt = false;
|
||||
m_pInterface->GetNeedsFieldMap(m_pLocation, &needsIt);
|
||||
if (needsIt) {
|
||||
GetDefaultFieldMap();
|
||||
if (m_pFieldMap) {
|
||||
*_retval = m_pFieldMap;
|
||||
m_pFieldMap->AddRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PL_strncasecmp(dataId, "sampleData-", 11)) {
|
||||
// extra the record number
|
||||
const char *pNum = dataId + 11;
|
||||
int32_t rNum = 0;
|
||||
while (*pNum) {
|
||||
rNum *= 10;
|
||||
rNum += (*pNum - '0');
|
||||
pNum++;
|
||||
}
|
||||
IMPORT_LOG1("Requesting sample data #: %ld\n", (long)rNum);
|
||||
if (m_pInterface) {
|
||||
nsCOMPtr<nsISupportsString> data = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
char16_t * pData = nullptr;
|
||||
bool found = false;
|
||||
rv = m_pInterface->GetSampleData(rNum, &found, &pData);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (found) {
|
||||
data->SetData(nsDependentString(pData));
|
||||
*_retval = data;
|
||||
NS_ADDREF(*_retval);
|
||||
}
|
||||
NS_Free(pData);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::SetData(const char *dataId, nsISupports *item)
|
||||
{
|
||||
NS_PRECONDITION(dataId != nullptr, "null ptr");
|
||||
if (!dataId)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (!PL_strcasecmp(dataId, "addressInterface")) {
|
||||
NS_IF_RELEASE(m_pInterface);
|
||||
if (item)
|
||||
item->QueryInterface(NS_GET_IID(nsIImportAddressBooks), (void **) &m_pInterface);
|
||||
}
|
||||
if (!PL_strcasecmp(dataId, "addressBooks")) {
|
||||
if (item)
|
||||
item->QueryInterface(NS_GET_IID(nsIArray), (void **) &m_Books);
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "addressLocation")) {
|
||||
m_pLocation = nullptr;
|
||||
|
||||
if (item) {
|
||||
nsresult rv;
|
||||
m_pLocation = do_QueryInterface(item, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
if (m_pInterface)
|
||||
m_pInterface->SetSampleLocation(m_pLocation);
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "addressDestination")) {
|
||||
if (item) {
|
||||
nsCOMPtr<nsISupportsCString> abString;
|
||||
item->QueryInterface(NS_GET_IID(nsISupportsCString), getter_AddRefs(abString));
|
||||
if (abString) {
|
||||
if (m_pDestinationUri)
|
||||
NS_Free(m_pDestinationUri);
|
||||
m_pDestinationUri = nullptr;
|
||||
nsAutoCString tempUri;
|
||||
abString->GetData(tempUri);
|
||||
m_pDestinationUri = ToNewCString(tempUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(dataId, "fieldMap")) {
|
||||
NS_IF_RELEASE(m_pFieldMap);
|
||||
if (item)
|
||||
item->QueryInterface(NS_GET_IID(nsIImportFieldMap), (void **) &m_pFieldMap);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::GetStatus(const char *statusKind, int32_t *_retval)
|
||||
{
|
||||
NS_PRECONDITION(statusKind != nullptr, "null ptr");
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!statusKind || !_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*_retval = 0;
|
||||
|
||||
if (!PL_strcasecmp(statusKind, "isInstalled")) {
|
||||
GetDefaultLocation();
|
||||
*_retval = (int32_t) m_found;
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(statusKind, "canUserSetLocation")) {
|
||||
GetDefaultLocation();
|
||||
*_retval = (int32_t) m_userVerify;
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(statusKind, "autoFind")) {
|
||||
GetDefaultLocation();
|
||||
*_retval = (int32_t) m_autoFind;
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(statusKind, "supportsMultiple")) {
|
||||
bool multi = false;
|
||||
if (m_pInterface)
|
||||
m_pInterface->GetSupportsMultiple(&multi);
|
||||
*_retval = (int32_t) multi;
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(statusKind, "needsFieldMap")) {
|
||||
bool needs = false;
|
||||
if (m_pInterface && m_pLocation)
|
||||
m_pInterface->GetNeedsFieldMap(m_pLocation, &needs);
|
||||
*_retval = (int32_t) needs;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsImportGenericAddressBooks::GetDefaultLocation(void)
|
||||
{
|
||||
if (!m_pInterface)
|
||||
return;
|
||||
|
||||
if ((m_pLocation && m_gotLocation) || m_autoFind)
|
||||
return;
|
||||
|
||||
if (m_description)
|
||||
NS_Free(m_description);
|
||||
m_description = nullptr;
|
||||
m_pInterface->GetAutoFind(&m_description, &m_autoFind);
|
||||
m_gotLocation = true;
|
||||
if (m_autoFind) {
|
||||
m_found = true;
|
||||
m_userVerify = false;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr <nsIFile> pLoc;
|
||||
m_pInterface->GetDefaultLocation(getter_AddRefs(pLoc), &m_found, &m_userVerify);
|
||||
if (!m_pLocation)
|
||||
m_pLocation = pLoc;
|
||||
}
|
||||
|
||||
void nsImportGenericAddressBooks::GetDefaultBooks(void)
|
||||
{
|
||||
if (!m_pInterface || m_Books)
|
||||
return;
|
||||
|
||||
if (!m_pLocation && !m_autoFind)
|
||||
return;
|
||||
|
||||
nsresult rv = m_pInterface->FindAddressBooks(m_pLocation, getter_AddRefs(m_Books));
|
||||
if (NS_FAILED(rv)) {
|
||||
IMPORT_LOG0("*** Error: FindAddressBooks failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void nsImportGenericAddressBooks::GetDefaultFieldMap(void)
|
||||
{
|
||||
if (!m_pInterface || !m_pLocation)
|
||||
return;
|
||||
|
||||
NS_IF_RELEASE(m_pFieldMap);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
IMPORT_LOG0("*** Unable to get nsIImportService.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rv = impSvc->CreateNewFieldMap(&m_pFieldMap);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
int32_t sz = 0;
|
||||
rv = m_pFieldMap->GetNumMozFields(&sz);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = m_pFieldMap->DefaultFieldMap(sz);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = m_pInterface->InitFieldMap(m_pFieldMap);
|
||||
if (NS_FAILED(rv)) {
|
||||
IMPORT_LOG0("*** Error: Unable to initialize field map\n");
|
||||
NS_IF_RELEASE(m_pFieldMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::WantsProgress(bool *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
GetDefaultLocation();
|
||||
GetDefaultBooks();
|
||||
|
||||
bool result = false;
|
||||
|
||||
if (m_Books) {
|
||||
uint32_t count = 0;
|
||||
uint32_t i;
|
||||
bool import;
|
||||
uint32_t size;
|
||||
uint32_t totalSize = 0;
|
||||
|
||||
m_Books->GetLength(&count);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(m_Books, i);
|
||||
if (book) {
|
||||
import = false;
|
||||
size = 0;
|
||||
nsresult rv = book->GetImport(&import);
|
||||
if (NS_SUCCEEDED(rv) && import) {
|
||||
(void) book->GetSize(&size);
|
||||
result = true;
|
||||
}
|
||||
totalSize += size;
|
||||
}
|
||||
}
|
||||
|
||||
m_totalSize = totalSize;
|
||||
}
|
||||
|
||||
m_doImport = result;
|
||||
|
||||
*_retval = result;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsImportGenericAddressBooks::SetLogs(nsString& success, nsString& error, nsISupportsString *pSuccess, nsISupportsString *pError)
|
||||
{
|
||||
nsAutoString str;
|
||||
if (pSuccess) {
|
||||
pSuccess->GetData(str);
|
||||
str.Append(success);
|
||||
pSuccess->SetData(success);
|
||||
}
|
||||
if (pError) {
|
||||
pError->GetData(str);
|
||||
str.Append(error);
|
||||
pError->SetData(error);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAddrDatabase> GetAddressBookFromUri(const char *pUri)
|
||||
{
|
||||
if (!pUri)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID);
|
||||
if (!abManager)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAbDirectory> directory;
|
||||
abManager->GetDirectory(nsDependentCString(pUri),
|
||||
getter_AddRefs(directory));
|
||||
if (!directory)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAbMDBDirectory> mdbDirectory = do_QueryInterface(directory);
|
||||
if (!mdbDirectory)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAddrDatabase> pDatabase;
|
||||
mdbDirectory->GetDatabase(getter_AddRefs(pDatabase));
|
||||
return pDatabase.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAddrDatabase> GetAddressBook(const char16_t *name,
|
||||
bool makeNew)
|
||||
{
|
||||
if (!makeNew) {
|
||||
// FIXME: How do I get the list of address books and look for a
|
||||
// specific name. Major bogosity!
|
||||
// For now, assume we didn't find anything with that name
|
||||
}
|
||||
|
||||
IMPORT_LOG0("In GetAddressBook\n");
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAddrDatabase> pDatabase;
|
||||
nsCOMPtr<nsIFile> dbPath;
|
||||
nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
/* Get the profile directory */
|
||||
rv = abManager->GetUserProfileDirectory(getter_AddRefs(dbPath));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// Create a new address book file - we don't care what the file
|
||||
// name is, as long as it's unique
|
||||
rv = dbPath->Append(NS_LITERAL_STRING("impab.mab"));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = dbPath->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
IMPORT_LOG0("Getting the address database factory\n");
|
||||
|
||||
nsCOMPtr<nsIAddrDatabase> addrDBFactory =
|
||||
do_GetService(NS_ADDRDATABASE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return nullptr;
|
||||
|
||||
IMPORT_LOG0("Opening the new address book\n");
|
||||
rv = addrDBFactory->Open(dbPath, true, true,
|
||||
getter_AddRefs(pDatabase));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
IMPORT_LOG0("Failed to get the user profile directory from the address book session\n");
|
||||
}
|
||||
|
||||
if (pDatabase && dbPath)
|
||||
{
|
||||
// We made a database, add it to the UI?!?!?!?!?!?!
|
||||
// This is major bogosity again! Why doesn't the address book
|
||||
// just handle this properly for me? Uggggg...
|
||||
|
||||
nsCOMPtr<nsIAbDirectory> parentDir;
|
||||
abManager->GetDirectory(NS_LITERAL_CSTRING(kAllDirectoryRoot),
|
||||
getter_AddRefs(parentDir));
|
||||
if (parentDir)
|
||||
{
|
||||
nsAutoCString URI("moz-abmdbdirectory://");
|
||||
nsAutoCString leafName;
|
||||
rv = dbPath->GetNativeLeafName(leafName);
|
||||
if (NS_FAILED(rv))
|
||||
IMPORT_LOG0("*** Error: Unable to get name of database file\n");
|
||||
else
|
||||
{
|
||||
URI.Append(leafName);
|
||||
rv = parentDir->CreateDirectoryByURI(nsDependentString(name), URI);
|
||||
if (NS_FAILED(rv))
|
||||
IMPORT_LOG0("*** Error: Unable to create address book directory\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
IMPORT_LOG0("Added new address book to the UI\n");
|
||||
else
|
||||
IMPORT_LOG0("*** Error: An error occurred while adding the address book to the UI\n");
|
||||
}
|
||||
|
||||
return pDatabase.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::BeginImport(nsISupportsString *successLog, nsISupportsString *errorLog, bool *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsString success;
|
||||
nsString error;
|
||||
|
||||
if (!m_doImport) {
|
||||
*_retval = true;
|
||||
nsImportStringBundle::GetStringByID(IMPORT_NO_ADDRBOOKS, m_stringBundle,
|
||||
success);
|
||||
SetLogs(success, error, successLog, errorLog);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!m_pInterface || !m_Books) {
|
||||
nsImportStringBundle::GetStringByID(IMPORT_ERROR_AB_NOTINITIALIZED,
|
||||
m_stringBundle, error);
|
||||
SetLogs(success, error, successLog, errorLog);
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool needsFieldMap = false;
|
||||
|
||||
if (NS_FAILED(m_pInterface->GetNeedsFieldMap(m_pLocation, &needsFieldMap)) ||
|
||||
(needsFieldMap && !m_pFieldMap)) {
|
||||
nsImportStringBundle::GetStringByID(IMPORT_ERROR_AB_NOTINITIALIZED,
|
||||
m_stringBundle, error);
|
||||
SetLogs(success, error, successLog, errorLog);
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(m_pSuccessLog);
|
||||
NS_IF_RELEASE(m_pErrorLog);
|
||||
m_pSuccessLog = successLog;
|
||||
m_pErrorLog = errorLog;
|
||||
NS_IF_ADDREF(m_pSuccessLog);
|
||||
NS_IF_ADDREF(m_pErrorLog);
|
||||
|
||||
|
||||
// create the info need to drive address book import. We're
|
||||
// not going to create a new thread for this since address books
|
||||
// don't tend to be large, and import is rare.
|
||||
m_pThreadData = new AddressThreadData();
|
||||
m_pThreadData->books = m_Books;
|
||||
NS_ADDREF(m_Books);
|
||||
m_pThreadData->addressImport = m_pInterface;
|
||||
NS_ADDREF(m_pInterface);
|
||||
m_pThreadData->fieldMap = m_pFieldMap;
|
||||
NS_IF_ADDREF(m_pFieldMap);
|
||||
m_pThreadData->errorLog = m_pErrorLog;
|
||||
NS_IF_ADDREF(m_pErrorLog);
|
||||
m_pThreadData->successLog = m_pSuccessLog;
|
||||
NS_IF_ADDREF(m_pSuccessLog);
|
||||
if (m_pDestinationUri)
|
||||
m_pThreadData->pDestinationUri = strdup(m_pDestinationUri);
|
||||
|
||||
uint32_t count = 0;
|
||||
m_Books->GetLength(&count);
|
||||
// Create/obtain any address books that we need here, so that we don't need
|
||||
// to do so inside the import thread which would just proxy the create
|
||||
// operations back to the main thread anyway.
|
||||
nsCOMPtr<nsIAddrDatabase> db = GetAddressBookFromUri(m_pDestinationUri);
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(m_Books, i);
|
||||
if (book)
|
||||
{
|
||||
if (!db)
|
||||
{
|
||||
nsString name;
|
||||
book->GetPreferredName(name);
|
||||
db = GetAddressBook(name.get(), true);
|
||||
}
|
||||
m_DBs.AppendObject(db);
|
||||
}
|
||||
}
|
||||
m_pThreadData->dBs = &m_DBs;
|
||||
|
||||
NS_IF_ADDREF(m_pThreadData->stringBundle = m_stringBundle);
|
||||
|
||||
nsresult rv;
|
||||
m_pThreadData->ldifService = do_GetService(NS_ABLDIFSERVICE_CONTRACTID, &rv);
|
||||
|
||||
ImportAddressThread(m_pThreadData);
|
||||
delete m_pThreadData;
|
||||
m_pThreadData = nullptr;
|
||||
*_retval = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::ContinueImport(bool *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*_retval = true;
|
||||
if (m_pThreadData) {
|
||||
if (m_pThreadData->fatalError)
|
||||
*_retval = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::GetProgress(int32_t *_retval)
|
||||
{
|
||||
// This returns the progress from the the currently
|
||||
// running import mail or import address book thread.
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (!m_pThreadData || !(m_pThreadData->threadAlive)) {
|
||||
*_retval = 100;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t sz = 0;
|
||||
if (m_pThreadData->currentSize && m_pInterface) {
|
||||
if (NS_FAILED(m_pInterface->GetImportProgress(&sz)))
|
||||
sz = 0;
|
||||
}
|
||||
|
||||
if (m_totalSize)
|
||||
*_retval = ((m_pThreadData->currentTotal + sz) * 100) / m_totalSize;
|
||||
else
|
||||
*_retval = 0;
|
||||
|
||||
// never return less than 5 so it looks like we are doing something!
|
||||
if (*_retval < 5)
|
||||
*_retval = 5;
|
||||
|
||||
// as long as the thread is alive don't return completely
|
||||
// done.
|
||||
if (*_retval > 99)
|
||||
*_retval = 99;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportGenericAddressBooks::CancelImport(void)
|
||||
{
|
||||
if (m_pThreadData) {
|
||||
m_pThreadData->abort = true;
|
||||
m_pThreadData = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
AddressThreadData::AddressThreadData()
|
||||
{
|
||||
fatalError = false;
|
||||
driverAlive = true;
|
||||
threadAlive = true;
|
||||
abort = false;
|
||||
currentTotal = 0;
|
||||
currentSize = 0;
|
||||
books = nullptr;
|
||||
addressImport = nullptr;
|
||||
successLog = nullptr;
|
||||
errorLog = nullptr;
|
||||
pDestinationUri = nullptr;
|
||||
fieldMap = nullptr;
|
||||
stringBundle = nullptr;
|
||||
ldifService = nullptr;
|
||||
}
|
||||
|
||||
AddressThreadData::~AddressThreadData()
|
||||
{
|
||||
if (pDestinationUri)
|
||||
NS_Free(pDestinationUri);
|
||||
|
||||
NS_IF_RELEASE(books);
|
||||
NS_IF_RELEASE(addressImport);
|
||||
NS_IF_RELEASE(errorLog);
|
||||
NS_IF_RELEASE(successLog);
|
||||
NS_IF_RELEASE(fieldMap);
|
||||
NS_IF_RELEASE(stringBundle);
|
||||
}
|
||||
|
||||
void nsImportGenericAddressBooks::ReportError(const char16_t *pName,
|
||||
nsString *pStream,
|
||||
nsIStringBundle* aBundle)
|
||||
{
|
||||
if (!pStream)
|
||||
return;
|
||||
// load the error string
|
||||
char16_t *pFmt = nsImportStringBundle::GetStringByID(IMPORT_ERROR_GETABOOK, aBundle);
|
||||
char16_t *pText = nsTextFormatter::smprintf(pFmt, pName);
|
||||
pStream->Append(pText);
|
||||
nsTextFormatter::smprintf_free(pText);
|
||||
NS_Free(pFmt);
|
||||
pStream->AppendLiteral(MSG_LINEBREAK);
|
||||
}
|
||||
|
||||
static void ImportAddressThread(void *stuff)
|
||||
{
|
||||
IMPORT_LOG0("In Begin ImportAddressThread\n");
|
||||
|
||||
AddressThreadData *pData = (AddressThreadData *)stuff;
|
||||
uint32_t count = 0;
|
||||
uint32_t i;
|
||||
bool import;
|
||||
uint32_t size;
|
||||
|
||||
nsString success;
|
||||
nsString error;
|
||||
|
||||
(void) pData->books->GetLength(&count);
|
||||
|
||||
for (i = 0; (i < count) && !(pData->abort); i++) {
|
||||
nsCOMPtr<nsIImportABDescriptor> book =
|
||||
do_QueryElementAt(pData->books, i);
|
||||
|
||||
if (book) {
|
||||
import = false;
|
||||
size = 0;
|
||||
nsresult rv = book->GetImport(&import);
|
||||
if (NS_SUCCEEDED(rv) && import)
|
||||
rv = book->GetSize(&size);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && size && import) {
|
||||
nsString name;
|
||||
book->GetPreferredName(name);
|
||||
|
||||
nsCOMPtr<nsIAddrDatabase> db = pData->dBs->ObjectAt(i);
|
||||
|
||||
bool fatalError = false;
|
||||
pData->currentSize = size;
|
||||
if (db) {
|
||||
char16_t *pSuccess = nullptr;
|
||||
char16_t *pError = nullptr;
|
||||
|
||||
/*
|
||||
if (pData->fieldMap) {
|
||||
int32_t sz = 0;
|
||||
int32_t mapIndex;
|
||||
bool active;
|
||||
pData->fieldMap->GetMapSize(&sz);
|
||||
IMPORT_LOG1("**** Field Map Size: %d\n", (int) sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
pData->fieldMap->GetFieldMap(i, &mapIndex);
|
||||
pData->fieldMap->GetFieldActive(i, &active);
|
||||
IMPORT_LOG3("Field map #%d: index=%d, active=%d\n", (int) i, (int) mapIndex, (int) active);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
rv = pData->addressImport->ImportAddressBook(book,
|
||||
db,
|
||||
pData->fieldMap,
|
||||
pData->ldifService,
|
||||
&pError,
|
||||
&pSuccess,
|
||||
&fatalError);
|
||||
if (NS_SUCCEEDED(rv) && pSuccess) {
|
||||
success.Append(pSuccess);
|
||||
NS_Free(pSuccess);
|
||||
}
|
||||
if (pError) {
|
||||
error.Append(pError);
|
||||
NS_Free(pError);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsImportGenericAddressBooks::ReportError(name.get(), &error, pData->stringBundle);
|
||||
}
|
||||
|
||||
pData->currentSize = 0;
|
||||
pData->currentTotal += size;
|
||||
|
||||
if (db)
|
||||
db->Close(true);
|
||||
|
||||
if (fatalError) {
|
||||
pData->fatalError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsImportGenericAddressBooks::SetLogs(success, error, pData->successLog, pData->errorLog);
|
||||
|
||||
if (pData->abort || pData->fatalError) {
|
||||
// FIXME: do what is necessary to get rid of what has been imported so far.
|
||||
// Nothing if we went into an existing address book! Otherwise, delete
|
||||
// the ones we created?
|
||||
}
|
||||
|
||||
}
|
||||
64
mailnews/import/src/nsImportEmbeddedImageData.cpp
Normal file
64
mailnews/import/src/nsImportEmbeddedImageData.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsImportEmbeddedImageData.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImportEmbeddedImageData, nsIMsgEmbeddedImageData)
|
||||
|
||||
nsImportEmbeddedImageData::nsImportEmbeddedImageData()
|
||||
{
|
||||
}
|
||||
|
||||
nsImportEmbeddedImageData::nsImportEmbeddedImageData(
|
||||
nsIURI *aUri, const nsACString &aCid) : m_uri(aUri), m_cid(aCid)
|
||||
{
|
||||
}
|
||||
|
||||
nsImportEmbeddedImageData::nsImportEmbeddedImageData(
|
||||
nsIURI *aUri, const nsACString &aCid, const nsACString &aName)
|
||||
: m_uri(aUri), m_cid(aCid), m_name(aName)
|
||||
{
|
||||
}
|
||||
|
||||
nsImportEmbeddedImageData::~nsImportEmbeddedImageData()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportEmbeddedImageData::GetUri(nsIURI **aUri)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aUri);
|
||||
NS_IF_ADDREF(*aUri = m_uri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportEmbeddedImageData::SetUri(nsIURI *aUri)
|
||||
{
|
||||
m_uri = aUri;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportEmbeddedImageData::GetCid(nsACString &aCid)
|
||||
{
|
||||
aCid = m_cid;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportEmbeddedImageData::SetCid(const nsACString &aCid)
|
||||
{
|
||||
m_cid = aCid;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportEmbeddedImageData::GetName(nsACString &aName)
|
||||
{
|
||||
aName = m_name;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportEmbeddedImageData::SetName(const nsACString &aName)
|
||||
{
|
||||
m_name = aName;
|
||||
return NS_OK;
|
||||
}
|
||||
32
mailnews/import/src/nsImportEmbeddedImageData.h
Normal file
32
mailnews/import/src/nsImportEmbeddedImageData.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef __IMPORTEMBEDDEDIMAGETDATA_H__
|
||||
#define __IMPORTEMBEDDEDIMAGETDATA_H__
|
||||
|
||||
#include "nsIMsgSend.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
class nsImportEmbeddedImageData final : public nsIMsgEmbeddedImageData
|
||||
{
|
||||
public:
|
||||
nsImportEmbeddedImageData(nsIURI *aUri, const nsACString &aCID);
|
||||
nsImportEmbeddedImageData(nsIURI *aUri, const nsACString &aCID, const nsACString &aName);
|
||||
nsImportEmbeddedImageData();
|
||||
NS_DECL_NSIMSGEMBEDDEDIMAGEDATA
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsCOMPtr<nsIURI> m_uri;
|
||||
nsCString m_cid;
|
||||
nsCString m_name;
|
||||
|
||||
private:
|
||||
~nsImportEmbeddedImageData();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
374
mailnews/import/src/nsImportEncodeScan.cpp
Normal file
374
mailnews/import/src/nsImportEncodeScan.cpp
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsImportEncodeScan.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#define kBeginAppleSingle 0
|
||||
#define kBeginDataFork 1
|
||||
#define kBeginResourceFork 2
|
||||
#define kAddEntries 3
|
||||
#define kScanningDataFork 4
|
||||
#define kScanningRsrcFork 5
|
||||
#define kDoneWithFile 6
|
||||
|
||||
uint32_t gAppleSingleHeader[6] = {0x00051600, 0x00020000, 0, 0, 0, 0};
|
||||
#define kAppleSingleHeaderSize (6 * sizeof(uint32_t))
|
||||
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
#include "MoreFilesExtras.h"
|
||||
#include "MoreDesktopMgr.h"
|
||||
|
||||
CInfoPBRec gCatInfoPB;
|
||||
U32 g2000Secs = 0;
|
||||
long gGMTDelta = 0;
|
||||
|
||||
long GetGmtDelta(void);
|
||||
U32 Get2000Secs(void);
|
||||
|
||||
|
||||
long GetGmtDelta(void)
|
||||
{
|
||||
MachineLocation myLocation;
|
||||
ReadLocation(&myLocation);
|
||||
long myDelta = BitAnd(myLocation.u.gmtDelta, 0x00FFFFFF);
|
||||
if (BitTst(&myDelta, 23))
|
||||
myDelta = BitOr(myDelta, 0xFF000000);
|
||||
return myDelta;
|
||||
}
|
||||
|
||||
U32 Get2000Secs(void)
|
||||
{
|
||||
DateTimeRec dr;
|
||||
dr.year = 2000;
|
||||
dr.month = 1;
|
||||
dr.day = 1;
|
||||
dr.hour = 0;
|
||||
dr.minute = 0;
|
||||
dr.second = 0;
|
||||
dr.dayOfWeek = 0;
|
||||
U32 result;
|
||||
DateToSeconds(&dr, &result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsImportEncodeScan::nsImportEncodeScan()
|
||||
{
|
||||
m_isAppleSingle = false;
|
||||
m_encodeScanState = 0;
|
||||
m_resourceForkSize = 0;
|
||||
m_dataForkSize = 0;
|
||||
}
|
||||
|
||||
nsImportEncodeScan::~nsImportEncodeScan()
|
||||
{
|
||||
}
|
||||
|
||||
bool nsImportEncodeScan::InitEncodeScan(bool appleSingleEncode, nsIFile *fileLoc, const char *pName, uint8_t * pBuf, uint32_t sz)
|
||||
{
|
||||
CleanUpEncodeScan();
|
||||
m_isAppleSingle = appleSingleEncode;
|
||||
m_encodeScanState = kBeginAppleSingle;
|
||||
m_pInputFile = do_QueryInterface(fileLoc);
|
||||
m_useFileName = pName;
|
||||
m_pBuf = pBuf;
|
||||
m_bufSz = sz;
|
||||
if (!m_isAppleSingle)
|
||||
{
|
||||
if (!m_inputStream)
|
||||
{
|
||||
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(m_inputStream), m_pInputFile);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
|
||||
InitScan(m_inputStream, pBuf, sz);
|
||||
}
|
||||
else {
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
// Fill in the file sizes
|
||||
m_resourceForkSize = fileLoc.GetMacFileSize(UFileLocation::eResourceFork);
|
||||
m_dataForkSize = fileLoc.GetMacFileSize(UFileLocation::eDataFork);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsImportEncodeScan::CleanUpEncodeScan(void)
|
||||
{
|
||||
m_pInputStream->Close();
|
||||
m_pInputStream = nullptr;
|
||||
m_pInputFile = nullptr;
|
||||
}
|
||||
|
||||
|
||||
// 26 + 12 per entry
|
||||
|
||||
void nsImportEncodeScan::FillInEntries(int numEntries)
|
||||
{
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
int len = m_useFileName.GetLength();
|
||||
if (len < 32)
|
||||
len = 32;
|
||||
long entry[3];
|
||||
long fileOffset = 26 + (12 * numEntries);
|
||||
entry[0] = 3;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = m_useFileName.GetLength();
|
||||
fileOffset += len;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
|
||||
|
||||
Str255 comment;
|
||||
comment[0] = 0;
|
||||
OSErr err = FSpDTGetComment(m_inputFileLoc, comment);
|
||||
if (comment[0] > 200)
|
||||
comment[0] = 200;
|
||||
entry[0] = 4;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = comment[0];
|
||||
fileOffset += 200;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
|
||||
|
||||
entry[0] = 8;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = 16;
|
||||
fileOffset += 16;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
|
||||
entry[0] = 9;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = 32;
|
||||
fileOffset += 32;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
|
||||
|
||||
entry[0] = 10;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = 4;
|
||||
fileOffset += 4;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
|
||||
if (m_resourceForkSize) {
|
||||
entry[0] = 2;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = m_resourceForkSize;
|
||||
fileOffset += m_resourceForkSize;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
}
|
||||
|
||||
if (m_dataForkSize) {
|
||||
entry[0] = 1;
|
||||
entry[1] = fileOffset;
|
||||
entry[2] = m_dataForkSize;
|
||||
fileOffset += m_dataForkSize;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
|
||||
m_bytesInBuf += 12;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool nsImportEncodeScan::AddEntries(void)
|
||||
{
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
if (!g2000Secs) {
|
||||
g2000Secs = Get2000Secs();
|
||||
gGMTDelta = GetGmtDelta();
|
||||
}
|
||||
MemCpy(m_pBuf + m_bytesInBuf, (PC_S8) m_useFileName, m_useFileName.GetLength());
|
||||
m_bytesInBuf += m_useFileName.GetLength();
|
||||
if (m_useFileName.GetLength() < 32) {
|
||||
int len = m_useFileName.GetLength();
|
||||
while (len < 32) {
|
||||
*((P_S8)m_pBuf + m_bytesInBuf) = 0;
|
||||
m_bytesInBuf++;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
Str255 comment;
|
||||
comment[0] = 0;
|
||||
OSErr err = FSpDTGetComment(m_inputFileLoc, comment);
|
||||
comment[0] = 200;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, &(comment[1]), comment[0]);
|
||||
m_bytesInBuf += comment[0];
|
||||
|
||||
long dates[4];
|
||||
dates[0] = gCatInfoPB.hFileInfo.ioFlCrDat;
|
||||
dates[1] = gCatInfoPB.hFileInfo.ioFlMdDat;
|
||||
dates[2] = gCatInfoPB.hFileInfo.ioFlBkDat;
|
||||
dates[3] = 0x80000000;
|
||||
for (short i = 0; i < 3; i++) {
|
||||
dates[i] -= g2000Secs;
|
||||
dates[i] += gGMTDelta;
|
||||
}
|
||||
MemCpy(m_pBuf + m_bytesInBuf, dates, 16);
|
||||
m_bytesInBuf += 16;
|
||||
|
||||
|
||||
FInfo fInfo = gCatInfoPB.hFileInfo.ioFlFndrInfo;
|
||||
FXInfo fxInfo = gCatInfoPB.hFileInfo.ioFlXFndrInfo;
|
||||
fInfo.fdFlags = 0;
|
||||
fInfo.fdLocation.h = 0;
|
||||
fInfo.fdLocation.v = 0;
|
||||
fInfo.fdFldr = 0;
|
||||
MemSet(&fxInfo, 0, sizeof(fxInfo));
|
||||
MemCpy(m_pBuf + m_bytesInBuf, &fInfo, 16);
|
||||
m_bytesInBuf += 16;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, &fxInfo, 16);
|
||||
m_bytesInBuf += 16;
|
||||
|
||||
|
||||
dates[0] = 0;
|
||||
if ((gCatInfoPB.hFileInfo.ioFlAttrib & 1) != 0)
|
||||
dates[0] |= 1;
|
||||
MemCpy(m_pBuf + m_bytesInBuf, dates, 4);
|
||||
m_bytesInBuf += 4;
|
||||
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsImportEncodeScan::Scan(bool *pDone)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
*pDone = false;
|
||||
if (m_isAppleSingle) {
|
||||
// Stuff the buffer with things needed to encode the file...
|
||||
// then just allow UScanFile to handle each fork, but be careful
|
||||
// when handling eof.
|
||||
switch(m_encodeScanState) {
|
||||
case kBeginAppleSingle: {
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
OSErr err = GetCatInfoNoName(m_inputFileLoc.GetVRefNum(), m_inputFileLoc.GetParID(), m_inputFileLoc.GetFileNamePtr(), &gCatInfoPB);
|
||||
if (err != noErr)
|
||||
return FALSE;
|
||||
#endif
|
||||
m_eof = false;
|
||||
m_pos = 0;
|
||||
memcpy(m_pBuf, gAppleSingleHeader, kAppleSingleHeaderSize);
|
||||
m_bytesInBuf = kAppleSingleHeaderSize;
|
||||
int numEntries = 5;
|
||||
if (m_dataForkSize)
|
||||
numEntries++;
|
||||
if (m_resourceForkSize)
|
||||
numEntries++;
|
||||
memcpy(m_pBuf + m_bytesInBuf, &numEntries, sizeof(numEntries));
|
||||
m_bytesInBuf += sizeof(numEntries);
|
||||
FillInEntries(numEntries);
|
||||
m_encodeScanState = kAddEntries;
|
||||
return ScanBuffer(pDone);
|
||||
}
|
||||
break;
|
||||
|
||||
case kBeginDataFork: {
|
||||
if (!m_dataForkSize) {
|
||||
m_encodeScanState = kDoneWithFile;
|
||||
return true;
|
||||
}
|
||||
// Initialize the scan of the data fork...
|
||||
if (!m_inputStream)
|
||||
{
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(m_inputStream), m_pInputFile);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
m_encodeScanState = kScanningDataFork;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case kScanningDataFork: {
|
||||
bool result = FillBufferFromFile();
|
||||
if (!result)
|
||||
return false;
|
||||
if (m_eof) {
|
||||
m_eof = false;
|
||||
result = ScanBuffer(pDone);
|
||||
if (!result)
|
||||
return false;
|
||||
m_inputStream->Close();
|
||||
m_inputStream = nullptr;
|
||||
m_encodeScanState = kDoneWithFile;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return ScanBuffer(pDone);
|
||||
}
|
||||
break;
|
||||
|
||||
case kScanningRsrcFork: {
|
||||
bool result = FillBufferFromFile();
|
||||
if (!result)
|
||||
return false;
|
||||
if (m_eof) {
|
||||
m_eof = false;
|
||||
result = ScanBuffer(pDone);
|
||||
if (!result)
|
||||
return false;
|
||||
m_inputStream->Close();
|
||||
m_inputStream = nullptr;
|
||||
m_encodeScanState = kBeginDataFork;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return ScanBuffer(pDone);
|
||||
}
|
||||
break;
|
||||
|
||||
case kBeginResourceFork: {
|
||||
if (!m_resourceForkSize) {
|
||||
m_encodeScanState = kBeginDataFork;
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
// FIXME: Open the resource fork on the Mac!!!
|
||||
m_fH = UFile::OpenRsrcFileRead(m_inputFileLoc);
|
||||
if (m_fH == TR_FILE_ERROR)
|
||||
return FALSE;
|
||||
*/
|
||||
m_encodeScanState = kScanningRsrcFork;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case kAddEntries: {
|
||||
ShiftBuffer();
|
||||
if (!AddEntries())
|
||||
return false;
|
||||
m_encodeScanState = kBeginResourceFork;
|
||||
return ScanBuffer(pDone);
|
||||
}
|
||||
break;
|
||||
|
||||
case kDoneWithFile: {
|
||||
ShiftBuffer();
|
||||
m_eof = true;
|
||||
if (!ScanBuffer(pDone))
|
||||
return false;
|
||||
*pDone = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
return nsImportScanFile::Scan(pDone);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
39
mailnews/import/src/nsImportEncodeScan.h
Normal file
39
mailnews/import/src/nsImportEncodeScan.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportEncodeScan_h___
|
||||
#define nsImportEncodeScan_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsImportScanFile.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
class nsImportEncodeScan : public nsImportScanFile {
|
||||
public:
|
||||
nsImportEncodeScan();
|
||||
~nsImportEncodeScan();
|
||||
|
||||
bool InitEncodeScan(bool appleSingleEncode, nsIFile *pFile, const char *pName, uint8_t * pBuf, uint32_t sz);
|
||||
void CleanUpEncodeScan(void);
|
||||
|
||||
virtual bool Scan(bool *pDone) override;
|
||||
|
||||
protected:
|
||||
void FillInEntries(int numEntries);
|
||||
bool AddEntries(void);
|
||||
|
||||
protected:
|
||||
bool m_isAppleSingle;
|
||||
nsCOMPtr<nsIFile> m_pInputFile;
|
||||
nsCOMPtr<nsIInputStream> m_inputStream;
|
||||
int m_encodeScanState;
|
||||
long m_resourceForkSize;
|
||||
long m_dataForkSize;
|
||||
nsCString m_useFileName;
|
||||
};
|
||||
|
||||
#endif /* nsImportEncodeScan_h__ */
|
||||
|
||||
384
mailnews/import/src/nsImportFieldMap.cpp
Normal file
384
mailnews/import/src/nsImportFieldMap.cpp
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsImportFieldMap.h"
|
||||
#include "nsImportStringBundle.h"
|
||||
#include "nsCRTGlue.h"
|
||||
#include "ImportDebug.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_METHOD nsImportFieldMap::Create(nsIStringBundle *aBundle, nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsImportFieldMap *it = new nsImportFieldMap(aBundle);
|
||||
if (it == nullptr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImportFieldMap, nsIImportFieldMap)
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetSkipFirstRecord(bool *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = m_skipFirstRecord;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetSkipFirstRecord(bool aResult)
|
||||
{
|
||||
m_skipFirstRecord = aResult;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsImportFieldMap::nsImportFieldMap(nsIStringBundle *aBundle)
|
||||
{
|
||||
m_numFields = 0;
|
||||
m_pFields = nullptr;
|
||||
m_pActive = nullptr;
|
||||
m_allocated = 0;
|
||||
// need to init the description array
|
||||
m_mozFieldCount = 0;
|
||||
m_skipFirstRecord = false;
|
||||
nsCOMPtr<nsIStringBundle> pBundle = aBundle;
|
||||
|
||||
nsString *pStr;
|
||||
for (int32_t i = IMPORT_FIELD_DESC_START; i <= IMPORT_FIELD_DESC_END; i++, m_mozFieldCount++) {
|
||||
pStr = new nsString();
|
||||
if (pBundle) {
|
||||
nsImportStringBundle::GetStringByID(i, pBundle, *pStr);
|
||||
}
|
||||
else
|
||||
pStr->AppendInt(i);
|
||||
m_descriptions.AppendElement(pStr);
|
||||
}
|
||||
}
|
||||
|
||||
nsImportFieldMap::~nsImportFieldMap()
|
||||
{
|
||||
if (m_pFields)
|
||||
delete [] m_pFields;
|
||||
if (m_pActive)
|
||||
delete [] m_pActive;
|
||||
|
||||
nsString * pStr;
|
||||
for (int32_t i = 0; i < m_mozFieldCount; i++) {
|
||||
pStr = m_descriptions.ElementAt(i);
|
||||
delete pStr;
|
||||
}
|
||||
m_descriptions.Clear();
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetNumMozFields(int32_t *aNumFields)
|
||||
{
|
||||
NS_PRECONDITION(aNumFields != nullptr, "null ptr");
|
||||
if (!aNumFields)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aNumFields = m_mozFieldCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetMapSize(int32_t *aNumFields)
|
||||
{
|
||||
NS_PRECONDITION(aNumFields != nullptr, "null ptr");
|
||||
if (!aNumFields)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aNumFields = m_numFields;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldDescription(int32_t index, char16_t **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*_retval = nullptr;
|
||||
if ((index < 0) || ((size_t)index >= m_descriptions.Length()))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*_retval = ToNewUnicode(*(m_descriptions.ElementAt(index)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldMapSize(int32_t size)
|
||||
{
|
||||
nsresult rv = Allocate(size);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
m_numFields = size;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::DefaultFieldMap(int32_t size)
|
||||
{
|
||||
nsresult rv = SetFieldMapSize(size);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
m_pFields[i] = i;
|
||||
m_pActive[i] = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldMap(int32_t index, int32_t *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*_retval = m_pFields[index];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldMap(int32_t index, int32_t fieldNum)
|
||||
{
|
||||
if (index == -1) {
|
||||
nsresult rv = Allocate(m_numFields + 1);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
index = m_numFields;
|
||||
m_numFields++;
|
||||
}
|
||||
else {
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if ((fieldNum != -1) && ((fieldNum < 0) || (fieldNum >= m_mozFieldCount)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
m_pFields[index] = fieldNum;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldActive(int32_t index, bool *active)
|
||||
{
|
||||
NS_PRECONDITION(active != nullptr, "null ptr");
|
||||
if (!active)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*active = m_pActive[index];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldActive(int32_t index, bool active)
|
||||
{
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
m_pActive[index] = active;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldValue(nsIAddrDatabase *database, nsIMdbRow *row, int32_t fieldNum, const char16_t *value)
|
||||
{
|
||||
NS_PRECONDITION(database != nullptr, "null ptr");
|
||||
NS_PRECONDITION(row != nullptr, "null ptr");
|
||||
NS_PRECONDITION(value != nullptr, "null ptr");
|
||||
if (!database || !row || !value)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Allow the special value for a null field
|
||||
if (fieldNum == -1)
|
||||
return NS_OK;
|
||||
|
||||
if ((fieldNum < 0) || (fieldNum >= m_mozFieldCount))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// UGGG!!!!! lot's of typing here!
|
||||
nsresult rv;
|
||||
|
||||
nsString str(value);
|
||||
char *pVal = ToNewUTF8String(str);
|
||||
|
||||
switch(fieldNum) {
|
||||
case 0:
|
||||
rv = database->AddFirstName(row, pVal);
|
||||
break;
|
||||
case 1:
|
||||
rv = database->AddLastName(row, pVal);
|
||||
break;
|
||||
case 2:
|
||||
rv = database->AddDisplayName(row, pVal);
|
||||
break;
|
||||
case 3:
|
||||
rv = database->AddNickName(row, pVal);
|
||||
break;
|
||||
case 4:
|
||||
rv = database->AddPrimaryEmail(row, pVal);
|
||||
break;
|
||||
case 5:
|
||||
rv = database->Add2ndEmail(row, pVal);
|
||||
break;
|
||||
case 6:
|
||||
rv = database->AddWorkPhone(row, pVal);
|
||||
break;
|
||||
case 7:
|
||||
rv = database->AddHomePhone(row, pVal);
|
||||
break;
|
||||
case 8:
|
||||
rv = database->AddFaxNumber(row, pVal);
|
||||
break;
|
||||
case 9:
|
||||
rv = database->AddPagerNumber(row, pVal);
|
||||
break;
|
||||
case 10:
|
||||
rv = database->AddCellularNumber(row, pVal);
|
||||
break;
|
||||
case 11:
|
||||
rv = database->AddHomeAddress(row, pVal);
|
||||
break;
|
||||
case 12:
|
||||
rv = database->AddHomeAddress2(row, pVal);
|
||||
break;
|
||||
case 13:
|
||||
rv = database->AddHomeCity(row, pVal);
|
||||
break;
|
||||
case 14:
|
||||
rv = database->AddHomeState(row, pVal);
|
||||
break;
|
||||
case 15:
|
||||
rv = database->AddHomeZipCode(row, pVal);
|
||||
break;
|
||||
case 16:
|
||||
rv = database->AddHomeCountry(row, pVal);
|
||||
break;
|
||||
case 17:
|
||||
rv = database->AddWorkAddress(row, pVal);
|
||||
break;
|
||||
case 18:
|
||||
rv = database->AddWorkAddress2(row, pVal);
|
||||
break;
|
||||
case 19:
|
||||
rv = database->AddWorkCity(row, pVal);
|
||||
break;
|
||||
case 20:
|
||||
rv = database->AddWorkState(row, pVal);
|
||||
break;
|
||||
case 21:
|
||||
rv = database->AddWorkZipCode(row, pVal);
|
||||
break;
|
||||
case 22:
|
||||
rv = database->AddWorkCountry(row, pVal);
|
||||
break;
|
||||
case 23:
|
||||
rv = database->AddJobTitle(row, pVal);
|
||||
break;
|
||||
case 24:
|
||||
rv = database->AddDepartment(row, pVal);
|
||||
break;
|
||||
case 25:
|
||||
rv = database->AddCompany(row, pVal);
|
||||
break;
|
||||
case 26:
|
||||
rv = database->AddWebPage1(row, pVal);
|
||||
break;
|
||||
case 27:
|
||||
rv = database->AddWebPage2(row, pVal);
|
||||
break;
|
||||
case 28:
|
||||
rv = database->AddBirthYear(row, pVal);
|
||||
break;
|
||||
case 29:
|
||||
rv = database->AddBirthMonth(row, pVal);
|
||||
break;
|
||||
case 30:
|
||||
rv = database->AddBirthDay(row, pVal);
|
||||
break;
|
||||
case 31:
|
||||
rv = database->AddCustom1(row, pVal);
|
||||
break;
|
||||
case 32:
|
||||
rv = database->AddCustom2(row, pVal);
|
||||
break;
|
||||
case 33:
|
||||
rv = database->AddCustom3(row, pVal);
|
||||
break;
|
||||
case 34:
|
||||
rv = database->AddCustom4(row, pVal);
|
||||
break;
|
||||
case 35:
|
||||
rv = database->AddNotes(row, pVal);
|
||||
break;
|
||||
case 36:
|
||||
rv = database->AddAimScreenName(row, pVal);
|
||||
break;
|
||||
default:
|
||||
/* Get the field description, and add it as an anonymous attr? */
|
||||
/* OR WHAT???? */
|
||||
{
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
NS_Free(pVal);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsImportFieldMap::Allocate(int32_t newSize)
|
||||
{
|
||||
if (newSize <= m_allocated)
|
||||
return NS_OK;
|
||||
|
||||
int32_t sz = m_allocated;
|
||||
while (sz < newSize)
|
||||
sz += 30;
|
||||
|
||||
int32_t *pData = new int32_t[ sz];
|
||||
if (!pData)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
bool *pActive = new bool[sz];
|
||||
if (!pActive) {
|
||||
delete [] pData;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < sz; i++) {
|
||||
pData[i] = -1;
|
||||
pActive[i] = true;
|
||||
}
|
||||
if (m_numFields) {
|
||||
for (i = 0; i < m_numFields; i++) {
|
||||
pData[i] = m_pFields[i];
|
||||
pActive[i] = m_pActive[i];
|
||||
}
|
||||
delete [] m_pFields;
|
||||
delete [] m_pActive;
|
||||
}
|
||||
m_allocated = sz;
|
||||
m_pFields = pData;
|
||||
m_pActive = pActive;
|
||||
return NS_OK;
|
||||
}
|
||||
46
mailnews/import/src/nsImportFieldMap.h
Normal file
46
mailnews/import/src/nsImportFieldMap.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportFieldMap_h___
|
||||
#define nsImportFieldMap_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsIImportFieldMap.h"
|
||||
#include "nsIAddrDatabase.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsIStringBundle;
|
||||
|
||||
class nsImportFieldMap : public nsIImportFieldMap
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
NS_DECL_NSIIMPORTFIELDMAP
|
||||
|
||||
nsImportFieldMap(nsIStringBundle *aBundle);
|
||||
|
||||
static NS_METHOD Create(nsIStringBundle *aBundle, nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
private:
|
||||
virtual ~nsImportFieldMap();
|
||||
nsresult Allocate(int32_t newSize);
|
||||
|
||||
private:
|
||||
int32_t m_numFields;
|
||||
int32_t * m_pFields;
|
||||
bool * m_pActive;
|
||||
int32_t m_allocated;
|
||||
nsTArray<nsString*> m_descriptions;
|
||||
int32_t m_mozFieldCount;
|
||||
bool m_skipFirstRecord;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
1208
mailnews/import/src/nsImportMail.cpp
Normal file
1208
mailnews/import/src/nsImportMail.cpp
Normal file
File diff suppressed because it is too large
Load diff
39
mailnews/import/src/nsImportMailboxDescriptor.cpp
Normal file
39
mailnews/import/src/nsImportMailboxDescriptor.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsImportMailboxDescriptor.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
NS_METHOD nsImportMailboxDescriptor::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsImportMailboxDescriptor *it = new nsImportMailboxDescriptor();
|
||||
if (it == nullptr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImportMailboxDescriptor, nsIImportMailboxDescriptor)
|
||||
|
||||
nsImportMailboxDescriptor::nsImportMailboxDescriptor()
|
||||
{
|
||||
m_import = true;
|
||||
m_size = 0;
|
||||
m_depth = 0;
|
||||
m_id = 0;
|
||||
m_pFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
||||
}
|
||||
63
mailnews/import/src/nsImportMailboxDescriptor.h
Normal file
63
mailnews/import/src/nsImportMailboxDescriptor.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportMailboxDescriptor_h___
|
||||
#define nsImportMailboxDescriptor_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIImportMailboxDescriptor.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class nsImportMailboxDescriptor : public nsIImportMailboxDescriptor
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetIdentifier(uint32_t *pIdentifier) override { *pIdentifier = m_id; return NS_OK;}
|
||||
NS_IMETHOD SetIdentifier(uint32_t ident) override { m_id = ident; return NS_OK;}
|
||||
|
||||
/* attribute unsigned long depth; */
|
||||
NS_IMETHOD GetDepth(uint32_t *pDepth) override { *pDepth = m_depth; return NS_OK;}
|
||||
NS_IMETHOD SetDepth(uint32_t theDepth) override { m_depth = theDepth; return NS_OK;}
|
||||
|
||||
/* attribute unsigned long size; */
|
||||
NS_IMETHOD GetSize(uint32_t *pSize) override { *pSize = m_size; return NS_OK;}
|
||||
NS_IMETHOD SetSize(uint32_t theSize) override { m_size = theSize; return NS_OK;}
|
||||
|
||||
/* attribute wstring displayName; */
|
||||
NS_IMETHOD GetDisplayName(char16_t **pName) override { *pName = ToNewUnicode(m_displayName); return NS_OK;}
|
||||
NS_IMETHOD SetDisplayName(const char16_t * pName) override { m_displayName = pName; return NS_OK;}
|
||||
|
||||
/* attribute boolean import; */
|
||||
NS_IMETHOD GetImport(bool *pImport) override { *pImport = m_import; return NS_OK;}
|
||||
NS_IMETHOD SetImport(bool doImport) override { m_import = doImport; return NS_OK;}
|
||||
|
||||
/* readonly attribute nsIFile file; */
|
||||
NS_IMETHOD GetFile(nsIFile * *aFile) override { if (m_pFile) { NS_ADDREF(*aFile = m_pFile); return NS_OK;} else return NS_ERROR_FAILURE; }
|
||||
|
||||
|
||||
|
||||
nsImportMailboxDescriptor();
|
||||
|
||||
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
private:
|
||||
virtual ~nsImportMailboxDescriptor() {}
|
||||
uint32_t m_id; // used by creator of the structure
|
||||
uint32_t m_depth; // depth in the hierarchy
|
||||
nsString m_displayName;// name of this mailbox
|
||||
nsCOMPtr <nsIFile> m_pFile; // source file (if applicable)
|
||||
uint32_t m_size;
|
||||
bool m_import; // import it or not?
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
411
mailnews/import/src/nsImportMimeEncode.cpp
Normal file
411
mailnews/import/src/nsImportMimeEncode.cpp
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsImportMimeEncode.h"
|
||||
|
||||
#include "ImportCharSet.h"
|
||||
#include "ImportTranslate.h"
|
||||
|
||||
#define kNoState 0
|
||||
#define kStartState 1
|
||||
#define kEncodeState 2
|
||||
#define kDoneState 3
|
||||
|
||||
#define kEncodeBufferSz (8192 * 8)
|
||||
|
||||
nsImportMimeEncode::nsImportMimeEncode()
|
||||
{
|
||||
m_pOut = nullptr;
|
||||
m_state = kNoState;
|
||||
m_bytesProcessed = 0;
|
||||
m_pInputBuf = nullptr;
|
||||
}
|
||||
|
||||
nsImportMimeEncode::~nsImportMimeEncode()
|
||||
{
|
||||
delete [] m_pInputBuf;
|
||||
}
|
||||
|
||||
void nsImportMimeEncode::EncodeFile(nsIFile *pInFile, ImportOutFile *pOut, const char *pFileName, const char *pMimeType)
|
||||
{
|
||||
m_fileName = pFileName;
|
||||
m_mimeType = pMimeType;
|
||||
|
||||
m_pMimeFile = pInFile;
|
||||
|
||||
m_pOut = pOut;
|
||||
m_state = kStartState;
|
||||
}
|
||||
|
||||
void nsImportMimeEncode::CleanUp(void)
|
||||
{
|
||||
CleanUpEncodeScan();
|
||||
}
|
||||
|
||||
bool nsImportMimeEncode::SetUpEncode(void)
|
||||
{
|
||||
nsCString errStr;
|
||||
if (!m_pInputBuf) {
|
||||
m_pInputBuf = new uint8_t[kEncodeBufferSz];
|
||||
}
|
||||
|
||||
m_appleSingle = false;
|
||||
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
// First let's see just what kind of beast we have?
|
||||
// For files with only a data fork and a known mime type
|
||||
// proceed with normal mime encoding just as on the PC.
|
||||
// For unknown mime types and files with both forks,
|
||||
// encode as AppleSingle format.
|
||||
if (m_filePath.GetMacFileSize(UFileLocation::eResourceFork) || !pMimeType) {
|
||||
m_appleSingle = TRUE;
|
||||
m_mimeType = "application/applefile";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!InitEncodeScan(m_appleSingle, m_pMimeFile, m_fileName.get(), m_pInputBuf, kEncodeBufferSz)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_state = kEncodeState;
|
||||
m_lineLen = 0;
|
||||
|
||||
// Write out the boundary header
|
||||
bool bResult = true;
|
||||
bResult = m_pOut->WriteStr("Content-type: ");
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr(m_mimeType.get());
|
||||
|
||||
#ifdef _MAC_IMPORT_CODE
|
||||
// include the type an creator here
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr("; x-mac-type=\"");
|
||||
U8 hex[8];
|
||||
LongToHexBytes(m_filePath.GetFileType(), hex);
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteData(hex, 8);
|
||||
LongToHexBytes(m_filePath.GetFileCreator(), hex);
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr("\"; x-mac-creator=\"");
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteData(hex, 8);
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr("\"");
|
||||
#endif
|
||||
|
||||
/*
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr(gMimeTypeFileName);
|
||||
*/
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr(";\x0D\x0A");
|
||||
|
||||
nsCString fName;
|
||||
bool trans = TranslateFileName(m_fileName, fName);
|
||||
if (bResult)
|
||||
bResult = WriteFileName(fName, trans, "name");
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr("Content-transfer-encoding: base64");
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteEol();
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteStr("Content-Disposition: attachment;\x0D\x0A");
|
||||
if (bResult)
|
||||
bResult = WriteFileName(fName, trans, "filename");
|
||||
if (bResult)
|
||||
bResult = m_pOut->WriteEol();
|
||||
|
||||
if (!bResult) {
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
bool nsImportMimeEncode::DoWork(bool *pDone)
|
||||
{
|
||||
*pDone = false;
|
||||
switch(m_state) {
|
||||
case kNoState:
|
||||
return false;
|
||||
break;
|
||||
case kStartState:
|
||||
return SetUpEncode();
|
||||
break;
|
||||
case kEncodeState:
|
||||
if (!Scan(pDone)) {
|
||||
CleanUp();
|
||||
return false;
|
||||
}
|
||||
if (*pDone) {
|
||||
*pDone = false;
|
||||
m_state = kDoneState;
|
||||
}
|
||||
break;
|
||||
case kDoneState:
|
||||
CleanUp();
|
||||
m_state = kNoState;
|
||||
*pDone = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t gBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
bool nsImportMimeEncode::ScanBuffer(bool *pDone)
|
||||
{
|
||||
|
||||
uint32_t pos = m_pos;
|
||||
uint32_t start = pos;
|
||||
uint8_t * pChar = m_pBuf + pos;
|
||||
uint32_t max = m_bytesInBuf;
|
||||
uint8_t byte[4];
|
||||
uint32_t lineLen = m_lineLen;
|
||||
|
||||
while ((pos + 2) < max) {
|
||||
// Encode 3 bytes
|
||||
byte[0] = gBase64[*pChar >> 2];
|
||||
byte[1] = gBase64[(((*pChar) & 0x3)<< 4) | (((*(pChar + 1)) & 0xF0) >> 4)];
|
||||
pChar++;
|
||||
byte[2] = gBase64[(((*pChar) & 0xF) << 2) | (((*(pChar + 1)) & 0xC0) >>6)];
|
||||
pChar++;
|
||||
byte[3] = gBase64[(*pChar) & 0x3F];
|
||||
if (!m_pOut->WriteData(byte, 4))
|
||||
return false;
|
||||
pos += 3;
|
||||
pChar++;
|
||||
lineLen += 4;
|
||||
if (lineLen > 71) {
|
||||
if (!m_pOut->WriteEol())
|
||||
return false;
|
||||
lineLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pos < max) && m_eof) {
|
||||
// Get the last few bytes!
|
||||
byte[0] = gBase64[*pChar >> 2];
|
||||
pos++;
|
||||
if (pos < max) {
|
||||
byte[1] = gBase64[(((*pChar) & 0x3)<< 4) | (((*(pChar + 1)) & 0xF0) >> 4)];
|
||||
pChar++;
|
||||
pos++;
|
||||
if (pos < max) {
|
||||
// Should be dead code!! (Then why is it here doofus?)
|
||||
byte[2] = gBase64[(((*pChar) & 0xF) << 2) | (((*(pChar + 1)) & 0xC0) >>6)];
|
||||
pChar++;
|
||||
byte[3] = gBase64[(*pChar) & 0x3F];
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
byte[2] = gBase64[(((*pChar) & 0xF) << 2)];
|
||||
byte[3] = '=';
|
||||
}
|
||||
}
|
||||
else {
|
||||
byte[1] = gBase64[(((*pChar) & 0x3)<< 4)];
|
||||
byte[2] = '=';
|
||||
byte[3] = '=';
|
||||
}
|
||||
|
||||
if (!m_pOut->WriteData(byte, 4))
|
||||
return false;
|
||||
if (!m_pOut->WriteEol())
|
||||
return false;
|
||||
}
|
||||
else if (m_eof) {
|
||||
/*
|
||||
byte[0] = '=';
|
||||
if (!m_pOut->WriteData(byte, 1))
|
||||
return FALSE;
|
||||
*/
|
||||
if (!m_pOut->WriteEol())
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lineLen = (int) lineLen;
|
||||
m_pos = pos;
|
||||
m_bytesProcessed += (pos - start);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsImportMimeEncode::TranslateFileName(nsCString& inFile, nsCString& outFile)
|
||||
{
|
||||
const uint8_t * pIn = (const uint8_t *) inFile.get();
|
||||
int len = inFile.Length();
|
||||
|
||||
while (len) {
|
||||
if (!ImportCharSet::IsUSAscii(*pIn))
|
||||
break;
|
||||
len--;
|
||||
pIn++;
|
||||
}
|
||||
if (len) {
|
||||
// non US ascii!
|
||||
// assume this string needs translating...
|
||||
if (!ImportTranslate::ConvertString(inFile, outFile, true)) {
|
||||
outFile = inFile;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
outFile = inFile;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool nsImportMimeEncode::WriteFileName(nsCString& fName, bool wasTrans, const char *pTag)
|
||||
{
|
||||
int tagNum = 0;
|
||||
int idx = 0;
|
||||
bool result = true;
|
||||
int len;
|
||||
nsCString numStr;
|
||||
|
||||
while ((((fName.Length() - idx) + strlen(pTag)) > 70) && result) {
|
||||
len = 68 - strlen(pTag) - 5;
|
||||
if (wasTrans) {
|
||||
if (fName.CharAt(idx + len - 1) == '%')
|
||||
len--;
|
||||
else if (fName.CharAt(idx + len - 2) == '%')
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (result)
|
||||
result = m_pOut->WriteStr("\x09");
|
||||
if (result)
|
||||
result = m_pOut->WriteStr(pTag);
|
||||
numStr = "*";
|
||||
numStr.AppendInt(tagNum);
|
||||
if (result)
|
||||
result = m_pOut->WriteStr(numStr.get());
|
||||
if (wasTrans && result)
|
||||
result = m_pOut->WriteStr("*=");
|
||||
else if (result)
|
||||
result = m_pOut->WriteStr("=\"");
|
||||
if (result)
|
||||
result = m_pOut->WriteData(((const uint8_t *)fName.get()) + idx, len);
|
||||
if (wasTrans && result)
|
||||
result = m_pOut->WriteStr("\x0D\x0A");
|
||||
else if (result)
|
||||
result = m_pOut->WriteStr("\"\x0D\x0A");
|
||||
idx += len;
|
||||
tagNum++;
|
||||
}
|
||||
|
||||
if (idx) {
|
||||
if ((fName.Length() - idx) > 0) {
|
||||
if (result)
|
||||
result = m_pOut->WriteStr("\x09");
|
||||
if (result)
|
||||
result = m_pOut->WriteStr(pTag);
|
||||
numStr = "*";
|
||||
numStr.AppendInt(tagNum);
|
||||
if (result)
|
||||
result = m_pOut->WriteStr(numStr.get());
|
||||
if (wasTrans && result)
|
||||
result = m_pOut->WriteStr("*=");
|
||||
else if (result)
|
||||
result = m_pOut->WriteStr("=\"");
|
||||
if (result)
|
||||
result = m_pOut->WriteData(((const uint8_t *)fName.get()) + idx, fName.Length() - idx);
|
||||
if (wasTrans && result)
|
||||
result = m_pOut->WriteStr("\x0D\x0A");
|
||||
else if (result)
|
||||
result = m_pOut->WriteStr("\"\x0D\x0A");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (result)
|
||||
result = m_pOut->WriteStr("\x09");
|
||||
if (result)
|
||||
result = m_pOut->WriteStr(pTag);
|
||||
if (wasTrans && result)
|
||||
result = m_pOut->WriteStr("*=");
|
||||
else if (result)
|
||||
result = m_pOut->WriteStr("=\"");
|
||||
if (result)
|
||||
result = m_pOut->WriteStr(fName.get());
|
||||
if (wasTrans && result)
|
||||
result = m_pOut->WriteStr("\x0D\x0A");
|
||||
else if (result)
|
||||
result = m_pOut->WriteStr("\"\x0D\x0A");
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
nsIImportMimeEncodeImpl::nsIImportMimeEncodeImpl()
|
||||
{
|
||||
m_pOut = nullptr;
|
||||
m_pEncode = nullptr;
|
||||
}
|
||||
|
||||
nsIImportMimeEncodeImpl::~nsIImportMimeEncodeImpl()
|
||||
{
|
||||
if (m_pOut)
|
||||
delete m_pOut;
|
||||
if (m_pEncode)
|
||||
delete m_pEncode;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsIImportMimeEncodeImpl, nsIImportMimeEncode)
|
||||
|
||||
NS_METHOD nsIImportMimeEncodeImpl::EncodeFile(nsIFile *inFile, nsIFile *outFile, const char *fileName, const char *mimeType)
|
||||
{
|
||||
return Initialize(inFile, outFile, fileName, mimeType);
|
||||
}
|
||||
|
||||
NS_METHOD nsIImportMimeEncodeImpl::DoWork(bool *done, bool *_retval)
|
||||
{
|
||||
if (done && _retval && m_pEncode) {
|
||||
*_retval = m_pEncode->DoWork(done);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD nsIImportMimeEncodeImpl::NumBytesProcessed(int32_t *_retval)
|
||||
{
|
||||
if (m_pEncode && _retval)
|
||||
*_retval = m_pEncode->NumBytesProcessed();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsIImportMimeEncodeImpl::DoEncoding(bool *_retval)
|
||||
{
|
||||
if (_retval && m_pEncode) {
|
||||
bool done = false;
|
||||
while (m_pEncode->DoWork(&done) && !done);
|
||||
*_retval = done;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD nsIImportMimeEncodeImpl::Initialize(nsIFile *inFile, nsIFile *outFile, const char *fileName, const char *mimeType)
|
||||
{
|
||||
delete m_pEncode;
|
||||
delete m_pOut;
|
||||
|
||||
m_pOut = new ImportOutFile();
|
||||
m_pOut->InitOutFile(outFile);
|
||||
|
||||
m_pEncode = new nsImportMimeEncode();
|
||||
m_pEncode->EncodeFile(inFile, m_pOut, fileName, mimeType);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
73
mailnews/import/src/nsImportMimeEncode.h
Normal file
73
mailnews/import/src/nsImportMimeEncode.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
#ifndef nsImportMimeEncode_h__
|
||||
#define nsImportMimeEncode_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsImportScanFile.h"
|
||||
#include "ImportOutFile.h"
|
||||
#include "nsImportEncodeScan.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIImportMimeEncode.h"
|
||||
|
||||
|
||||
// Content-Type: image/gif; name="blah.xyz"
|
||||
// Content-Transfer-Encoding: base64
|
||||
// Content-Disposition: attachment; filename="blah.xyz"
|
||||
|
||||
class nsImportMimeEncode : public nsImportEncodeScan {
|
||||
public:
|
||||
nsImportMimeEncode();
|
||||
~nsImportMimeEncode();
|
||||
|
||||
void EncodeFile(nsIFile *pInFile, ImportOutFile *pOut, const char *pFileName, const char *pMimeType);
|
||||
|
||||
bool DoWork(bool *pDone);
|
||||
|
||||
long NumBytesProcessed(void) { long val = m_bytesProcessed; m_bytesProcessed = 0; return val;}
|
||||
|
||||
protected:
|
||||
void CleanUp(void);
|
||||
bool SetUpEncode(void);
|
||||
bool WriteFileName(nsCString& fName, bool wasTrans, const char *pTag);
|
||||
bool TranslateFileName(nsCString& inFile, nsCString& outFile);
|
||||
|
||||
|
||||
virtual bool ScanBuffer(bool *pDone) override;
|
||||
|
||||
|
||||
protected:
|
||||
nsCString m_fileName;
|
||||
nsCOMPtr <nsIFile> m_pMimeFile;
|
||||
ImportOutFile * m_pOut;
|
||||
nsCString m_mimeType;
|
||||
|
||||
int m_state;
|
||||
long m_bytesProcessed;
|
||||
uint8_t * m_pInputBuf;
|
||||
bool m_appleSingle;
|
||||
|
||||
// Actual encoding variables
|
||||
int m_lineLen;
|
||||
};
|
||||
|
||||
|
||||
class nsIImportMimeEncodeImpl : public nsIImportMimeEncode {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_DECL_NSIIMPORTMIMEENCODE
|
||||
|
||||
nsIImportMimeEncodeImpl();
|
||||
|
||||
private:
|
||||
virtual ~nsIImportMimeEncodeImpl();
|
||||
ImportOutFile * m_pOut;
|
||||
nsImportMimeEncode * m_pEncode;
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsImportMimeEncode_h__ */
|
||||
|
||||
172
mailnews/import/src/nsImportScanFile.cpp
Normal file
172
mailnews/import/src/nsImportScanFile.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nscore.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsImportScanFile.h"
|
||||
#include "ImportCharSet.h"
|
||||
|
||||
nsImportScanFile::nsImportScanFile()
|
||||
{
|
||||
m_allocated = false;
|
||||
m_eof = false;
|
||||
m_pBuf = nullptr;
|
||||
}
|
||||
|
||||
nsImportScanFile::~nsImportScanFile()
|
||||
{
|
||||
if (m_allocated)
|
||||
CleanUpScan();
|
||||
}
|
||||
|
||||
void nsImportScanFile::InitScan(nsIInputStream *pInputStream, uint8_t * pBuf, uint32_t sz)
|
||||
{
|
||||
m_pInputStream = pInputStream;
|
||||
m_pBuf = pBuf;
|
||||
m_bufSz = sz;
|
||||
m_bytesInBuf = 0;
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
void nsImportScanFile::CleanUpScan(void)
|
||||
{
|
||||
m_pInputStream = nullptr;
|
||||
if (m_allocated) {
|
||||
delete [] m_pBuf;
|
||||
m_pBuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void nsImportScanFile::ShiftBuffer(void)
|
||||
{
|
||||
uint8_t * pTop;
|
||||
uint8_t * pCurrent;
|
||||
|
||||
if (m_pos < m_bytesInBuf) {
|
||||
pTop = m_pBuf;
|
||||
pCurrent = pTop + m_pos;
|
||||
uint32_t cnt = m_bytesInBuf - m_pos;
|
||||
while (cnt) {
|
||||
*pTop = *pCurrent;
|
||||
pTop++; pCurrent++;
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
m_bytesInBuf -= m_pos;
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
bool nsImportScanFile::FillBufferFromFile(void)
|
||||
{
|
||||
uint64_t available;
|
||||
nsresult rv = m_pInputStream->Available(&available);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
// Fill up a buffer and scan it
|
||||
ShiftBuffer();
|
||||
|
||||
// Read in some more bytes
|
||||
uint32_t cnt = m_bufSz - m_bytesInBuf;
|
||||
// To distinguish from disk errors
|
||||
// Check first for end of file?
|
||||
// Set a done flag if true...
|
||||
uint32_t read;
|
||||
char *pBuf = (char *)m_pBuf;
|
||||
pBuf += m_bytesInBuf;
|
||||
rv = m_pInputStream->Read(pBuf, (int32_t) cnt, &read);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
rv = m_pInputStream->Available(&available);
|
||||
if (NS_FAILED(rv))
|
||||
m_eof = true;
|
||||
|
||||
m_bytesInBuf += cnt;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsImportScanFile::Scan(bool *pDone)
|
||||
{
|
||||
uint64_t available;
|
||||
nsresult rv = m_pInputStream->Available(&available);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
if (m_pos < m_bytesInBuf)
|
||||
ScanBuffer(pDone);
|
||||
*pDone = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill up a buffer and scan it
|
||||
if (!FillBufferFromFile())
|
||||
return false;
|
||||
|
||||
return ScanBuffer(pDone);
|
||||
}
|
||||
|
||||
bool nsImportScanFile::ScanBuffer(bool *)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool nsImportScanFileLines::ScanBuffer(bool *pDone)
|
||||
{
|
||||
// m_pos, m_bytesInBuf, m_eof, m_pBuf are relevant
|
||||
|
||||
uint32_t pos = m_pos;
|
||||
uint32_t max = m_bytesInBuf;
|
||||
uint8_t * pChar = m_pBuf + pos;
|
||||
uint32_t startPos;
|
||||
|
||||
while (pos < max) {
|
||||
if (m_needEol) {
|
||||
// Find the next eol...
|
||||
while ((pos < max) && (*pChar != ImportCharSet::cCRChar) && (*pChar != ImportCharSet::cLinefeedChar)) {
|
||||
pos++;
|
||||
pChar++;
|
||||
}
|
||||
m_pos = pos;
|
||||
if (pos < max)
|
||||
m_needEol = false;
|
||||
if (pos == max) // need more buffer for an end of line
|
||||
break;
|
||||
}
|
||||
// Skip past any eol characters
|
||||
while ((pos < max) && ((*pChar == ImportCharSet::cCRChar) || (*pChar == ImportCharSet::cLinefeedChar))) {
|
||||
pos++;
|
||||
pChar++;
|
||||
}
|
||||
m_pos = pos;
|
||||
if (pos == max)
|
||||
break;
|
||||
// Make sure we can find either the eof or the
|
||||
// next end of line
|
||||
startPos = pos;
|
||||
while ((pos < max) && (*pChar != ImportCharSet::cCRChar) && (*pChar != ImportCharSet::cLinefeedChar)) {
|
||||
pos++;
|
||||
pChar++;
|
||||
}
|
||||
|
||||
// Is line too big for our buffer?
|
||||
if ((pos == max) && !m_eof) {
|
||||
if (!m_pos) { // line too big for our buffer
|
||||
m_pos = pos;
|
||||
m_needEol = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ProcessLine(m_pBuf + startPos, pos - startPos, pDone)) {
|
||||
return false;
|
||||
}
|
||||
m_pos = pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
54
mailnews/import/src/nsImportScanFile.h
Normal file
54
mailnews/import/src/nsImportScanFile.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportScanFile_h__
|
||||
#define nsImportScanFile_h__
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
class nsImportScanFile {
|
||||
public:
|
||||
nsImportScanFile();
|
||||
virtual ~nsImportScanFile();
|
||||
|
||||
void InitScan(nsIInputStream *pInputStream, uint8_t * pBuf, uint32_t sz);
|
||||
|
||||
void CleanUpScan(void);
|
||||
|
||||
virtual bool Scan(bool *pDone);
|
||||
|
||||
protected:
|
||||
void ShiftBuffer(void);
|
||||
bool FillBufferFromFile(void);
|
||||
virtual bool ScanBuffer(bool *pDone);
|
||||
|
||||
protected:
|
||||
nsCOMPtr <nsIInputStream> m_pInputStream;
|
||||
uint8_t * m_pBuf;
|
||||
uint32_t m_bufSz;
|
||||
uint32_t m_bytesInBuf;
|
||||
uint32_t m_pos;
|
||||
bool m_eof;
|
||||
bool m_allocated;
|
||||
};
|
||||
|
||||
class nsImportScanFileLines : public nsImportScanFile {
|
||||
public:
|
||||
nsImportScanFileLines() {m_needEol = false;}
|
||||
|
||||
void ResetLineScan(void) { m_needEol = false;}
|
||||
|
||||
virtual bool ProcessLine(uint8_t * /* pLine */, uint32_t /* len */, bool * /* pDone */) {return true;}
|
||||
|
||||
protected:
|
||||
virtual bool ScanBuffer(bool *pDone) override;
|
||||
|
||||
bool m_needEol;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsImportScanFile_h__ */
|
||||
583
mailnews/import/src/nsImportService.cpp
Normal file
583
mailnews/import/src/nsImportService.cpp
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsICharsetConverterManager.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIImportModule.h"
|
||||
#include "nsIImportService.h"
|
||||
#include "nsImportMailboxDescriptor.h"
|
||||
#include "nsImportABDescriptor.h"
|
||||
#include "nsIImportGeneric.h"
|
||||
#include "nsImportFieldMap.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "plstr.h"
|
||||
#include "prmem.h"
|
||||
#include "nsMsgCompCID.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "ImportDebug.h"
|
||||
#include "nsImportService.h"
|
||||
#include "nsImportStringBundle.h"
|
||||
#include "nsCRTGlue.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsIMsgSend.h"
|
||||
#include "nsMsgUtils.h"
|
||||
|
||||
PRLogModuleInfo *IMPORTLOGMODULE = nullptr;
|
||||
|
||||
static nsIImportService * gImportService = nullptr;
|
||||
static const char * kWhitespace = "\b\t\r\n ";
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
nsImportService::nsImportService() : m_pModules(nullptr)
|
||||
{
|
||||
// Init logging module.
|
||||
if (!IMPORTLOGMODULE)
|
||||
IMPORTLOGMODULE = PR_NewLogModule("IMPORT");
|
||||
IMPORT_LOG0("* nsImport Service Created\n");
|
||||
|
||||
m_didDiscovery = false;
|
||||
m_pDecoder = nullptr;
|
||||
m_pEncoder = nullptr;
|
||||
|
||||
nsresult rv = nsImportStringBundle::GetStringBundle(IMPORT_MSGS_URL, getter_AddRefs(m_stringBundle));
|
||||
if (NS_FAILED(rv))
|
||||
IMPORT_LOG0("Failed to get string bundle for Importing Mail");
|
||||
}
|
||||
|
||||
|
||||
nsImportService::~nsImportService()
|
||||
{
|
||||
NS_IF_RELEASE(m_pDecoder);
|
||||
NS_IF_RELEASE(m_pEncoder);
|
||||
|
||||
gImportService = nullptr;
|
||||
|
||||
if (m_pModules != nullptr)
|
||||
delete m_pModules;
|
||||
|
||||
IMPORT_LOG0("* nsImport Service Deleted\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsImportService, nsIImportService)
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportService::DiscoverModules(void)
|
||||
{
|
||||
m_didDiscovery = false;
|
||||
return DoDiscover();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::CreateNewFieldMap(nsIImportFieldMap **_retval)
|
||||
{
|
||||
return nsImportFieldMap::Create(m_stringBundle, nullptr, NS_GET_IID(nsIImportFieldMap), (void**)_retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::CreateNewMailboxDescriptor(nsIImportMailboxDescriptor **_retval)
|
||||
{
|
||||
return nsImportMailboxDescriptor::Create(nullptr, NS_GET_IID(nsIImportMailboxDescriptor), (void**)_retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::CreateNewABDescriptor(nsIImportABDescriptor **_retval)
|
||||
{
|
||||
return nsImportABDescriptor::Create(nullptr, NS_GET_IID(nsIImportABDescriptor), (void**)_retval);
|
||||
}
|
||||
|
||||
extern nsresult NS_NewGenericMail(nsIImportGeneric** aImportGeneric);
|
||||
|
||||
NS_IMETHODIMP nsImportService::CreateNewGenericMail(nsIImportGeneric **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (! _retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return NS_NewGenericMail(_retval);
|
||||
}
|
||||
|
||||
extern nsresult NS_NewGenericAddressBooks(nsIImportGeneric** aImportGeneric);
|
||||
|
||||
NS_IMETHODIMP nsImportService::CreateNewGenericAddressBooks(nsIImportGeneric **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (! _retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return NS_NewGenericAddressBooks(_retval);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportService::GetModuleCount(const char *filter, int32_t *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (! _retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
DoDiscover();
|
||||
|
||||
if (m_pModules != nullptr) {
|
||||
ImportModuleDesc * pDesc;
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
|
||||
pDesc = m_pModules->GetModuleDesc(i);
|
||||
if (pDesc->SupportsThings(filter))
|
||||
count++;
|
||||
}
|
||||
*_retval = count;
|
||||
}
|
||||
else
|
||||
*_retval = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::GetModuleWithCID(const nsCID& cid, nsIImportModule **ppModule)
|
||||
{
|
||||
NS_PRECONDITION(ppModule != nullptr, "null ptr");
|
||||
if (!ppModule)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*ppModule = nullptr;
|
||||
nsresult rv = DoDiscover();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (m_pModules == nullptr)
|
||||
return NS_ERROR_FAILURE;
|
||||
int32_t cnt = m_pModules->GetCount();
|
||||
ImportModuleDesc *pDesc;
|
||||
for (int32_t i = 0; i < cnt; i++) {
|
||||
pDesc = m_pModules->GetModuleDesc(i);
|
||||
if (!pDesc)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (pDesc->GetCID().Equals(cid)) {
|
||||
*ppModule = pDesc->GetModule();
|
||||
|
||||
IMPORT_LOG0("* nsImportService::GetSpecificModule - attempted to load module\n");
|
||||
|
||||
if (*ppModule == nullptr)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
IMPORT_LOG0("* nsImportService::GetSpecificModule - module not found\n");
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::GetModuleInfo(const char *filter, int32_t index, char16_t **name, char16_t **moduleDescription)
|
||||
{
|
||||
NS_PRECONDITION(name != nullptr, "null ptr");
|
||||
NS_PRECONDITION(moduleDescription != nullptr, "null ptr");
|
||||
if (!name || !moduleDescription)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*name = nullptr;
|
||||
*moduleDescription = nullptr;
|
||||
|
||||
DoDiscover();
|
||||
if (!m_pModules)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if ((index < 0) || (index >= m_pModules->GetCount()))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ImportModuleDesc * pDesc;
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
|
||||
pDesc = m_pModules->GetModuleDesc(i);
|
||||
if (pDesc->SupportsThings(filter)) {
|
||||
if (count == index) {
|
||||
*name = NS_strdup(pDesc->GetName());
|
||||
*moduleDescription = NS_strdup(pDesc->GetDescription());
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::GetModuleName(const char *filter, int32_t index, char16_t **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*_retval = nullptr;
|
||||
|
||||
DoDiscover();
|
||||
if (!m_pModules)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if ((index < 0) || (index >= m_pModules->GetCount()))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ImportModuleDesc * pDesc;
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
|
||||
pDesc = m_pModules->GetModuleDesc(i);
|
||||
if (pDesc->SupportsThings(filter)) {
|
||||
if (count == index) {
|
||||
*_retval = NS_strdup(pDesc->GetName());
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportService::GetModuleDescription(const char *filter, int32_t index, char16_t **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*_retval = nullptr;
|
||||
|
||||
DoDiscover();
|
||||
if (!m_pModules)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if ((index < 0) || (index >= m_pModules->GetCount()))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ImportModuleDesc * pDesc;
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
|
||||
pDesc = m_pModules->GetModuleDesc(i);
|
||||
if (pDesc->SupportsThings(filter)) {
|
||||
if (count == index) {
|
||||
*_retval = NS_strdup(pDesc->GetDescription());
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
class nsProxySendRunnable : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
nsProxySendRunnable(nsIMsgIdentity *aIdentity,
|
||||
nsIMsgCompFields *aMsgFields,
|
||||
const char *attachment1_type,
|
||||
const nsACString &attachment1_body,
|
||||
bool aIsDraft,
|
||||
nsIArray *aLoadedAttachments,
|
||||
nsIArray *aEmbeddedAttachments,
|
||||
nsIMsgSendListener *aListener);
|
||||
NS_DECL_NSIRUNNABLE
|
||||
private:
|
||||
nsCOMPtr<nsIMsgIdentity> m_identity;
|
||||
nsCOMPtr<nsIMsgCompFields> m_compFields;
|
||||
bool m_isDraft;
|
||||
nsCString m_bodyType;
|
||||
nsCString m_body;
|
||||
nsCOMPtr<nsIArray> m_loadedAttachments;
|
||||
nsCOMPtr<nsIArray> m_embeddedAttachments;
|
||||
nsCOMPtr<nsIMsgSendListener> m_listener;
|
||||
|
||||
};
|
||||
|
||||
nsProxySendRunnable::nsProxySendRunnable(nsIMsgIdentity *aIdentity,
|
||||
nsIMsgCompFields *aMsgFields,
|
||||
const char *aBodyType,
|
||||
const nsACString &aBody,
|
||||
bool aIsDraft,
|
||||
nsIArray *aLoadedAttachments,
|
||||
nsIArray *aEmbeddedAttachments,
|
||||
nsIMsgSendListener *aListener) :
|
||||
m_identity(aIdentity), m_compFields(aMsgFields),
|
||||
m_isDraft(aIsDraft), m_bodyType(aBodyType),
|
||||
m_body(aBody), m_loadedAttachments(aLoadedAttachments),
|
||||
m_embeddedAttachments(aEmbeddedAttachments),
|
||||
m_listener(aListener)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsProxySendRunnable::Run()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMsgSend> msgSend = do_CreateInstance(NS_MSGSEND_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return msgSend->CreateRFC822Message(m_identity, m_compFields,
|
||||
m_bodyType.get(), m_body,
|
||||
m_isDraft, m_loadedAttachments,
|
||||
m_embeddedAttachments,
|
||||
m_listener);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImportService::CreateRFC822Message(nsIMsgIdentity *aIdentity,
|
||||
nsIMsgCompFields *aMsgFields,
|
||||
const char *aBodyType,
|
||||
const nsACString &aBody,
|
||||
bool aIsDraft,
|
||||
nsIArray *aLoadedAttachments,
|
||||
nsIArray *aEmbeddedAttachments,
|
||||
nsIMsgSendListener *aListener)
|
||||
{
|
||||
RefPtr<nsProxySendRunnable> runnable =
|
||||
new nsProxySendRunnable(aIdentity,
|
||||
aMsgFields,
|
||||
aBodyType,
|
||||
aBody,
|
||||
aIsDraft,
|
||||
aLoadedAttachments,
|
||||
aEmbeddedAttachments,
|
||||
aListener);
|
||||
// invoke the callback
|
||||
return NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportService::GetModule(const char *filter, int32_t index, nsIImportModule **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nullptr, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*_retval = nullptr;
|
||||
|
||||
DoDiscover();
|
||||
if (!m_pModules)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if ((index < 0) || (index >= m_pModules->GetCount()))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ImportModuleDesc * pDesc;
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
|
||||
pDesc = m_pModules->GetModuleDesc(i);
|
||||
if (pDesc->SupportsThings(filter)) {
|
||||
if (count == index) {
|
||||
*_retval = pDesc->GetModule();
|
||||
break;
|
||||
}
|
||||
else
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (! (*_retval))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsImportService::DoDiscover(void)
|
||||
{
|
||||
if (m_didDiscovery)
|
||||
return NS_OK;
|
||||
|
||||
if (m_pModules != nullptr)
|
||||
m_pModules->ClearList();
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
rv = catMan->EnumerateCategory("mailnewsimport", getter_AddRefs(e));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsCOMPtr<nsISupportsCString> contractid;
|
||||
rv = e->GetNext(getter_AddRefs(supports));
|
||||
while (NS_SUCCEEDED(rv) && supports)
|
||||
{
|
||||
contractid = do_QueryInterface(supports);
|
||||
if (!contractid)
|
||||
break;
|
||||
|
||||
nsCString contractIdStr;
|
||||
contractid->ToString(getter_Copies(contractIdStr));
|
||||
nsCString supportsStr;
|
||||
rv = catMan->GetCategoryEntry("mailnewsimport", contractIdStr.get(), getter_Copies(supportsStr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
LoadModuleInfo(contractIdStr.get(), supportsStr.get());
|
||||
rv = e->GetNext(getter_AddRefs(supports));
|
||||
}
|
||||
|
||||
m_didDiscovery = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsImportService::LoadModuleInfo(const char *pClsId, const char *pSupports)
|
||||
{
|
||||
if (!pClsId || !pSupports)
|
||||
return NS_OK;
|
||||
|
||||
if (m_pModules == nullptr)
|
||||
m_pModules = new nsImportModuleList();
|
||||
|
||||
// load the component and get all of the info we need from it....
|
||||
// then call AddModule
|
||||
nsresult rv;
|
||||
|
||||
nsCID clsId;
|
||||
clsId.Parse(pClsId);
|
||||
nsIImportModule * module;
|
||||
rv = CallCreateInstance(clsId, &module);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsString theTitle;
|
||||
nsString theDescription;
|
||||
rv = module->GetName(getter_Copies(theTitle));
|
||||
if (NS_FAILED(rv))
|
||||
theTitle.AssignLiteral("Unknown");
|
||||
|
||||
rv = module->GetDescription(getter_Copies(theDescription));
|
||||
if (NS_FAILED(rv))
|
||||
theDescription.AssignLiteral("Unknown description");
|
||||
|
||||
// call the module to get the info we need
|
||||
m_pModules->AddModule(clsId, pSupports, theTitle.get(), theDescription.get());
|
||||
|
||||
module->Release();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsIImportModule *ImportModuleDesc::GetModule(bool keepLoaded)
|
||||
{
|
||||
if (m_pModule)
|
||||
{
|
||||
m_pModule->AddRef();
|
||||
return m_pModule;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
rv = CallCreateInstance(m_cid, &m_pModule);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
m_pModule = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (keepLoaded)
|
||||
{
|
||||
m_pModule->AddRef();
|
||||
return m_pModule;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIImportModule *pModule = m_pModule;
|
||||
m_pModule = nullptr;
|
||||
return pModule;
|
||||
}
|
||||
}
|
||||
|
||||
void ImportModuleDesc::ReleaseModule(void)
|
||||
{
|
||||
if (m_pModule)
|
||||
{
|
||||
m_pModule->Release();
|
||||
m_pModule = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImportModuleDesc::SupportsThings(const char *pThings)
|
||||
{
|
||||
if (!pThings || !*pThings)
|
||||
return true;
|
||||
|
||||
nsCString thing(pThings);
|
||||
nsCString item;
|
||||
int32_t idx;
|
||||
|
||||
while ((idx = thing.FindChar(',')) != -1)
|
||||
{
|
||||
item = StringHead(thing, idx);
|
||||
item.Trim(kWhitespace);
|
||||
ToLowerCase(item);
|
||||
if (item.Length() && (m_supports.Find(item) == -1))
|
||||
return false;
|
||||
thing = Substring(thing, idx + 1);
|
||||
}
|
||||
thing.Trim(kWhitespace);
|
||||
ToLowerCase(thing);
|
||||
return thing.IsEmpty() || (m_supports.Find(thing) != -1);
|
||||
}
|
||||
|
||||
void nsImportModuleList::ClearList(void)
|
||||
{
|
||||
if (m_pList)
|
||||
{
|
||||
for (int i = 0; i < m_count; i++)
|
||||
{
|
||||
delete m_pList[i];
|
||||
m_pList[i] = nullptr;
|
||||
}
|
||||
m_count = 0;
|
||||
delete [] m_pList;
|
||||
m_pList = nullptr;
|
||||
m_alloc = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void nsImportModuleList::AddModule(const nsCID& cid, const char *pSupports, const char16_t *pName, const char16_t *pDesc)
|
||||
{
|
||||
if (!m_pList)
|
||||
{
|
||||
m_alloc = 10;
|
||||
m_pList = new ImportModuleDesc *[m_alloc];
|
||||
m_count = 0;
|
||||
memset(m_pList, 0, sizeof(ImportModuleDesc *) * m_alloc);
|
||||
}
|
||||
|
||||
if (m_count == m_alloc)
|
||||
{
|
||||
ImportModuleDesc **pList = new ImportModuleDesc *[m_alloc + 10];
|
||||
memset(&(pList[m_alloc]), 0, sizeof(ImportModuleDesc *) * 10);
|
||||
memcpy(pList, m_pList, sizeof(ImportModuleDesc *) * m_alloc);
|
||||
for(int i = 0; i < m_count; i++)
|
||||
delete m_pList[i];
|
||||
delete [] m_pList;
|
||||
m_pList = pList;
|
||||
m_alloc += 10;
|
||||
}
|
||||
|
||||
m_pList[m_count] = new ImportModuleDesc();
|
||||
m_pList[m_count]->SetCID(cid);
|
||||
m_pList[m_count]->SetSupports(pSupports);
|
||||
m_pList[m_count]->SetName(pName);
|
||||
m_pList[m_count]->SetDescription(pDesc);
|
||||
|
||||
m_count++;
|
||||
#ifdef IMPORT_DEBUG
|
||||
IMPORT_LOG3("* nsImportService registered import module: %s, %s, %s\n", NS_LossyConvertUTF16toASCII(pName).get(), NS_LossyConvertUTF16toASCII(pDesc).get(), pSupports);
|
||||
#endif
|
||||
}
|
||||
|
||||
96
mailnews/import/src/nsImportService.h
Normal file
96
mailnews/import/src/nsImportService.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportService_h__
|
||||
#define nsImportService_h__
|
||||
|
||||
#include "nsICharsetConverterManager.h"
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIImportModule.h"
|
||||
#include "nsIImportService.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIStringBundle.h"
|
||||
|
||||
class nsImportModuleList;
|
||||
|
||||
class nsImportService : public nsIImportService
|
||||
{
|
||||
public:
|
||||
|
||||
nsImportService();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
NS_DECL_NSIIMPORTSERVICE
|
||||
|
||||
private:
|
||||
virtual ~nsImportService();
|
||||
nsresult LoadModuleInfo(const char*pClsId, const char *pSupports);
|
||||
nsresult DoDiscover(void);
|
||||
|
||||
private:
|
||||
nsImportModuleList * m_pModules;
|
||||
bool m_didDiscovery;
|
||||
nsCString m_sysCharset;
|
||||
nsIUnicodeDecoder * m_pDecoder;
|
||||
nsIUnicodeEncoder * m_pEncoder;
|
||||
nsCOMPtr<nsIStringBundle> m_stringBundle;
|
||||
};
|
||||
|
||||
class ImportModuleDesc {
|
||||
public:
|
||||
ImportModuleDesc() { m_pModule = nullptr;}
|
||||
~ImportModuleDesc() { ReleaseModule(); }
|
||||
|
||||
void SetCID(const nsCID& cid) { m_cid = cid;}
|
||||
void SetName(const char16_t *pName) { m_name = pName;}
|
||||
void SetDescription(const char16_t *pDesc) { m_description = pDesc;}
|
||||
void SetSupports(const char *pSupports) { m_supports = pSupports;}
|
||||
|
||||
nsCID GetCID(void) { return m_cid;}
|
||||
const char16_t *GetName(void) { return m_name.get();}
|
||||
const char16_t *GetDescription(void) { return m_description.get();}
|
||||
const char * GetSupports(void) { return m_supports.get();}
|
||||
|
||||
nsIImportModule * GetModule(bool keepLoaded = false); // Adds ref
|
||||
void ReleaseModule(void);
|
||||
|
||||
bool SupportsThings(const char *pThings);
|
||||
|
||||
private:
|
||||
nsCID m_cid;
|
||||
nsString m_name;
|
||||
nsString m_description;
|
||||
nsCString m_supports;
|
||||
nsIImportModule *m_pModule;
|
||||
};
|
||||
|
||||
class nsImportModuleList {
|
||||
public:
|
||||
nsImportModuleList() { m_pList = nullptr; m_alloc = 0; m_count = 0;}
|
||||
~nsImportModuleList() { ClearList(); }
|
||||
|
||||
void AddModule(const nsCID& cid, const char *pSupports, const char16_t *pName, const char16_t *pDesc);
|
||||
|
||||
void ClearList(void);
|
||||
|
||||
int32_t GetCount(void) { return m_count;}
|
||||
|
||||
ImportModuleDesc * GetModuleDesc(int32_t idx)
|
||||
{ if ((idx < 0) || (idx >= m_count)) return nullptr; else return m_pList[idx];}
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
ImportModuleDesc ** m_pList;
|
||||
int32_t m_alloc;
|
||||
int32_t m_count;
|
||||
};
|
||||
|
||||
#endif // nsImportService_h__
|
||||
80
mailnews/import/src/nsImportStringBundle.cpp
Normal file
80
mailnews/import/src/nsImportStringBundle.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "prprf.h"
|
||||
#include "prmem.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsImportStringBundle.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
nsresult nsImportStringBundle::GetStringBundle(const char *aPropertyURL,
|
||||
nsIStringBundle **aBundle)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> sBundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
NS_ENSURE_TRUE(sBundleService, NS_ERROR_UNEXPECTED);
|
||||
rv = sBundleService->CreateBundle(aPropertyURL, aBundle);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void nsImportStringBundle::GetStringByID(int32_t aStringID,
|
||||
nsIStringBundle *aBundle,
|
||||
nsString &aResult)
|
||||
{
|
||||
aResult.Adopt(GetStringByID(aStringID, aBundle));
|
||||
}
|
||||
|
||||
char16_t *nsImportStringBundle::GetStringByID(int32_t aStringID,
|
||||
nsIStringBundle *aBundle)
|
||||
{
|
||||
if (aBundle)
|
||||
{
|
||||
char16_t *ptrv = nullptr;
|
||||
nsresult rv = aBundle->GetStringFromID(aStringID, &ptrv);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && ptrv)
|
||||
return ptrv;
|
||||
}
|
||||
|
||||
nsString resultString(NS_LITERAL_STRING("[StringID "));
|
||||
resultString.AppendInt(aStringID);
|
||||
resultString.AppendLiteral("?]");
|
||||
|
||||
return ToNewUnicode(resultString);
|
||||
}
|
||||
|
||||
void nsImportStringBundle::GetStringByName(const char *aName,
|
||||
nsIStringBundle *aBundle,
|
||||
nsString &aResult)
|
||||
{
|
||||
aResult.Adopt(GetStringByName(aName, aBundle));
|
||||
}
|
||||
|
||||
char16_t *nsImportStringBundle::GetStringByName(const char *aName,
|
||||
nsIStringBundle *aBundle)
|
||||
{
|
||||
if (aBundle)
|
||||
{
|
||||
char16_t *ptrv = nullptr;
|
||||
nsresult rv = aBundle->GetStringFromName(
|
||||
NS_ConvertUTF8toUTF16(aName).get(), &ptrv);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && ptrv)
|
||||
return ptrv;
|
||||
}
|
||||
|
||||
nsString resultString(NS_LITERAL_STRING("[StringName "));
|
||||
resultString.Append(NS_ConvertUTF8toUTF16(aName).get());
|
||||
resultString.AppendLiteral("?]");
|
||||
|
||||
return ToNewUnicode(resultString);
|
||||
}
|
||||
48
mailnews/import/src/nsImportStringBundle.h
Normal file
48
mailnews/import/src/nsImportStringBundle.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef _nsImportStringBundle_H__
|
||||
#define _nsImportStringBundle_H__
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
class nsIStringBundle;
|
||||
|
||||
class nsImportStringBundle
|
||||
{
|
||||
public:
|
||||
static char16_t* GetStringByID(int32_t aStringID,
|
||||
nsIStringBundle *aBundle = nullptr);
|
||||
static void GetStringByID(int32_t aStringID,
|
||||
nsIStringBundle *aBundle,
|
||||
nsString &aResult);
|
||||
static char16_t* GetStringByName(const char *aName,
|
||||
nsIStringBundle *aBundle = nullptr);
|
||||
static void GetStringByName(const char *aName,
|
||||
nsIStringBundle *aBundle,
|
||||
nsString &aResult);
|
||||
static nsresult GetStringBundle(const char *aPropertyURL,
|
||||
nsIStringBundle **aBundle);
|
||||
};
|
||||
|
||||
#define IMPORT_MSGS_URL "chrome://messenger/locale/importMsgs.properties"
|
||||
|
||||
|
||||
#define IMPORT_NO_ADDRBOOKS 2000
|
||||
#define IMPORT_ERROR_AB_NOTINITIALIZED 2001
|
||||
#define IMPORT_ERROR_AB_NOTHREAD 2002
|
||||
#define IMPORT_ERROR_GETABOOK 2003
|
||||
#define IMPORT_NO_MAILBOXES 2004
|
||||
#define IMPORT_ERROR_MB_NOTINITIALIZED 2005
|
||||
#define IMPORT_ERROR_MB_NOTHREAD 2006
|
||||
#define IMPORT_ERROR_MB_NOPROXY 2007
|
||||
#define IMPORT_ERROR_MB_FINDCHILD 2008
|
||||
#define IMPORT_ERROR_MB_CREATE 2009
|
||||
#define IMPORT_ERROR_MB_NODESTFOLDER 2010
|
||||
|
||||
#define IMPORT_FIELD_DESC_START 2100
|
||||
#define IMPORT_FIELD_DESC_END 2136
|
||||
|
||||
|
||||
#endif /* _nsImportStringBundle_H__ */
|
||||
296
mailnews/import/src/nsImportTranslator.cpp
Normal file
296
mailnews/import/src/nsImportTranslator.cpp
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "ImportOutFile.h"
|
||||
#include "nsImportTranslator.h"
|
||||
|
||||
#include "ImportCharSet.h"
|
||||
|
||||
|
||||
bool nsImportTranslator::ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
|
||||
{
|
||||
if (pProcessed)
|
||||
*pProcessed = inLen;
|
||||
return (pOutFile->WriteData(pIn, inLen));
|
||||
}
|
||||
|
||||
void CMHTranslator::ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut)
|
||||
{
|
||||
while (inLen) {
|
||||
if (!ImportCharSet::IsUSAscii(*pIn) || ImportCharSet::Is822SpecialChar(*pIn) || ImportCharSet::Is822CtlChar(*pIn) ||
|
||||
(*pIn == ImportCharSet::cSpaceChar) || (*pIn == '*') || (*pIn == '\'') ||
|
||||
(*pIn == '%')) {
|
||||
// needs to be encode as %hex val
|
||||
*pOut = '%'; pOut++;
|
||||
ImportCharSet::ByteToHex(*pIn, pOut);
|
||||
pOut += 2;
|
||||
}
|
||||
else {
|
||||
*pOut = *pIn;
|
||||
pOut++;
|
||||
}
|
||||
pIn++; inLen--;
|
||||
}
|
||||
*pOut = 0;
|
||||
}
|
||||
|
||||
bool CMHTranslator::ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
|
||||
{
|
||||
uint8_t hex[2];
|
||||
while (inLen) {
|
||||
if (!ImportCharSet::IsUSAscii(*pIn) || ImportCharSet::Is822SpecialChar(*pIn) || ImportCharSet::Is822CtlChar(*pIn) ||
|
||||
(*pIn == ImportCharSet::cSpaceChar) || (*pIn == '*') || (*pIn == '\'') ||
|
||||
(*pIn == '%')) {
|
||||
// needs to be encode as %hex val
|
||||
if (!pOutFile->WriteByte('%'))
|
||||
return false;
|
||||
ImportCharSet::ByteToHex(*pIn, hex);
|
||||
if (!pOutFile->WriteData(hex, 2))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (!pOutFile->WriteByte(*pIn))
|
||||
return false;
|
||||
}
|
||||
pIn++; inLen--;
|
||||
}
|
||||
|
||||
if (pProcessed)
|
||||
*pProcessed = inLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool C2047Translator::ConvertToFileQ(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
|
||||
{
|
||||
if (!inLen)
|
||||
return true;
|
||||
|
||||
int maxLineLen = 64;
|
||||
int curLineLen = m_startLen;
|
||||
bool startLine = true;
|
||||
|
||||
uint8_t hex[2];
|
||||
while (inLen) {
|
||||
if (startLine) {
|
||||
if (!pOutFile->WriteStr(" =?"))
|
||||
return false;
|
||||
if (!pOutFile->WriteStr(m_charset.get()))
|
||||
return false;
|
||||
if (!pOutFile->WriteStr("?q?"))
|
||||
return false;
|
||||
curLineLen += (6 + m_charset.Length());
|
||||
startLine = false;
|
||||
}
|
||||
|
||||
if (!ImportCharSet::IsUSAscii(*pIn) || ImportCharSet::Is822SpecialChar(*pIn) || ImportCharSet::Is822CtlChar(*pIn) ||
|
||||
(*pIn == ImportCharSet::cSpaceChar) || (*pIn == '?') || (*pIn == '=')) {
|
||||
// needs to be encode as =hex val
|
||||
if (!pOutFile->WriteByte('='))
|
||||
return false;
|
||||
ImportCharSet::ByteToHex(*pIn, hex);
|
||||
if (!pOutFile->WriteData(hex, 2))
|
||||
return false;
|
||||
curLineLen += 3;
|
||||
}
|
||||
else {
|
||||
if (!pOutFile->WriteByte(*pIn))
|
||||
return false;
|
||||
curLineLen++;
|
||||
}
|
||||
pIn++; inLen--;
|
||||
if (curLineLen > maxLineLen) {
|
||||
if (!pOutFile->WriteStr("?="))
|
||||
return false;
|
||||
if (inLen) {
|
||||
if (!pOutFile->WriteStr("\x0D\x0A "))
|
||||
return false;
|
||||
}
|
||||
|
||||
startLine = true;
|
||||
curLineLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!startLine) {
|
||||
// end the encoding!
|
||||
if (!pOutFile->WriteStr("?="))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pProcessed)
|
||||
*pProcessed = inLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C2047Translator::ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
|
||||
{
|
||||
if (m_useQuotedPrintable)
|
||||
return ConvertToFileQ(pIn, inLen, pOutFile, pProcessed);
|
||||
|
||||
if (!inLen)
|
||||
return true;
|
||||
|
||||
int maxLineLen = 64;
|
||||
int curLineLen = m_startLen;
|
||||
bool startLine = true;
|
||||
int encodeMax;
|
||||
uint8_t * pEncoded = new uint8_t[maxLineLen * 2];
|
||||
|
||||
while (inLen) {
|
||||
if (startLine) {
|
||||
if (!pOutFile->WriteStr(" =?")) {
|
||||
delete [] pEncoded;
|
||||
return false;
|
||||
}
|
||||
if (!pOutFile->WriteStr(m_charset.get())) {
|
||||
delete [] pEncoded;
|
||||
return false;
|
||||
}
|
||||
if (!pOutFile->WriteStr("?b?")) {
|
||||
delete [] pEncoded;
|
||||
return false;
|
||||
}
|
||||
curLineLen += (6 + m_charset.Length());
|
||||
startLine = false;
|
||||
}
|
||||
encodeMax = maxLineLen - curLineLen;
|
||||
encodeMax *= 3;
|
||||
encodeMax /= 4;
|
||||
if ((uint32_t)encodeMax > inLen)
|
||||
encodeMax = (int)inLen;
|
||||
|
||||
// encode the line, end the line
|
||||
// then continue. Update curLineLen, pIn, startLine, and inLen
|
||||
UMimeEncode::ConvertBuffer(pIn, encodeMax, pEncoded, maxLineLen, maxLineLen, "\x0D\x0A");
|
||||
|
||||
if (!pOutFile->WriteStr((const char *)pEncoded)) {
|
||||
delete [] pEncoded;
|
||||
return false;
|
||||
}
|
||||
|
||||
pIn += encodeMax;
|
||||
inLen -= encodeMax;
|
||||
startLine = true;
|
||||
curLineLen = 0;
|
||||
if (!pOutFile->WriteStr("?=")) {
|
||||
delete [] pEncoded;
|
||||
return false;
|
||||
}
|
||||
if (inLen) {
|
||||
if (!pOutFile->WriteStr("\x0D\x0A ")) {
|
||||
delete [] pEncoded;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete [] pEncoded;
|
||||
|
||||
if (pProcessed)
|
||||
*pProcessed = inLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t UMimeEncode::GetBufferSize(uint32_t inBytes)
|
||||
{
|
||||
// it takes 4 base64 bytes to represent 3 regular bytes
|
||||
inBytes += 3;
|
||||
inBytes /= 3;
|
||||
inBytes *= 4;
|
||||
// This should be plenty, but just to be safe
|
||||
inBytes += 4;
|
||||
|
||||
// now allow for end of line characters
|
||||
inBytes += ((inBytes + 39) / 40) * 4;
|
||||
|
||||
return inBytes;
|
||||
}
|
||||
|
||||
static uint8_t gBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
uint32_t UMimeEncode::ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut, uint32_t maxLen, uint32_t firstLineLen, const char * pEolStr)
|
||||
{
|
||||
|
||||
uint32_t pos = 0;
|
||||
uint32_t len = 0;
|
||||
uint32_t lineLen = 0;
|
||||
uint32_t maxLine = firstLineLen;
|
||||
int eolLen = 0;
|
||||
if (pEolStr)
|
||||
eolLen = strlen(pEolStr);
|
||||
|
||||
while ((pos + 2) < inLen) {
|
||||
// Encode 3 bytes
|
||||
*pOut = gBase64[*pIn >> 2];
|
||||
pOut++; len++; lineLen++;
|
||||
*pOut = gBase64[(((*pIn) & 0x3)<< 4) | (((*(pIn + 1)) & 0xF0) >> 4)];
|
||||
pIn++; pOut++; len++; lineLen++;
|
||||
*pOut = gBase64[(((*pIn) & 0xF) << 2) | (((*(pIn + 1)) & 0xC0) >>6)];
|
||||
pIn++; pOut++; len++; lineLen++;
|
||||
*pOut = gBase64[(*pIn) & 0x3F];
|
||||
pIn++; pOut++; len++; lineLen++;
|
||||
pos += 3;
|
||||
if (lineLen >= maxLine) {
|
||||
lineLen = 0;
|
||||
maxLine = maxLen;
|
||||
if (pEolStr) {
|
||||
memcpy(pOut, pEolStr, eolLen);
|
||||
pOut += eolLen;
|
||||
len += eolLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((pos < inLen) && ((lineLen + 3) > maxLine)) {
|
||||
lineLen = 0;
|
||||
maxLine = maxLen;
|
||||
if (pEolStr) {
|
||||
memcpy(pOut, pEolStr, eolLen);
|
||||
pOut += eolLen;
|
||||
len += eolLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos < inLen) {
|
||||
// Get the last few bytes!
|
||||
*pOut = gBase64[*pIn >> 2];
|
||||
pOut++; len++;
|
||||
pos++;
|
||||
if (pos < inLen) {
|
||||
*pOut = gBase64[(((*pIn) & 0x3)<< 4) | (((*(pIn + 1)) & 0xF0) >> 4)];
|
||||
pIn++; pOut++; pos++; len++;
|
||||
if (pos < inLen) {
|
||||
// Should be dead code!! (Then why is it here doofus?)
|
||||
*pOut = gBase64[(((*pIn) & 0xF) << 2) | (((*(pIn + 1)) & 0xC0) >>6)];
|
||||
pIn++; pOut++; len++;
|
||||
*pOut = gBase64[(*pIn) & 0x3F];
|
||||
pos++; pOut++; len++;
|
||||
}
|
||||
else {
|
||||
*pOut = gBase64[(((*pIn) & 0xF) << 2)];
|
||||
pOut++; len++;
|
||||
*pOut = '=';
|
||||
pOut++; len++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*pOut = gBase64[(((*pIn) & 0x3)<< 4)];
|
||||
pOut++; len++;
|
||||
*pOut = '=';
|
||||
pOut++; len++;
|
||||
*pOut = '=';
|
||||
pOut++; len++;
|
||||
}
|
||||
}
|
||||
|
||||
*pOut = 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
66
mailnews/import/src/nsImportTranslator.h
Normal file
66
mailnews/import/src/nsImportTranslator.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsImportTranslator_h___
|
||||
#define nsImportTranslator_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class ImportOutFile;
|
||||
|
||||
class UMimeEncode {
|
||||
public:
|
||||
static uint32_t GetBufferSize(uint32_t inByes);
|
||||
static uint32_t ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t *pOut, uint32_t maxLen = 72, uint32_t firstLineLen = 72, const char * pEolStr = nullptr);
|
||||
};
|
||||
|
||||
|
||||
class nsImportTranslator {
|
||||
public:
|
||||
virtual ~nsImportTranslator() {}
|
||||
virtual bool Supports8bitEncoding(void) { return false;}
|
||||
virtual uint32_t GetMaxBufferSize(uint32_t inLen) { return inLen + 1;}
|
||||
virtual void ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut) { memcpy(pOut, pIn, inLen); pOut[inLen] = 0;}
|
||||
virtual bool ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed = nullptr);
|
||||
virtual bool FinishConvertToFile(ImportOutFile * /* pOutFile */) { return true;}
|
||||
|
||||
virtual void GetCharset(nsCString& charSet) { charSet = "us-ascii";}
|
||||
virtual void GetLanguage(nsCString& lang) { lang = "en";}
|
||||
virtual void GetEncoding(nsCString& encoding) { encoding.Truncate();}
|
||||
};
|
||||
|
||||
// Specialized encoder, not a vaild language translator, used for Mime headers.
|
||||
// rfc2231
|
||||
class CMHTranslator : public nsImportTranslator {
|
||||
public:
|
||||
virtual uint32_t GetMaxBufferSize(uint32_t inLen) override { return (inLen * 3) + 1;}
|
||||
virtual void ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut) override;
|
||||
virtual bool ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed = nullptr) override;
|
||||
};
|
||||
|
||||
// Specialized encoder, not a vaild language translator, used for mail headers
|
||||
// rfc2047
|
||||
class C2047Translator : public nsImportTranslator {
|
||||
public:
|
||||
virtual ~C2047Translator() {}
|
||||
|
||||
C2047Translator(const char *pCharset, uint32_t headerLen) { m_charset = pCharset; m_startLen = headerLen; m_useQuotedPrintable = false;}
|
||||
|
||||
void SetUseQuotedPrintable(void) { m_useQuotedPrintable = true;}
|
||||
|
||||
virtual bool ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed = nullptr) override;
|
||||
bool ConvertToFileQ(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed);
|
||||
|
||||
protected:
|
||||
bool m_useQuotedPrintable;
|
||||
nsCString m_charset;
|
||||
uint32_t m_startLen;
|
||||
};
|
||||
|
||||
#endif /* nsImportTranslator_h__ */
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue