Mozilla/mozilla/calendar/modules/core/src/nsCapiCallbackReader.cpp
dmose%mozilla.org 630d8b77f1 updating license boilerplate
git-svn-id: svn://10.0.0.236/trunk@52521 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 06:13:48 +00:00

406 lines
14 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsCapiCallbackReader.h"
#include "nspr.h"
const t_int32 nsCapiCallbackReader::m_MAXBUFFERSIZE = 1024;
const t_int32 nsCapiCallbackReader::m_NOMORECHUNKS = 404;
//---------------------------------------------------------------------
nsCapiCallbackReader::nsCapiCallbackReader()
{
PR_ASSERT(FALSE);
}
//---------------------------------------------------------------------
void
nsCapiCallbackReader::AddBuffer(nsCapiBufferStruct * cBuf)
{
if (m_Chunks == 0)
m_Chunks = new JulianPtrArray();
PR_ASSERT(m_Chunks != 0);
if (m_Chunks != 0)
{
m_Chunks->Add(cBuf);
}
}
//---------------------------------------------------------------------
nsCapiCallbackReader::nsCapiCallbackReader(PRMonitor * monitor,
nsCalUtility::MimeEncoding encoding)
{
m_Monitor = monitor;
m_bFinished = FALSE;
m_ChunkIndex = 0;
m_Chunks = 0;
m_Init = TRUE;
m_Pos = 0;
m_Mark = -1;
m_ChunkMark = -1;
m_Encoding = encoding;
}
//---------------------------------------------------------------------
void nsCapiCallbackReader::deleteCapiBufferStructVector(JulianPtrArray * bufferVector)
{
t_int32 i;
if (bufferVector != 0)
{
nsCapiBufferStruct * cbBuf;
for (i = bufferVector->GetSize() - 1; i >= 0; i--)
{
cbBuf = (nsCapiBufferStruct *) bufferVector->GetAt(i);
if (0 != cbBuf->m_pBuf)
{
delete [] (cbBuf->m_pBuf);
cbBuf->m_pBuf = 0;
}
delete cbBuf; cbBuf = 0;
}
}
}
//---------------------------------------------------------------------
nsCapiCallbackReader::~nsCapiCallbackReader()
{
if (m_Chunks != 0)
{
deleteCapiBufferStructVector(m_Chunks);
delete m_Chunks; m_Chunks = 0;
}
}
//---------------------------------------------------------------------
t_int8 nsCapiCallbackReader::read(ErrorCode & status)
{
t_int32 i = 0;
status = ZERO_ERROR;
while (TRUE)
{
if (m_Chunks == 0 || m_Chunks->GetSize() == 0 ||
m_ChunkIndex >= m_Chunks->GetSize())
{
status = m_NOMORECHUNKS; // no more chunks, should block
return -1;
}
else
{
// read from linked list of UnicodeString's
// delete front string when finished reading from it
nsCapiBufferStruct * cbBuf = (nsCapiBufferStruct *) m_Chunks->GetAt(m_ChunkIndex);
char * buf = cbBuf->m_pBuf;
char c;
if ((size_t) m_Pos < cbBuf->m_pBufSize)
{
if (nsCalUtility::MimeEncoding_QuotedPrintable == m_Encoding)
{
char * buf = cbBuf->m_pBuf;
c = buf[m_Pos];
if ('=' == c)
{
if (cbBuf->m_pBufSize >= (size_t) (m_Pos + 3))
{
if (ICalReader::isHex(buf[m_Pos + 1]) && ICalReader::isHex(buf[m_Pos + 2]))
{
c = ICalReader::convertHex(buf[m_Pos + 1], buf[m_Pos + 2]);
m_Pos += 3;
return c;
}
else
{
return (t_int8) buf[m_Pos++];
}
}
else
{
PRInt32 lenDiff = cbBuf->m_pBufSize - m_Pos;
char fToken, sToken;
PRBool bSetFToken = FALSE;
PRInt32 tempIndex = m_ChunkIndex;
UnicodeString token;
while (TRUE)
{
// lenDiff = 1, 2 always
// the =XX spans different chunks
// if last chunk, return out of chunks status
if (tempIndex == m_Chunks->GetSize() - 1)
{
status = m_NOMORECHUNKS;
return -1;
}
else
{
nsCapiBufferStruct * cbNextBuf = (nsCapiBufferStruct *) m_Chunks->GetAt(tempIndex + 1);
char * nextBuf = cbNextBuf->m_pBuf;
tempIndex++;
if (cbNextBuf->m_pBufSize >= 2)
{
if (lenDiff == 2)
{
fToken = buf[cbBuf->m_pBufSize - 1];
sToken = nextBuf[0];
if (ICalReader::isHex(fToken) && ICalReader::isHex(sToken))
{
c = ICalReader::convertHex(fToken, sToken);
m_Pos = 1;
m_ChunkIndex = tempIndex;
bSetFToken = FALSE;
return c;
}
else
{
return (t_int8) buf[m_Pos++];
}
}
else
{
// lenDiff = 1
if (bSetFToken)
{
sToken = nextBuf[0];
}
else
{
fToken = nextBuf[0];
sToken = nextBuf[1];
}
if (ICalReader::isHex(fToken) && ICalReader::isHex(sToken))
{
c = ICalReader::convertHex(fToken, sToken);
m_Pos = 2;
m_ChunkIndex = tempIndex;
bSetFToken = FALSE;
return c;
}
else
{
return (t_int8) buf[m_Pos++];
}
}
}
else
{
if (cbNextBuf->m_pBufSize > 0)
{
if (!bSetFToken)
{
fToken = nextBuf[0];
bSetFToken = TRUE;
}
else
{
sToken = nextBuf[0];
if (ICalReader::isHex(fToken) && ICalReader::isHex(sToken))
{
c = ICalReader::convertHex(fToken, sToken);
m_Pos = 1;
m_ChunkIndex = tempIndex;
bSetFToken = FALSE;
return c;
}
else
{
return (t_int8) buf[m_Pos++];
}
}
}
}
}
}
}
}
else
{
return (t_int8) buf[m_Pos++];
}
}
else
{
return (t_int8) buf[m_Pos++];
}
}
else
{
m_ChunkIndex++;
m_Pos = 0;
}
}
}
status = 1;
return -1;
}
//---------------------------------------------------------------------
UnicodeString &
nsCapiCallbackReader::createLine(t_int32 oldPos, t_int32 oldChunkIndex,
t_int32 newPos, t_int32 newChunkIndex,
UnicodeString & aLine)
{
PR_ASSERT(oldChunkIndex <= newChunkIndex);
UnicodeString u;
if (oldChunkIndex == newChunkIndex)
{
u = *((UnicodeString *) m_Chunks->GetAt(oldChunkIndex));
u.extractBetween(oldPos, newPos, aLine);
return aLine;
}
else {
//(oldChunkIndex < newChunkIndex)
t_int32 i;
UnicodeString v, temp;
u = *((UnicodeString *) m_Chunks->GetAt(oldChunkIndex));
u.extractBetween(oldPos, u.size(), aLine);
v = *((UnicodeString *) m_Chunks->GetAt(newChunkIndex));
v.extractBetween(0, newPos, temp);
i = oldChunkIndex + 1;
while (i < newChunkIndex)
{
v = *((UnicodeString *) m_Chunks->GetAt(i));
aLine += v;
i++;
}
aLine += temp;
return aLine;
}
}
//---------------------------------------------------------------------
UnicodeString &
nsCapiCallbackReader::readFullLine(UnicodeString & aLine, ErrorCode & status, t_int32 iTemp)
{
status = ZERO_ERROR;
t_int32 i;
PR_EnterMonitor(m_Monitor);
t_int32 oldpos = m_Pos;
t_int32 oldChunkIndex = m_ChunkIndex;
readLine(aLine, status);
if (status == m_NOMORECHUNKS)
{
if (m_bFinished)
{
// do nothing.
}
else
{
PR_Wait(m_Monitor,PR_INTERVAL_NO_TIMEOUT);
}
}
UnicodeString aSubLine;
while (TRUE)
{
mark();
i = read(status);
if (status == m_NOMORECHUNKS)
{
if (m_bFinished)
{
// do nothing
break;
}
else
{
PR_Wait(m_Monitor,PR_INTERVAL_NO_TIMEOUT);
}
}
else if (i == ' ')
{
aLine += readLine(aSubLine, status);
}
else
{
reset();
break;
}
}
PR_ExitMonitor(m_Monitor);
return aLine;
}
//---------------------------------------------------------------------
UnicodeString &
nsCapiCallbackReader::readLine(UnicodeString & aLine, ErrorCode & status)
{
aLine = "";
if (m_Chunks == 0 || m_Chunks->GetSize() == 0 ||
m_ChunkIndex >= m_Chunks->GetSize())
{
status = m_NOMORECHUNKS; // no more chunks, should block
return aLine;
}
else
{
nsCapiBufferStruct * cbBuf =
(nsCapiBufferStruct *) m_Chunks->GetAt(m_ChunkIndex);
char * currentBuf = cbBuf->m_pBuf;
char * line = 0;
PRInt32 i;
t_bool bFoundNewLine = FALSE;
for (i = m_Pos; 0 != currentBuf[i] &&
((size_t) i < cbBuf->m_pBufSize); i++)
{
if ('\n' == currentBuf[i])
{
currentBuf[i] = 0;
bFoundNewLine = TRUE;
break;
}
}
if (!bFoundNewLine)
{
// todo: mark this chunk needs to be saved
if (m_ChunkIndex < m_Chunks->GetSize() - 1)
{
m_ChunkIndex++;
m_Pos = 0;
}
//else
//{
// status = m_NOMORECHUNKS;
//}
return aLine;
}
line = currentBuf + m_Pos;
m_Pos = i + 1;
aLine = line;
return aLine;
}
}
//---------------------------------------------------------------------