home *** CD-ROM | disk | FTP | other *** search
- #include <exec/memory.h>
- #include <dos/dosextens.h>
- #include <clib/macros.h>
- #include "classbase.h"
-
- struct FFRHandle {
- APTR fh_SysBase;
- struct StandardPacket fh_Pkt;
- struct MsgPort fh_ReplyPort;
- BYTE fh_Pending,fh_Mode;
- struct FileHandle *fh_Handle;
- UBYTE *fh_Buffer,
- *fh_Pre,
- *fh_Ptr;
- ULONG fh_Left,
- fh_BufferSize;
- UBYTE *fh_Buf1,*fh_Buf2;
- };
-
- #define FIRST_BLOCK 512L
- #define BUFFER_SIZE 32768L
-
- #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)
-
- ASM(STATIC VOID) BeginAction(REG(a1,struct FFRHandle *fh),REG(d0,LONG bytes))
- { LREG(a6,APTR SysBase) = fh->fh_SysBase;
-
- fh->fh_Pending = -1;
-
- fh->fh_Pkt.sp_Pkt.dp_Port = &fh->fh_ReplyPort;
- fh->fh_Pkt.sp_Pkt.dp_Arg2 = (LONG)fh->fh_Pre;
- fh->fh_Pkt.sp_Pkt.dp_Arg3 = bytes;
-
- PutMsg(fh->fh_Handle->fh_Type,&fh->fh_Pkt.sp_Msg);
- }
-
- STATIC LONG EndAction(struct FFRHandle *fh,LONG cont)
- { LREG(a6,APTR SysBase) = fh->fh_SysBase;
- LONG size,res1 = fh->fh_BufferSize;
-
- if (!fh->fh_ReplyPort.mp_Node.ln_Pri) {
- if (fh->fh_Pending) {
- fh->fh_Pending = 0;
- fh->fh_ReplyPort.mp_Flags = PA_SIGNAL;
- Remove((struct Node *)WaitPort(&fh->fh_ReplyPort));
- fh->fh_ReplyPort.mp_Flags = PA_IGNORE;
- if ((res1=fh->fh_Pkt.sp_Pkt.dp_Res1) < 0) {
- fh->fh_ReplyPort.mp_Node.ln_Pri = -1; mySetIoErr(fh,fh->fh_Pkt.sp_Pkt.dp_Res2); return FALSE;
- }
- }
- } else return FALSE;
-
- fh->fh_Ptr = fh->fh_Pre;
- fh->fh_Pre = fh->fh_Buffer;
- fh->fh_Buffer = fh->fh_Ptr;
-
- if (cont) {
- if (fh->fh_Mode != FFR_MODE_READ || res1 == fh->fh_Pkt.sp_Pkt.dp_Arg3)
- if ((size=fh->fh_BufferSize-fh->fh_Left))
- BeginAction(fh,size);
- fh->fh_Left = res1;
- }
-
- return TRUE;
- }
-
- LONG FFRGetC(struct FFRHandle *fh)
- {
- if (fh->fh_Left || (fh->fh_Pending && (mySetIoErr(fh,0),EndAction(fh,TRUE)) && fh->fh_Left)) {
- fh->fh_Left--; return *fh->fh_Ptr++;
- }
-
- return -1L;
- }
-
- LONG FFRRead(struct FFRHandle *fh,UBYTE *buffer,LONG bytes)
- { LREG(a6,APTR SysBase) = fh->fh_SysBase;
- LONG left,size;
-
- if (bytes <= fh->fh_Left) {
- CopyMem(fh->fh_Ptr,buffer,bytes);
- fh->fh_Ptr += bytes; fh->fh_Left -= bytes; return bytes;
- }
-
- if ((left=bytes) > 0)
- do {
- if ((size=MIN(fh->fh_Left,left))) {
- CopyMem(fh->fh_Ptr,buffer,size);
- fh->fh_Ptr += size; buffer += size; fh->fh_Left -= size;
- }
- if ((left-=size))
- if (!fh->fh_Pending)
- break;
- else if (!EndAction(fh,TRUE))
- return -1L;
- } while (left > 0);
-
- return bytes-left;
- }
-
- LONG FFRWrite(struct FFRHandle *fh,UBYTE *buffer,LONG bytes)
- { LREG(a6,APTR SysBase) = fh->fh_SysBase;
- LONG left,size;
-
- if (bytes <= fh->fh_Left) {
- CopyMem(buffer,fh->fh_Ptr,bytes);
- fh->fh_Ptr += bytes; fh->fh_Left -= bytes; return bytes;
- }
-
- if ((left=bytes) > 0)
- do {
- if ((size=MIN(fh->fh_Left,left))) {
- CopyMem(buffer,fh->fh_Ptr,size);
- fh->fh_Ptr += size; buffer += size; fh->fh_Left-=size; left -= size;
- }
- if (!fh->fh_Left && !EndAction(fh,TRUE))
- return -1L;
- } while (left > 0);
-
- return bytes;
- }
-
- LONG CloseFFR(struct FFRHandle *fh)
- { LREG(a6,APTR SysBase) = fh->fh_SysBase;
- LONG result;
-
- if (fh->fh_Mode != FFR_MODE_READ)
- EndAction(fh,TRUE);
- result = EndAction(fh,FALSE);
- FreeVec(fh->fh_Buf2);
- FreeVec(fh->fh_Buf1);
-
- return result;
- }
-
- struct FFRHandle *OpenFFR(struct ClassBase *cb,APTR pool,LONG mode,BPTR handle)
- { LONG bufferSize,firstBlock,newSize;
- LREG(a6,APTR SysBase),DOSBase;
- struct InfoData *infoData;
- struct FFRHandle *fh;
-
- if (handle && (DOSBase=cb->DOSBase,SysBase=cb->SysBase,(fh=AllocPooled(pool,sizeof(*fh))))) {
-
- fh->fh_SysBase = SysBase;
-
- fh->fh_Pkt.sp_Msg.mn_Node.ln_Name = (char *)&fh->fh_Pkt.sp_Pkt;
-
- fh->fh_Pkt.sp_Pkt.dp_Link = &fh->fh_Pkt.sp_Msg;
- fh->fh_Pkt.sp_Pkt.dp_Type = (mode != FFR_MODE_READ ? ACTION_WRITE : ACTION_READ);
- fh->fh_Pkt.sp_Pkt.dp_Arg1 = (fh->fh_Handle=BADDR(handle))->fh_Arg1;
-
- fh->fh_ReplyPort.mp_Node.ln_Type = NT_MSGPORT;
-
- fh->fh_ReplyPort.mp_Flags = PA_IGNORE;
- fh->fh_ReplyPort.mp_SigBit = SIGB_SINGLE;
- fh->fh_ReplyPort.mp_SigTask = FindTask(NULL);
- NEWLIST(&fh->fh_ReplyPort.mp_MsgList);
-
- fh->fh_Mode = mode;
-
- bufferSize = BUFFER_SIZE; firstBlock = FIRST_BLOCK;
-
- if ((infoData=AllocVec(sizeof(*infoData),MEMF_PUBLIC)) != NULL) {
- if (DoPkt1(fh->fh_Handle->fh_Type,ACTION_DISK_INFO,MKBADDR(infoData)) != DOSFALSE) {
- if ((newSize=infoData->id_BytesPerBlock) > 0) {
- firstBlock = newSize;
- for (; newSize<bufferSize; newSize<<=1);
- bufferSize = newSize;
- }
- }
- SysBase = fh->fh_SysBase; FreeVec(infoData);
- }
-
- fh->fh_BufferSize = bufferSize;
-
- if ((fh->fh_Buf1=AllocVec(bufferSize+15,MEMF_PUBLIC)) != NULL) {
- fh->fh_Ptr = fh->fh_Buffer = (UBYTE *)(((ULONG)(fh->fh_Buf1+15))&~15);
- if ((fh->fh_Buf2=AllocVec(bufferSize+15,MEMF_PUBLIC)) != NULL) {
- fh->fh_Pre = (UBYTE *)(((ULONG)(fh->fh_Buf2+15))&~15);
- if (fh->fh_Mode == FFR_MODE_READ) {
- bufferSize = 0; BeginAction(fh,firstBlock-Seek(MKBADDR(fh->fh_Handle),0,OFFSET_CURRENT)%firstBlock);
- }
- fh->fh_Left = bufferSize; return fh;
- }
- FreeVec(fh->fh_Buf1);
- }
- /*FreePooled(pool,fh,sizeof(*fh));*/
- }
-
- return NULL;
- }
-