iffparse.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. {
  2. This file is part of the Free Pascal run time library.
  3. iffparse.library interface unit, MorphOS version
  4. Copyright (c) 1998-2003 by Nils Sjoholm
  5. member of the Amiga RTL development team.
  6. MorphOS adaptation
  7. Copyright (c) 2014 by Karoly Balogh
  8. member of the Free Pascal development team
  9. See the file COPYING.FPC, included in this distribution,
  10. for details about the copyright.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. **********************************************************************}
  15. {$PACKRECORDS 2}
  16. {$IFNDEF FPC_DOTTEDUNITS}
  17. unit iffparse;
  18. {$ENDIF FPC_DOTTEDUNITS}
  19. INTERFACE
  20. {$IFDEF FPC_DOTTEDUNITS}
  21. uses Amiga.Core.Exec, Amiga.Core.Clipboard, Amiga.Core.Utility;
  22. {$ELSE FPC_DOTTEDUNITS}
  23. uses exec, clipboard, utility;
  24. {$ENDIF FPC_DOTTEDUNITS}
  25. const
  26. IFFPARSENAME : PAnsiChar = 'iffparse.library';
  27. {
  28. * Struct associated with an active IFF stream.
  29. * "iff_Stream" is a value used by the client's read/write/seek functions -
  30. * it will not be accessed by the library itself and can have any value
  31. * (could even be a pointer or a BPTR).
  32. }
  33. Type
  34. pIFFHandle = ^tIFFHandle;
  35. tIFFHandle = record
  36. iff_Stream,
  37. iff_Flags : DWord;
  38. iff_Depth : LONGINT; { Depth of context stack. }
  39. { There are private fields hiding here. }
  40. END;
  41. {
  42. * Bit masks for "iff_Flags" field.
  43. }
  44. CONST
  45. IFFF_READ = 0; { read mode - default }
  46. IFFF_WRITE = 1; { write mode }
  47. IFFF_RWBITS = (IFFF_READ + IFFF_WRITE); { read/write bits }
  48. IFFF_FSEEK = 2; { forward seek only }
  49. IFFF_RSEEK = 4; { random seek }
  50. IFFF_RESERVED = $FFFF0000; { Don't touch these bits. }
  51. {
  52. * When the library calls your stream handler, you'll be passed a pointer
  53. * to this structure as the "message packet".
  54. }
  55. Type
  56. pIFFStreamCmd = ^tIFFStreamCmd;
  57. tIFFStreamCmd = record
  58. sc_Command : Longint; { Operation to be performed (IFFCMD_) }
  59. sc_Buf : Pointer; { Pointer to data buffer }
  60. sc_NBytes : Longint; { Number of bytes to be affected }
  61. END;
  62. {
  63. * A node associated with a context on the iff_Stack. Each node
  64. * represents a chunk, the stack representing the current nesting
  65. * of chunks in the open IFF file. Each context node has associated
  66. * local context items in the (private) LocalItems list. The ID, type,
  67. * size and scan values describe the chunk associated with this node.
  68. }
  69. pContextNode = ^tContextNode;
  70. tContextNode = record
  71. cn_Node : tMinNode;
  72. cn_ID,
  73. cn_Type,
  74. cn_Size, { Size of this chunk }
  75. cn_Scan : Longint; { # of bytes read/written so far }
  76. { There are private fields hiding here. }
  77. END;
  78. {
  79. * Local context items live in the ContextNode's. Each class is identified
  80. * by its lci_Ident code and has a (private) purge vector for when the
  81. * parent context node is popped.
  82. }
  83. pLocalContextItem = ^tLocalContextItem;
  84. tLocalContextItem = record
  85. lci_Node : tMinNode;
  86. lci_ID,
  87. lci_Type,
  88. lci_Ident : DWord;
  89. { There are private fields hiding here. }
  90. END;
  91. {
  92. * StoredProperty: a local context item containing the data stored
  93. * from a previously encountered property chunk.
  94. }
  95. pStoredProperty = ^tStoredProperty;
  96. tStoredProperty = Record
  97. sp_Size : Longint;
  98. sp_Data : Pointer;
  99. END;
  100. {
  101. * Collection Item: the actual node in the collection list at which
  102. * client will look. The next pointers cross context boundaries so
  103. * that the complete list is accessable.
  104. }
  105. pCollectionItem = ^tCollectionItem;
  106. tCollectionItem = record
  107. ci_Next : pCollectionItem;
  108. ci_Size : Longint;
  109. ci_Data : Pointer;
  110. END;
  111. {
  112. * Structure returned by OpenClipboard(). You may do CMD_POSTs and such
  113. * using this structure. However, once you call OpenIFF(), you may not
  114. * do any more of your own I/O to the clipboard until you call CloseIFF().
  115. }
  116. pClipboardHandle = ^tClipBoardHandle;
  117. tClipboardHandle = record
  118. cbh_Req : tIOClipReq;
  119. cbh_CBport,
  120. cbh_SatisfyPort : tMsgPort;
  121. END;
  122. {
  123. * IFF return codes. Most functions return either zero for success or
  124. * one of these codes. The exceptions are the read/write functions which
  125. * return positive values for number of bytes or records read or written,
  126. * or a negative error code. Some of these codes are not errors per sae,
  127. * but valid conditions such as EOF or EOC (End of Chunk).
  128. }
  129. CONST
  130. IFFERR_EOF = -1 ; { Reached logical END of file }
  131. IFFERR_EOC = -2 ; { About to leave context }
  132. IFFERR_NOSCOPE = -3 ; { No valid scope for property }
  133. IFFERR_NOMEM = -4 ; { Internal memory alloc failed}
  134. IFFERR_READ = -5 ; { Stream read error }
  135. IFFERR_WRITE = -6 ; { Stream write error }
  136. IFFERR_SEEK = -7 ; { Stream seek error }
  137. IFFERR_MANGLED = -8 ; { Data in file is corrupt }
  138. IFFERR_SYNTAX = -9 ; { IFF syntax error }
  139. IFFERR_NOTIFF = -10; { Not an IFF file }
  140. IFFERR_NOHOOK = -11; { No call-back hook provided }
  141. IFF_RETURN2CLIENT = -12; { Client handler normal return}
  142. {
  143. MAKE_ID(a,b,c,d) \
  144. ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
  145. }
  146. {
  147. * Universal IFF identifiers.
  148. }
  149. ID_FORM = 1179603533;
  150. ID_LIST = 1279873876;
  151. ID_CAT = 1128354848;
  152. ID_PROP = 1347571536;
  153. ID_NULL = 538976288;
  154. {
  155. * Ident codes for universally recognized local context items.
  156. }
  157. IFFLCI_PROP = 1886547824;
  158. IFFLCI_COLLECTION = 1668246636;
  159. IFFLCI_ENTRYHANDLER = 1701734500;
  160. IFFLCI_EXITHANDLER = 1702389860;
  161. {
  162. * Control modes for ParseIFF() function.
  163. }
  164. IFFPARSE_SCAN = 0;
  165. IFFPARSE_STEP = 1;
  166. IFFPARSE_RAWSTEP = 2;
  167. {
  168. * Control modes for StoreLocalItem().
  169. }
  170. IFFSLI_ROOT = 1; { Store in default context }
  171. IFFSLI_TOP = 2; { Store in current context }
  172. IFFSLI_PROP = 3; { Store in topmost FORM OR LIST }
  173. {
  174. * "Flag" for writing functions. If you pass this value in as a size
  175. * to PushChunk() when writing a file, the parser will figure out the
  176. * size of the chunk for you. (Chunk sizes >= 2**31 are forbidden by the
  177. * IFF specification, so this works.)
  178. }
  179. IFFSIZE_UNKNOWN = -1;
  180. {
  181. * Possible call-back command values. (Using 0 as the value for IFFCMD_INIT
  182. * was, in retrospect, probably a bad idea.)
  183. }
  184. IFFCMD_INIT = 0; { Prepare the stream for a session }
  185. IFFCMD_CLEANUP = 1; { Terminate stream session }
  186. IFFCMD_READ = 2; { Read bytes from stream }
  187. IFFCMD_WRITE = 3; { Write bytes to stream }
  188. IFFCMD_SEEK = 4; { Seek on stream }
  189. IFFCMD_ENTRY = 5; { You just entered a new context }
  190. IFFCMD_EXIT = 6; { You're about to leave a context }
  191. IFFCMD_PURGELCI= 7; { Purge a LocalContextItem }
  192. { Backward compatibility. Don't use these in new code. }
  193. IFFSCC_INIT = IFFCMD_INIT;
  194. IFFSCC_CLEANUP = IFFCMD_CLEANUP;
  195. IFFSCC_READ = IFFCMD_READ;
  196. IFFSCC_WRITE = IFFCMD_WRITE;
  197. IFFSCC_SEEK = IFFCMD_SEEK;
  198. { Seek modes for SeekChunkBytes and SeekChunkRecords }
  199. IFFOFFSET_BEGINNING = 0;
  200. IFFOFFSET_END = 1;
  201. IFFOFFSET_CURRENT = 2;
  202. VAR IFFParseBase : pLibrary = nil;
  203. FUNCTION AllocIFF : pIFFHandle; syscall IFFParseBase 030;
  204. FUNCTION AllocLocalItem(typ : LONGINT location 'd0'; id : LONGINT location 'd1'; ident : LONGINT location 'd2'; dataSize : LONGINT location 'd3') : pLocalContextItem; syscall IFFParseBase 186;
  205. PROCEDURE CloseClipboard(clipHandle : pClipboardHandle location 'a0'); syscall IFFParseBase 252;
  206. PROCEDURE CloseIFF(iff : pIFFHandle location 'a0'); syscall IFFParseBase 048;
  207. FUNCTION CollectionChunk(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 138;
  208. FUNCTION CollectionChunks(iff : pIFFHandle location 'a0'; const propArray : pLONGINT location 'a1'; numPairs : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 144;
  209. FUNCTION CurrentChunk(const iff : pIFFHandle location 'a0') : pContextNode; syscall IFFParseBase 174;
  210. FUNCTION EntryHandler(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1'; position : LONGINT location 'd2'; handler : pHook location 'a1'; obj : POINTER location 'a2') : LONGINT; syscall IFFParseBase 102;
  211. FUNCTION ExitHandler(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1'; position : LONGINT location 'd2'; handler : pHook location 'a1'; obj : POINTER location 'a2') : LONGINT; syscall IFFParseBase 108;
  212. FUNCTION FindCollection(const iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1') : pCollectionItem; syscall IFFParseBase 162;
  213. FUNCTION FindLocalItem(const iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1'; ident : LONGINT location 'd2') : pLocalContextItem; syscall IFFParseBase 210;
  214. FUNCTION FindProp(const iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1') : pStoredProperty; syscall IFFParseBase 156;
  215. FUNCTION FindPropContext(const iff : pIFFHandle location 'a0') : pContextNode; syscall IFFParseBase 168;
  216. PROCEDURE FreeIFF(iff : pIFFHandle location 'a0'); syscall IFFParseBase 054;
  217. PROCEDURE FreeLocalItem(localItem : pLocalContextItem location 'a0'); syscall IFFParseBase 204;
  218. FUNCTION GoodID(id : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 258;
  219. FUNCTION GoodType(typ : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 264;
  220. FUNCTION IDtoStr(id : LONGINT location 'd0'; buf : PAnsiChar location 'a0') : PAnsiChar; syscall IFFParseBase 270;
  221. PROCEDURE InitIFF(iff : pIFFHandle location 'a0'; flags : LONGINT location 'd0'; const streamHook : pHook location 'a1'); syscall IFFParseBase 228;
  222. PROCEDURE InitIFFasClip(iff : pIFFHandle location 'a0'); syscall IFFParseBase 240;
  223. PROCEDURE InitIFFasDOS(iff : pIFFHandle location 'a0'); syscall IFFParseBase 234;
  224. FUNCTION LocalItemData(const localItem : pLocalContextItem location 'a0') : POINTER; syscall IFFParseBase 192;
  225. FUNCTION OpenClipboard(unitNumber : LONGINT location 'd0') : pClipboardHandle; syscall IFFParseBase 246;
  226. FUNCTION OpenIFF(iff : pIFFHandle location 'a0'; rwMode : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 036;
  227. FUNCTION ParentChunk(const contextNode : pContextNode location 'a0') : pContextNode; syscall IFFParseBase 180;
  228. FUNCTION ParseIFF(iff : pIFFHandle location 'a0'; control : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 042;
  229. FUNCTION PopChunk(iff : pIFFHandle location 'a0') : LONGINT; syscall IFFParseBase 090;
  230. FUNCTION PropChunk(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 114;
  231. FUNCTION PropChunks(iff : pIFFHandle location 'a0'; const propArray : pLONGINT location 'a1'; numPairs : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 120;
  232. FUNCTION PushChunk(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1'; size : LONGINT location 'd2') : LONGINT; syscall IFFParseBase 084;
  233. FUNCTION ReadChunkBytes(iff : pIFFHandle location 'a0'; buf : POINTER location 'a1'; numBytes : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 060;
  234. FUNCTION ReadChunkRecords(iff : pIFFHandle location 'a0'; buf : POINTER location 'a1'; bytesPerRecord : LONGINT location 'd0'; numRecords : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 072;
  235. PROCEDURE SetLocalItemPurge(localItem : pLocalContextItem location 'a0'; const purgeHook : pHook location 'a1'); syscall IFFParseBase 198;
  236. FUNCTION StopChunk(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 126;
  237. FUNCTION StopChunks(iff : pIFFHandle location 'a0'; const propArray : pLONGINT location 'a1'; numPairs : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 132;
  238. FUNCTION StopOnExit(iff : pIFFHandle location 'a0'; typ : LONGINT location 'd0'; id : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 150;
  239. PROCEDURE StoreItemInContext(iff : pIFFHandle location 'a0'; localItem : pLocalContextItem location 'a1'; contextNode : pContextNode location 'a2'); syscall IFFParseBase 222;
  240. FUNCTION StoreLocalItem(iff : pIFFHandle location 'a0'; localItem : pLocalContextItem location 'a1'; position : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 216;
  241. FUNCTION WriteChunkBytes(iff : pIFFHandle location 'a0'; const buf : POINTER location 'a1'; numBytes : LONGINT location 'd0') : LONGINT; syscall IFFParseBase 066;
  242. FUNCTION WriteChunkRecords(iff : pIFFHandle location 'a0'; const buf : POINTER location 'a1'; bytesPerRecord : LONGINT location 'd0'; numRecords : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 078;
  243. { MorphOS specific }
  244. FUNCTION SeekChunkBytes(iff : pIFFHandle location 'a0'; numBytes : LONGINT location 'd0'; mode : LONGINT location 'd1') : LONGINT; syscall IFFParseBase 276;
  245. FUNCTION SeekChunkRecords(iff : pIFFHandle location 'a0'; bytesPerRecord : LONGINT location 'd0'; numRecords : LONGINT location 'd1'; mode : LONGINT location 'd2') : LONGINT; syscall IFFParseBase 282;
  246. Function Make_ID(const str : ShortString) : LONGINT;
  247. function InitIFFPARSELibrary: boolean;
  248. IMPLEMENTATION
  249. function Make_ID(const str : ShortString) : LONGINT;
  250. begin
  251. Make_ID := (LONGINT(Ord(Str[1])) shl 24) or
  252. (LONGINT(Ord(Str[2])) shl 16 ) or
  253. (LONGINT(Ord(Str[3])) shl 8 ) or
  254. (LONGINT(Ord(Str[4])));
  255. end;
  256. const
  257. { Change VERSION and LIBVERSION to proper values }
  258. VERSION : string[2] = '0';
  259. LIBVERSION : longword = 0;
  260. function InitIFFParseLibrary: boolean;
  261. begin
  262. InitIFFParseLibrary := Assigned(IFFParseBase);
  263. end;
  264. initialization
  265. IFFParseBase := OpenLibrary(IFFPARSENAME,LIBVERSION);
  266. finalization
  267. if Assigned(IFFParseBase) then
  268. CloseLibrary(IFFParseBase);
  269. END. (* UNIT IFFPARSE *)