/// <summary> /// Build a binary data frame form the frame object. /// </summary> /// <param name="frame">ID3 Frame</param> /// <returns>binary frame representation</returns> public byte[] Make(FrameBase frame, out ushort flags) { flags = GetFlags(frame); var buffer = frame.Make(); var memoryStream = new MemoryStream(); var writer = new BinaryWriter(memoryStream); if (frame.Group.HasValue == true) { writer.Write((byte)frame.Group); } if (frame.Compression == true) { switch (Version) { case 3: { writer.Write(Swap.Int32(buffer.Length)); break; } case 4: { writer.Write(Sync.UnsafeBigEndian(Swap.UInt32((uint)buffer.Length))); break; } default: { throw new NotImplementedException("ID3v2 Version " + Version + " is not supported."); } } var buf = new byte[2048]; var deflater = new Deflater(Deflater.BEST_COMPRESSION); deflater.SetInput(buffer, 0, buffer.Length); deflater.Finish(); while (!deflater.IsNeedingInput) { int len = deflater.Deflate(buf, 0, buf.Length); if (len <= 0) { break; } memoryStream.Write(buf, 0, len); } if (!deflater.IsNeedingInput) { //TODO: Skip and remove invalid frames. throw new InvalidFrameException("Can't decompress frame '" + frame.FrameId + "' missing data"); } } else { memoryStream.Write(buffer, 0, buffer.Length); } if (frame.Encryption == true) { //TODO: Encryption throw new NotImplementedException("Encryption is not implemented, consequently it is not supported."); } if (frame.Unsynchronisation == true) { MemoryStream synchStream = new MemoryStream(); Sync.Unsafe(memoryStream, synchStream, (uint)memoryStream.Position); memoryStream = synchStream; } return(memoryStream.ToArray()); }
internal byte[] Make([NotNull] FrameBase frame, out ushort flags) { flags = GetFlags(frame); var buffer = frame.Make(); var memoryStream = new MemoryStream(); var streamsToClose = new List <Stream>(2) { memoryStream }; try { using (var writer = new BinaryWriter(memoryStream, Encoding.UTF8, true)) { if (frame.Group.HasValue) { writer.Write((byte)frame.Group); } if (frame.Compression) { switch (_version) { case 3: writer.Write(Swap.Int32(buffer.Length)); break; case 4: writer.Write(Sync.UnsafeBigEndian(Swap.UInt32((uint)buffer.Length))); break; default: throw new NotImplementedException($"ID3v2 Version {_version} is not supported."); } var buf = new byte[2048]; var deflater = new Deflater(Deflater.BEST_COMPRESSION); deflater.SetInput(buffer, 0, buffer.Length); deflater.Finish(); while (!deflater.IsNeedingInput) { var len = deflater.Deflate(buf, 0, buf.Length); if (len <= 0) { break; } memoryStream.Write(buf, 0, len); } //TODO: Skip and remove invalid frames. if (!deflater.IsNeedingInput) { throw new InvalidFrameException($"Can't decompress frame '{frame.FrameId}' missing data"); } } else { memoryStream.Write(buffer, 0, buffer.Length); } //TODO: Encryption if (frame.Encryption) { throw new NotImplementedException( "Encryption is not implemented, consequently it is not supported."); } if (frame.Unsynchronisation) { var synchStream = new MemoryStream(); streamsToClose.Add(synchStream); Sync.Unsafe(memoryStream, synchStream, (uint)memoryStream.Position); memoryStream = synchStream; } return(memoryStream.ToArray()); } } finally { foreach (var streamToClose in streamsToClose) { streamToClose.Close(); } } }