/// <summary> /// Decodes the specified discovery metadata packet. /// </summary> /// <param name="packet">The packet to decode.</param> public static DiscoveryMetadata Decode(byte[] packet) { // packet contains a length and a checksum at very least if (packet.Length < sizeof(Int32) * 2) { return(null); } // check content length var contentLength = BitConverter.ToInt32(packet, 0); if (packet.Length != contentLength + sizeof(Int32) * 2) // content + length + checksum { return(null); } // validate checksum var checksum = BitConverter.ToUInt32(packet, sizeof(Int32)); var crc = new Crc32Calculator(); crc.UpdateWithBlock(packet, sizeof(Int32) * 2, contentLength); if (checksum != crc.Crc32) { return(null); } // decode contents var contents = packet.Skip(sizeof(Int32) * 2).ToArray(); var data = Encoding.UTF8.GetString(contents).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); if (data.Length < 1) { return(null); } // extract signature and create the packet var signature = Unescape(data.First()); var dp = CreateDiscoveryMetadata(signature); if (dp == null) { return(null); } // populate properties foreach (var pair in data.Skip(1)) { var entry = pair.Split('='); dp.Properties[Unescape(entry.First())] = Unescape(entry.Last()); } return(dp); }
void UpdateTop() { uint newHash = Crc32Calculator.Compute(description); if (descriptionHash == newHash) { return; } descriptionHash = newHash; panel.TextTop.SetText(description); }
/// <summary> /// Extracts the specified entry. /// </summary> /// <param name="entry">Zip file entry to extract.</param> /// <exception cref="System.InvalidOperationException"> is thrown when the file header signature doesn't match.</exception> public Stream Extract(Entry entry) { Stream outputStream = new MemoryStream(); // check file signature Stream.Seek(entry.HeaderOffset, SeekOrigin.Begin); if (Reader.ReadInt32() != FileSignature) { throw new InvalidDataException("File signature doesn't match."); } // move to file data Stream.Seek(entry.DataOffset, SeekOrigin.Begin); var inputStream = Stream; if (entry.Deflated) { inputStream = new DeflateStream(Stream, CompressionMode.Decompress, true); } // allocate buffer, prepare for CRC32 calculation var count = entry.OriginalSize; var bufferSize = Math.Min(BufferSize, entry.OriginalSize); var buffer = new byte[bufferSize]; var crc32Calculator = new Crc32Calculator(); while (count > 0) { // decompress data var read = inputStream.Read(buffer, 0, bufferSize); if (read == 0) { break; } crc32Calculator.UpdateWithBlock(buffer, read); // copy to the output stream outputStream.Write(buffer, 0, read); count -= read; } if (crc32Calculator.Crc32 != entry.Crc32) { throw new InvalidDataException(string.Format( "Corrupted archive: CRC32 doesn't match on file {0}: expected {1:x8}, got {2:x8}.", entry.Name, entry.Crc32, crc32Calculator.Crc32)); } return(outputStream); }
internal uint GenerateNameIdentifier(NamedProperty namedProperty) { switch (namedProperty.Kind) { case PropertyKind.Lid: return(namedProperty.NameIdentifier); case PropertyKind.Name: return(Crc32Calculator.CalculateCrc32(Encoding.Unicode.GetBytes(namedProperty.Name))); default: throw new NotImplementedException(); } }
/// <summary> /// Encodes the specified discovery metadata packet into byte array. /// </summary> /// <param name="dp">The packet to encode.</param> public static byte[] Encode(DiscoveryMetadata dp) { // convert the packet into string var sb = new StringBuilder(); sb.AppendFormat("{0}|", Escape(dp.Signature)); foreach (var entry in dp.Properties) { sb.AppendFormat("{0}={1}|", Escape(entry.Key), Escape(entry.Value)); } // calculate checksum and merge var content = Encoding.UTF8.GetBytes(sb.ToString()); var crc = new Crc32Calculator(); crc.UpdateWithBlock(content, 0, content.Length); var checksum = BitConverter.GetBytes(crc.Crc32); var contentLength = BitConverter.GetBytes(content.Length); // packet contents: length, checksum, content return(contentLength.Concat(checksum).Concat(content).ToArray()); }
/// <summary> /// Extracts the specified entry. /// </summary> /// <param name="entry">Zip file entry to extract.</param> /// <param name="outputStream">The stream to write the data to.</param> /// <exception cref="System.InvalidOperationException"> is thrown when the file header signature doesn't match.</exception> public void Extract(Entry entry, Stream outputStream) { // check file signature Stream.Seek(entry.HeaderOffset, SeekOrigin.Begin); // move to file data Stream.Seek(entry.DataOffset, SeekOrigin.Begin); var inputStream = Stream; if (entry.Deflated) { inputStream = new DeflateStream(Stream, CompressionMode.Decompress, true); } // allocate buffer, prepare for CRC32 calculation var count = entry.OriginalSize; var bufferSize = Math.Min(BufferSize, entry.OriginalSize); var buffer = new byte[bufferSize]; var crc32Calculator = new Crc32Calculator(); while (count > 0) { // decompress data var read = inputStream.Read(buffer, 0, bufferSize); if (read == 0) { break; } crc32Calculator.UpdateWithBlock(buffer, read); // copy to the output stream outputStream.Write(buffer, 0, read); count -= read; } }
/// <summary> /// Extracts the specified entry. /// </summary> /// <param name="entry">Zip file entry to extract.</param> /// <param name="outputStream">The stream to write the data to.</param> /// <exception cref="System.InvalidOperationException"> is thrown when the file header signature doesn't match.</exception> public void Extract(Entry entry, Stream outputStream) { // check file signature Stream.Seek(entry.HeaderOffset, SeekOrigin.Begin); if (Reader.ReadInt32() != FileSignature) { throw new InvalidDataException("File signature doesn't match."); } // move to file data Stream.Seek(entry.DataOffset, SeekOrigin.Begin); var inputStream = Stream; if (entry.Deflated) { inputStream = new DeflateStream(Stream, CompressionMode.Decompress, true); } // allocate buffer, prepare for CRC32 calculation var count = entry.OriginalSize; var bufferSize = Math.Min(BufferSize, entry.OriginalSize); var buffer = new byte[bufferSize]; var crc32Calculator = new Crc32Calculator(); while (count > 0) { // decompress data var read = inputStream.Read(buffer, 0, bufferSize); if (read == 0) { break; } crc32Calculator.UpdateWithBlock(buffer, read); // copy to the output stream outputStream.Write(buffer, 0, read); count -= read; } if (crc32Calculator.Crc32 != entry.Crc32) { throw new InvalidDataException(string.Format( "Corrupted archive: CRC32 doesn't match on file {0}: expected {1:x8}, got {2:x8}.", entry.Name, entry.Crc32, crc32Calculator.Crc32)); } }