home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UBufferedFileStream.cp < prev    next >
Encoding:
Text File  |  1994-03-14  |  4.0 KB  |  180 lines  |  [TEXT/MPS ]

  1. // Copyright © 1993 Peter Speck (speck@dat.ruc.dk).  All rights reserved.
  2. // UBufferedFileStream.cp
  3.  
  4. #include "UBufferedFileStream.h"
  5. #include "FileTools.h"
  6. #include "Tools.h"
  7.  
  8. #include <Errors.h>
  9.  
  10. #pragma segment MyTools
  11.  
  12. pascal void TBufferedFileStream::Initialize()
  13. {
  14.     inherited::Initialize();
  15.     fFile = nil;
  16.     fInBufferP = nil;
  17.     fOutBufferP = nil;
  18.     fInBufferPosP = nil;
  19.     fOutBufferPosP = nil;
  20.     fBytesInInBuffer = 0;
  21.     fBytesInOutBuffer = 0;
  22.     fPBP = nil;
  23. }
  24.     
  25. pascal void TBufferedFileStream::IBufferedFileStream(TFile* itsFile, long inBufferSize, long outBufferSize)
  26. {
  27.     inherited::IStream();
  28.     FailNonObject(itsFile);
  29.     fFile = itsFile;
  30.     fPBP = (ParamBlockRec*)NewPermPtr(sizeof(ParamBlockRec));
  31.     fInBufferSize = inBufferSize;
  32.     fOutBufferSize = outBufferSize;
  33.     if (fInBufferSize)
  34.     {
  35.         fInBufferP = NewPermPtr(inBufferSize);
  36.         fInBufferPosP = fInBufferP;
  37.     }
  38.     if (fOutBufferSize)
  39.     {
  40.         fOutBufferP = NewPermPtr(outBufferSize);
  41.         fOutBufferPosP = fOutBufferP;
  42.     }
  43.     FailOSErr(fFile->SetDataMark(0, fsFromStart));
  44. }
  45.  
  46. pascal void TBufferedFileStream::Free()
  47. {
  48.     FlushBuffers();
  49.     fInBufferP = DisposeIfPtr(fInBufferP);
  50.     fOutBufferP = DisposeIfPtr(fOutBufferP);
  51.     DisposeIfPtr(Ptr(fPBP)); fPBP = nil;
  52.     inherited::Free();
  53. }
  54.  
  55. void TBufferedFileStream::FlushBuffers()
  56. {
  57.     FlushInputBuffer();
  58.     FlushOutputBuffer();
  59. }
  60.  
  61. void TBufferedFileStream::FlushOutputBuffer()
  62. {
  63.     if (fOutBufferP == nil)
  64.         return;
  65.     if (fBytesInOutBuffer == 0)
  66.         return;
  67.     WriteASyncToFile(*fPBP, fFile, fOutBufferP, fBytesInOutBuffer);
  68.     fOutBufferPosP = fOutBufferP;
  69.     fBytesInOutBuffer = 0;
  70. }
  71.  
  72. void TBufferedFileStream::FlushInputBuffer()
  73. {
  74.     if (fBytesInInBuffer)
  75.         FailOSErr(fFile->SetDataMark(-fBytesInInBuffer, fsFromMark)); // rewind
  76.     fBytesInInBuffer = 0;
  77. }
  78.  
  79. void TBufferedFileStream::FillInputBuffer()
  80. {
  81.     FailNIL(fInBufferP);
  82.     long noReadBytes = fInBufferSize;
  83.     ReadASyncFromFile(*fPBP, fFile, fInBufferP, noReadBytes);
  84. #if qDebug & 0
  85.     fprintf(stderr, "Read %ld bytes async:\n", noReadBytes);
  86.     for (long i = 0; i <= 20 && i <= noReadBytes; ++i)
  87.         fprintf(stderr, "%6ld: %ld\n", i, long(fInBufferP[i]));
  88. #endif
  89.     fBytesInInBuffer = noReadBytes;
  90.     fInBufferPosP = fInBufferP;
  91. }
  92.  
  93. pascal long TBufferedFileStream::GetPosition()
  94. {
  95.     FlushBuffers();
  96.     long itsDataMark;
  97.     FailOSErr(fFile->GetDataMark(itsDataMark));
  98.     return itsDataMark;
  99. }
  100.  
  101. pascal void TBufferedFileStream::SetPosition(long newPosition)
  102. {
  103.     FlushBuffers();
  104.     FailOSErr(fFile->SetDataMark(newPosition, fsFromStart));
  105. }
  106.  
  107. pascal long TBufferedFileStream::GetSize()
  108. {
  109.     FlushOutputBuffer();
  110.     long itsDataLength;
  111.     FailOSErr(fFile->GetDataLength(itsDataLength));
  112.     return itsDataLength;
  113. }
  114.  
  115. pascal void TBufferedFileStream::SetSize(long newSize)
  116. {
  117.     FlushBuffers();
  118.     FailOSErr(fFile->SetDataLength(newSize));
  119. }    
  120.  
  121. pascal void TBufferedFileStream::ReadBytes(void* p, long count)
  122. {
  123.     if (!fInBufferP)
  124.         FailNIL(fInBufferP);
  125.     Ptr destP = Ptr(p);
  126.     while (true)
  127.     {
  128.         long subCount = Min(count, fBytesInInBuffer);
  129.         BytesMove(fInBufferPosP, destP, subCount);
  130.         fBytesInInBuffer -= subCount;
  131.         fInBufferPosP += subCount;
  132.         destP += subCount;
  133.         count -= subCount;
  134.         if (!count)
  135.             break;
  136.         if (count > fInBufferSize)
  137.         {
  138.             subCount = count;
  139.             ReadASyncFromFile(*fPBP, fFile, destP, subCount);
  140.             return;
  141.         }
  142.         FillInputBuffer();
  143.         if (!fBytesInInBuffer)
  144.             FailOSErr(eofErr);
  145.     }
  146. }
  147.  
  148. pascal void TBufferedFileStream::WriteBytes(const void* p, long count)
  149. {
  150.     if (!fOutBufferP)
  151.         FailNIL(fOutBufferP);
  152.     const char *fromP = (const char*)p;
  153.     while (count)
  154.     {
  155.         long subCount = Min(count, fOutBufferSize - fBytesInOutBuffer);
  156.         BytesMove(fromP, fOutBufferPosP, subCount);
  157.         fBytesInOutBuffer += subCount;
  158.         fOutBufferPosP += subCount;
  159.         fromP += subCount;
  160.         count -= subCount;
  161.         if (!count)
  162.             break;
  163.         FlushOutputBuffer();
  164.         if (count > fOutBufferSize)
  165.         {
  166.             WriteASyncToFile(*fPBP, fFile, fromP, count);
  167.             return;
  168.         }
  169.     }
  170. }
  171.  
  172. //--------------
  173.  
  174. TBufferedFileStream *NewBufferedFileStream(TFile* itsFile, long inBufferSize, long outBufferSize)
  175. {
  176.     TBufferedFileStream *bfs = new TBufferedFileStream();
  177.     bfs->IBufferedFileStream(itsFile, inBufferSize, outBufferSize);
  178.     return bfs;
  179. }
  180.