예제 #1
0
 /// <inheritdoc />
 public override int Deserialize(Core.Utility.BinaryReader reader)
 {
     Primary   = reader.ReadInt32();
     Secondary = reader.ReadInt32();
     Current   = reader.ReadInt32();
     return(DeserializeByteCount);
 }
예제 #2
0
        private static ExtraFlags ReadExtraFlags(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var extraFlags = (ExtraFlags)reader.ReadByte();

            bytesRead += sizeof(ExtraFlags);
            return(extraFlags);
        }
예제 #3
0
        private static GZipOS ReadOperatingSystem(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var operatingSystem = (GZipOS)reader.ReadByte();

            bytesRead += sizeof(GZipOS);
            return(operatingSystem);
        }
예제 #4
0
        private static CfgVarMetadataIdTag DecodeBlockType(Core.Utility.BinaryReader reader)
        {
            var type          = CfgVarMetadataIdTag.Invalid;
            var payloadLength = reader.BaseStream.Length;
            var data          = new byte[payloadLength];
            var bytesRead     = 0;
            var foundEquals   = false;

            while (!foundEquals && (bytesRead < payloadLength))
            {
                var byteChar  = reader.ReadByte();
                var character = Convert.ToChar(byteChar);
                foundEquals = character == '=';
                if (!foundEquals)
                {
                    data[bytesRead++] = byteChar;
                }
            }
            if (foundEquals)
            {
                var tagString = System.Text.Encoding.UTF8.GetString(data, 0, data.Length).Trim('\0').Trim();
                type = tagString.ToCfgVarMetadataIdTag();
            }
            return(type);
        }
예제 #5
0
        private static object DateMetadataParser(Core.Utility.BinaryReader reader, byte payloadLength)
        {
            System.Diagnostics.Debug.Assert(payloadLength >= 1, "LUIGI Year metadata should contain at least one byte.");
            var date = reader.ParseDateTimeFromMetadata(payloadLength);

            return(date);
        }
예제 #6
0
        private static object StringMetadataParser(Core.Utility.BinaryReader reader, byte payloadLength)
        {
            // Documentation indicates this could be ASCII or UTF-8...
            var stringResult = reader.ParseStringFromMetadata(payloadLength, allowLineBreaks: false);

            return(stringResult);
        }
예제 #7
0
 /// <inheritdoc />
 public override int Deserialize(Core.Utility.BinaryReader reader)
 {
     using (var file = new System.IO.FileStream(FileInfo.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Write))
     {
         reader.BaseStream.CopyTo(file);
     }
     return((int)FileInfo.Length);
 }
예제 #8
0
        private static string DeserializePayload(Core.Utility.BinaryReader reader)
        {
            var payloadSize = (int)reader.BaseStream.Length;
            var bytes       = reader.ReadBytes(payloadSize);
            var payload     = System.Text.Encoding.UTF8.GetString(bytes);

            return(payload);
        }
예제 #9
0
        private static string ReadComment(Core.Utility.BinaryReader reader, MetadataFlags flags, ref int bytesRead)
        {
            string comment = null;

            if (flags.HasFlag(MetadataFlags.Comment))
            {
                comment = ReadNullTerminatedString(reader, ref bytesRead);
            }
            return(comment);
        }
예제 #10
0
        private static void CheckHeader(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var identifier = reader.ReadBytes(MagicIdentifier.Length);

            bytesRead += identifier.Length;
            if (!identifier.SequenceEqual(MagicIdentifier))
            {
                throw new InvalidOperationException(Resources.Strings.GZipHeaderError_InvalidMagic);
            }
        }
예제 #11
0
        /// <inheritdoc />
        /// <remarks>The precondition here is that the reader is positioned immediately after the ROM metadata block type.</remarks>
        public override int Deserialize(Core.Utility.BinaryReader reader)
        {
            var deserializedPayloadLength = DeserializePayload(reader);

            if (deserializedPayloadLength != Length)
            {
                throw new System.InvalidOperationException(Resources.Strings.RomMetadata_FailedToDeserializePayload);
            }
            return((int)deserializedPayloadLength);
        }
