public void Write()
        {
            var buffer = new byte[stream.Length - 1];

            stream.Write(buffer, 0, buffer.Length);

            Assert.AreEqual(stream.Length - 1, stream.Position);
        }
Beispiel #2
0
        public void ToStream(Stream stream)
        {
            Trace.WriteLine(Type, "Saving");

            ConstrainedStream constrainedStream = ConstrainedStream.WrapStream(stream);
            long offset = constrainedStream.Position;

            ulong calculatedLength = CalculateSize() + (ulong)(Size == 1 ? 0 : 8);

            uint  size      = 1;
            ulong largeSize = 0;

            if (calculatedLength > uint.MaxValue)
            {
                largeSize = (ulong)calculatedLength;
            }
            else
            {
                size = (uint)calculatedLength - 8;
            }

            constrainedStream.PushConstraint(size);

            constrainedStream.WriteBEUInt32(size);
            constrainedStream.WriteBEUInt32(Type.FourCC);

            if (Size == 1)
            {
                constrainedStream.WriteBEUInt64(largeSize);
            }

            if (Type.FourCC == uuidType)
            {
                constrainedStream.WriteBytes(Type.UserType.ToByteArray());
            }

            SaveToStream(constrainedStream);

            if (this is ISuperBox)
            {
                SaveChildrenToStream(constrainedStream);
            }

            // TODO: Handle IContentBox properly
            if (this is IContentBox && this.HasContent)
            {
                // TODO: Support unseekable streams for the case of Size=0
                if (_sourceStream != null && _sourceStream.CanSeek)
                {
                    ConstrainedStream source = new ConstrainedStream(_sourceStream);
                    source.PushConstraint((long)this.ContentOffset.Value, (long)this.ContentSize.Value);
                    source.Seek((long)this.ContentOffset.Value, SeekOrigin.Begin);

                    ulong remaining = this.ContentSize.Value;

                    byte[] buffer = ArrayPool <byte> .Shared.Rent(4096);

                    int len = 0;
                    do
                    {
                        len        = source.Read(buffer, 0, (ulong)buffer.Length < remaining ? buffer.Length : (int)remaining);
                        remaining -= (ulong)len;
                        constrainedStream.Write(buffer, 0, len);
                    }while (len == buffer.Length);

                    ArrayPool <byte> .Shared.Return(buffer);
                }
            }

            long remainder = offset + (size == 1 ? (long)largeSize : size) - constrainedStream.Position;

            if (remainder > 0)
            {
                Trace.WriteLine("Undershot by " + remainder + " bytes.  Padding with 0s.", "WARNING");

                for (long i = 0; i < remainder; i++)
                {
                    constrainedStream.WriteByte(0);
                }
            }

            constrainedStream.PopConstraint();
        }