iffparse.pas 11 KB

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