mirror of
				https://github.com/ClassiCube/ClassiCube.git
				synced 2025-11-03 19:16:45 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			124 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
 | 
						|
using System;
 | 
						|
using System.IO;
 | 
						|
 | 
						|
namespace ClassicalSharp.Network {
 | 
						|
	
 | 
						|
	internal class GZipHeaderReader {
 | 
						|
		
 | 
						|
		enum State {
 | 
						|
			Header1, Header2, CompressionMethod, Flags,
 | 
						|
			LastModifiedTime, CompressionFlags, OperatingSystem,
 | 
						|
			HeaderChecksum, Filename, Comment, Done,
 | 
						|
		}
 | 
						|
		
 | 
						|
		State state = State.Header1;
 | 
						|
		public bool done;
 | 
						|
		int flags;
 | 
						|
		int partsRead;
 | 
						|
		
 | 
						|
		public bool ReadHeader( Stream s ) {
 | 
						|
			switch( state ) {
 | 
						|
					
 | 
						|
				case State.Header1:
 | 
						|
					if( !ReadAndCheckHeaderByte( s, 0x1F ) )
 | 
						|
						return false;
 | 
						|
					goto case State.Header2;
 | 
						|
					
 | 
						|
				case State.Header2:
 | 
						|
					if( !ReadAndCheckHeaderByte( s, 0x8B ) )
 | 
						|
						return false;
 | 
						|
					goto case State.CompressionMethod;
 | 
						|
					
 | 
						|
				case State.CompressionMethod:
 | 
						|
					if( !ReadAndCheckHeaderByte( s, 0x08 ) )
 | 
						|
						return false;
 | 
						|
					goto case State.Flags;
 | 
						|
					
 | 
						|
				case State.Flags:
 | 
						|
					if( !ReadHeaderByte( s, out flags ) )
 | 
						|
						return false;
 | 
						|
					if( (flags & 0x04) != 0 )
 | 
						|
						throw new NotSupportedException( "Unsupported gzip flags: " + flags );
 | 
						|
					goto case State.LastModifiedTime;
 | 
						|
					
 | 
						|
				case State.LastModifiedTime:
 | 
						|
					for( ; partsRead < 4; partsRead++ ) {
 | 
						|
						int part = s.ReadByte();
 | 
						|
						if( part == -1 )
 | 
						|
							return false;
 | 
						|
					}
 | 
						|
					partsRead = 0;
 | 
						|
					state = State.CompressionFlags;
 | 
						|
					goto case State.CompressionFlags;
 | 
						|
					
 | 
						|
				case State.CompressionFlags:
 | 
						|
					int comFlags;
 | 
						|
					if( !ReadHeaderByte( s, out comFlags ) )
 | 
						|
						return false;
 | 
						|
					goto case State.OperatingSystem;
 | 
						|
					
 | 
						|
				case State.OperatingSystem:
 | 
						|
					int os;
 | 
						|
					if( !ReadHeaderByte( s, out os ) )
 | 
						|
						return false;
 | 
						|
					goto case State.Filename;
 | 
						|
					
 | 
						|
				case State.Filename:
 | 
						|
					if( (flags & 0x08) != 0 ) {
 | 
						|
						for( ; ; ) {
 | 
						|
							int part = s.ReadByte();
 | 
						|
							if( part == -1 ) return false;
 | 
						|
							if( part == 0 ) break;
 | 
						|
						}
 | 
						|
					}
 | 
						|
					state = State.Comment;
 | 
						|
					goto case State.Comment;
 | 
						|
					
 | 
						|
				case State.Comment:
 | 
						|
					if( (flags & 0x10) != 0 ) {
 | 
						|
						for( ; ; ) {
 | 
						|
							int part = s.ReadByte();
 | 
						|
							if( part == -1 ) return false;
 | 
						|
							if( part == 0 ) break;
 | 
						|
						}
 | 
						|
					}
 | 
						|
					state = State.HeaderChecksum;
 | 
						|
					goto case State.HeaderChecksum;					
 | 
						|
					
 | 
						|
				case State.HeaderChecksum:
 | 
						|
					if( ( flags & 0x02 ) != 0 ) {
 | 
						|
						for( ; partsRead < 2; partsRead++ ) {
 | 
						|
							int part = s.ReadByte();
 | 
						|
							if( part == -1 )
 | 
						|
								return false;
 | 
						|
						}
 | 
						|
					}
 | 
						|
					partsRead = 0;
 | 
						|
					state = State.Done;
 | 
						|
					done = true;
 | 
						|
					return true;
 | 
						|
			}
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
		
 | 
						|
		bool ReadAndCheckHeaderByte( Stream s, byte expected ) {
 | 
						|
			int value;
 | 
						|
			if( !ReadHeaderByte( s, out value ) )
 | 
						|
				return false;
 | 
						|
			
 | 
						|
			if( value != expected )
 | 
						|
				throw new InvalidDataException( "Unepxected constant in GZip header. (" + expected + "-" + value + ")" );
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
		
 | 
						|
		bool ReadHeaderByte( Stream s, out int value ) {
 | 
						|
			value = s.ReadByte();
 | 
						|
			if( value == -1 )
 | 
						|
				return false;
 | 
						|
			
 | 
						|
			state++;
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
	}
 | 
						|
} |