WalnutStream.Mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Willie-Sue, July 11, 1985 1:31:04 pm PDT
Contents: types and procedures which take an explicit stream parameter
Last Edited by: Willie-Sue, January 4, 1985 12:57:47 pm PST
Last Edited by: Donahue, December 11, 1984 10:47:03 am PST
(Changed to make consistent with new WalnutLog)
(Changed NextEntryID to return a REF TEXT for the message ID, rather than a ROPE)
(Took out no logging option -- log files use normal Alpine transactions always!)
DIRECTORY
GVBasics USING [RName, Timestamp],
GVRetrieve USING [Handle],
IO USING [STREAM],
Rope USING [ROPE],
ViewerTools USING [TiogaContents],
WalnutKernelDefs USING [LogEntry, MsgLogEntry, LogEntryObject];
WalnutStream: CEDAR DEFINITIONS =
BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
LogEntry: TYPE = WalnutKernelDefs.LogEntry;
LogEntryObject: TYPE = WalnutKernelDefs.LogEntryObject;
MsgLogEntry: TYPE = WalnutKernelDefs.MsgLogEntry;
Opening streams (log files are assumed to be on alpine servers, but that is enforced by the higher levels)
Open: PROC[name: ROPE, readOnly: BOOLFALSE, pages: INT ← 200,
  useOldIfFound: BOOLFALSE, exclusive: BOOLFALSE] RETURNS [strm: STREAM];
if exclusive then an file is opened in [$write, $fail] mode (not used by WalnutRoot)
Miscellaneous stream operations
Aborted: PROC [strm: STREAM] RETURNS [aborted: BOOL];
AbortStream: PROC [strm: STREAM];
FlushStream: PROC[strm: STREAM, setCreateDate: BOOLFALSE];
flushes the stream and sets the create date to BasicTime.Now if requested
SetHighWaterMark: PROC[
 strm: STREAM, hwmBytes: INT, numPages: INT, setCreateDate: BOOLFALSE];
sets the high water mark and length for an alpine file; if the length of the file is more than numPages, then it is truncated to that length; if numPages = -1, don't change the page count
SetPosition: PROC[strm: STREAM, index: INT] RETURNS[ok: BOOL];
set the index on the stream, returns FALSE if index is beyond EndOfStream; if index = -1 then position to end
ReadRope: PROC[strm: STREAM, len: INT] RETURNS[ROPE];
reads a ROPE from strm, starting at the current position; returns NIL IF EndOfStream was encountered
Reading and writing log entries
FindNextEntry: PROC[strm: STREAM] RETURNS[startPos: INT];
find the next entry, starting at the current position of the stream, returns -1 if there are no more entries
ReadEntry: PROC[strm: STREAM, quick: BOOLFALSE] RETURNS[le: LogEntry, length: INT];
returns NIL if there is not a valid entry at pos, and doesn't change the log position. The stream will be positioned just beyond the entry. If quick is TRUE, a message does not get its headers parsed; the length of the headers is returned instead.
PeekEntry: PROC[strm: STREAM] RETURNS[ident: ATOM, msgID: REF TEXT, length: INT];
returns ident = NIL if there is not a valid entry at the current log position. The stream index is NOT advanced by this operation. The length is the length of the entire entry, not just that portion of it read in this operation.
Does not check if ident is for a legal log entry, allowing parsing of "illegal" logs
WriteEntry: PROC[strm: STREAM, le: LogEntry, pos: INT← -1] RETURNS[startPos: INT];
startPos (of the entry just written) is needed by the code which reads messages from grapevine
WalnutStream provides a set of pre-allocated LogEntry records that can be filled in for use with WriteEntry
-- the following appear in the other log files
logFileInfo: READONLY REF LogFileInfo LogEntryObject;
createMsg: READONLY REF CreateMsg LogEntryObject;
expungeMsgs: READONLY REF ExpungeMsgs LogEntryObject;
writeExpungeLog: READONLY REF WriteExpungeLog LogEntryObject;
createMsgSet: READONLY REF CreateMsgSet LogEntryObject;
emptyMsgSet: READONLY REF EmptyMsgSet LogEntryObject;
destroyMsgSet: READONLY REF DestroyMsgSet LogEntryObject;
addMsg: READONLY REF AddMsg LogEntryObject;
removeMsg: READONLY REF RemoveMsg LogEntryObject;
moveMsg: READONLY REF MoveMsg LogEntryObject;
hasbeenRead: READONLY REF HasBeenRead LogEntryObject;
recordNewMailInfo: READONLY REF RecordNewMailInfo LogEntryObject;
startCopyNewMail: READONLY REF StartCopyNewMail LogEntryObject;
endCopyNewMailInfo: READONLY REF EndCopyNewMailInfo LogEntryObject;
acceptNewMail: READONLY REF AcceptNewMail LogEntryObject;
startReadArchiveFile: READONLY REF StartReadArchiveFile LogEntryObject;
endReadArchiveFile: READONLY REF EndReadArchiveFile LogEntryObject;
startCopyReadArchive: READONLY REF StartCopyReadArchive LogEntryObject;
endCopyReadArchiveInfo: READONLY REF EndCopyReadArchiveInfo LogEntryObject;
GVMsgToStream: PROC[strm: STREAM, msg: ROPE, gvH: GVRetrieve.Handle]
RETURNS[ok: BOOL];
read the next message from grapevine; returns TRUE if all went well
WriteMsgBody: PROC[strm: STREAM, body: ViewerTools.TiogaContents];
writes body on at the end of strm, followed by a CR
Overwrite: PROC[to, from: STREAM, startPos: INT, fromPos: INT← -1];
if startPos is -1 then writing is done at the end of to, if fromPos is -1 then don't reposition from
CopyBytes: PROC[from, to: STREAM, num: INT];
copies num bytes from from to to
MsgEntryInfoFromStream: PROC[strm: STREAM, mle: MsgLogEntry];
parses the headers (that walnut is interested in) of a msg directly from stream
ConstructMsgID: PROC[ts: GVBasics.Timestamp, gvSender: GVBasics.RName]
RETURNS[msgID: Rope.ROPE];
END.