BCMailLog:
PUBLIC
PROC[
fileData: BlackCherry.BCFileData, strmProc: MsgFromStreamProc, ropeProc: MsgFromRopesProc]
RETURNS[ok: BOOL ¬ FALSE] = {
writeStream: STREAM = fileData.writeStream;
posForEntry: INT ~ writeStream.GetIndex[];
endOfMsgs, posForMsgs: INT;
numMsgs: INT ¬ 0;
msgH, lastMsgH, thisMsgH: MsgHandle;
writeStream.PutF[relTocPointerEntryTemplate, [integer[0]], [integer[0]] ];
posForMsgs ¬ writeStream.GetIndex[];
DO
entryPos, msgTemplatePos, headersPos, thisTextLen, thisFormatLen: INT;
streamForMsg: STREAM;
thisMsgID, text, formatting: ROPE;
unRead: BOOL;
IF strmProc #
NIL
THEN {
[streamForMsg, thisMsgID, unRead, thisTextLen, thisFormatLen] ¬ strmProc[];
IF streamForMsg = NIL THEN EXIT;
}
ELSE {
[thisMsgID, text, formatting, unRead] ¬ ropeProc[];
IF thisMsgID = NIL THEN EXIT;
IF NOT Rope.IsEmpty[formatting] THEN text ¬ text.Substr[1];
};
numMsgs ¬ numMsgs + 1;
writeStream.SetIndex[entryPos ¬ writeStream.GetLength[]];
writeStream.PutF1[headerEntryTemplate, [integer[0]] ];
msgTemplatePos ¬ writeStream.GetIndex[];
writeStream.PutF[createMsgTemplate, [rope[thisMsgID]], [integer[0]], [integer[0]] ];
headersPos ¬ writeStream.GetIndex[];
IF streamForMsg #
NIL
THEN
CopyBytes[to: writeStream, from: streamForMsg, num: thisTextLen+thisFormatLen]
ELSE {
writeStream.PutRope[text];
writeStream.PutRope[formatting];
thisTextLen ¬ text.Length[];
thisFormatLen ¬ formatting.Length[];
};
writeStream.PutChar['\r];
writeStream.SetIndex[msgTemplatePos];
writeStream.PutF[createMsgTemplate, [rope[thisMsgID]], [integer[thisTextLen]], [integer[thisFormatLen]] ];
writeStream.SetIndex[entryPos];
writeStream.PutF1[headerEntryTemplate, [integer[writeStream.GetLength[] - entryPos]] ];
thisMsgH ¬ NEW[MsgHandleRec ¬ [headersPos: headersPos, textLen: thisTextLen, formatPos: headersPos+thisTextLen, formatLen: thisFormatLen] ];
thisMsgH.unRead ¬ unRead;
thisMsgH.entryStart ¬ entryPos;
thisMsgH.entryLen ¬ writeStream.GetLength[] - entryPos;
IF
( msgH =
NIL )
THEN msgH ¬ lastMsgH ¬ thisMsgH
ELSE IF ( thisMsgH #
NIL )
THEN { lastMsgH.next ¬ thisMsgH; lastMsgH ¬ thisMsgH };
ENDLOOP;
endOfMsgs ¬ writeStream.GetLength[];
writeStream.SetIndex[posForEntry];
writeStream.PutF[relTocPointerEntryTemplate, [integer[posForMsgs-posForEntry]], [integer[endOfMsgs]] ];
[] ¬ BlackCherryInternal.WriteTOC[fileData.readStream, writeStream, numMsgs, 0, msgH, TRUE];
fileData.writeStream.Close[];
fileData.readStream.Close[ ! IO.Error => CONTINUE];
ok ¬ TRUE;
};