home *** CD-ROM | disk | FTP | other *** search
- #include <exec/memory.h>
- #include <dos/dosextens.h>
- #include <clib/macros.h>
- #include <proto/exec.h>
-
- struct FFRHandle {
- struct StandardPacket fh_Pkt;
- struct FileHandle *fh_Handle;
- struct MsgPort fh_ReplyPort;
- BYTE fh_Flag,pad;
- UBYTE *fh_Buffer,
- *fh_Pre,
- *fh_Ptr;
- ULONG fh_Left;
- };
-
- #define BUFFER_SIZE 32768L
- #define FIRST_BLOCK 512L
-
- #define mySetIoErr(fh,e) ((struct Process *)fh->fh_ReplyPort.mp_SigTask)->pr_Result2=(e)
-
- #define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
- /*(l)->lh_Tail = NULL,*/ \
- (l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
-
- VOID BeginRead(struct FFRHandle *fh,LONG bytes)
- {
- struct ExecBase *SysBase = *(struct ExecBase **)4L;
- struct StandardPacket *sp;
-
- fh->fh_Flag = -1; sp = &fh->fh_Pkt;
-
- sp->sp_Msg.mn_Node.ln_Name = (char *)&sp->sp_Pkt;
- sp->sp_Msg.mn_ReplyPort = &fh->fh_ReplyPort;
- sp->sp_Msg.mn_Length = sizeof(struct StandardPacket);
-
- sp->sp_Pkt.dp_Link = &sp->sp_Msg;
- sp->sp_Pkt.dp_Port = &fh->fh_ReplyPort;
-
- sp->sp_Pkt.dp_Type = ACTION_READ;
- sp->sp_Pkt.dp_Arg1 = fh->fh_Handle->fh_Arg1;
- sp->sp_Pkt.dp_Arg2 = (LONG)fh->fh_Pre;
- sp->sp_Pkt.dp_Arg3 = bytes;
-
- PutMsg(fh->fh_Handle->fh_Type,&sp->sp_Msg);
- }
-
- LONG EndRead(struct FFRHandle *fh)
- {
- struct ExecBase *SysBase = *(struct ExecBase **)4L;
- struct StandardPacket *sp = &fh->fh_Pkt;
- LONG res1;
-
- (VOID) WaitPort(&fh->fh_ReplyPort);
- (VOID) GetMsg(&fh->fh_ReplyPort);
-
- fh->fh_Flag = FALSE;
-
- if ((res1=sp->sp_Pkt.dp_Res1) < 0)
- { mySetIoErr(fh,sp->sp_Pkt.dp_Res2); return FALSE; }
-
- fh->fh_Ptr = fh->fh_Pre;
- fh->fh_Pre = fh->fh_Buffer;
- fh->fh_Buffer = fh->fh_Ptr;
- fh->fh_Left = res1;
-
- if (res1 == sp->sp_Pkt.dp_Arg3)
- BeginRead(fh,BUFFER_SIZE);
-
- return TRUE;
- }
-
- LONG FFRGetC(struct FFRHandle *fh)
- {
- mySetIoErr(fh,0);
-
- if (fh->fh_Left || (fh->fh_Flag && EndRead(fh) && fh->fh_Left))
- { fh->fh_Left--; return *fh->fh_Ptr++; };
-
- return -1L;
- }
-
- LONG FFRRead(struct FFRHandle *fh,APTR buffer,LONG bytes)
- {
- struct ExecBase *SysBase = *(struct ExecBase **)4L;
- UBYTE *ptr;
- LONG left,size;
-
- if (bytes <= fh->fh_Left)
- {
- CopyMem(fh->fh_Ptr,buffer,bytes);
- fh->fh_Ptr += bytes; fh->fh_Left -= bytes;
-
- return bytes;
- }
-
- left = bytes; ptr = buffer;
-
- if (left > 0)
- do {
- size = MIN(fh->fh_Left,left);
-
- if (size != 0)
- {
- CopyMem(fh->fh_Ptr,ptr,size);
- fh->fh_Ptr += size; fh->fh_Left -= size;
- ptr += size; left -= size;
- }
-
- if (left)
- if (!fh->fh_Flag)
- break;
- else if (!EndRead(fh))
- return -1L;
- } while(left > 0);
-
- return bytes-left;
- }
-
- VOID CloseFFR(struct FFRHandle *fh)
- {
- struct ExecBase *SysBase = *(struct ExecBase **)4L;
-
- if (fh->fh_Flag != FALSE)
- { (VOID) WaitPort(&fh->fh_ReplyPort); (VOID) GetMsg(&fh->fh_ReplyPort); }
-
- FreeVec(fh->fh_Pre);
- FreeVec(fh->fh_Buffer);
- FreeSignal(fh->fh_ReplyPort.mp_SigBit);
- FreeVec(fh);
- }
-
- struct FFRHandle *OpenFFR(BPTR handle,LONG preRead)
- {
- if (handle != NULL)
- {
- struct ExecBase *SysBase = *(struct ExecBase **)4L;
- struct FFRHandle *fh;
-
- if ((fh=AllocVec(sizeof(struct FFRHandle),MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
- {
- fh->fh_Handle = (struct FileHandle *)BADDR(handle);
-
- fh->fh_ReplyPort.mp_Node.ln_Type = NT_MSGPORT;
- if ((BYTE)(fh->fh_ReplyPort.mp_SigBit=AllocSignal(-1))>=0)
- {
- fh->fh_ReplyPort.mp_SigTask = FindTask(NULL);
- NEWLIST(&fh->fh_ReplyPort.mp_MsgList);
-
- if ((fh->fh_Buffer=AllocVec(BUFFER_SIZE,MEMF_PUBLIC)) != NULL)
- {
- if ((fh->fh_Pre=AllocVec(BUFFER_SIZE,MEMF_PUBLIC)) != NULL)
- {
- BeginRead(fh, FIRST_BLOCK-preRead); return fh;
- }
- FreeVec(fh->fh_Buffer);
- }
- FreeSignal(fh->fh_ReplyPort.mp_SigBit);
- }
- FreeVec(fh);
- }
- }
- return NULL;
- }
-