home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
filutl
/
decuf13.ark
/
DECUF.IF0
< prev
next >
Wrap
Text File
|
1989-09-27
|
4KB
|
123 lines
{*
* CHUNKS : The decoded data is buffered into a number of buffers,
* called chunks in this program, which are allocated in the heap.
* If the heap is full or if the end statement is encountered in the
* inputfile, the chunks in the heap are written to the result file.
* In this way a rapid alteration of reading from the input and writing
* to the result file are avoided, hopefully resulting in an increased
* performance.
*}
procedure FlushChunks ;
{*
* FlushChunks - Write all chunks in memory to the result file. While
* writing, the chunks are released to the heap.
*
* The chunks are written as an integral number of 128-byte records. The
* last record is padded with zeroes if necessary.
*}
var
Chunk : ChunkPtr ; { Next chunk to write to disk }
Flushed : Boolean ; { Something written (flushed) to file }
I : Integer ; { Loop control variable }
begin
Chunk := HeadChunkList ;
Flushed:= False ;
while Chunk<>Nil do
begin
HeadChunkList:= HeadChunkList^.NextChunk ;
I := Chunk^.ChunkSize ;
if I>0 then
begin
while (I and $007F) <> 0 do
begin
Chunk^.Data[I]:= 0 ;
Inc( I ) ;
end ;
I:= I shr 7 ; { Number of records to write }
BlockWrite( OutputFile, Chunk^.Data, I ) ;
BytesWritten:= BytesWritten + I ; { Update record (!) count }
Flushed := True ;
end ; { of if }
Dispose( Chunk ) ;
Chunk:= HeadChunkList ;
end ; { of while }
TailChunkList:= Nil ;
if Flushed then
Inc( HeapFlushes ) ;
end ; { of FlushChunks }
procedure ReleaseChunks ;
{*
* ReleaseChunks - Return all chunks to the free heap space. Any data
* gathered in chunks is lost.
*}
var
Chunk : ChunkPtr ; { Pointer to a chunk }
begin
Chunk:= HeadChunkList ;
while Chunk<>Nil do
begin
HeadChunkList:= HeadChunkList^.NextChunk ;
Dispose( Chunk ) ;
Chunk:= HeadChunkList ;
end ; { of while }
TailChunkList:= Nil ;
end ; { of ReleaseChunks }
procedure AllocateChunk ;
{*
* AllocateChunk - Allocate a new chunk to write data into. If there
* is no space left in the heap, it is flushed to make
* room for more data.
*}
var
Chunk : ChunkPtr ; { (pointer to) new chunk }
begin
if (MaxAvail>0) and (SizeOf(Chunks)>MaxAvail) then
FlushChunks ;
New( Chunk ) ;
Chunk^.NextChunk:= Nil ;
Chunk^.ChunkSize:= 0 ;
if HeadChunkList=Nil then
begin
HeadChunkList:= Chunk ;
TailChunkList:= Chunk ;
end
else
begin
TailChunkList^.NextChunk:= Chunk ;
TailChunkList := Chunk ;
end ; { of if }
end ; { of AllocateChunk }
procedure WriteByteToChunk( NextByte : Byte ) ;
{*
* WriteByteToChunk - Write one byte into the next free location in the
* 'current' chunk. If the chunk is full, a new one
* is allocated.
*}
var
Chunk : ChunkPtr ; { Pointer to 'current' chunk in chain }
begin
if TailChunkList^.ChunkSize>=MaxChunkSize then
AllocateChunk ;
Chunk:= TailChunkList ;
Chunk^.ChunkSize:= Succ(Chunk^.ChunkSize) ;
Chunk^.Data[Chunk^.ChunkSize]:= NextByte ;
{*
* If a CarriageReturn character is written, it is assumed that it is the
* end of a line. If the result file is a normal ascii text file, the
* number of lines can be counted by counting the CarriageReturn's.
*}
if NextByte=$0D then
Inc( LinesWritten ) ;
end ; { of WriteByteToChunk }