PRBool CMbxScanner::DoWork( PRBool *pAbort, PRUint32 *pDone, PRUint32 *pCount) { m_mbxOffset = kMbxHeaderSize; m_didBytes = kMbxHeaderSize; while (!(*pAbort) && ((m_mbxOffset + kMbxMessageHeaderSz) < m_mbxFileSize)) { PRUint32 msgSz; if (!WriteMailItem( 0, m_mbxOffset, 0, &msgSz)) { if (!WasErrorFatal()) ReportReadError( m_mbxFile); return( PR_FALSE); } m_mbxOffset += msgSz; m_didBytes += msgSz; m_msgCount++; if (pDone) *pDone = m_didBytes; if (pCount) *pCount = m_msgCount; } CleanUp(); return( PR_TRUE); }
// Does parsing; indicates whether the parsing was successful or not bool XML_Configure::DoParse() { // Sanity check if (!CurrentElement) return false; // Create the parser Parser = XML_ParserCreate("iso-8859-1"); XML_SetUnknownEncodingHandler(Parser, XML_JapaneseEncodingHandler, NULL); // Set up the callbacks XML_SetUserData(Parser, this); XML_SetElementHandler(Parser, StaticStartElement, StaticEndElement); XML_SetCharacterDataHandler(Parser, StaticCharacterData); NumInterpretErrors = 0; LastOne = true; do { if (!GetData()) { // Report a read error ReportReadError(); XML_ParserFree(Parser); return false; } // Expat should really be using size_t for BufLen if (!XML_Parse(Parser, Buffer, (int)BufLen, LastOne)) { // Report a parse error ReportParseError( XML_ErrorString(XML_GetErrorCode(Parser)), XML_GetCurrentLineNumber(Parser)); XML_ParserFree(Parser); return false; } if (RequestAbort()) { XML_ParserFree(Parser); return false; } } while (!LastOne); XML_ParserFree(Parser); return (NumInterpretErrors == 0); }
PRBool CMbxScanner::CopyMbxFileBytes(PRUint32 flags, PRUint32 numBytes) { if (!numBytes) return( PR_TRUE); PRUint32 cnt; PRUint8 last[2] = {0, 0}; PRUint32 inIdx = 0; PRBool first = PR_TRUE; PRUint8 * pIn; PRUint8 * pStart; PRInt32 fromLen = strlen( m_pFromLine); nsresult rv; PRInt32 cntRead; PRUint8 * pChar; while (numBytes) { if (numBytes > (m_bufSz - inIdx)) cnt = m_bufSz - inIdx; else cnt = numBytes; // Read some of the message from the file... pChar = m_pInBuffer + inIdx; rv = m_mbxFile->Read( (char **) &pChar, (PRInt32)cnt, &cntRead); if (NS_FAILED( rv) || (cntRead != (PRInt32)cnt)) { ReportReadError( m_mbxFile); return( PR_FALSE); } // Keep track of the last 2 bytes of the message for terminating EOL logic if (cnt < 2) { last[0] = last[1]; last[1] = m_pInBuffer[cnt - 1]; } else { last[0] = m_pInBuffer[cnt - 2]; last[1] = m_pInBuffer[cnt - 1]; } inIdx = 0; // Handle the beginning line, don't duplicate an existing From separator if (first) { // check the first buffer to see if it already starts with a From line // If it does, throw it away and use our own if (IsFromLineKey( m_pInBuffer, cnt)) { // skip past the first line while ((inIdx < cnt) && (m_pInBuffer[inIdx] != 0x0D)) inIdx++; while ((inIdx < cnt) && (IS_ANY_SPACE( m_pInBuffer[inIdx]))) inIdx++; if (inIdx >= cnt) { // This should not occurr - it means the message starts // with a From separator line that is longer than our // file buffer! In this bizarre case, just skip this message // since it is probably bogus anyway. return( PR_TRUE); } } // Begin every message with a From separator rv = m_dstFile->Write( m_pFromLine, fromLen, &cntRead); if (NS_FAILED( rv) || (cntRead != fromLen)) { ReportWriteError( m_dstFile); return( PR_FALSE); } char statusLine[50]; PRUint32 msgFlags = flags; // need to convert from OE flags to mozilla flags PR_snprintf(statusLine, sizeof(statusLine), X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, msgFlags & 0xFFFF); rv = m_dstFile->Write(statusLine, strlen(statusLine), &cntRead); if (NS_SUCCEEDED(rv) && cntRead == fromLen) { PR_snprintf(statusLine, sizeof(statusLine), X_MOZILLA_STATUS2_FORMAT MSG_LINEBREAK, msgFlags & 0xFFFF0000); rv = m_dstFile->Write(statusLine, strlen(statusLine), &cntRead); } if (NS_FAILED( rv) || (cntRead != fromLen)) { ReportWriteError( m_dstFile); return( PR_FALSE); } first = PR_FALSE; } // Handle generic data, escape any lines that begin with "From " pIn = m_pInBuffer + inIdx; numBytes -= cnt; m_didBytes += cnt; pStart = pIn; cnt -= inIdx; inIdx = 0; while (cnt) { if (*pIn == 0x0D) { // need more in buffer? if ((cnt < 7) && numBytes) { break; } else if (cnt > 6) { if ((pIn[1] == 0x0A) && (IsFromLineKey( pIn + 2, cnt))) { inIdx += 2; // Match, escape it rv = m_dstFile->Write( (const char *)pStart, (PRInt32)inIdx, &cntRead); if (NS_SUCCEEDED( rv) && (cntRead == (PRInt32)inIdx)) rv = m_dstFile->Write( ">", 1, &cntRead); if (NS_FAILED( rv) || (cntRead != 1)) { ReportWriteError( m_dstFile); return( PR_FALSE); } cnt -= 2; pIn += 2; inIdx = 0; pStart = pIn; continue; } } } // == 0x0D cnt--; inIdx++; pIn++; } rv = m_dstFile->Write( (const char *)pStart, (PRInt32)inIdx, &cntRead); if (NS_FAILED( rv) || (cntRead != (PRInt32)inIdx)) { ReportWriteError( m_dstFile); return( PR_FALSE); } if (cnt) { inIdx = cnt; memcpy( m_pInBuffer, pIn, cnt); } else inIdx = 0; } // I used to check for an eol before writing one but // it turns out that adding a proper EOL before the next // separator never really hurts so better to be safe // and always do it. // if ((last[0] != 0x0D) || (last[1] != 0x0A)) { rv = m_dstFile->Write( "\x0D\x0A", 2, &cntRead); if (NS_FAILED( rv) || (cntRead != 2)) { ReportWriteError( m_dstFile); return( PR_FALSE); } // } return( PR_TRUE); }