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;
 | 
						|
		}
 | 
						|
	}
 | 
						|
} |