Browse Source

small cleanups

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6872 8c9fc860-2736-0410-a75d-ab315db34111
eth.guenter 9 năm trước cách đây
mục cha
commit
e9b5c95d89
1 tập tin đã thay đổi với 35 bổ sung50 xóa
  1. 35 50
      source/OZip.mod

+ 35 - 50
source/OZip.mod

@@ -1,6 +1,6 @@
 module OZip; (** AUTHOR GF; PURPOSE "files and streams compression tool"; *)
 
-import Streams, Commands, Files, Strings, Kernel, Log := KernelLog;
+import Streams, Commands, Files, Strings, Log := KernelLog;
 
 const 
 	BlockSize = 8*1024;
@@ -33,7 +33,7 @@ type
 		val: longint
 	end;
 	
-	CodeTable = array 256 of Codebits;
+	CodeTable = pointer to array 256 of Codebits;
 	
 		
 	HuffmanCode = object
@@ -95,7 +95,7 @@ type
 			end
 		end AppendBits;
 				
-		procedure EncodeBlock( const tab: CodeTable;  const buf: array of char;  length: longint );
+		procedure EncodeBlock( tab: CodeTable;  const buf: array of char;  length: longint );
 		var i: longint;
 		begin
 			Clear;
@@ -127,6 +127,7 @@ type
 	end;
 	
 	PatternArray = array 256 of Pattern;
+	
 	PatternFrequencies = pointer to array of Pattern;		(* ordered by frequency *)
 	
 	MTFList = pointer to record
@@ -137,40 +138,22 @@ type
 	
 	procedure Compress*( r: Streams.Reader;  w: Streams.Writer );
 	var 
-		huff: HuffmanCode;  n, needed, ofs, got, chunksize, timeout: longint;
+		huff: HuffmanCode;  chunksize: longint;
 		codeTable: CodeTable;
 		pf: PatternFrequencies;
 		bwIndex: longint;
-		buffer: pointer to array of char;
-		timer: Kernel.Timer;
+		buffer: array BlockSize of char;
 	begin 
-		new( huff );  new( timer );  new( buffer, BlockSize );
+		new( huff );  new( codeTable );
 		w.RawLInt( ComprTag );
 		loop
-			if r is Files.Reader then
-				r.Bytes( buffer^, 0, BlockSize, chunksize );
-			else
-				(* give reader some time (~3 sec) to accumulate data *)
-				timeout := 100;  ofs := 0;  needed := BlockSize;
-				repeat  n := r.Available( );
-					if n > 0 then
-						if n > needed then  n := needed  end;
-						r.Bytes( buffer^, ofs, n, got );  inc( ofs, got );  dec( needed, got )
-					end;
-					if needed > 0 then 
-						if timeout <= 1600 then  timer.Sleep( timeout );  timeout := 2*timeout
-						else  needed := 0
-						end;  
-					end;
-				until needed = 0;
-				chunksize := ofs
-			end;
+			r.Bytes( buffer, 0, BlockSize, chunksize );
 			if chunksize < 1 then  exit  end;
-			BWEncode( buffer^, chunksize, bwIndex );
-			pf := CountPatterns( buffer^, chunksize );
+			BWEncode( buffer, chunksize, bwIndex );
+			pf := CountPatterns( buffer, chunksize );
 			WriteFrequencies( pf, w );
-			InitCodeTable( codeTable, BuildHuffmanTree( pf ) );
-			huff.EncodeBlock( codeTable, buffer^, chunksize );
+			codeTable := BuildCodeTable( BuildHuffmanTree( pf ) );
+			huff.EncodeBlock( codeTable, buffer, chunksize );
 			huff.WriteCode( w );
 			w.RawLInt( bwIndex );
 			w.Update;
@@ -184,21 +167,21 @@ type
 	var 
 		tree: HuffmanNode;
 		huff: HuffmanCode;
-		buffer: pointer to array of char;
 		tag, chunksize, i, bwIndex: longint;
+		buffer: array BlockSize of char;
 	begin 
 		r.RawLInt( tag );
 		if tag # ComprTag  then
 			msg := "OZip.Uncompress: bad input (compressed stream expected)"; 
 			return false
 		end;
-		new( huff ); new( buffer, BlockSize );
+		new( huff ); 
 		while r.Available( ) >= 15 (* min size of a compressed block *) do
 			tree := BuildHuffmanTree( ReadFrequencies( r ) );
 			huff.ReadCode( r );
-			huff.DecodeBlock( tree,  buffer^, chunksize );
+			huff.DecodeBlock( tree,  buffer, chunksize );
 			r.RawLInt( bwIndex );
-			BWDecode( buffer^, chunksize, bwIndex );
+			BWDecode( buffer, chunksize, bwIndex );
 			for i := 0 to chunksize - 1 do  w.Char( buffer[i] )  end
 		end;
 		w.Update;
