|##########|
|#MAGIC   #|CLABLMDG
|#PROJECT #|""
|#PATHS   #|"StdProject"
|#FLAGS   #|xx-x-x-xx---x-x-----------------
|#USERSW  #|--------------------------------
|#USERMASK#|--------------------------------
|#SWITCHES#|xx---xxxxx-xx---
|##########|
(* $A- *)
DEFINITION MODULE IFFParse;

FROM Exec      IMPORT MinNode,LibraryPtr,MsgPort;
FROM System    IMPORT Regs,SysStringPtr;
FROM Utility   IMPORT HookPtr;
FROM Clipboard IMPORT IOClipboardPtr;

TYPE
|
| IFF return codes.  Most functions return either zero for success or
| one of these codes.   The exceptions are the read/write functions which
| return positive values for number of bytes or records read or written,
| or a negative error code.  Some of these codes are not errors per sae,
| but valid conditions such as EOF or EOC (End of Chunk).

  IFFErr = (normalReturn = -12, noHook, notIFF, syntax, mangled, seek,
	    write,read, noMem, noScope, eoc, eof, ok);

|       eof                            Reached logical end of file
|       eoc                            About to leave context
|       noScope                        No valid scope for property
|       noMem                          Internal memory alloc failed
|       read                           Stream read error
|       write                          Stream write error
|       seek                           Stream seek error
|       mangled                        Data in file is corrupt
|       syntax                         IFF syntax error
|       notIFF                         Not an IFF file
|       noHook                         No call-back hook provided
|       normalReturn                   Client handler normal return


|
| Universal IFF identifiers.
CONST
  IDFORM              = $464F524D;  | "FORM"
  IDLIST              = $4C495354;  | "LIST"
  IDCAT               = $43415420;  | "CAT "
  IDPROP              = $50524F50;  | "PROP"
  IDNULL              = $20202020;  | "NULL"

|
| Ident codes for universally recognized local context items.

  IFFLCIPROP          = $70726F70;  | "prop"
  IFFLCICOLLECTION    = $636F6C6C;  | "coll"
  IFFLCIENTRYHANDLER  = $656E6864;  | "enhd"
  IFFLCIEXITHANDLER   = $65786864;  | "exhd"


TYPE
|
| Control modes for ParseIFF() function.

  ParseIFFMode  = (scan, step, rawStep, dummy = 31);

|
| Control modes for StoreLocalItem().


  StoreLocalItemMode    = (root = 1, top, prop, dummy = 31);

|
| "Flag" for writing functions.  If you pass this value in as a size
| to PushChunk() when writing a file, the parser will figure out the
| size of the chunk for you.  (Chunk sizes >= 2**31 are forbidden by the
| IFF specification, so this works.)

CONST   IFFSizeUnknown          = -1;

TYPE
|
| Possible call-back command values.  (Using 0 as the value for IFFCMD_INIT
| was, in retrospect, probably a bad idea.)

  IFFCmd      = (init, cleanup, read, write, seek, entry, exit, purgeLCI);

|       init          |  Prepare the stream for a session
|       cleanup       |  Terminate stream session
|       read          |  Read bytes from stream
|       write         |  Write bytes to stream
|       seek          |  Seek on stream
|       entry         |  You just entered a new context
|       exit          |  You're about to leave a context
|       purgeLCI      |  Purge a LocalContextItem

|
| Struct associated with an active IFF stream.
| "iff_Stream" is a value used by the client's read/write/seek functions -
| it will not be accessed by the library itself and can have any value
| (could even be a pointer or a BPTR).
|

| Bit masks for "iff_Flags" field.

  IFFFlags      = (read, write, fseek, rseek,
		   reserved1 = 16,reserved16 = 31);
  IFFFlagSet    = SET OF IFFFlags;

  IFFHandlePtr  = POINTER TO IFFHandle;
  IFFHandle     = RECORD
		    stream      : ANYPTR;
		    flags       : IFFFlagSet;
		    depth       : LONGINT;   |  Depth of context stack.
		  END;

|
| When the library calls your stream handler, you'll be passed a pointer
| to this structure as the "message packet".

  IFFStreamCmdPtr = POINTER TO IFFStreamCmd;
  IFFStreamCmd    = RECORD
		      command : IFFCmd;  |  Operation to be performed
		      buf     : ANYPTR;  |  Pointer to data buffer
		      nBytes  : LONGINT; |  Number of bytes to be affected
		    END;

|
| A node associated with a context on the iff_Stack.  Each node
| represents a chunk, the stack representing the current nesting
| of chunks in the open IFF file.  Each context node has associated
| local context items in the (private) LocalItems list.  The ID, type,
| size and scan values describe the chunk associated with this node.

  ContextNodePtr= POINTER TO ContextNode;
  ContextNode   = RECORD
		    node        : MinNode;
		    iD          : LONGINT;
		    type        : LONGINT;
		    size        : LONGINT;  |  Size of this chunk
		    scan        : LONGINT;  |  # of bytes read/written so
					    |  far
		  END;

