/// <summary> /// Read the sequence data. /// </summary> /// <param name="data">Sequence data.</param> /// <param name="byteOrder">Byte order.</param> public void Read(byte[] data, ByteOrder byteOrder) { //New reader. MemoryStream src = new MemoryStream(data); BinaryDataReader br = new BinaryDataReader(src) { ByteOrder = byteOrder }; //Read the data. Commands = new List <SequenceCommand>(); bool ended = false; while (br.Position < data.Length && !ended) { //Add command. var s = SequenceCommand.Read(br); Commands.Add(s); //If the command is end, and the rest is just padding. if (s as FinCommand != null) { long currPos = br.Position; byte[] raw = br.ReadBytes((int)(data.Length - currPos)); if (raw.Length > 0) { if (raw.Max() == 0) { ended = true; } } else { ended = true; } br.Position = currPos; } } //Go ahead and convert the public offsets to command indices. for (int i = 0; i < PublicLabelOffsets.Count; i++) { //Convert the offset to an index. PublicLabelOffsets[PublicLabelOffsets.ElementAt(i).Key] = OffsetToCommandIndex(Commands, PublicLabelOffsets.ElementAt(i).Value); } //Fix control commands. for (int i = 0; i < Commands.Count; i++) { //Make sure the command is a control command. if ((CommandType)Commands[i].Identifier == CommandType.Call || (CommandType)Commands[i].Identifier == CommandType.Jump || (CommandType)Commands[i].Identifier == CommandType.OpenTrack || (CommandType)Commands[i].Identifier == CommandType.If) { if ((CommandType)Commands[i].Identifier == CommandType.If) { //The first parameter is going to be the offset. int offset = 0; if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Call || (CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Jump) { offset = (int)((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[0]).Value; } else if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.OpenTrack) { offset = (int)((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[1]).Value; } //Get the index. int index = OffsetToCommandIndex(Commands, offset); //Set the property to this. if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Call || (CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.Jump) { ((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[0]).Value = (uint)index; } else if ((CommandType)((IfCommand)Commands[i]).SequenceCommand.Identifier == CommandType.OpenTrack) { ((UInt24)((IfCommand)Commands[i]).SequenceCommand.Parameters[1]).Value = (uint)index; } } else { //The first parameter is going to be the offset. int offset = 0; if ((CommandType)Commands[i].Identifier == CommandType.Call || (CommandType)Commands[i].Identifier == CommandType.Jump) { offset = (int)((UInt24)Commands[i].Parameters[0]).Value; } else { offset = (int)((UInt24)Commands[i].Parameters[1]).Value; } //Get the index. int index = OffsetToCommandIndex(Commands, offset); //Set the property to this. if ((CommandType)Commands[i].Identifier == CommandType.Call || (CommandType)Commands[i].Identifier == CommandType.Jump) { ((UInt24)Commands[i].Parameters[0]).Value = (uint)index; } else { ((UInt24)Commands[i].Parameters[1]).Value = (uint)index; } } } } //Update private offsets. RefreshPrivateOffsets(); //Free. br.Dispose(); }