@@ -208,10 +191,9 @@ type
 	
 	procedure BuildPatternFrequencies( var a: PatternArray ): PatternFrequencies;
 	var 
-		i, n, start: longint;
-		pf: PatternFrequencies;
+		i, n, start: longint;  pf: PatternFrequencies;
 		
-		procedure SortPF( low, high: longint );  
+		procedure SortPatterns( low, high: longint );  
 		var 
 			i, j, m: longint;  tmp: Pattern;
 		begin
@@ -226,12 +208,12 @@ type
 						inc( i );  dec( j )
 					end;
 				until i > j;
-				SortPF( low, j );  SortPF( i, high )
+				SortPatterns( low, j );  SortPatterns( i, high )
 			end
-		end SortPF;
+		end SortPatterns;
 		
 	begin
-		SortPF( 0, 255 );	(* sort patterns by frequency *)
+		SortPatterns( 0, 255 );	(* sort patterns by frequency *)
 		i := 0;
 		while a[i].frequency = 0 do  inc( i )  end; 	(* skip unused patterns *)
 		n := 256 - i;  start := i;
@@ -281,9 +263,10 @@ type
 	end BuildHuffmanTree;
 	
 	
-	procedure InitCodeTable( var table: CodeTable; huffmanTree: HuffmanNode );
+	procedure BuildCodeTable( huffmanTree: HuffmanNode ): CodeTable;
 	var 
 		start: Codebits; i: longint;
+		table: CodeTable;
 	
 		procedure Traverse( node: HuffmanNode;  bits: Codebits );
 		begin
@@ -297,10 +280,12 @@ type
 		end Traverse;
 	
 	begin
+		new( table );
 		for i := 0 to 255 do  table[i].bitsize := 0;  table[i].val := 0  end;
 		start.bitsize := 0;  start.val := 0;
 		Traverse( huffmanTree, start );
-	end InitCodeTable;
+		return table
+	end BuildCodeTable;
 	
 	
 	procedure ReadFrequencies( r: Streams.Reader ): PatternFrequencies;
@@ -344,8 +329,7 @@ type
 			lastbyte: char  
 		end;
 	var 
-		r: pointer to array of Rotation;
-		i, j: longint;
+		i, j: longint;  r: pointer to array of Rotation;
 	
 		procedure Less( a, b: longint ): boolean;
 		var i, x1, x2, i1, i2: longint;  c1, c2: char;
@@ -361,7 +345,7 @@ type
 			return false
 		end Less;
 				
-		procedure SortR( lo, hi: longint );
+		procedure SortRotations( lo, hi: longint );
 		var i, j, m: longint;  tmp: Rotation;
 		begin
 			if lo < hi then
@@ -375,9 +359,9 @@ type
 						inc( i );  dec( j )
 					end
 				until i > j;
-				SortR( lo, j );  SortR( i, hi )
+				SortRotations( lo, j );  SortRotations( i, hi )
 			end
-		end SortR;
+		end SortRotations;
 		
 	begin
 		new( r, length );
@@ -386,7 +370,7 @@ type
 			if i = 0 then  j := length - 1  else  j := i - 1  end;
 			r[i].lastbyte := buf[j]
 		end;
-		SortR( 0, length -1 );
+		SortRotations( 0, length - 1 );
 		(* replace buffer by column L *)
 		for i := 0 to length -1 do  buf[i] := r[i].lastbyte  end;
 		(* find index of the original row *)
@@ -494,7 +478,7 @@ type
 		return Files.New( name )
 	end NewFile;
 	
-	
+	(** OZip.CompressFile  infile [outfile] ~ *)
 	procedure CompressFile*( c: Commands.Context );
 	var
 		f1, f2: Files.File;
@@ -510,7 +494,6 @@ type
 				Files.OpenReader( r, f1, 0 ); 
 				f2 := NewFile( name2 );  Files.OpenWriter( w, f2, 0 );
 				Compress( r, w );  w.Update;  Files.Register( f2 );
-				Log.Ln;
 				Log.String( "Compression finished, outfile = " );  Log.String( name2 );  Log.Ln; 
 			else
 				c.error.String( "could not open file  " );  c.error.String( name1 );  c.error.Ln
@@ -522,6 +505,7 @@ type
 	end CompressFile;
 	
 	
+	(** OZip.UncompressFile  infile [outfile] ~ *)
 	procedure UncompressFile*( c: Commands.Context );
 	var
 		f1, f2: Files.File;
@@ -540,7 +524,8 @@ type
 				Files.OpenReader( r, f1, 0 );	 
 				f2 := NewFile( name2 );  Files.OpenWriter( w, f2, 0 );
 				if Uncompress( r, w, msg ) then
-					w.Update;  Files.Register( f2 )	
+					w.Update;  Files.Register( f2 );
+					Log.String( "Uncompression finished, outfile = " );  Log.String( name2 );  Log.Ln; 
 				else
 					c.error.String( msg );  c.error.Ln
 				end