Пример #1
0
        public VorbisFile(VorbisFile original, VorbisComments replacement)
        {
            // Extract comments from original file
            VorbisHeader           commentHeader    = original.GetPageHeaders().Select(p => p.GetCommentHeader()).Single(h => h != null);
            VorbisCommentsFromFile originalComments = commentHeader.ExtractComments();

            // Get new comments header into byte array
            byte[] replacementData;
            using (var ms = new MemoryStream()) {
                replacement.WriteTo(ms);
                replacementData = ms.ToArray();
            }
            if (replacementData.Length + 7 >= 255)
            {
                throw new Exception("Comment header is too long for this program to handle (must be under 248 bytes)");
            }

            // Calculate new filesize and allocate memory
            this.Length = original.Length
                          - (int)(originalComments.OrigEnd - originalComments.OrigStart)
                          + replacementData.Length;
            this.Data = Marshal.AllocHGlobal(this.Length);

            // Copy section before comment header
            byte *sourcePtr      = (byte *)original.Data;
            byte *endPtr         = sourcePtr + original.Length;
            byte *destinationPtr = (byte *)this.Data;

            while (sourcePtr < originalComments.OrigStart)
            {
                *destinationPtr++ = *sourcePtr++;
            }

            // Copy new comment header
            Marshal.Copy(replacementData, 0, (IntPtr)destinationPtr, replacementData.Length);
            destinationPtr += replacementData.Length;

            // Copy section after comment header
            sourcePtr = originalComments.OrigEnd;
            while (sourcePtr < endPtr)
            {
                *destinationPtr++ = *sourcePtr++;
            }

            if (destinationPtr - this.Length != (byte *)this.Data)
            {
                throw new Exception("not enough data written");
            }

            // Update length of segment containing comments
            byte *comment_header_segment_table_entry = (byte *)this.Data + (commentHeader.segment_table_entry - (byte *)original.Data);

            *comment_header_segment_table_entry = (byte)(replacementData.Length + 7);

            // Recalculate all checksums
            foreach (OggPage page in GetPageHeaders())
            {
                page.RecalculateCrc32();
            }
        }
Пример #2
0
 internal OggPage(VorbisFile parent, OggPageHeader *header)
 {
     this.Parent = parent;
     this.Header = header;
 }