-- File: MailFile.mesa  - Last edited by
-- Sandman: 20-Mar-81  9:37:25
-- Karlton:  1-Apr-81 16:12:29

DIRECTORY
  Environment USING [Block],
  Stream USING [Handle];
  
MailFile: DEFINITIONS =

  BEGIN

  -- Types and Constants --

  ErrorCode: TYPE = {
    tooManyMessages, messageTooLarge, fileBusy, fileNotFound, 
    classIsNotEmpty, classExists, noSuchClass, other};

  Handle: TYPE = LONG POINTER TO Object;
  Object: TYPE;
  nullHandle: Handle = NIL;
  
  Block: TYPE = Environment.Block;
  
  MsgNumber: TYPE = CARDINAL;
  nullMessage: MsgNumber = LAST[CARDINAL];
  
  CharProc: TYPE = PROCEDURE RETURNS [CHARACTER];

  Enumerator: TYPE = PROCEDURE [msg: MsgNumber] RETURNS [BOOLEAN];

  AttributeIndex: TYPE = MACHINE DEPENDENT {
    deleted(0), examined(1), stampOnly(2), answered(3), firstClass(8), lastClass(31)};
  ClassIndex: TYPE = AttributeIndex[firstClass..lastClass];
  Attributes: TYPE = PACKED ARRAY AttributeIndex OF BOOLEAN ← ALL[FALSE];

  -- Signals --

  Error: ERROR [code: ErrorCode];

  -- Procedures --

  Create: PROCEDURE [name: LONG STRING, user: LONG STRING, createFile: BOOLEAN ← FALSE]
    RETURNS [Handle];
  -- user is not consumed
  
  Destroy: PROCEDURE [h: Handle];

  CreateInsert: PROCEDURE [h: Handle, length: CARDINAL, msg: MsgNumber ← nullMessage]
    RETURNS [Stream.Handle];

  Delete, UnDelete, MarkExamined, UnMarkExamined: PROCEDURE [h: Handle, msg: MsgNumber];

  Enumerate: PROCEDURE [
    h: Handle, from, to: MsgNumber, enumerator: Enumerator,
    mask: Attributes ← ALL[FALSE], filter: Attributes ← ALL[FALSE]];

  Expunge: PROCEDURE [h: Handle];

  ForceOut: PROCEDURE [h: Handle];

  GetAttributes: PROCEDURE [h: Handle, name: LONG STRING ← NIL] RETURNS [
    nMessages: CARDINAL, dirty: BOOLEAN, fileLength: LONG CARDINAL];

  GetMsgAttributes: PROCEDURE [h: Handle, msg: MsgNumber] RETURNS [attributes: Attributes];

  SetMsgAttribute: PROCEDURE [
    h: Handle, msg: MsgNumber, attribute: AttributeIndex, value: BOOLEAN];
  SetMsgFlag: PROCEDURE [h: Handle, msg: MsgNumber, flag: CHARACTER];
    
  SetUser: PROCEDURE [h: Handle, user: LONG STRING];
  
  TOC: PROCEDURE [h: Handle] RETURNS [toc: Block];

  TOCIndexToMsg: PROCEDURE [h: Handle, index: LONG CARDINAL] RETURNS [msg: MsgNumber];
  TOCEntry: PROCEDURE [h: Handle, msg: MsgNumber] RETURNS [entry: Block];
  MsgToTOCIndex: PROCEDURE [h: Handle, msg: MsgNumber] RETURNS [index: CARDINAL];

  MsgBody: PROCEDURE [h: Handle, msg: MsgNumber] RETURNS [body: Block];

  AddClass: PROCEDURE [h: Handle, class: LONG STRING];
  RemoveClass: PROCEDURE [h: Handle, class: LONG STRING];
  ClassToClassIndex: PROCEDURE [h: Handle, class: LONG STRING] RETURNS [ClassIndex];
     -- string body belongs to client for above 3 procedures
  ClassIndexToClass: PROCEDURE [h: Handle, index: ClassIndex, class: LONG STRING];
     -- string body is filled in (as much as fits)
  
  END.