Example #1
0
        /// <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);
        }
Example #2
0
        void UpdateTop()
        {
            uint newHash = Crc32Calculator.Compute(description);

            if (descriptionHash == newHash)
            {
                return;
            }

            descriptionHash = newHash;
            panel.TextTop.SetText(description);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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();
            }
        }
Example #5
0
        /// <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());
        }
Example #6
0
    /// <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;
        }
    }
Example #7
0
        /// <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));
            }
        }