home *** CD-ROM | disk | FTP | other *** search
/ Merciful 3 / Merciful_Release_3.bin / software / b / bmpdatatypev40.5.lha / BMPdt / Source / ffr.c < prev    next >
C/C++ Source or Header  |  1996-04-11  |  4KB  |  165 lines

  1. #include <exec/memory.h>
  2. #include <dos/dosextens.h>
  3. #include <clib/macros.h>
  4. #include <proto/exec.h>
  5.  
  6. struct FFRHandle {
  7.   struct StandardPacket  fh_Pkt;
  8.   struct FileHandle     *fh_Handle;
  9.   struct MsgPort         fh_ReplyPort;
  10.   BYTE                   fh_Flag,pad;
  11.   UBYTE                 *fh_Buffer,
  12.                         *fh_Pre,
  13.                         *fh_Ptr;
  14.   ULONG                  fh_Left;
  15. };
  16.  
  17. #define BUFFER_SIZE 32768L
  18. #define FIRST_BLOCK 512L
  19.  
  20. #define mySetIoErr(fh,e) ((struct Process *)fh->fh_ReplyPort.mp_SigTask)->pr_Result2=(e)
  21.  
  22. #define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
  23.                     /*(l)->lh_Tail = NULL,*/ \
  24.                     (l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
  25.  
  26. VOID BeginRead(struct FFRHandle *fh,LONG bytes)
  27. {
  28.   struct ExecBase *SysBase = *(struct ExecBase **)4L;
  29.   struct StandardPacket *sp;
  30.  
  31.   fh->fh_Flag = -1; sp = &fh->fh_Pkt;
  32.  
  33.   sp->sp_Msg.mn_Node.ln_Name = (char *)&sp->sp_Pkt;
  34.   sp->sp_Msg.mn_ReplyPort    = &fh->fh_ReplyPort;
  35.   sp->sp_Msg.mn_Length       = sizeof(struct StandardPacket);
  36.  
  37.   sp->sp_Pkt.dp_Link         = &sp->sp_Msg;
  38.   sp->sp_Pkt.dp_Port         = &fh->fh_ReplyPort;
  39.  
  40.   sp->sp_Pkt.dp_Type         = ACTION_READ;
  41.   sp->sp_Pkt.dp_Arg1         = fh->fh_Handle->fh_Arg1;
  42.   sp->sp_Pkt.dp_Arg2         = (LONG)fh->fh_Pre;
  43.   sp->sp_Pkt.dp_Arg3         = bytes;
  44.  
  45.   PutMsg(fh->fh_Handle->fh_Type,&sp->sp_Msg);
  46. }
  47.  
  48. LONG EndRead(struct FFRHandle *fh)
  49. {
  50.   struct ExecBase *SysBase = *(struct ExecBase **)4L;
  51.   struct StandardPacket *sp = &fh->fh_Pkt;
  52.   LONG res1;
  53.  
  54.   (VOID) WaitPort(&fh->fh_ReplyPort);
  55.   (VOID) GetMsg(&fh->fh_ReplyPort);
  56.  
  57.   fh->fh_Flag   = FALSE;
  58.  
  59.   if ((res1=sp->sp_Pkt.dp_Res1) < 0)
  60.     { mySetIoErr(fh,sp->sp_Pkt.dp_Res2); return FALSE; }
  61.  
  62.   fh->fh_Ptr    = fh->fh_Pre;
  63.   fh->fh_Pre    = fh->fh_Buffer;
  64.   fh->fh_Buffer = fh->fh_Ptr;
  65.   fh->fh_Left   = res1;
  66.  
  67.   if (res1 == sp->sp_Pkt.dp_Arg3)
  68.     BeginRead(fh,BUFFER_SIZE);
  69.  
  70.   return TRUE;
  71. }
  72.  
  73. LONG FFRGetC(struct FFRHandle *fh)
  74. {
  75.   mySetIoErr(fh,0);
  76.  
  77.   if (fh->fh_Left || (fh->fh_Flag && EndRead(fh) && fh->fh_Left))
  78.     { fh->fh_Left--; return *fh->fh_Ptr++; };
  79.  
  80.   return -1L;
  81. }
  82.  
  83. LONG FFRRead(struct FFRHandle *fh,APTR buffer,LONG bytes)
  84. {
  85.   struct ExecBase *SysBase = *(struct ExecBase **)4L;
  86.   UBYTE *ptr;
  87.   LONG left,size;
  88.  
  89.   if (bytes <= fh->fh_Left)
  90.   {
  91.     CopyMem(fh->fh_Ptr,buffer,bytes);
  92.     fh->fh_Ptr += bytes; fh->fh_Left -= bytes;
  93.  
  94.     return bytes;
  95.   }
  96.  
  97.   left = bytes; ptr = buffer;
  98.  
  99.   if (left > 0)
  100.     do {
  101.       size = MIN(fh->fh_Left,left);
  102.  
  103.       if (size != 0)
  104.       {
  105.         CopyMem(fh->fh_Ptr,ptr,size);
  106.         fh->fh_Ptr += size; fh->fh_Left -= size;
  107.         ptr += size; left -= size;
  108.       }
  109.  
  110.       if (left)
  111.         if (!fh->fh_Flag)
  112.           break;
  113.       else if (!EndRead(fh))
  114.              return -1L;
  115.     } while(left > 0);
  116.  
  117.   return bytes-left;
  118. }
  119.  
  120. VOID CloseFFR(struct FFRHandle *fh)
  121. {
  122.   struct ExecBase *SysBase = *(struct ExecBase **)4L;
  123.  
  124.   if (fh->fh_Flag != FALSE)
  125.     { (VOID) WaitPort(&fh->fh_ReplyPort); (VOID) GetMsg(&fh->fh_ReplyPort); }
  126.  
  127.   FreeVec(fh->fh_Pre);
  128.   FreeVec(fh->fh_Buffer);
  129.   FreeSignal(fh->fh_ReplyPort.mp_SigBit);
  130.   FreeVec(fh);
  131. }
  132.  
  133. struct FFRHandle *OpenFFR(BPTR handle,LONG preRead)
  134. {
  135.   if (handle != NULL)
  136.   {
  137.     struct ExecBase *SysBase = *(struct ExecBase **)4L;
  138.     struct FFRHandle *fh;
  139.  
  140.     if ((fh=AllocVec(sizeof(struct FFRHandle),MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
  141.     {
  142.       fh->fh_Handle = (struct FileHandle *)BADDR(handle);
  143.  
  144.       fh->fh_ReplyPort.mp_Node.ln_Type = NT_MSGPORT;
  145.       if ((BYTE)(fh->fh_ReplyPort.mp_SigBit=AllocSignal(-1))>=0)
  146.       {
  147.         fh->fh_ReplyPort.mp_SigTask = FindTask(NULL);
  148.         NEWLIST(&fh->fh_ReplyPort.mp_MsgList);
  149.  
  150.         if ((fh->fh_Buffer=AllocVec(BUFFER_SIZE,MEMF_PUBLIC)) != NULL)
  151.         {
  152.           if ((fh->fh_Pre=AllocVec(BUFFER_SIZE,MEMF_PUBLIC)) != NULL)
  153.           {
  154.             BeginRead(fh, FIRST_BLOCK-preRead); return fh;
  155.           }
  156.           FreeVec(fh->fh_Buffer);
  157.         }
  158.         FreeSignal(fh->fh_ReplyPort.mp_SigBit);
  159.       }
  160.       FreeVec(fh);
  161.     }
  162.   }
  163.   return NULL;
  164. }
  165.