1 /* SCCS Id: @(#)macfile.c 3.1 93/01/24 */
2 /* Copyright (c) Jon W{tte, Hao-Yang Wang, Jonathan Handler 1992. */
3 /* NetHack may be freely redistributed. See license for details. */
6 * MAC file I/O routines
15 #include <resources.h>
17 #include <TextUtils.h>
18 #include <ToolUtils.h>
24 * We should get the default dirID and volRefNum (from name) from prefs and
25 * the situation at startup... For now, this will have to do.
29 /* The HandleFiles are resources built into the application which are treated
30 as read-only files: if we fail to open a file we look for a resource */
32 #define FIRST_HF 32000 /* file ID of first HandleFile */
33 #define MAX_HF 6 /* Max # of open HandleFiles */
35 #define APP_NAME_RES_ID (-16396)
37 typedef struct handlefile {
38 long type; /* Resource type */
39 short id; /* Resource id */
40 long mark; /* Current position */
41 long size; /* total size */
42 Handle data; /* The resource, purgeable */
45 static HandleFile *FDECL(IsHandleFile,(int));
46 static int FDECL(OpenHandleFile,(const unsigned char *, long));
47 static int FDECL(CloseHandleFile,(int));
48 static int FDECL(ReadHandleFile,(int, void *, unsigned));
49 static long FDECL(SetHandleFilePos,(int, short, long));
51 HandleFile theHandleFiles [MAX_HF];
52 MacDirs theDirs; /* also referenced in macwin.c */
58 HandleFile *hfp = NULL;
60 if (fd >= FIRST_HF && fd < FIRST_HF+MAX_HF) {
61 /* in valid range, check for data */
62 hfp = &theHandleFiles[fd-FIRST_HF];
63 if (!hfp->data) hfp = NULL;
70 OpenHandleFile (const unsigned char *name, long fileType)
76 for (i = 0; i < MAX_HF; i ++) {
77 if (theHandleFiles[i].data == 0L) break;
83 h = GetNamedResource (fileType, name);
86 theHandleFiles[i].data = h;
87 theHandleFiles[i].size = GetHandleSize (h);
88 GetResInfo (h, &theHandleFiles[i].id, (void*) &theHandleFiles[i].type, s);
89 theHandleFiles[i].mark = 0L;
96 CloseHandleFile (int fd)
98 if (!IsHandleFile (fd)) {
102 ReleaseResource (theHandleFiles[fd].data);
103 theHandleFiles[fd].data = 0L;
109 ReadHandleFile (int fd, void *ptr, unsigned len)
114 if (!IsHandleFile (fd)) return -1;
117 maxBytes = theHandleFiles[fd].size - theHandleFiles[fd].mark;
118 if (len > maxBytes) len = maxBytes;
120 h = theHandleFiles[fd].data;
123 BlockMove (*h + theHandleFiles[fd].mark, ptr, len);
125 theHandleFiles[fd].mark += len;
132 SetHandleFilePos (int fd, short whence, long pos)
136 if (!IsHandleFile (fd)) return -1;
140 curpos = theHandleFiles [fd].mark;
146 curpos = theHandleFiles[fd].size - pos;
155 else if (curpos > theHandleFiles [fd].size)
156 curpos = theHandleFiles [fd].size;
158 theHandleFiles [fd].mark = curpos;
165 C2P (const char *c, unsigned char *p)
167 int len = strlen (c), i;
169 if (len > 255) len = 255;
171 for (i = len; i > 0; i--)
177 P2C (const unsigned char *p, char *c)
180 for (; idx > 0; idx--)
187 replace_resource(Handle new_res, ResType its_type, short its_id, Str255 its_name)
192 old_res = Get1Resource(its_type, its_id);
195 RemoveResource(old_res);
196 DisposeHandle(old_res);
199 AddResource(new_res, its_type, its_id, its_name);
204 maccreat (const char *name, long fileType){
205 return macopen (name, O_RDWR | O_CREAT | O_TRUNC, fileType);
210 macopen (const char *name, int flags, long fileType)
217 if (flags & O_CREAT) {
218 if (HCreate (theDirs.dataRefNum, theDirs.dataDirID, s ,
219 TEXT_CREATOR, fileType) && (flags & O_EXCL)) {
223 if (fileType == SAVE_TYPE) {
225 HCreateResFile(theDirs.dataRefNum, theDirs.dataDirID, s);
226 resRef = HOpenResFile(theDirs.dataRefNum, theDirs.dataDirID, s,
232 C2P(plname, plnamep);
233 name = (Handle)NewString(plnamep);
235 replace_resource(name, 'STR ', PLAYER_NAME_RES_ID,
238 /* The application name resource. See IM VI, page 9-21. */
239 name = (Handle)GetString(APP_NAME_RES_ID);
241 DetachResource(name);
242 replace_resource(name, 'STR ', APP_NAME_RES_ID,
243 "\pApplication Name");
246 CloseResFile(resRef);
252 * Here, we should check for file type, maybe a SFdialog if
253 * we fail with default, etc. etc. Besides, we should use HOpen
256 if ((flags & O_RDONLY) == O_RDONLY) {
259 if ((flags & O_WRONLY) == O_WRONLY) {
262 if ((flags & O_RDWR) == O_RDWR) {
265 if (HOpen (theDirs.dataRefNum, theDirs.dataDirID, s, perm, &refNum)) {
266 return OpenHandleFile (s, fileType);
268 if (flags & O_TRUNC) {
269 if (SetEOF (refNum, 0L)) {
281 if (IsHandleFile (fd)) {
282 CloseHandleFile (fd);
287 FlushVol ((StringPtr) 0, theDirs . dataRefNum);
294 macread (int fd, void *ptr, unsigned len)
298 if (IsHandleFile (fd)) {
299 return ReadHandleFile (fd, ptr, amt);
301 short err = FSRead (fd, &amt, ptr);
303 return ((err == noErr) || (err == eofErr && len)) ? amt : -1;
308 #if 0 /* this function isn't used, if you use it, uncomment prototype in macwin.h */
310 macgets (int fd, char *ptr, unsigned len)
316 if (macread (fd, ptr + idx, 1) <= 0)
319 if (c == '\n' || c == '\r')
329 macwrite (int fd, void *ptr, unsigned len)
333 if (IsHandleFile (fd)) return -1;
334 if (FSWrite(fd, &amt, ptr) == noErr)
342 macseek (int fd, long where, short whence)
347 if (IsHandleFile (fd)) {
348 return SetHandleFilePos (fd, whence, where);
353 posMode = fsFromStart;
356 posMode = fsFromMark;
359 posMode = fsFromLEOF;
363 if (SetFPos(fd, posMode, where) == noErr && GetFPos(fd, &curPos) == noErr)
371 macunlink(const char *name)
377 return (HDelete(theDirs.dataRefNum, theDirs.dataDirID, pname) == noErr ? 0 : -1);
382 /* ---------------------------------------------------------------------- */
384 boolean rsrc_dlb_init(void) {
388 void rsrc_dlb_cleanup(void) {
391 boolean rsrc_dlb_fopen(dlb *dp, const char *name, const char *mode) {
392 #if defined(__SC__) || defined(__MRC__)
393 # pragma unused(mode)
398 dp->fd = OpenHandleFile(pname, 'File'); /* automatically read-only */
402 int rsrc_dlb_fclose(dlb *dp) {
403 return CloseHandleFile(dp->fd);
406 int rsrc_dlb_fread(char *buf, int size, int quan, dlb *dp) {
409 if (size < 0 || quan < 0) return 0;
410 nread = ReadHandleFile(dp->fd, buf, (unsigned)size * (unsigned)quan);
412 return nread/size; /* # of whole pieces (== quan in normal case) */
415 int rsrc_dlb_fseek(dlb *dp, long pos, int whence) {
416 return SetHandleFilePos(dp->fd, whence, pos);
419 char *rsrc_dlb_fgets(char *buf, int len, dlb *dp) {
420 HandleFile *hfp = IsHandleFile(dp->fd);
422 int bytesLeft, n = 0;
424 if (hfp && hfp->mark < hfp->size) {
425 bytesLeft = hfp->size - hfp->mark;
430 for (n = 0, p = *hfp->data+hfp->mark; n < len; n++, p++) {
432 if (*p == '\r') buf[n] = '\n';
433 if (buf[n] == '\n') {
434 n++; /* we want the return in the buffer */
442 buf[n] = '\0'; /* null terminate result */
445 return n ? buf : NULL;
448 int rsrc_dlb_fgetc(dlb *dp) {
449 HandleFile *hfp = IsHandleFile(dp->fd);
452 if (!hfp || hfp->size <= hfp->mark) return EOF;
454 ret = *(unsigned char *)(*hfp->data + hfp->mark);
459 long rsrc_dlb_ftell(dlb *dp) {
460 HandleFile *hfp = IsHandleFile(dp->fd);