예제 #12
0
        public static IEnumerable <GZipMemberEntry> GetMemberEntries(Stream stream, int maxNumberOfEntries = -1)
        {
            var length          = stream.Length;
            var initialPosition = stream.Position;
            var currentPosition = stream.Seek(0, SeekOrigin.Begin);
            var memberEntries   = new List <GZipMemberEntry>();

            if (maxNumberOfEntries < 0)
            {
                maxNumberOfEntries = int.MaxValue;
            }

            var entryOffset = 0L;

            while ((memberEntries.Count < maxNumberOfEntries) && (stream.Position < length))
            {
                try
                {
                    var entry = Inflate(stream);
                    entry.Offset = entryOffset;
                    memberEntries.Add(entry);
                    if (memberEntries.Count < maxNumberOfEntries)
                    {
                        using (var reader = new Core.Utility.BinaryReader(stream))
                        {
                            currentPosition = FindNextEntry(reader, entry);
                            entryOffset     = currentPosition;
                        }
                    }
                }
                catch (InvalidOperationException)
                {
                    // We thought we found another entry, but failed to parse the header - so we hit
                    // a false positive. We *could* resume the search and keep on searching... but
                    // this is all pretty fragile so let's just give up.
                    break;
                }
            }

            var defaultFileName       = GetDefaultEntryName(stream);
            var baseFileName          = Path.GetFileNameWithoutExtension(defaultFileName);
            var originalFileExtension = Path.GetExtension(defaultFileName);

            for (int i = 0; i < memberEntries.Count; ++i)
            {
                var entry = memberEntries[i];
                if (!entry.Flags.HasFlag(MetadataFlags.FileName) && (memberEntries.FindIndex(e => e.Name == defaultFileName) != i))
                {
                    entry._name = string.Format(CultureInfo.InvariantCulture, "{0}_{1}{2}", baseFileName, i, originalFileExtension);
                }
            }

            stream.Seek(initialPosition, SeekOrigin.Begin);
            return(memberEntries);
        }
예제 #13
0
        private static MetadataFlags ReadFlags(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var flags = (MetadataFlags)reader.ReadByte();

            bytesRead += sizeof(MetadataFlags);
            if (flags.HasFlag(MetadataFlags.Reserved5 | MetadataFlags.Reserved6 | MetadataFlags.Reserved7))
            {
                throw new InvalidOperationException(Resources.Strings.GZipHeaderError_ReservedFlagsSet);
            }
            return(flags);
        }
예제 #14
0
        /// <summary>
        /// Deserializes the payload.
        /// </summary>
        /// <param name="reader">The binary reader containing the data to deserialize to create the object.</param>
        /// <returns>The number of bytes deserialized.</returns>
        /// <remarks>The default implementation merely validates that the payload is correct. Specific subclasses may override this implementation if
        /// any specific data from the payload is desired.</remarks>
        /// <exception cref="System.IO.EndOfStreamException">Thrown if the data stream does not contain enough data as specified by payload length.</exception>
        /// <exception cref="System.IO.InvalidDataException">Thrown if the payload checksum differs from the expected checksum.</exception>
        protected virtual int DeserializePayload(Core.Utility.BinaryReader reader)
        {
            var payload = reader.ReadBytes(Length);

            if (payload.Length < Length)
            {
                throw new System.IO.EndOfStreamException();
            }
            ValidatePayloadCrc(payload);
            return(Length);
        }
예제 #15
0
        private static CompressionMethod ReadCompressionMethod(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var compressionMethod = (CompressionMethod)reader.ReadByte();

            bytesRead += sizeof(CompressionMethod);
            if (compressionMethod != CompressionMethod.Deflate)
            {
                throw new InvalidOperationException(Resources.Strings.GZipHeaderError_InvalidCompression);
            }
            return(compressionMethod);
        }
