Merge pull request #12 from davel/davel/sqsh
[debian-nspark.git] / pack.c
blob18016485b99564f4e8056d1158ca972b3bef1e97
2 /*
3 * pack/unpack archive files
5 * $Header: pack.c 1.5 95/08/01 $
6 * $Log: pack.c,v $
7 * Revision 1.5 95/08/01 xx:xx:xx BB
8 * Fixed for Borland C/C++
10 * Revision 1.4 92/12/07 17:19:29 duplain
11 * reformatted source.
13 * Revision 1.3 92/11/09 14:48:36 duplain
14 * Added putc_init() to re-initialise variables.
16 * Revision 1.2 92/10/01 11:22:35 duplain
17 * Added check for EOF.
19 * Revision 1.1 92/09/29 18:02:25 duplain
20 * Initial revision
24 #include <stdio.h>
25 #include "spark.h"
26 #include "main.h"
27 #include "crc.h"
28 #include "garble.h"
29 #include "error.h"
31 /* BB changed next line because of conflict with Borland's io.h */
33 /* #include "io.h" */
34 #include "nsparkio.h"
36 #include "pack.h"
38 static short running;
39 static Word complen;
42 void
43 putc_init()
45 running = 0;
49 * write run-length encoding to output file
52 void
53 putc_ncr(FILE *ofp, Byte byte)
55 static Byte prevbyte;
57 if (running)
59 if (!byte)
60 { /* means write RUNMARK to output */
61 calccrc(RUNMARK);
62 if (!testing)
63 write_byte(ofp, RUNMARK);
65 else
67 /* BB changed next line */
68 /* Borland C++ is `a bit fuzzy' about next line */
69 /* while (--byte) { */
70 #ifdef __MSDOS__
71 while (--byte != 0)
73 #else
74 while (--byte)
76 #endif
77 calccrc(prevbyte);
78 if (!testing)
79 write_byte(ofp, prevbyte);
82 running = 0;
84 else if (byte == RUNMARK)
86 running++;
88 else
90 prevbyte = byte; /* save in case next byte is RUNMARK */
91 calccrc(byte);
92 if (!testing)
93 write_byte(ofp, byte);
97 Status
98 unpack(Header *header, FILE *ifp, FILE *ofp)
100 register Word len = header->complen;
102 init_garble();
104 crc = 0;
105 putc_init();
106 while (len--)
108 if (check_stream(ifp) != FNOERR)
109 break;
110 putc_ncr(ofp, ungarble(read_byte(ifp)));
113 if (check_stream(ifp) == FRWERR)
114 return (RERR);
115 if (!testing && check_stream(ofp) == FRWERR)
116 return (WERR);
117 if ((Halfword) crc != header->crc)
118 return (CRCERR);
119 if (testing)
120 msg("OK (packed)");
121 else
122 msg("unpacked");
123 return (NOERR);
126 void
127 write_ncr(FILE *ofp, Byte byte, int bytecount)
129 int i;
131 if (bytecount > 1)
133 fputc((int)garble(byte), ofp);
134 fputc((int)garble(RUNMARK), ofp);
135 fputc((int)garble(bytecount), ofp);
136 complen += 3;
137 for (i = 0; i < bytecount; i++)
139 calccrc(byte);
142 else
144 if (byte == RUNMARK)
146 calccrc(RUNMARK);
147 fputc((int)garble(RUNMARK), ofp);
148 fputc(garble(0), ofp);
149 complen += 2;
151 else
153 calccrc(byte);
154 fputc((int)garble(byte), ofp);
155 complen += 1;
160 Status
161 pack(Header *header, FILE *ifp, FILE *ofp)
163 register Word len = header->origlen;
164 Byte prevbyte = '\0', byte;
165 int bytecount = 0;
167 init_garble();
169 complen = 0;
170 crc = 0;
171 prevbyte = read_byte(ifp);
172 len--;
173 bytecount = 1;
174 while (len--)
176 byte = read_byte(ifp);
177 if(prevbyte == RUNMARK)
179 write_ncr(ofp, prevbyte, 1);
180 bytecount = 1;
182 else if (byte == prevbyte && bytecount < 254)
184 bytecount++;
186 else
188 write_ncr(ofp, prevbyte, bytecount);
189 bytecount = 1;
191 prevbyte = byte;
192 if (check_stream(ifp) != FNOERR)
193 break;
195 write_ncr(ofp, prevbyte, bytecount);
197 if (check_stream(ifp) == FRWERR)
198 return (RERR);
199 if (!testing && check_stream(ofp) == FRWERR)
200 return (WERR);
201 if (testing)
202 msg("OK (packed)");
203 else
204 msg("packed");
206 header->crc = (Halfword) crc;
207 header->complen = complen;
209 return (NOERR);