1 /* NetHack 3.6 macfile.c $NHDT-Date: 1432512798 2015/05/25 00:13:18 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */
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.
28 /* The HandleFiles are resources built into the application which are treated
29 as read-only files: if we fail to open a file we look for a resource */
31 #define FIRST_HF 32000 /* file ID of first HandleFile */
32 #define MAX_HF 6 /* Max # of open HandleFiles */
34 #define APP_NAME_RES_ID (-16396)
36 typedef struct handlefile {
37 long type; /* Resource type */
38 short id; /* Resource id */
39 long mark; /* Current position */
40 long size; /* total size */
41 Handle data; /* The resource, purgeable */
44 static HandleFile *FDECL(IsHandleFile, (int));
45 static int FDECL(OpenHandleFile, (const unsigned char *, long));
46 static int FDECL(CloseHandleFile, (int));
47 static int FDECL(ReadHandleFile, (int, void *, unsigned));
48 static long FDECL(SetHandleFilePos, (int, short, long));
50 HandleFile theHandleFiles[MAX_HF];
51 MacDirs theDirs; /* also referenced in macwin.c */
56 HandleFile *hfp = NULL;
58 if (fd >= FIRST_HF && fd < FIRST_HF + MAX_HF) {
59 /* in valid range, check for data */
60 hfp = &theHandleFiles[fd - FIRST_HF];
68 OpenHandleFile(const unsigned char *name, long fileType)
74 for (i = 0; i < MAX_HF; i++) {
75 if (theHandleFiles[i].data == 0L)
82 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;
91 return (i + FIRST_HF);
95 CloseHandleFile(int fd)
97 if (!IsHandleFile(fd)) {
101 ReleaseResource(theHandleFiles[fd].data);
102 theHandleFiles[fd].data = 0L;
107 ReadHandleFile(int fd, void *ptr, unsigned len)
112 if (!IsHandleFile(fd))
116 maxBytes = theHandleFiles[fd].size - theHandleFiles[fd].mark;
120 h = theHandleFiles[fd].data;
123 BlockMove(*h + theHandleFiles[fd].mark, ptr, len);
125 theHandleFiles[fd].mark += len;
131 SetHandleFilePos(int fd, short whence, long pos)
135 if (!IsHandleFile(fd))
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;
164 C2P(const char *c, unsigned char *p)
166 int len = strlen(c), i;
171 for (i = len; i > 0; i--)
177 P2C(const unsigned char *p, char *c)
180 for (; idx > 0; idx--)
186 replace_resource(Handle new_res, ResType its_type, short its_id,
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);
203 maccreat(const char *name, long fileType)
205 return macopen(name, O_RDWR | O_CREAT | O_TRUNC, fileType);
209 macopen(const char *name, int flags, long fileType)
216 if (flags & O_CREAT) {
217 if (HCreate(theDirs.dataRefNum, theDirs.dataDirID, s, TEXT_CREATOR,
218 fileType) && (flags & O_EXCL)) {
221 #if 0 /* Fails during makedefs */
222 if (fileType == SAVE_TYPE) {
224 HCreateResFile(theDirs.dataRefNum, theDirs.dataDirID, s);
225 resRef = HOpenResFile(theDirs.dataRefNum, theDirs.dataDirID, s,
231 C2P(plname, plnamep);
232 name = (Handle)NewString(plnamep);
234 replace_resource(name, 'STR ', PLAYER_NAME_RES_ID,
237 /* The application name resource. See IM VI, page 9-21. */
238 name = (Handle)GetString(APP_NAME_RES_ID);
240 DetachResource(name);
241 replace_resource(name, 'STR ', APP_NAME_RES_ID,
242 "\pApplication Name");
245 CloseResFile(resRef);
251 * Here, we should check for file type, maybe a SFdialog if
252 * we fail with default, etc. etc. Besides, we should use HOpen
255 if ((flags & O_RDONLY) == O_RDONLY) {
258 if ((flags & O_WRONLY) == O_WRONLY) {
261 if ((flags & O_RDWR) == O_RDWR) {
264 if (HOpen(theDirs.dataRefNum, theDirs.dataDirID, s, perm, &refNum)) {
265 return OpenHandleFile(s, fileType);
267 if (flags & O_TRUNC) {
268 if (SetEOF(refNum, 0L)) {
279 if (IsHandleFile(fd)) {
285 FlushVol((StringPtr) 0, theDirs.dataRefNum);
291 macread(int fd, void *ptr, unsigned len)
295 if (IsHandleFile(fd)) {
296 return ReadHandleFile(fd, ptr, amt);
298 short err = FSRead(fd, &amt, ptr);
300 return ((err == noErr) || (err == eofErr && len)) ? amt : -1;
304 #if 0 /* this function isn't used, if you use it, uncomment prototype in \
307 macgets (int fd, char *ptr, unsigned len)
313 if (macread (fd, ptr + idx, 1) <= 0)
316 if (c == '\n' || c == '\r')
325 macwrite(int fd, void *ptr, unsigned len)
329 if (IsHandleFile(fd))
331 if (FSWrite(fd, &amt, ptr) == noErr)
338 macseek(int fd, long where, short whence)
343 if (IsHandleFile(fd)) {
344 return SetHandleFilePos(fd, whence, where);
349 posMode = fsFromStart;
352 posMode = fsFromMark;
355 posMode = fsFromLEOF;
359 if (SetFPos(fd, posMode, where) == noErr && GetFPos(fd, &curPos) == noErr)
366 macunlink(const char *name)
371 return (HDelete(theDirs.dataRefNum, theDirs.dataDirID, pname) == noErr
376 /* ---------------------------------------------------------------------- */
385 rsrc_dlb_cleanup(void)
390 rsrc_dlb_fopen(dlb *dp, const char *name, const char *mode)
392 #if defined(__SC__) || defined(__MRC__)
398 dp->fd = OpenHandleFile(pname, 'File'); /* automatically read-only */
403 rsrc_dlb_fclose(dlb *dp)
405 return CloseHandleFile(dp->fd);
409 rsrc_dlb_fread(char *buf, int size, int quan, dlb *dp)
413 if (size < 0 || quan < 0)
415 nread = ReadHandleFile(dp->fd, buf, (unsigned) size * (unsigned) quan);
417 return nread / size; /* # of whole pieces (== quan in normal case) */
421 rsrc_dlb_fseek(dlb *dp, long pos, int whence)
423 return SetHandleFilePos(dp->fd, whence, pos);
427 rsrc_dlb_fgets(char *buf, int len, dlb *dp)
429 HandleFile *hfp = IsHandleFile(dp->fd);
431 int bytesLeft, n = 0;
433 if (hfp && hfp->mark < hfp->size) {
434 bytesLeft = hfp->size - hfp->mark;
439 for (n = 0, p = *hfp->data + hfp->mark; n < len; n++, p++) {
443 if (buf[n] == '\n') {
444 n++; /* we want the return in the buffer */
452 buf[n] = '\0'; /* null terminate result */
455 return n ? buf : NULL;
459 rsrc_dlb_fgetc(dlb *dp)
461 HandleFile *hfp = IsHandleFile(dp->fd);
464 if (!hfp || hfp->size <= hfp->mark)
467 ret = *(unsigned char *) (*hfp->data + hfp->mark);
473 rsrc_dlb_ftell(dlb *dp)
475 HandleFile *hfp = IsHandleFile(dp->fd);