예제 #16
0
        private static ushort ReadCrc16(Core.Utility.BinaryReader reader, MetadataFlags flags, ref int bytesRead)
        {
            ushort crc16 = 0;

            if (flags.HasFlag(MetadataFlags.Crc16Present))
            {
                crc16      = reader.ReadUInt16();
                bytesRead += sizeof(ushort);
            }
            return(crc16);
        }
예제 #17
0
        private void ValidateHeaderCrc(Core.Utility.BinaryReader reader, int bytesRead)
        {
            reader.BaseStream.Seek(-bytesRead, System.IO.SeekOrigin.Current);
            var data = reader.ReadBytes(bytesRead - 1);
            var crc8 = Crc8.OfBlock(data);

            reader.BaseStream.Seek(bytesRead, System.IO.SeekOrigin.Begin);
            if (crc8 != Crc)
            {
                throw new System.IO.InvalidDataException(string.Format(CultureInfo.CurrentCulture, Resources.Strings.InvalidDataBlockChecksumFormat, crc8, Crc));
            }
        }
예제 #18
0
        private static DateTime ReadLastModifiedTime(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var lastModifiedTime    = DateTime.MinValue;
            var modifiedTimeUnixUtc = reader.ReadUInt32();

            if (modifiedTimeUnixUtc != 0)
            {
                var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
                lastModifiedTime = epoch.AddSeconds(modifiedTimeUnixUtc);
            }
            bytesRead += sizeof(uint);
            return(lastModifiedTime);
        }
예제 #19
0
        private static long FindNextEntry(Core.Utility.BinaryReader reader, GZipMemberEntry currentEntry)
        {
            var foundMagic          = false;
            var positionOfNextEntry = -1L;

            try
            {
                var magic = reader.ReadByte();
                while (true)
                {
                    if (magic == MagicIdentifier[0])
                    {
                        magic = reader.ReadByte();
                        if (magic == MagicIdentifier[1])
                        {
                            foundMagic = true;
                            break;
                        }
                    }
                    else
                    {
                        magic = reader.ReadByte();
                    }
                }
            }
            catch (EndOfStreamException)
            {
                positionOfNextEntry = reader.BaseStream.Length;
            }
            catch (IOException)
            {
            }

            if (foundMagic || (positionOfNextEntry == reader.BaseStream.Length))
            {
                // go back 4 (CRC32) + 4 (size mod 2^32) [+ 2 (magic)]
                var offset = sizeof(uint) + sizeof(int);
                var origin = SeekOrigin.End;
                if (foundMagic)
                {
                    offset += MagicIdentifier.Length;
                    origin  = SeekOrigin.Current;
                }
                reader.BaseStream.Seek(-offset, origin);
                currentEntry.Crc32   = reader.ReadUInt32();
                currentEntry._length = reader.ReadInt32();
                positionOfNextEntry  = reader.BaseStream.Position;
            }

            return(positionOfNextEntry);
        }
예제 #20
0
        private static uint DecodeLength(Core.Utility.BinaryReader reader, out int additionalBytesInPayloadLength)
        {
            var  data          = reader.ReadByte();
            uint payloadLength = (uint)(data & ~PayloadLengthMask); // low 6 bits are the low 6 bits of payload length

            additionalBytesInPayloadLength = (data & PayloadLengthMask) >> PayloadLengthBitShift;
            for (var i = 0; i < additionalBytesInPayloadLength; ++i)
            {
                uint partialLengthBits = reader.ReadByte();
                partialLengthBits = partialLengthBits << ((i * 8) + PayloadLengthBitShift);
                payloadLength    |= partialLengthBits;
            }
            return(payloadLength);
        }
