home *** CD-ROM | disk | FTP | other *** search
/ MACD 9 / MACD9.iso / Datatypes / BMPdt / source / ffr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-20  |  5.6 KB  |  196 lines

  1. #include <exec/memory.h>
  2. #include <dos/dosextens.h>
  3. #include <clib/macros.h>
  4. #include "classbase.h"
  5.  
  6. struct FFRHandle {
  7.   APTR                   fh_SysBase;
  8.   struct StandardPacket  fh_Pkt;
  9.   struct MsgPort         fh_ReplyPort;
  10.   BYTE                   fh_Pending,fh_Mode;
  11.   struct FileHandle     *fh_Handle;
  12.   UBYTE                 *fh_Buffer,
  13.                         *fh_Pre,
  14.                         *fh_Ptr;
  15.   ULONG                  fh_Left,
  16.                          fh_BufferSize;
  17.   UBYTE                 *fh_Buf1,*fh_Buf2;
  18. };
  19.  
  20. #define FIRST_BLOCK   512L
  21. #define BUFFER_SIZE 32768L
  22.  
  23. #define mySetIoErr(fh,e) ((struct Process *)fh->fh_ReplyPort.mp_SigTask)->pr_Result2=(e)
  24.  
  25. #define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
  26.                     /*(l)->lh_Tail = NULL,*/ \
  27.                     (l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
  28.  
  29. ASM(STATIC VOID) BeginAction(REG(a1,struct FFRHandle *fh),REG(d0,LONG bytes))
  30. { LREG(a6,APTR SysBase) = fh->fh_SysBase;
  31.  
  32.   fh->fh_Pending = -1;
  33.  
  34.   fh->fh_Pkt.sp_Pkt.dp_Port = &fh->fh_ReplyPort;
  35.   fh->fh_Pkt.sp_Pkt.dp_Arg2 = (LONG)fh->fh_Pre;
  36.   fh->fh_Pkt.sp_Pkt.dp_Arg3 = bytes;
  37.  
  38.   PutMsg(fh->fh_Handle->fh_Type,&fh->fh_Pkt.sp_Msg);
  39. }
  40.  
  41. STATIC LONG EndAction(struct FFRHandle *fh,LONG cont)
  42. { LREG(a6,APTR SysBase) = fh->fh_SysBase;
  43.   LONG size,res1 = fh->fh_BufferSize;
  44.  
  45.   if (!fh->fh_ReplyPort.mp_Node.ln_Pri) {
  46.     if (fh->fh_Pending) {
  47.       fh->fh_Pending = 0;
  48.       fh->fh_ReplyPort.mp_Flags = PA_SIGNAL;
  49.       Remove((struct Node *)WaitPort(&fh->fh_ReplyPort));
  50.       fh->fh_ReplyPort.mp_Flags = PA_IGNORE;
  51.       if ((res1=fh->fh_Pkt.sp_Pkt.dp_Res1) < 0) {
  52.         fh->fh_ReplyPort.mp_Node.ln_Pri = -1; mySetIoErr(fh,fh->fh_Pkt.sp_Pkt.dp_Res2); return FALSE;
  53.       }
  54.     }
  55.   } else return FALSE;
  56.  
  57.   fh->fh_Ptr    = fh->fh_Pre;
  58.   fh->fh_Pre    = fh->fh_Buffer;
  59.   fh->fh_Buffer = fh->fh_Ptr;
  60.  
  61.   if (cont) {
  62.     if (fh->fh_Mode != FFR_MODE_READ || res1 == fh->fh_Pkt.sp_Pkt.dp_Arg3)
  63.       if ((size=fh->fh_BufferSize-fh->fh_Left))
  64.         BeginAction(fh,size);
  65.     fh->fh_Left = res1;
  66.   }
  67.  
  68.   return TRUE;
  69. }
  70.  
  71. LONG FFRGetC(struct FFRHandle *fh)
  72. {
  73.   if (fh->fh_Left || (fh->fh_Pending && (mySetIoErr(fh,0),EndAction(fh,TRUE)) && fh->fh_Left)) {
  74.     fh->fh_Left--; return *fh->fh_Ptr++;
  75.   }
  76.  
  77.   return -1L;
  78. }
  79.  
  80. LONG FFRRead(struct FFRHandle *fh,UBYTE *buffer,LONG bytes)
  81. { LREG(a6,APTR SysBase) = fh->fh_SysBase;
  82.   LONG left,size;
  83.  
  84.   if (bytes <= fh->fh_Left) {
  85.     CopyMem(fh->fh_Ptr,buffer,bytes);
  86.     fh->fh_Ptr += bytes; fh->fh_Left -= bytes; return bytes;
  87.   }
  88.  
  89.   if ((left=bytes) > 0)
  90.     do {
  91.       if ((size=MIN(fh->fh_Left,left))) {
  92.         CopyMem(fh->fh_Ptr,buffer,size);
  93.         fh->fh_Ptr += size; buffer += size; fh->fh_Left -= size;
  94.       }
  95.       if ((left-=size))
  96.         if (!fh->fh_Pending)
  97.           break;
  98.       else if (!EndAction(fh,TRUE))
  99.              return -1L;
  100.     } while (left > 0);
  101.  
  102.   return bytes-left;
  103. }
  104.  
  105. LONG FFRWrite(struct FFRHandle *fh,UBYTE *buffer,LONG bytes)
  106. { LREG(a6,APTR SysBase) = fh->fh_SysBase;
  107.   LONG left,size;
  108.  
  109.   if (bytes <= fh->fh_Left) {
  110.     CopyMem(buffer,fh->fh_Ptr,bytes);
  111.     fh->fh_Ptr += bytes; fh->fh_Left -= bytes; return bytes;
  112.   }
  113.  
  114.   if ((left=bytes) > 0)
  115.     do {
  116.       if ((size=MIN(fh->fh_Left,left))) {
  117.         CopyMem(buffer,fh->fh_Ptr,size);
  118.         fh->fh_Ptr += size; buffer += size; fh->fh_Left-=size; left -= size;
  119.       }
  120.       if (!fh->fh_Left && !EndAction(fh,TRUE))
  121.         return -1L;
  122.     } while (left > 0);
  123.  
  124.   return bytes;
  125. }
  126.  
  127. LONG CloseFFR(struct FFRHandle *fh)
  128. { LREG(a6,APTR SysBase) = fh->fh_SysBase;
  129.   LONG result;
  130.  
  131.   if (fh->fh_Mode != FFR_MODE_READ)
  132.     EndAction(fh,TRUE);
  133.   result = EndAction(fh,FALSE);
  134.   FreeVec(fh->fh_Buf2);
  135.   FreeVec(fh->fh_Buf1);
  136.  
  137.   return result;
  138. }
  139.  
  140. struct FFRHandle *OpenFFR(struct ClassBase *cb,APTR pool,LONG mode,BPTR handle)
  141. { LONG bufferSize,firstBlock,newSize;
  142.   LREG(a6,APTR SysBase),DOSBase;
  143.   struct InfoData *infoData;
  144.   struct FFRHandle *fh;
  145.  
  146.   if (handle && (DOSBase=cb->DOSBase,SysBase=cb->SysBase,(fh=AllocPooled(pool,sizeof(*fh))))) {
  147.  
  148.     fh->fh_SysBase = SysBase;
  149.  
  150.     fh->fh_Pkt.sp_Msg.mn_Node.ln_Name = (char *)&fh->fh_Pkt.sp_Pkt;
  151.  
  152.     fh->fh_Pkt.sp_Pkt.dp_Link = &fh->fh_Pkt.sp_Msg;
  153.     fh->fh_Pkt.sp_Pkt.dp_Type = (mode != FFR_MODE_READ ? ACTION_WRITE : ACTION_READ);
  154.     fh->fh_Pkt.sp_Pkt.dp_Arg1 = (fh->fh_Handle=BADDR(handle))->fh_Arg1;
  155.  
  156.     fh->fh_ReplyPort.mp_Node.ln_Type = NT_MSGPORT;
  157.  
  158.     fh->fh_ReplyPort.mp_Flags   = PA_IGNORE;
  159.     fh->fh_ReplyPort.mp_SigBit  = SIGB_SINGLE;
  160.     fh->fh_ReplyPort.mp_SigTask = FindTask(NULL);
  161.     NEWLIST(&fh->fh_ReplyPort.mp_MsgList);
  162.  
  163.     fh->fh_Mode = mode;
  164.  
  165.     bufferSize = BUFFER_SIZE; firstBlock = FIRST_BLOCK;
  166.  
  167.     if ((infoData=AllocVec(sizeof(*infoData),MEMF_PUBLIC)) != NULL) {
  168.       if (DoPkt1(fh->fh_Handle->fh_Type,ACTION_DISK_INFO,MKBADDR(infoData)) != DOSFALSE) {
  169.         if ((newSize=infoData->id_BytesPerBlock) > 0) {
  170.           firstBlock = newSize;
  171.           for (; newSize<bufferSize; newSize<<=1);
  172.           bufferSize = newSize;
  173.         }
  174.       }
  175.       SysBase = fh->fh_SysBase; FreeVec(infoData);
  176.     }
  177.  
  178.     fh->fh_BufferSize = bufferSize;
  179.  
  180.     if ((fh->fh_Buf1=AllocVec(bufferSize+15,MEMF_PUBLIC)) != NULL) {
  181.       fh->fh_Ptr = fh->fh_Buffer = (UBYTE *)(((ULONG)(fh->fh_Buf1+15))&~15);
  182.       if ((fh->fh_Buf2=AllocVec(bufferSize+15,MEMF_PUBLIC)) != NULL) {
  183.         fh->fh_Pre = (UBYTE *)(((ULONG)(fh->fh_Buf2+15))&~15);
  184.         if (fh->fh_Mode == FFR_MODE_READ) {
  185.           bufferSize = 0; BeginAction(fh,firstBlock-Seek(MKBADDR(fh->fh_Handle),0,OFFSET_CURRENT)%firstBlock);
  186.         }
  187.         fh->fh_Left = bufferSize; return fh;
  188.       }
  189.       FreeVec(fh->fh_Buf1);
  190.     }
  191.     /*FreePooled(pool,fh,sizeof(*fh));*/
  192.   }
  193.  
  194.   return NULL;
  195. }
  196.