Update interpreters to latest Garglk codebase
[projects/chimara/chimara.git] / interpreters / nitfol / iff.c
1 /*  Nitfol - z-machine interpreter using Glk for output.
2     Copyright (C) 1999  Evin Robertson
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18     The author can be reached at nitfol@deja.com
19 */
20 #include "nitfol.h"
21
22 BOOL iffgetchunk(strid_t stream, char *desttype, glui32 *ulength,
23                  glui32 file_size)
24 {
25   int i;
26   glui32 c;
27   unsigned char length[4];
28
29   c = glk_stream_get_position(stream);
30   if(c & 1) {
31     glk_get_char_stream(stream);    /* Eat padding */
32     c++;
33   }
34
35   if(glk_get_buffer_stream(stream, desttype, 4) != 4)
36     return FALSE;
37   if(glk_get_buffer_stream(stream, (char *) length, 4) != 4)
38     return FALSE;
39
40   *ulength = MSBdecode4(length);
41
42   for(i = 0; i < 4; i++)
43     if(desttype[i] < 0x20 || desttype[i] > 0x7e)
44       return FALSE;
45
46   c += 8;
47
48   return ((c + *ulength) <= file_size);
49 }
50
51
52 BOOL ifffindchunk(strid_t stream, const char *type, glui32 *length, glui32 loc)
53 {
54   char t[4];
55   glui32 file_size;
56
57   glk_stream_set_position(stream, 0, seekmode_End);
58   file_size = glk_stream_get_position(stream);
59
60   glk_stream_set_position(stream, loc, seekmode_Start);
61   *length = 0;
62   do {
63     glk_stream_set_position(stream, *length, seekmode_Current);
64     if(!iffgetchunk(stream, t, length, file_size))
65       return FALSE;
66    } while((t[0] != type[0]) || (t[1] != type[1]) ||
67            (t[2] != type[2]) || (t[3] != type[3]));
68
69   return TRUE;
70 }
71
72
73 void iffputchunk(strid_t stream, const char *type, glui32 ulength)
74 {
75   glui32 c;
76   unsigned char length[4];
77
78   c = glk_stream_get_position(stream);
79   if(c & 1)
80     glk_put_char_stream(stream, 0);  /* Spew padding */
81
82   MSBencode4(length, ulength);
83
84   w_glk_put_buffer_stream(stream, type, 4);
85   w_glk_put_buffer_stream(stream, (char *) length, 4);
86 }
87
88
89 void iffpadend(strid_t stream)
90 {
91   glui32 c;
92   
93   c = glk_stream_get_position(stream);
94   if(c & 1)
95     glk_put_char_stream(stream, 0);  /* Spew padding */
96 }