예제 #21
0
        private static string ReadFileName(Core.Utility.BinaryReader reader, MetadataFlags flags, ref int bytesRead)
        {
            string name = null;

            if (flags.HasFlag(MetadataFlags.FileName))
            {
                name = ReadNullTerminatedString(reader, ref bytesRead);
            }
            else
            {
                name = GetDefaultEntryName(reader.BaseStream);
            }
            return(name);
        }
예제 #22
0
        private static SubfieldId ReadExtraFields(Core.Utility.BinaryReader reader, MetadataFlags flags, ref int bytesRead)
        {
            var subfieldIdentifier = SubfieldId.None;

            if (flags.HasFlag(MetadataFlags.ExtraFieldsPresent))
            {
                subfieldIdentifier = (SubfieldId)reader.ReadUInt16();
                bytesRead         += sizeof(SubfieldId);

                var subfieldDataLength = reader.ReadUInt16();                   // little-endian
                bytesRead += sizeof(ushort);
                reader.BaseStream.Seek(subfieldDataLength, SeekOrigin.Current); // just skip
            }
            return(subfieldIdentifier);
        }
예제 #23
0
        /// <inheritdoc/>
        protected override int DeserializePayload(Core.Utility.BinaryReader reader)
        {
            // This is inefficient, but simple. Read and walk the payload twice. First time validates its checksum. Second pass actually parses it.
            base.DeserializePayload(reader);
            reader.BaseStream.Seek(-Length, System.IO.SeekOrigin.Current);

            var runningBytesRead = 0;

            while (runningBytesRead < Length)
            {
                var tag = (LuigiMetadataIdTag)reader.ReadByte();
                ++runningBytesRead;
                var dataLength = reader.ReadByte();
                ++runningBytesRead;

                MetadataParser parser;
                if (!MetadataParsers.TryGetValue(tag, out parser))
                {
                    parser = DefaultMetadataParser;
                }

                var metadata = parser(reader, dataLength);
                runningBytesRead += dataLength;

                switch (tag)
                {
                case LuigiMetadataIdTag.Date:
                    var date = (MetadataDateTime)metadata;
                    _releaseDates.Add(date);
                    break;

                default:
                    List <string> metadataStringStorage;
                    if (_stringMetadataEntries.TryGetValue(tag, out metadataStringStorage))
                    {
                        var stringResult = (string)metadata;
                        metadataStringStorage.Add(stringResult);
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Either failed to parse or could not find storage for tag: " + tag);
                    }
                    break;
                }
            }
            return(Length);
        }
예제 #24
0
        /// <inheritdoc />
        /// <remarks>The precondition here is that the reader is positioned immediately after the LUIGI block type value.</remarks>
        public override int Deserialize(Core.Utility.BinaryReader reader)
        {
            Length = reader.ReadUInt16();
            var bytesRead = PayloadLengthSize;

            HeaderCrc  = reader.ReadByte();
            bytesRead += HeaderChecksumSize;
            ValidateHeaderCrc();

            if (Length > 0)
            {
                PayloadCrc = reader.ReadUInt32();
                bytesRead += PayloadChecksumSize;
                bytesRead += DeserializePayload(reader);
            }
            return(bytesRead);
        }
예제 #25
0
        private static string ReadNullTerminatedString(Core.Utility.BinaryReader reader, ref int bytesRead)
        {
            var  fileNameBytes    = new List <byte>();
            byte currentCharacter = 0;

            do
            {
                currentCharacter = reader.ReadByte();
                ++bytesRead;
                fileNameBytes.Add(currentCharacter);
            }while (currentCharacter != 0);

            var encoding = Encoding.GetEncoding("iso-8859-1");

            var stringValue = encoding.GetString(fileNameBytes.ToArray(), 0, fileNameBytes.Count - 1);

            return(stringValue);
        }
