home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / filutl / decuf13.ark / DECUF.IF0 < prev    next >
Text File  |  1989-09-27  |  4KB  |  123 lines

  1. {*
  2.  * CHUNKS : The decoded data is buffered into a number of buffers,
  3.  * called chunks in this program, which are allocated in the heap.
  4.  * If the heap is full or if the end statement is encountered in the
  5.  * inputfile, the chunks in the heap are written to the result file.
  6.  * In this way a rapid alteration of reading from the input and writing
  7.  * to the result file are avoided, hopefully resulting in an increased
  8.  * performance.
  9.  *}
  10.  
  11. procedure FlushChunks ;
  12. {*
  13.  * FlushChunks - Write all chunks in memory to the result file.  While
  14.  *               writing, the chunks are released to the heap.
  15.  *
  16.  * The chunks are written as an integral number of 128-byte records.  The
  17.  * last record is padded with zeroes if necessary.
  18.  *}
  19. var
  20.    Chunk   : ChunkPtr ;  { Next chunk to write to disk }
  21.    Flushed :  Boolean ;  { Something written (flushed) to file }
  22.    I       :  Integer ;  { Loop control variable }
  23. begin
  24.    Chunk  := HeadChunkList ;
  25.    Flushed:= False ;
  26.    while Chunk<>Nil do
  27.     begin
  28.      HeadChunkList:= HeadChunkList^.NextChunk ;
  29.      I            := Chunk^.ChunkSize ;
  30.      if I>0 then
  31.       begin
  32.        while (I and $007F) <> 0 do
  33.         begin
  34.          Chunk^.Data[I]:= 0 ;
  35.          Inc( I ) ;
  36.         end ;
  37.  
  38.        I:= I shr 7 ;  { Number of records to write }
  39.        BlockWrite( OutputFile, Chunk^.Data, I ) ;
  40.  
  41.        BytesWritten:= BytesWritten + I ;  { Update record (!) count }
  42.        Flushed     := True ;
  43.       end ;  { of if }
  44.      Dispose( Chunk ) ;
  45.      Chunk:= HeadChunkList ;
  46.     end ;  { of while }
  47.    TailChunkList:= Nil ;
  48.  
  49.    if Flushed then
  50.      Inc( HeapFlushes ) ;
  51. end ;  { of FlushChunks }
  52.  
  53. procedure ReleaseChunks ;
  54. {*
  55.  * ReleaseChunks - Return all chunks to the free heap space.  Any data
  56.  *                 gathered in chunks is lost.
  57.  *}
  58. var
  59.    Chunk : ChunkPtr ;  { Pointer to a chunk }
  60. begin
  61.    Chunk:= HeadChunkList ;
  62.    while Chunk<>Nil do
  63.     begin
  64.      HeadChunkList:= HeadChunkList^.NextChunk ;
  65.      Dispose( Chunk ) ;
  66.      Chunk:= HeadChunkList ;
  67.     end ;  { of while }
  68.    TailChunkList:= Nil ;
  69. end ;  { of ReleaseChunks }
  70.  
  71. procedure AllocateChunk ;
  72. {*
  73.  * AllocateChunk - Allocate a new chunk to write data into.  If there
  74.  *                 is no space left in the heap, it is flushed to make
  75.  *                 room for more data.
  76.  *}
  77. var
  78.    Chunk : ChunkPtr ;  { (pointer to) new chunk }
  79. begin
  80.    if (MaxAvail>0) and (SizeOf(Chunks)>MaxAvail) then
  81.      FlushChunks ;
  82.  
  83.    New( Chunk ) ;
  84.    Chunk^.NextChunk:= Nil ;
  85.    Chunk^.ChunkSize:=   0 ;
  86.  
  87.    if HeadChunkList=Nil then
  88.     begin
  89.      HeadChunkList:= Chunk ;
  90.      TailChunkList:= Chunk ;
  91.     end
  92.    else
  93.     begin
  94.      TailChunkList^.NextChunk:= Chunk ;
  95.      TailChunkList           := Chunk ;
  96.     end ;  { of if }
  97. end ;  { of AllocateChunk }
  98.  
  99. procedure WriteByteToChunk( NextByte : Byte ) ;
  100. {*
  101.  * WriteByteToChunk - Write one byte into the next free location in the
  102.  *                    'current' chunk.  If the chunk is full, a new one
  103.  *                    is allocated.
  104.  *}
  105. var
  106.    Chunk : ChunkPtr ;  { Pointer to 'current' chunk in chain }
  107. begin
  108.    if TailChunkList^.ChunkSize>=MaxChunkSize then
  109.      AllocateChunk ;
  110.  
  111.    Chunk:= TailChunkList ;
  112.    Chunk^.ChunkSize:= Succ(Chunk^.ChunkSize) ;
  113.    Chunk^.Data[Chunk^.ChunkSize]:= NextByte ;
  114. {*
  115.  * If a CarriageReturn character is written, it is assumed that it is the
  116.  * end of a line.  If the result file is a normal ascii text file, the
  117.  * number of lines can be counted by counting the CarriageReturn's.
  118.  *}
  119.    if NextByte=$0D then
  120.      Inc( LinesWritten ) ;
  121. end ;  { of WriteByteToChunk }
  122.  
  123.