1 { 2 This file is part of the Free Pascal run time library. 3 Copyright (c) 2016 by Free Pascal development team 4 5 iffparse.library functions for Amiga OS 4.x 6 7 See the file COPYING.FPC, included in this distribution, 8 for details about the copyright. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 **********************************************************************} 15 {$PACKRECORDS 2} 16 17 unit iffparse; 18 19 interface 20 21 uses 22 exec, clipboard, utility; 23 24 25 // Struct associated with an active IFF stream. "iff_Stream" is a value used by the client's read/write/seek functions - 26 // it will not be accessed by the library itself and can have any value (could even be a pointer or a BPTR). 27 // This structure can only be allocated by iffparse.library 28 type 29 PIFFHandle = ^TIFFHandle; 30 TIFFHandle = record 31 iff_Stream: LongWord; 32 iff_Flags: LongWord; 33 iff_Depth: LongInt; // Depth of context stack. 34 end; 35 36 // Bit masks for "iff_Flags" field. 37 const 38 IFFF_READ = 0; // read mode - default 39 IFFF_WRITE = 1; // write mode 40 IFFF_RWBITS = IFFF_READ + IFFF_WRITE; // read/write bits 41 IFFF_FSEEK = 1 shl 1; // forward seek only 42 IFFF_RSEEK = 1 shl 2; // random seek 43 IFFF_RESERVED = $FFFF0000; // Don't touch these bits. 44 45 // When the library calls your stream handler, you'll be passed a pointer to this structure as the "message packet". 46 type 47 PIFFStreamCmd = ^TIFFStreamCmd; 48 TIFFStreamCmd = record 49 sc_Command: LongInt; // Operation to be performed (IFFCMD_) 50 sc_Buf: APTR; // Pointer to data buffer 51 sc_NBytes: LongInt; // Number of bytes to be affected 52 end; 53 54 // 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 55 // open IFF file. Each context node has associated local context items in the (private) LocalItems list. 56 // The ID, type, size and scan values describe the chunk associated with this node. 57 // This structure can only be allocated by iffparse.library 58 PContextNode = ^TContextNode; 59 TContextNode = record 60 cn_Node: TMinNode; 61 cn_ID: LongInt; 62 cn_Type: LongInt; 63 cn_Size: LongInt; // Size of this chunk 64 cn_Scan: LongInt; // # of bytes read/written so far 65 end; 66 67 // 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 68 // parent context node is popped. This structure can only be allocated by iffparse.library 69 PLocalContextItem = ^TLocalContextItem; 70 TLocalContextItem = record 71 lci_Node: TMinNode; 72 lci_ID: LongWord; 73 lci_Type: LongWord; 74 lci_Ident: LongWord; 75 end; 76 // StoredProperty: a local context item containing the data stored from a previously encountered property chunk. 77 PStoredProperty = ^TStoredProperty; 78 TStoredProperty = record 79 sp_Size: LongInt; 80 sp_Data: APTR; 81 end; 82 83 // Collection Item: the actual node in the collection list at which client will look. 84 // The next pointers cross context boundaries so that the complete list is accessable. 85 PCollectionItem = ^TCollectionItem; 86 TCollectionItem = record 87 ci_Next: PCollectionItem; 88 ci_Size: LongInt; 89 ci_Data: APTR; 90 end; 91 // Structure returned by OpenClipboard(). You may do CMD_POSTs and such using this structure. 92 // However, once you call OpenIFF(), you may not do any more of your own I/O to the clipboard until you call CloseIFF(). 93 PClipboardHandle = ^TClipBoardHandle; 94 TClipboardHandle = record 95 cbh_Req: TIOClipReq; 96 cbh_CBport: TMsgPort; 97 cbh_SatisfyPort: TMsgPort; 98 end; 99 100 const 101 // IFF return codes. Most functions return either zero for success or one of these codes. The exceptions are the read/write functions which 102 // return positive values for number of bytes or records read or written, or a negative error code. 103 // Some of these codes are not errors per sae, but valid conditions such as EOF or EOC (End of Chunk). 104 IFFERR_EOF = -1; // Reached logical END of file 105 IFFERR_EOC = -2; // About to leave context 106 IFFERR_NOSCOPE = -3; // No valid scope for property 107 IFFERR_NOMEM = -4; // Internal memory alloc failed 108 IFFERR_READ = -5; // Stream read error 109 IFFERR_WRITE = -6; // Stream write error 110 IFFERR_SEEK = -7; // Stream seek error 111 IFFERR_MANGLED = -8; // Data in file is corrupt 112 IFFERR_SYNTAX = -9; // IFF syntax error 113 IFFERR_NOTIFF = -10; // Not an IFF file 114 IFFERR_NOHOOK = -11; // No call-back hook provided 115 IFF_RETURN2CLIENT = -12; // Client handler normal return 116 117 // Universal IFF identifiers. 118 ID_FORM = 1179603533; // 'FORM' 119 ID_LIST = 1279873876; // 'LIST' 120 ID_CAT = 1128354848; // 'CAT ' 121 ID_PROP = 1347571536; // 'PROP' 122 ID_NULL = 538976288; // ' ' 123 // Ident codes for universally recognized local context items. 124 IFFLCI_PROP = 1886547824; // 'prop' 125 IFFLCI_COLLECTION = 1668246636; // 'coll' 126 IFFLCI_ENTRYHANDLER = 1701734500; // 'enhd' 127 IFFLCI_EXITHANDLER = 1702389860; // 'exhd' 128 129 // Control modes for ParseIFF() function. 130 IFFPARSE_SCAN = 0; 131 IFFPARSE_STEP = 1; 132 IFFPARSE_RAWSTEP = 2; 133 134 // Control modes for StoreLocalItem() function IFFSLI_ROOTnull135 IFFSLI_ROOT = 1; // Store in default context 136 IFFSLI_TOP = 2; // Store in current context 137 IFFSLI_PROP = 3; // Store in topmost FORM OR LIST 138 139 // Magic value for writing functions. If you pass this value in as a size to PushChunk() when writing a file, the parser will figure out the 140 // size of the chunk for you. If you know the size, is it better to provide as it makes things faster. 141 IFFSIZE_UNKNOWN = -1; 142 143 144 // Possible call-back command values. 145 IFFCMD_INIT = 0; // Prepare the stream for a session 146 IFFCMD_CLEANUP = 1; // Terminate stream session 147 IFFCMD_READ = 2; // Read bytes from stream 148 IFFCMD_WRITE = 3; // Write bytes to stream 149 IFFCMD_SEEK = 4; // Seek on stream 150 IFFCMD_ENTRY = 5; // You just entered a new context 151 IFFCMD_EXIT = 6; // You're about to leave a context 152 IFFCMD_PURGELCI = 7; // Purge a LocalContextItem 153 154 const 155 IFFPARSENAME: PChar = 'iffparse.library'; 156 157 var 158 IFFParseBase: PLibrary = nil; 159 IIFFParse: PInterface = nil; 160 161 function IFFParseObtain(): LongWord; syscall IIFFParse 60; 162 function IFFParseRelease(): LongWord; syscall IIFFParse 64; 163 procedure IFFParseExpunge(); syscall IIFFParse 68; 164 function IFFParseClone(): PInterface; syscall IIFFParse 72; 165 function AllocIFF: PIFFHandle; syscall IIFFParse 76; 166 function OpenIFF(Iff: PIFFHandle; RWMode: LongInt): LongInt; syscall IIFFParse 80; 167 function ParseIFF(Iff: PIFFHandle; Control: LongInt): LongInt; syscall IIFFParse 84; 168 procedure CloseIFF(Iff: PIFFHandle); syscall IIFFParse 88; 169 procedure FreeIFF(Iff: PIFFHandle); syscall IIFFParse 92; 170 function ReadChunkBytes(Iff: PIFFHandle; Buf: APTR; NumBytes: LongInt): LongInt; syscall IIFFParse 96; 171 function WriteChunkBytes(Iff: PIFFHandle; const Buf: APTR; NumBytes: LongInt): LongInt; syscall IIFFParse 100; 172 function ReadChunkRecords(Iff: PIFFHandle; Buf: APTR; BytesPerRecord: LongInt; NumRecords: LongInt): LongInt; syscall IIFFParse 104; 173 function WriteChunkRecords(Iff: PIFFHandle; const Buf: APTR; BytesPerRecord: LongInt; NumRecords: LongInt): LongInt; syscall IIFFParse 108; 174 function PushChunk(Iff: PIFFHandle; Type_, ID, Size: LongInt): LongInt; syscall IIFFParse 112; 175 function PopChunk(Iff: PIFFHandle): LongInt; syscall IIFFParse 116; 176 function EntryHandler(Iff: PIFFHandle; Type_, ID, Position: LongInt; Handler: PHook; Obj: APTR): LongInt; syscall IIFFParse 120; 177 function ExitHandler(Iff: PIFFHandle; Type_, ID, Position: LongInt; Handler: PHook; Obj: APTR): LongInt; syscall IIFFParse 124; 178 function PropChunk(Iff: PIFFHandle; Type_, ID: LongInt): LongInt; syscall IIFFParse 128; 179 function PropChunks(Iff: PIFFHandle; const PropArray: PLongInt; NumPairs: LongInt): LongInt; syscall IIFFParse 132; 180 function StopChunk(Iff: PIFFHandle; Type_, ID: LongInt): LongInt; syscall IIFFParse 136; 181 function StopChunks(Iff: PIFFHandle; const PropArray: PLongInt; NumPairs: LongInt): LongInt; syscall IIFFParse 140; 182 function CollectionChunk(Iff: PIFFHandle; Type_, ID: LongInt): LongInt; syscall IIFFParse 144; 183 function CollectionChunks(Iff: PIFFHandle; const PropArray: PLongInt; NumPairs: LongInt): LongInt; syscall IIFFParse 148; 184 function StopOnExit(Iff: PIFFHandle; Type_, ID: LongInt): LongInt; syscall IIFFParse 152; 185 function FindProp(const Iff: PIFFHandle; Type_, ID: LongInt): PStoredProperty; syscall IIFFParse 156; 186 function FindCollection(const Iff: PIFFHandle; Type_, ID: LongInt): PCollectionItem; syscall IIFFParse 160; 187 function FindPropContext(const Iff: PIFFHandle): PContextNode; syscall IIFFParse 164; 188 function CurrentChunk(const Iff: PIFFHandle): PContextNode; syscall IIFFParse 168; 189 function ParentChunk(const ContextNode: PContextNode): PContextNode; syscall IIFFParse 172; 190 function AllocLocalItem(Type_, ID, Ident, DataSize: LongInt): PLocalContextItem; syscall IIFFParse 176; 191 function LocalItemData(const LocalItem: PLocalContextItem): POINTER; syscall IIFFParse 180; 192 procedure SetLocalItemPurge(LocalItem: PLocalContextItem; const PurgeHook: PHook); syscall IIFFParse 184; 193 procedure FreeLocalItem(LocalItem: PLocalContextItem); syscall IIFFParse 188; 194 function FindLocalItem(const Iff: PIFFHandle; Type_, ID, Ident: LongInt): PLocalContextItem; syscall IIFFParse 192; 195 function StoreLocalItem(Iff: PIFFHandle; LocalItem: PLocalContextItem; Position: LongInt): LongInt; syscall IIFFParse 196; 196 procedure StoreItemInContext(Iff: PIFFHandle; LocalItem: PLocalContextItem; ContextNode: PContextNode); syscall IIFFParse 200; 197 procedure InitIFF(Iff: PIFFHandle; Flags: LongInt; const StreamHook: PHook); syscall IIFFParse 204; 198 procedure InitIFFasDOS(Iff: PIFFHandle); syscall IIFFParse 208; 199 procedure InitIFFasClip(Iff: PIFFHandle); syscall IIFFParse 212; 200 function OpenClipboard(UnitNumber: LongInt): PClipboardHandle; syscall IIFFParse 216; 201 procedure CloseClipboard(clipHandle: PClipboardHandle); syscall IIFFParse 220; 202 function GoodID(ID: LongInt): LongInt; syscall IIFFParse 224; 203 function GoodType(Type_: LongInt): LongInt; syscall IIFFParse 228; 204 function IDtoStr(ID: LongInt; Buf: STRPTR): STRPTR; syscall IIFFParse 232; 205 206 function Make_ID(Str: string): LongWord; 207 208 implementation 209 210 function Make_ID(Str: string): LongWord; 211 begin 212 Make_ID := 0; 213 if Length(Str) >= 4 then 214 Make_ID := (LongWord(Ord(Str[1])) shl 24) or 215 (LongWord(Ord(Str[2])) shl 16) or 216 (LongWord(Ord(Str[3])) shl 8) or 217 (LongWord(Ord(Str[4]))); 218 end; 219 220 const 221 { Change LIBVERSION to proper values } 222 LIBVERSION : longword = 0; 223 224 initialization 225 IFFParseBase := OpenLibrary(IFFPARSENAME,LIBVERSION); 226 if Assigned(IFFParseBase) then 227 IIFFParse := GetInterface(PLibrary(IFFParseBase), 'main', 1, nil); 228 finalization 229 if Assigned(IIFFParse) then 230 DropInterface(IIFFParse); 231 if Assigned(IFFParseBase) then 232 CloseLibrary(IFFParseBase); 233 end. 234 235 236 237 238 239