|
| Local context items live in the ContextNode's.  Each class is identified
| by its lci_Ident code and has a (private) purge vector for when the
| parent context node is popped.

  LocalContextItemPtr = POINTER TO LocalContextItem;
  LocalContextItem    = RECORD
			  node        : MinNode;
			  iD,
			  type,
			  ident       : LONGCARD;
			END;

|
| StoredProperty: a local context item containing the data stored
| from a previously encountered property chunk.

  StoredPropertyPtr = POINTER TO StoredProperty;
  StoredProperty    = RECORD
			size       : LONGINT;
			data       : ANYPTR;
		      END;

|
| Collection Item: the actual node in the collection list at which
| client will look.  The next pointers cross context boundaries so
| that the complete list is accessable.

  CollectionItemPtr = POINTER TO CollectionItem;
  CollectionItem    = RECORD
			next       : CollectionItemPtr;
			size       : LONGINT;
			data       : ANYPTR;
		      END;

|
| Structure returned by OpenClipboard().  You may do CMD_POSTs and such
| using this structure.  However, once you call OpenIFF(), you may not
| do any more of your own I/O to the clipboard until you call CloseIFF().

ClipboardHandlePtr = POINTER TO ClipboardHandle;
ClipboardHandle    = RECORD
		       req         : IOClipboardPtr;
		       cBPort      : MsgPort;
		       satisfyPort : MsgPort;
		     END;

VAR
  IFFParseBase  : LibraryPtr;


LIBRARY IFFParseBase BY -30
  PROCEDURE AllocIFF() : IFFHandlePtr;

LIBRARY IFFParseBase BY -36
  PROCEDURE OpenIFF(iff    IN A0: IFFHandlePtr;
		    rwMode IN D0: IFFFlagSet): IFFErr;

LIBRARY IFFParseBase BY -42
  PROCEDURE ParseIFF(iff     IN A0: IFFHandlePtr;
		     control IN D0: ParseIFFMode): IFFErr;

LIBRARY IFFParseBase BY -48
  PROCEDURE CloseIFF(iff IN A0: IFFHandlePtr);

LIBRARY IFFParseBase BY -54
  PROCEDURE FreeIFF(iff IN A0: IFFHandlePtr);

LIBRARY IFFParseBase BY -60
  PROCEDURE ReadChunkBytes(iff  IN A0: IFFHandlePtr;
			   buf  IN A1: ANYPTR;
			   size IN D0: LONGINT): LONGINT;