예제 #26
0
        /// <inheritdoc />
        public override int Deserialize(Core.Utility.BinaryReader reader)
        {
            int bytesRead = 0;

            CheckHeader(reader, ref bytesRead);
            Compression           = ReadCompressionMethod(reader, ref bytesRead);
            Flags                 = ReadFlags(reader, ref bytesRead);
            _lastModificationTime = ReadLastModifiedTime(reader, ref bytesRead);
            CompressionHint       = ReadExtraFlags(reader, ref bytesRead);
            OperatingSystem       = ReadOperatingSystem(reader, ref bytesRead);
            SubfieldIdentifier    = ReadExtraFields(reader, Flags, ref bytesRead);
            _name                 = ReadFileName(reader, Flags, ref bytesRead);
            Comment               = ReadComment(reader, Flags, ref bytesRead);
            Crc16                 = ReadCrc16(reader, Flags, ref bytesRead);
            _deserializeByteCount = bytesRead;

            return(bytesRead);
        }
예제 #27
0
        /// <inheritdoc />
        public override int Deserialize(Core.Utility.BinaryReader reader)
        {
            var responseBuffer = new byte[UniqueIdSize];
            var numRead        = reader.Read(responseBuffer, 0, UniqueIdSize);
            var lowPart        = System.BitConverter.ToUInt64(responseBuffer, 0);
            var highPart       = System.BitConverter.ToUInt64(responseBuffer, 8);

            UniqueId = highPart.ToString("X16") + lowPart.ToString("X16");
            var lowStatusBits  = (DeviceStatusFlagsLo)reader.ReadUInt64();
            var highStatusBits = (DeviceStatusFlagsHi)reader.ReadUInt64();

            DeviceStatusFlags = new Model.DeviceStatusFlags(lowStatusBits, highStatusBits);
            numRead          += StatusBytesSize;

            // TODO: throw here?
            System.Diagnostics.Debug.Assert(numRead == DeserializeByteCount, "Failed to deserialize correct number of bytes in DeviceStatusResponse.");
            return(numRead);
        }
예제 #28
0
        /// <inheritdoc />
        /// <remarks>The precondition here is that the reader is positioned immediately after the ROM metadata block type.</remarks>
        public override int Deserialize(Core.Utility.BinaryReader reader)
        {
            int deserializedPayloadLength = 0;
            var payloadLength             = reader.BaseStream.Length;
            var data = new byte[payloadLength];

            try
            {
                while (deserializedPayloadLength < payloadLength)
                {
                    data[deserializedPayloadLength++] = reader.ReadByte();
                }
            }
            catch (System.IO.EndOfStreamException)
            {
            }
            var payload = ConvertPayloadToString(data);

            Parse(payload);
            return(deserializedPayloadLength);
        }
예제 #29
0
        /// <inheritdoc/>
        protected override int DeserializePayload(Core.Utility.BinaryReader reader)
        {
            // Verify we're not going to be truncated.
            if ((reader.BaseStream.Length - reader.BaseStream.Position) < Length)
            {
                throw new System.IO.EndOfStreamException();
            }

            // Get the clear portion of the key - the DRUID.
            var responseBuffer = new byte[UniqueIdSize];

            reader.Read(responseBuffer, 0, UniqueIdSize);
            var lowPart  = System.BitConverter.ToUInt64(responseBuffer, 0);
            var highPart = System.BitConverter.ToUInt64(responseBuffer, 8);

            UniqueId = highPart.ToString("X16") + lowPart.ToString("X16");

            // Skip past the rest of it - we've got all we care about.
            reader.BaseStream.Seek(Length - UniqueIdSize, System.IO.SeekOrigin.Current);

            // NOTE: Scrambled blocks *CANNOT* be validated by a CRC check!
            return(Length);
        }
예제 #30
0
 private static object DefaultMetadataParser(Core.Utility.BinaryReader reader, byte payloadLength)
 {
     reader.BaseStream.Seek(payloadLength, System.IO.SeekOrigin.Current);
     return(null);
 }