/// <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());
        }
Exemple #2
0
        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();
                }
            }
        }