LIBRARY IFFParseBase BY -66
  PROCEDURE WriteChunkBytes(iff  IN A0: IFFHandlePtr;
			    buf  IN A1: ANYPTR;
			    size IN D0: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -72
  PROCEDURE ReadChunkRecords(iff            IN A0: IFFHandlePtr;
			     buf            IN A1: ANYPTR;
			     bytesPerRecord IN D0: LONGINT;
			     nRecords       IN D1: LONGINT): LONGINT;

LIBRARY IFFParseBase BY -78
  PROCEDURE WriteChunkRecords(iff            IN A0: IFFHandlePtr;
			      buf            IN A1: ANYPTR;
			      bytesPerRecord IN D0: LONGINT;
			      nRecords       IN D1: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -84
  PROCEDURE PushChunk(iff  IN A0: IFFHandlePtr;
		      type IN D0: LONGINT;
		      id   IN D1: LONGINT;
		      size IN D2: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -90
  PROCEDURE PopChunk(iff IN A0: IFFHandlePtr): IFFErr;

LIBRARY IFFParseBase BY -102
  PROCEDURE EntryHandler(iff      IN A0: IFFHandlePtr;
			 type     IN D0: LONGINT;
			 id       IN D1: LONGINT;
			 position IN D2: LONGINT;
			 handler  IN A1: HookPtr;
			 object   IN A2: ANYPTR): IFFErr;

LIBRARY IFFParseBase BY -108
  PROCEDURE ExitHandler(iff      IN A0: IFFHandlePtr;
			 type     IN D0: LONGINT;
			 id       IN D1: LONGINT;
			 position IN D2: LONGINT;
			 handler  IN A1: HookPtr;
			 object   IN A2: ANYPTR): IFFErr;

LIBRARY IFFParseBase BY -114
  PROCEDURE PropChunk(iff  IN A0: IFFHandlePtr;
		      type IN D0: LONGINT;
		      id   IN D1: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -120
  PROCEDURE PropChunks(    iff       IN A0: IFFHandlePtr;
		       VAR propArray IN A1: ARRAY OF LONGINT;
			   nProps    IN D0: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -126
  PROCEDURE StopChunk(iff  IN A0: IFFHandlePtr;
		      type IN D0: LONGINT;
		      id   IN D1: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -132
  PROCEDURE StopChunks(    iff       IN A0: IFFHandlePtr;
		       VAR propArray IN A1: ARRAY OF LONGINT;
			   nProps    IN D0: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -138
  PROCEDURE CollectionChunk(iff  IN A0: IFFHandlePtr;
			    type IN D0: LONGINT;
			    id   IN D1: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -144
  PROCEDURE CollectionChunks(    iff       IN A0: IFFHandlePtr;
			     VAR propArray IN A1: ARRAY OF LONGINT;
				 nProps    IN D0: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -150
  PROCEDURE StopOnExit(iff  IN A0: IFFHandlePtr;
		       type IN D0: LONGINT;
		       id   IN D1: LONGINT): IFFErr;

LIBRARY IFFParseBase BY -156
  PROCEDURE FindProp(iff  IN A0: IFFHandlePtr;
		     type IN D0: LONGINT;
		     id   IN D1: LONGINT): StoredPropertyPtr;

LIBRARY IFFParseBase BY -162
  PROCEDURE FindCollection(iff  IN A0: IFFHandlePtr;
			   type IN D0: LONGINT;
			   id   IN D1: LONGINT): CollectionItemPtr;

LIBRARY IFFParseBase BY -168
  PROCEDURE FindPropContext(iff IN A0: IFFHandlePtr): ContextNodePtr;

LIBRARY IFFParseBase BY -174
  PROCEDURE CurrentChunk(iff IN A0: IFFHandlePtr): ContextNodePtr;

LIBRARY IFFParseBase BY -180
  PROCEDURE ParentChunk(contextNode IN A0: ContextNodePtr): ContextNodePtr;

LIBRARY IFFParseBase BY -186
  PROCEDURE AllocLocalItem(type     IN D0: LONGINT;
			   id       IN D1: LONGINT;
			   ident    IN D2: LONGINT;
			   dataSize IN D3: LONGINT): LocalContextItemPtr;

LIBRARY IFFParseBase BY -192
  PROCEDURE LocalItemData(localItem IN A0: LocalContextItemPtr): ANYPTR;

LIBRARY IFFParseBase BY -198
  PROCEDURE SetLocalItemPurge(localItem IN A0: LocalContextItemPtr;
			      purgeHook IN A1: HookPtr);

LIBRARY IFFParseBase BY -204
  PROCEDURE FreeLocalItem(localItem IN A0: LocalContextItemPtr);

LIBRARY IFFParseBase BY -210
  PROCEDURE FindLocalItem(iff   IN A0: IFFHandlePtr;
			  type  IN D0: LONGINT;
			  id    IN D1: LONGINT;
			  ident IN D2: LONGINT): LocalContextItemPtr;

LIBRARY IFFParseBase BY -216
  PROCEDURE StoreLocalItem(iff       IN A0: IFFHandlePtr;
			   localItem IN A1: LocalContextItemPtr;
			   position  IN D0: StoreLocalItemMode): IFFErr;

LIBRARY IFFParseBase BY -222
  PROCEDURE StoreItemInContext(iff         IN A0: IFFHandlePtr;
			       localItem   IN A1: LocalContextItemPtr;
			       contextNode IN A2: ContextNodePtr);

LIBRARY IFFParseBase BY -228
  PROCEDURE InitIFF(iff        IN A0: IFFHandlePtr;
		    flags      IN D0: LONGINT;
		    streamHook IN A1: HookPtr);

LIBRARY IFFParseBase BY -234
  PROCEDURE InitIFFasDOS(iff IN A0: IFFHandlePtr);

LIBRARY IFFParseBase BY -240
  PROCEDURE InitIFFasClip(iff IN A0: IFFHandlePtr);

LIBRARY IFFParseBase BY -246
  PROCEDURE OpenClipboard(unitNum IN D0: LONGINT): ClipboardHandlePtr;

LIBRARY IFFParseBase BY -252
  PROCEDURE CloseClipboard(clipboard IN A0: ClipboardHandlePtr);

LIBRARY IFFParseBase BY -258
  PROCEDURE GoodID(id IN D0: LONGINT): LONGINT;

LIBRARY IFFParseBase BY -264
  PROCEDURE GoodType(type IN D0: LONGINT): LONGINT;

LIBRARY IFFParseBase BY -270
  PROCEDURE IDtoStr(    id  IN D0: LONGINT;
		    VAR buf IN A0: STRING): SysStringPtr;

END IFFParse.
