1 /* aNetHack 0.0.1 macfile.c $ANH-Date: 1432512798 2015/05/25 00:13:18 $ $ANH-Branch: master $:$ANH-Revision: 1.11 $ */
2 /* Copyright (c) Jon W{tte, Hao-Yang Wang, Jonathan Handler 1992. */
3 /* aNetHack 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
);