private ByteVector RenderUniqueFields()
		{
			ByteVector data = new ByteVector();

			data.Add(ByteVector.FromString(owner, StringType.Latin1));
			data.Add(TextDelimiter(StringType.Latin1));
			data.Add(identifier);

			return data;
		}
예제 #2
0
 public override void SetCommentPacket (ByteVectorCollection packets, XiphComment comment)
 {
    if (packets == null)
       throw new ArgumentNullException ("packets");
    
    if (comment == null)
       throw new ArgumentNullException ("comment");
    
    ByteVector data = new ByteVector ((byte) 0x03);
    data.Add (id);
    data.Add (comment.Render (true));
    if (packets.Count > 1 && PacketType (packets [1]) == 0x03)
       packets [1] = data;
    else
       packets.Insert (1, data);
 }
		private ByteVector RenderPrivateFields()
		{
			ByteVector vector = new ByteVector();

			vector.Add(ByteVector.FromString(owner, StringType.Latin1));
			vector.Add(TextDelimiter(StringType.Latin1));
			vector.Add(data);

			return vector;
		}
 public override ByteVector Render()
 {
     ByteVector data = new ByteVector();
     foreach (TagLib.Asf.Object obj2 in this.children)
     {
         data.Add(obj2.Render());
     }
     data.Insert(0, TagLib.Asf.Object.RenderDWord((uint) data.Count));
     data.Insert(0, TagLib.Asf.Object.RenderWord(6));
     data.Insert(0, TagLib.Asf.Guid.AsfReserved1.ToByteArray());
     return base.Render(data);
 }
 public override ByteVector Render()
 {
     ByteVector data = new ByteVector();
     uint num = 0;
     foreach (TagLib.Asf.Object obj2 in this.children)
     {
         if (obj2.Guid != TagLib.Asf.Guid.AsfPaddingObject)
         {
             data.Add(obj2.Render());
             num++;
         }
     }
     long num2 = (data.Count + 30L) - ((long) base.OriginalSize);
     if (num2 != 0)
     {
         data.Add(new PaddingObject((num2 <= 0L) ? ((uint) -num2) : ((uint) 0x1000L)).Render());
         num++;
     }
     data.Insert(0, this.reserved);
     data.Insert(0, TagLib.Asf.Object.RenderDWord(num));
     return base.Render(data);
 }
예제 #6
0
 public ByteVector Render()
 {
     ByteVector vector = new ByteVector {
         ByteVector.FromUInt((uint) this.Type)
     };
     ByteVector data = ByteVector.FromString(this.MimeType, StringType.Latin1);
     vector.Add(ByteVector.FromUInt((uint) data.Count));
     vector.Add(data);
     ByteVector vector3 = ByteVector.FromString(this.Description, StringType.UTF8);
     vector.Add(ByteVector.FromUInt((uint) vector3.Count));
     vector.Add(vector3);
     vector.Add(ByteVector.FromUInt((uint) this.Width));
     vector.Add(ByteVector.FromUInt((uint) this.Height));
     vector.Add(ByteVector.FromUInt((uint) this.ColorDepth));
     vector.Add(ByteVector.FromUInt((uint) this.IndexedColors));
     vector.Add(ByteVector.FromUInt((uint) this.Data.Count));
     vector.Add(this.Data);
     return vector;
 }
		private string CreateDataString (int min_size)
		{
			string src = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

			ByteVector data = new ByteVector ();

			for (int i = 0; data.Count < min_size; i++)
			{
				int index = i % src.Length;
				data.Add (src.Substring (index, src.Length - index));
			}

			return data.ToString ();
		}
예제 #8
0
        /// <summary>
        ///    Overwrites all page headers in a file starting at a
        ///    specified position, shifting the page sequence numbers
        ///    a set amount.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="File" /> object containing the file to
        ///    update.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specify at what position to
        ///    start updating.
        /// </param>
        /// <param name="shiftTable">
        ///    A <see cref="T:System.Collections.Generic.IDictionary`2"
        ///    /> object where the key is the serial number of the
        ///    stream to update and the value is the amount to offset
        ///    the page sequence numbers in the stream.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> or <paramref name="shiftTable"
        ///    /> is <see langword="null" />.
        /// </exception>
        /// <remarks>
        ///    When the number of pages in a stream changes, all
        ///    subsequent pages in the stream need to have their page
        ///    sequence number update in order to remain valid.
        ///    Additionally, when the page sequence number changes, the
        ///    page needs to have its checksum recomputed. This makes
        ///    for a costly recalculation if large comment data is
        ///    added.
        /// </remarks>
        public static void OverwriteSequenceNumbers(File file,
                                                    long position,
                                                    IDictionary <uint, int> shiftTable)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            if (shiftTable == null)
            {
                throw new ArgumentNullException("shiftTable");
            }

            // Check to see if there are no changes to be made.
            bool done = true;

            foreach (KeyValuePair <uint, int> pair in shiftTable)
            {
                if (pair.Value != 0)
                {
                    done = false;
                    break;
                }
            }

            // If the file is fine, quit.
            if (done)
            {
                return;
            }

            while (position < file.Length - 27)
            {
                PageHeader header = new PageHeader(file, position);
                int        size   = (int)(header.Size + header.DataSize);

                if (shiftTable.ContainsKey(header.StreamSerialNumber) &&
                    shiftTable [header.StreamSerialNumber] != 0)
                {
                    file.Seek(position);
                    ByteVector page_data = file.ReadBlock(size);

                    ByteVector new_data = ByteVector.FromUInt(
                        (uint)(header.PageSequenceNumber +
                               shiftTable [header.StreamSerialNumber]),
                        false);

                    for (int i = 18; i < 22; i++)
                    {
                        page_data [i] = new_data [i - 18];
                    }
                    for (int i = 22; i < 26; i++)
                    {
                        page_data [i] = 0;
                    }

                    new_data.Add(ByteVector.FromUInt(
                                     page_data.Checksum, false));
                    file.Seek(position + 18);
                    file.WriteBlock(new_data);
                }
                position += size;
            }
        }
예제 #9
0
		/// <summary>
		///    Renders the current instance as a raw ID3v2 header.
		/// </summary>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered header.
		/// </returns>
		public ByteVector Render ()
		{
			ByteVector v = new ByteVector ();
			v.Add (FileIdentifier);
			v.Add (MajorVersion);
			v.Add (RevisionNumber);
			v.Add ((byte)flags);
			v.Add (SynchData.FromUInt (TagSize));
			return v;
		}
예제 #10
0
      public ByteVector Render ()
      {
         ByteVector data = new ByteVector ();

         data.Add ("OggS");
         data.Add (_version); // stream structure version
         data.Add ((byte) _flags);
         data.Add (ByteVector.FromULong (_absolute_granular_position, false));
         data.Add (ByteVector.FromUInt (_stream_serial_number, false));
         data.Add (ByteVector.FromUInt ((uint) _page_sequence_number, false));
         data.Add (new ByteVector (4, 0)); // checksum, to be filled in later.
         ByteVector page_segments = LacingValues;
         data.Add ((byte) page_segments.Count);
         data.Add (page_segments);

         return data;
      }
예제 #11
0
		/// <summary>
		///    Renders the current instance, including its children, to
		///    a new <see cref="ByteVector" /> object, preceeding the
		///    contents with a specified block of data.
		/// </summary>
		/// <param name="topData">
		///    A <see cref="ByteVector" /> object containing box
		///    specific header data to preceed the content.
		/// </param>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered version of the current instance.
		/// </returns>
		protected virtual ByteVector Render (ByteVector topData)
		{
			bool free_found = false;
			ByteVector output = new ByteVector ();
			
			if (Children != null)
				foreach (Box box in Children)
					if (box.GetType () == typeof (
						IsoFreeSpaceBox))
						free_found = true;
					else
						output.Add (box.Render ());
			else if (Data != null)
				output.Add (Data);
			
			// If there was a free, don't take it away, and let meta
			// be a special case.
			if (free_found || BoxType == Mpeg4.BoxType.Meta) {
				long size_difference = DataSize - output.Count;
				
				// If we have room for free space, add it so we
				// don't have to resize the file.
				if (header.DataSize != 0 && size_difference >= 8)
					output.Add ((new IsoFreeSpaceBox (
						size_difference)).Render ());
				
				// If we're getting bigger, get a lot bigger so
				// we might not have to again.
				else
					output.Add ((new IsoFreeSpaceBox (2048
						)).Render ());
			}
			
			// Adjust the header's data size to match the content.
			header.DataSize = topData.Count + output.Count;
			
			// Render the full box.
			output.Insert (0, topData);
			output.Insert (0, header.Render ());
			
			return output;
		}
예제 #12
0
        /// <summary>
        ///    Searches for an audio header in a <see cref="TagLib.File"
        ///    /> starting at a specified position and searching through
        ///    a specified number of bytes.
        /// </summary>
        /// <param name="header">
        ///    A <see cref="AudioHeader" /> object in which the found
        ///    header will be stored.
        /// </param>
        /// <param name="file">
        ///    A <see cref="TagLib.File" /> object to search.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specifying the seek position
        ///    in <paramref name="file" /> at which to start searching.
        /// </param>
        /// <param name="length">
        ///    A <see cref="int" /> value specifying the maximum number
        ///    of bytes to search before aborting.
        /// </param>
        /// <returns>
        ///    A <see cref="bool" /> value indicating whether or not a
        ///    header was found.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        public static bool Find(out AudioHeader header, TagLib.File file, long position, int length)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            long end = position + length;

            header = Unknown;

            file.Seek(position);

            ByteVector buffer = file.ReadBlock(3);

            if (buffer.Count < 3)
            {
                return(false);
            }

            do
            {
                file.Seek(position + 3);
                buffer = buffer.Mid(buffer.Count - 3);
                buffer.Add(file.ReadBlock(
                               (int)TagLib.File.BufferSize));

                for (int i = 0; i < buffer.Count - 3 &&
                     (length < 0 || position + i < end); i++)
                {
                    if (buffer[i] == 0xFF &&
                        buffer[i + 1] >= 0xF0)                            // 0xFFF
                    {
                        try {
                            BitStream bits = new BitStream(buffer.Mid(i, 7).Data);

                            // 12 bits sync header
                            bits.ReadInt32(12);

                            // 1 bit mpeg 2/4
                            bits.ReadInt32(1);

                            // 2 bits layer
                            bits.ReadInt32(2);

                            // 1 bit protection absent
                            bits.ReadInt32(1);

                            // 2 bits profile object type
                            bits.ReadInt32(2);

                            // 4 bits sampling frequency index
                            int samplerateindex = bits.ReadInt32(4);
                            if (samplerateindex >= sample_rates.Length)
                            {
                                return(false);
                            }
                            long samplerate = sample_rates[samplerateindex];

                            // 1 bit private bit
                            bits.ReadInt32(1);

                            // 3 bits channel configuration
                            int channelconfigindex = bits.ReadInt32(3);
                            if (channelconfigindex >= channels.Length)
                            {
                                return(false);
                            }

                            // 4 copyright bits
                            bits.ReadInt32(4);

                            // 13 bits frame length
                            long framelength = bits.ReadInt32(13);                              // double check framelength
                            if (framelength < 7)
                            {
                                return(false);
                            }

                            // 11 bits buffer fullness
                            bits.ReadInt32(11);

                            // 2 bits number of raw data blocks in frame
                            int numberofframes = bits.ReadInt32(2) + 1;

                            long numberofsamples = numberofframes * 1024;
                            long bitrate         = framelength * 8 * samplerate / numberofsamples;

                            header = new AudioHeader(channels[channelconfigindex],
                                                     (int)bitrate,
                                                     (int)samplerate,
                                                     (int)numberofsamples,
                                                     numberofframes);

                            return(true);
                        } catch (CorruptFileException) {
                        }
                    }
                }

                position += TagLib.File.BufferSize;
            } while (buffer.Count > 3 && (length < 0 || position < end));

            return(false);
        }
예제 #13
0
		/// <summary>
		///    Renders the current instance to a <see cref="ByteVector"/>
		/// </summary>
		/// <param name="is_bigendian">
		///    A <see cref="System.Boolean"/> indicating the endianess for rendering.
		/// </param>
		/// <param name="offset">
		///    A <see cref="System.UInt32"/> with the offset, the data is stored.
		/// </param>
		/// <param name="type">
		///    A <see cref="System.UInt16"/> the ID of the type, which is rendered
		/// </param>
		/// <param name="count">
		///    A <see cref="System.UInt32"/> with the count of the values which are
		///    rendered.
		/// </param>
		/// <returns>
		///    A <see cref="ByteVector"/> with the rendered data.
		/// </returns>
		public ByteVector Render (bool is_bigendian, uint offset, out ushort type, out uint count)
		{
			type = (ushort) IFDEntryType.SRational;
			count = 1;
			
			ByteVector data = new ByteVector ();
			data.Add (ByteVector.FromInt (Value.Numerator, is_bigendian));
			data.Add (ByteVector.FromInt (Value.Denominator, is_bigendian));
			
			return data;
		}
		/// <summary>
		///    Renders the values in the current instance into field
		///    data for a specified version.
		/// </summary>
		/// <param name="version">
		///    A <see cref="byte" /> indicating the ID3v2 version the
		///    field data is to be encoded in.
		/// </param>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered field data.
		/// </returns>
		protected override ByteVector RenderFields (byte version)
		{
			if (raw_data != null && raw_version == version)
				return raw_data;
			
			StringType encoding = CorrectEncoding (TextEncoding,
				version);
			ByteVector data = new ByteVector ();
			
			data.Add ((byte) encoding);
			
			if (version == 2) {
				switch (MimeType) {
				case "image/png":
					data.Add ("PNG");
					break;
				case "image/jpeg":
					data.Add ("JPG");
					break;
				default:
					data.Add ("XXX");
					break;
				}
			} else {
				data.Add (ByteVector.FromString (MimeType,
					StringType.Latin1));
				data.Add (ByteVector.TextDelimiter (
					StringType.Latin1));
			}
			
			data.Add ((byte) type);
			data.Add (ByteVector.FromString (Description, encoding));
			data.Add (ByteVector.TextDelimiter (encoding));
			data.Add (this.data);
			
			return data;
		}
예제 #15
0
파일: Frame.cs 프로젝트: asimshah/Music
        /// <summary>
        ///    Renders the current instance, encoded in a specified
        ///    ID3v2 version.
        /// </summary>
        /// <param name="version">
        ///    A <see cref="byte" /> value specifying the version of
        ///    ID3v2 to use when encoding the current instance.
        /// </param>
        /// <returns>
        ///    A <see cref="ByteVector" /> object containing the
        ///    rendered version of the current instance.
        /// </returns>
        /// <exception cref="NotImplementedException">
        ///    The current instance uses some feature that cannot be
        ///    implemented in the specified ID3v2 version, or uses a
        ///    feature, such as encryption or compression, which is not
        ///    yet implemented in the library.
        /// </exception>
        public virtual ByteVector Render(byte version)
        {
            // Remove flags that are not supported by older versions
            // of ID3v2.
            if (version < 4)
            {
                Flags &= ~(FrameFlags.DataLengthIndicator |
                           FrameFlags.Unsynchronisation);
            }

            if (version < 3)
            {
                Flags &= ~(FrameFlags.Compression |
                           FrameFlags.Encryption |
                           FrameFlags.FileAlterPreservation |
                           FrameFlags.GroupingIdentity |
                           FrameFlags.ReadOnly |
                           FrameFlags.TagAlterPreservation);
            }

            ByteVector field_data = RenderFields(version);

            // If we don't have any content, don't render anything.
            // This will cause the frame to not be rendered.
            if (field_data.Count == 0)
            {
                return(new ByteVector());
            }

            ByteVector front_data = new ByteVector();

            if ((Flags & (FrameFlags.Compression |
                          FrameFlags.DataLengthIndicator)) != 0)
            {
                front_data.Add(ByteVector.FromUInt((uint)
                                                   field_data.Count));
            }

            if ((Flags & FrameFlags.GroupingIdentity) != 0)
            {
                front_data.Add(group_id);
            }

            if ((Flags & FrameFlags.Encryption) != 0)
            {
                front_data.Add(encryption_id);
            }

            // FIXME: Implement compression.
            if ((Flags & FrameFlags.Compression) != 0)
            {
                throw new NotImplementedException(
                          "Compression not yet supported");
            }

            // FIXME: Implement encryption.
            if ((Flags & FrameFlags.Encryption) != 0)
            {
                throw new NotImplementedException(
                          "Encryption not yet supported");
            }

            if ((Flags & FrameFlags.Unsynchronisation) != 0)
            {
                SynchData.UnsynchByteVector(field_data);
            }

            if (front_data.Count > 0)
            {
                field_data.Insert(0, front_data);
            }

            header.FrameSize = (uint)field_data.Count;
            ByteVector header_data = header.Render(version);

            header_data.Add(field_data);

            return(header_data);
        }
예제 #16
0
        public static async Task HandleFile(FileInfo file, string language)
        {
            var fileName = Path.GetFileNameWithoutExtension(file.FullName);

            Console.WriteLine("Processing File: '{0}'", file.FullName);
            var movies = await SearchForMovie(fileName, language);

            Console.WriteLine("Which Movie is this file? (enter -1 to skip)");
            var count = 1;

            foreach (var movie in movies.Results)
            {
                Console.WriteLine("  [{0}] {1} - {2} - https://www.themoviedb.org/movie/{3}",
                                  count++,
                                  GetDateTime(movie.ReleaseDate).Year,
                                  movie.Title,
                                  movie.Id
                                  );
            }
            var movieNumber = -1;
            var userInput   = Console.ReadLine();

            int.TryParse(userInput, out movieNumber);
            var index = movieNumber - 1;

            if (index < 0 || index > movies.Results.Count() - 1)
            {
                Console.WriteLine("Not renaming '{0}'", fileName);
            }
            else
            {
                var searchMovie = movies.Results.ToArray()[index];
                var fullMovie   = await GetMovie(searchMovie.Id, language);

                using (TagLib.File tagFile = TagLib.File.Create(file.FullName, "video/mp4", ReadStyle.Average))
                {
                    TagLib.Mpeg4.AppleTag customTag = (TagLib.Mpeg4.AppleTag)tagFile.GetTag(TagLib.TagTypes.Apple, true);

                    // name
                    customTag.Title = fullMovie.Title;

                    // STIK || Media Type Tag
                    customTag.ClearData("stik");
                    var stikVector = new TagLib.ByteVector();
                    stikVector.Add((byte)9);
                    customTag.SetData("stik", stikVector, (int)TagLib.Mpeg4.AppleDataBox.FlagType.ContainsData);

                    // Short Description
                    customTag.ClearData("desc");
                    customTag.SetText("desc", ToShortDescription(fullMovie.Overview));

                    // Long Description
                    customTag.ClearData("ldes");
                    customTag.SetText("ldes", fullMovie.Overview);

                    // Release Date YYYY-MM-DD
                    var releaseDate = GetDateTime(fullMovie.ReleaseDate);
                    customTag.Year = (uint)releaseDate.Year;
                    customTag.ClearData("tdrl");
                    customTag.SetText("tdrl", fullMovie.Overview);

                    // Genre
                    var mainGenre = fullMovie.Genres.Select(g => g.Name).First();
                    customTag.Genres = new string[] { mainGenre };

                    // Cast / Actors
                    customTag.Performers = fullMovie.Credits.Cast.Select(c => c.Name).ToArray();

                    // HD Video
                    //customTag.ClearData("hdvd");
                    var inputFile = new MediaFile {
                        Filename = file.FullName
                    };
                    using (var engine = new Engine())
                    {
                        engine.GetMetadata(inputFile);
                    }
                    if (isHd(inputFile.Metadata.VideoData.FrameSize))
                    {
                        var hdvdVector = new ByteVector();
                        hdvdVector.Add(Convert.ToByte(true));
                        customTag.SetData("hdvd", hdvdVector, (int)TagLib.Mpeg4.AppleDataBox.FlagType.ContainsData);
                    }

                    // Artwork / Poster
                    if (!String.IsNullOrWhiteSpace(fullMovie.Poster))
                    {
                        Console.WriteLine("    getting movie poster");
                        var artworkUrl = "http://image.tmdb.org/t/p/original" + fullMovie.Poster;

                        using (var client = new HttpClient())
                        {
                            var response = await client.GetAsync(artworkUrl);

                            var bytes = await response.Content.ReadAsByteArrayAsync();

                            tagFile.Tag.Pictures = new IPicture[] { new TagLib.Picture(bytes) };
                        }
                    }

                    tagFile.Save();
                }

                var newFileName = SanitizeFileName(fullMovie.Title) + Path.GetExtension(file.FullName);
                var folder      = ConfigurationManager.AppSettings["to"];
                var newPath     = Path.Combine(folder, newFileName);
                Console.WriteLine("    moving file to {0}", newPath);
                file.MoveTo(newPath);
            }
            Console.WriteLine("=========================================================");
        }
예제 #17
0
파일: Picture.cs 프로젝트: juschubut/kenos
        /// <summary>
        ///    Renders the current instance as a raw Flac picture.
        /// </summary>
        /// <returns>
        ///    A <see cref="ByteVector" /> object containing the
        ///    rendered version of the current instance.
        /// </returns>
        public ByteVector Render()
        {
            ByteVector data = new ByteVector();

            data.Add(ByteVector.FromUInt((uint)Type));

            ByteVector mime_data = ByteVector.FromString(MimeType,
                                                         StringType.Latin1);

            data.Add(ByteVector.FromUInt((uint)mime_data.Count));
            data.Add(mime_data);

            ByteVector decription_data = ByteVector.FromString(
                Description, StringType.UTF8);

            data.Add(ByteVector.FromUInt((uint)
                                         decription_data.Count));
            data.Add(decription_data);

            data.Add(ByteVector.FromUInt((uint)Width));
            data.Add(ByteVector.FromUInt((uint)Height));
            data.Add(ByteVector.FromUInt((uint)ColorDepth));
            data.Add(ByteVector.FromUInt((uint)IndexedColors));

            data.Add(ByteVector.FromUInt((uint)Data.Count));
            data.Add(Data);

            return(data);
        }
예제 #18
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            // Boilerplate
            PreSave();

            Mode = AccessMode.Write;
            try {
                var data = new ByteVector();

                // Add the ID3 chunk and ID32 tag to the vector
                if (tag != null)
                {
                    ByteVector tag_data = tag.Render();
                    if (tag_data.Count > 10)
                    {
                        if (tag_data.Count % 2 == 1)
                        {
                            tag_data.Add(0);
                        }

                        data.Add("ID3 ");
                        data.Add(ByteVector.FromUInt((uint)tag_data.Count, true));
                        data.Add(tag_data);
                    }
                }

                Read(false, ReadStyle.None, out var aiff_size,
                     out var tag_start, out var tag_end);

                // If tagging info cannot be found, place it at
                // the end of the file.
                if (tag_start < 12 || tag_end < tag_start)
                {
                    tag_start = tag_end = Length;
                }

                int length = (int)(tag_end - tag_start + 8);

                // Insert the tagging data.
                Insert(data, tag_start, length);

                // If the data size changed update the aiff size.
                if (data.Count - length != 0 &&
                    tag_start <= aiff_size)
                {
                    // Depending, if a Tag has been added or removed,
                    // the length needs to be adjusted
                    if (tag == null)
                    {
                        length -= 16;
                    }
                    else
                    {
                        length -= 8;
                    }

                    Insert(ByteVector.FromUInt((uint)(aiff_size + data.Count - length), true), 4, 4);
                }
                // Update the tag types.
                TagTypesOnDisk = TagTypes;
            } finally {
                Mode = AccessMode.Closed;
            }
        }
        /// <summary>
        ///    Renders the current instance as a raw ASF object.
        /// </summary>
        /// <returns>
        ///    A <see cref="ByteVector" /> object containing the
        ///    rendered version of the current instance.
        /// </returns>
        public override ByteVector Render()
        {
            ByteVector output = new ByteVector ();
            uint child_count = 0;

            foreach (Object child in children)
                if (child.Guid != Asf.Guid.AsfPaddingObject) {
                    output.Add (child.Render ());
                    child_count ++;
                }

            long size_diff = (long) output.Count + 30 -
                (long) OriginalSize;

            if (size_diff != 0) {
                PaddingObject obj = new PaddingObject ((uint)
                    (size_diff > 0 ? 4096 : - size_diff));

                output.Add (obj.Render ());
                child_count ++;
            }

            output.Insert (0, reserved);
            output.Insert (0, RenderDWord (child_count));
            return Render (output);
        }
예제 #20
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            Mode = AccessMode.Write;
            try {
                // Update the tags at the beginning of the file.
                long metadata_start = StartTag.Write ();
                long metadata_end;

                // Get all the blocks, but don't read the data for ones
                // we're filling with stored data.
                IList<Block> old_blocks = ReadBlocks (ref metadata_start,
                    out metadata_end, BlockMode.Blacklist,
                    BlockType.XiphComment, BlockType.Picture);

                // Create new vorbis comments is they don't exist.
                GetTag (TagTypes.Xiph, true);

                // Create new blocks and add the basics.
                List<Block> new_blocks = new List<Block> ();
                new_blocks.Add (old_blocks [0]);

                // Add blocks we don't deal with from the file.
                foreach (Block block in old_blocks)
                    if (block.Type != BlockType.StreamInfo &&
                        block.Type != BlockType.XiphComment &&
                        block.Type != BlockType.Picture &&
                        block.Type != BlockType.Padding)
                        new_blocks.Add (block);

                new_blocks.Add (new Block (BlockType.XiphComment,
                    (GetTag (TagTypes.Xiph, true) as
                        Ogg.XiphComment).Render (false)));

                foreach (IPicture picture in metadata.Pictures) {
                    if (picture == null)
                        continue;

                    new_blocks.Add (new Block (BlockType.Picture,
                        new Picture (picture).Render ()));
                }

                // Get the length of the blocks.
                long length = 0;
                foreach (Block block in new_blocks)
                    length += block.TotalSize;

                // Find the padding size to avoid trouble. If that fails
                // make some.
                long padding_size = metadata_end - metadata_start -
                    BlockHeader.Size - length;
                if (padding_size < 0)
                    padding_size = 1024 * 4;

                // Add a padding block.
                if (padding_size != 0)
                    new_blocks.Add (new Block (BlockType.Padding,
                        new ByteVector ((int) padding_size)));

                // Render the blocks.
                ByteVector block_data = new ByteVector ();
                for (int i = 0; i < new_blocks.Count; i ++)
                    block_data.Add (new_blocks [i].Render (
                        i == new_blocks.Count - 1));

                // Update the blocks.
                Insert (block_data, metadata_start, metadata_end -
                    metadata_start);

                // Update the tags at the end of the file.
                EndTag.Write ();

                TagTypesOnDisk = TagTypes;
            } finally {
                Mode = AccessMode.Closed;
            }
        }
예제 #21
0
		/// <summary>
		///    Renders the current instance as an APEv2 item.
		/// </summary>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered version of the current instance.
		/// </returns>
		public ByteVector Render ()
		{
			uint flags = (uint) ((ReadOnly) ? 1 : 0) |
				((uint) Type << 1);
			
			if (IsEmpty)
				return new ByteVector ();
			
			ByteVector result = null;
			
			if (type == ItemType.Binary) {
				if (text == null && data != null)
					result = data;
			}
			
			if (result == null && text != null) {
				result = new ByteVector ();
				
				for (int i = 0; i < text.Length; i ++) {
					if (i != 0)
						result.Add ((byte) 0);
					
					result.Add (ByteVector.FromString (
						text [i], StringType.UTF8));
				}
			}
			
			// If no data is stored, don't write the item.
			if (result == null || result.Count == 0)
				return new ByteVector ();
			
			ByteVector output = new ByteVector ();
			output.Add (ByteVector.FromUInt ((uint) result.Count,
				false));
			output.Add (ByteVector.FromUInt (flags, false));
			output.Add (ByteVector.FromString (key, StringType.UTF8));
			output.Add ((byte) 0);
			output.Add (result);
			
			size_on_disk = output.Count;
			
			return output;
		}
		protected override ByteVector RenderFields (byte version) {
			if (raw_data != null && raw_version == version)
				return raw_data;
			
			StringType encoding = CorrectEncoding (TextEncoding,
				version);
			ByteVector v = new ByteVector ((byte) encoding);
			string [] text = text_fields;
			
			bool txxx = FrameId == FrameType.TXXX;
			
			if (version > 3 || txxx) {
				
				if (txxx) {
					if (text.Length == 0)
						text = new string [] {null, null};
					else if (text.Length == 1)
						text = new string [] {text [0],
							null};
				}
				
				for (int i = 0; i < text.Length; i++) {
					// Since the field list is null
					// delimited, if this is not the first
					// element in the list, append the
					// appropriate delimiter for this
					// encoding.
					
					if (i != 0)
						v.Add (ByteVector.TextDelimiter (
							encoding));
						
					if (text [i] != null)
						v.Add (ByteVector.FromString (
							text [i],
							encoding));
				}
			} else if (FrameId == FrameType.TCON) {
				byte id;
				bool prev_value_indexed = true;
				StringBuilder data = new StringBuilder ();
				foreach (string s in text) {
					if (!prev_value_indexed) {
						data.Append ("/").Append (s);
						continue;
					}
					
					if (prev_value_indexed =
						byte.TryParse (s, out id))
						data.AppendFormat (
							CultureInfo.InvariantCulture,
								"({0})", id);
					else
						data.Append (s);
				}
				
				v.Add (ByteVector.FromString (data.ToString (),
					encoding));
			} else {
				v.Add (ByteVector.FromString (
					string.Join ("/", text), encoding));
			}
			
			return v;
		}
예제 #23
0
		/// <summary>
		///    Saves the changes made in the current instance to the
		///    file it represents.
		/// </summary>
		public override void Save ()
		{
			Mode = AccessMode.Write;
			try {
				long end;
				List<Page> pages = new List<Page> ();
				Dictionary<uint, Bitstream> streams =
					ReadStreams (pages, out end);
				Dictionary<uint, Paginator> paginators =
					new Dictionary<uint, Paginator> ();
				List<List<Page>> new_pages =
					new List<List<Page>> ();
				Dictionary<uint, int> shifts =
					new Dictionary<uint, int> ();
				
				foreach (Page page in pages) {
					uint id = page.Header.StreamSerialNumber;
					if (!paginators.ContainsKey (id))
						paginators.Add (id,
							new Paginator (
								streams [id].Codec));
					
					paginators [id].AddPage (page);
				}
				
				foreach (uint id in paginators.Keys) {
					paginators [id].SetComment (
						tag.GetComment (id));
					int shift;
					new_pages.Add (new List<Page> (
						paginators [id]
							.Paginate (out shift)));
					shifts.Add (id, shift);
				}
				
				ByteVector output = new ByteVector ();
				bool empty;
				do {
					empty = true;
					foreach (List<Page> stream_pages in new_pages) {
						if (stream_pages.Count == 0)
							continue;
					
					output.Add (stream_pages [0].Render ());
					stream_pages.RemoveAt (0);
					
					if (stream_pages.Count != 0)
						empty = false;
					}
				} while (!empty);
				
				Insert (output, 0, end);
				InvariantStartPosition = output.Count;
				InvariantEndPosition = Length;
				
				TagTypesOnDisk = TagTypes;
				
				Page.OverwriteSequenceNumbers (this,
					output.Count, shifts);
			} finally {
				Mode = AccessMode.Closed;
			}
		}
예제 #24
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            Mode = AccessMode.Write;
            try
            {
                ByteVector data = new ByteVector();

                // Add the ID3 chunk and ID32 tag to the vector
                if (tag != null)
                {
                    ByteVector tag_data = tag.Render();
                    if (tag_data.Count > 10)
                    {
                        if (tag_data.Count%2 == 1)
                            tag_data.Add(0);

                        data.Add("ID3 ");
                        data.Add(ByteVector.FromUInt(
                                 	(uint) tag_data.Count,
                                 	true));
                        data.Add(tag_data);
                    }
                }

                // Read the file to determine the current AIFF
                // size and the area tagging is in.
                uint aiff_size;
                long tag_start, tag_end;
                Read(false, ReadStyle.None, out aiff_size,
                     out tag_start, out tag_end);

                // If tagging info cannot be found, place it at
                // the end of the file.
                if (tag_start < 12 || tag_end < tag_start)
                    tag_start = tag_end = Length;

                int length = (int) (tag_end - tag_start + 8);

                // Insert the tagging data.
                Insert(data, tag_start, length);

                // If the data size changed update the aiff size.
                if (data.Count - length != 0 &&
                    tag_start <= aiff_size)
                {
                    // Depending, if a Tag has been added or removed,
                    // the length needs to be adjusted
                    if (tag == null)
                    {
                        length -= 16;
                    }
                    else
                    {
                        length -= 8;
                    }

                    Insert(ByteVector.FromUInt((uint)
                                               (aiff_size + data.Count - length),
                                               true), 4, 4);
                }
                // Update the tag types.
                TagTypesOnDisk = TagTypes;
            }
            finally
            {
                Mode = AccessMode.Closed;
            }
        }
예제 #25
0
		public override void Save ()
		{
			Mode = AccessMode.Write;
			try {
				ByteVector data = new ByteVector ();

				if (id32_tag != null) {
					ByteVector tag_data = id32_tag.Render ();
					if (tag_data.Count > 10) {
						if (tag_data.Count % 2 == 1)
							tag_data.Add (0);
						data.Add ("ID32");
						data.Add (ByteVector.FromUInt (
							(uint) tag_data.Count,
							false));
						data.Add (tag_data);
					}
				}

				if (info_tag != null)
					data.Add (info_tag.RenderEnclosed ());

				if (mid_tag != null)
					data.Add (mid_tag.RenderEnclosed ());

				if (divx_tag != null && !divx_tag.IsEmpty) {
					ByteVector tag_data = divx_tag.Render ();
					data.Add ("IDVX");
					data.Add (ByteVector.FromUInt (
						(uint) tag_data.Count, false));
					data.Add (tag_data);
				}

				uint riff_size;
				long tag_start, tag_end;
				Read (false, ReadStyle.None, out riff_size,
					out tag_start, out tag_end);

				if (tag_start < 12 || tag_end < tag_start)
					tag_start = tag_end = Length;

				int length = (int)(tag_end - tag_start);
				int padding_size = length - data.Count - 8;
				if (padding_size < 0)
					padding_size = 1024;

				data.Add ("JUNK");
				data.Add (ByteVector.FromUInt (
					(uint)padding_size, false));
				data.Add (new ByteVector (padding_size));

				Insert (data, tag_start, length);

				if (data.Count - length != 0 &&
					tag_start <= riff_size)
					Insert (ByteVector.FromUInt ((uint)
						(riff_size + data.Count - length),
						false), 4, 4);

				TagTypesOnDisk = TagTypes;
			} finally {
				Mode = AccessMode.Closed;
			}
		}
예제 #26
0
        /// <summary>
        /// Constructs a <see cref="EBMLElement" /> parsing from provided
        /// file data.
        /// </summary>
        /// <param name="_file"><see cref="File" /> instance to read from.</param>
        /// <param name="position">Position to start reading from.</param>
        public EBMLElement(Matroska.File _file, ulong position)
        {
            if (_file == null)
            {
                throw new ArgumentNullException("file");
            }

            if (position > (ulong)(_file.Length - 4))
            {
                throw new ArgumentOutOfRangeException("position");
            }

            // Keep a reference to the file
            file = _file;

            file.Seek((long)position);

            // Get the header byte
            ByteVector vector      = file.ReadBlock(1);
            Byte       header_byte = vector [0];
            // Define a mask
            Byte mask = 0x80, id_length = 1;

            // Figure out the size in bytes
            while (id_length <= 4 && (header_byte & mask) == 0)
            {
                id_length++;
                mask >>= 1;
            }

            if (id_length > 4)
            {
                throw new CorruptFileException("invalid EBML id size");
            }

            // Now read the rest of the EBML ID
            if (id_length > 1)
            {
                vector.Add(file.ReadBlock(id_length - 1));
            }

            ebml_id = vector.ToUInt();

            vector.Clear();

            // Get the size length
            vector      = file.ReadBlock(1);
            header_byte = vector [0];
            mask        = 0x80;
            Byte size_length = 1;

            // Iterate through various possibilities
            while (size_length <= 8 && (header_byte & mask) == 0)
            {
                size_length++;
                mask >>= 1;
            }

            if (size_length > 8)
            {
                throw new CorruptFileException("invalid EBML element size");
            }

            // Clear the marker bit
            vector [0] &= (Byte)(mask - 1);

            // Now read the rest of the EBML element size
            if (size_length > 1)
            {
                vector.Add(file.ReadBlock(size_length - 1));
            }

            ebml_size = vector.ToULong();

            offset      = position;
            data_offset = offset + id_length + size_length;
        }
		public override ByteVector Render (byte version)
		{
			if (version != 3 || FrameId != FrameType.TDRC)
				return base.Render (version);
			
			string text = ToString ();
			if (text.Length < 10 || text [4] != '-' ||
				text [7] != '-')
				return base.Render (version);
			
			ByteVector output = new ByteVector ();
			TextInformationFrame f;
			
			f = new TextInformationFrame (FrameType.TYER, encoding);
			f.Text = new string [] {text.Substring (0, 4)};
			output.Add (f.Render (version));
			
			f = new TextInformationFrame (FrameType.TDAT, encoding);
			f.Text = new string [] {
				text.Substring (5, 2) + text.Substring (8, 2)
			};
			output.Add (f.Render (version));
			
			if (text.Length < 16 || text [10] != 'T' ||
				text [13] != ':')
				return output;
			
			f = new TextInformationFrame (FrameType.TIME, encoding);
			f.Text = new string [] {
				text.Substring (11, 2) + text.Substring (14, 2)
			};
			output.Add (f.Render (version));
			
			return output;
		}
        /// <summary>
        ///    Renders the IFD to an ByteVector where the offset of the IFD
        ///    itself is <paramref name="ifd_offset"/> and all offsets
        ///    contained in the IFD are adjusted accroding it.
        /// </summary>
        /// <param name="directory">
        ///    A <see cref="IFDDirectory"/> with the directory to render.
        /// </param>
        /// <param name="ifd_offset">
        ///    A <see cref="System.UInt32"/> with the offset of the IFD
        /// </param>
        /// <param name="last">
        ///    A <see cref="System.Boolean"/> which is true, if the IFD is
        ///    the last one, i.e. the offset to the next IFD, which is
        ///    stored inside the IFD, is 0. If the value is false, the
        ///    offset to the next IFD is set that it starts directly after
        ///    the current one.
        /// </param>
        /// <returns>
        ///    A <see cref="ByteVector"/> with the rendered IFD.
        /// </returns>
        private ByteVector RenderIFD(IFDDirectory directory, uint ifd_offset, bool last)
        {
            if (directory.Count > (int)UInt16.MaxValue)
                throw new Exception (String.Format ("Directory has too much entries: {0}", directory.Count));

            // Remove empty SUB ifds.
            var tags = new List<ushort> (directory.Keys);
            foreach (var tag in tags) {
                var entry = directory [tag];
                if (entry is SubIFDEntry && (entry as SubIFDEntry).ChildCount == 0) {
                    directory.Remove (tag);
                }
            }

            ushort entry_count = (ushort) directory.Count;

            // ifd_offset + size of entry_count + entries + next ifd offset
            uint data_offset = ifd_offset + 2 + 12 * (uint) entry_count + 4;

            // store the entries itself
            ByteVector entry_data = new ByteVector ();

            // store the data referenced by the entries
            ByteVector offset_data = new ByteVector ();

            entry_data.Add (ByteVector.FromUShort (entry_count, is_bigendian));

            foreach (IFDEntry entry in directory.Values)
                RenderEntryData (entry, entry_data, offset_data, data_offset);

            if (last)
                entry_data.Add ("\0\0\0\0");
            else
                entry_data.Add (ByteVector.FromUInt ((uint) (data_offset + offset_data.Count), is_bigendian));

            if (data_offset - ifd_offset != entry_data.Count)
                throw new Exception (String.Format ("Expected IFD data size was {0} but is {1}", data_offset - ifd_offset, entry_data.Count));

            entry_data.Add (offset_data);

            return entry_data;
        }
		/// <summary>
		///    Renders the values in the current instance into field
		///    data for a specified version.
		/// </summary>
		/// <param name="version">
		///    A <see cref="byte" /> indicating the ID3v2 version the
		///    field data is to be encoded in.
		/// </param>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered field data.
		/// </returns>
		protected override ByteVector RenderFields(byte version)
		{
			StringType encoding = CorrectEncoding (TextEncoding,
				version);
			ByteVector v = new ByteVector();
			
			v.Add ((byte) encoding);
			v.Add (ByteVector.FromString (Language, StringType.Latin1));
			v.Add (ByteVector.FromString (description, encoding));
			v.Add (ByteVector.TextDelimiter(encoding));
			v.Add (ByteVector.FromString (text, encoding));

		return v;
		}
        /// <summary>
        ///    Renders the current instance to a <see cref="ByteVector"/>.
        /// </summary>
        /// <returns>
        ///    A <see cref="ByteVector"/> containing the rendered IFD.
        /// </returns>
        public ByteVector Render()
        {
            ByteVector ifd_data = new ByteVector ();

            uint current_offset = ifd_offset;
            var directories = structure.directories;

            for (int index = 0; index < directories.Count; index++) {
                ByteVector data = RenderIFD (directories [index], current_offset, index == directories.Count - 1);
                current_offset += (uint) data.Count;
                ifd_data.Add (data);
            }

            return ifd_data;
        }
예제 #31
0
		/// <summary>
		///    Renders the current instance as a raw ASF Description
		///    Record.
		/// </summary>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered version of the current instance.
		/// </returns>
		public ByteVector Render ()
		{
			ByteVector value = null;
			
			switch (type)
			{
			case DataType.Unicode:
				value = Object.RenderUnicode (strValue);
				break;
			case DataType.Bytes:
				value = byteValue;
				break;
			case DataType.Bool:
			case DataType.DWord:
				value = Object.RenderDWord ((uint) longValue);
				break;
			case DataType.QWord:
				value = Object.RenderQWord (longValue);
				break;
			case DataType.Word:
				value = Object.RenderWord ((ushort) longValue);
				break;
			case DataType.Guid:
				value = guidValue.ToByteArray ();
				break;
			default:
				return null;
			}
			
			ByteVector name = Object.RenderUnicode (this.name);
			
			ByteVector output = new ByteVector ();
			output.Add (Object.RenderWord (lang_list_index));
			output.Add (Object.RenderWord (stream_number));
			output.Add (Object.RenderWord ((ushort) name.Count));
			output.Add (Object.RenderWord ((ushort) type));
			output.Add (Object.RenderDWord ((uint) value.Count));
			output.Add (name);
			output.Add (value);
			
			return output;
		}
예제 #32
0
        /// <summary>
        ///    Renders the tags contained in the current instance.
        /// </summary>
        /// <returns>
        ///    A <see cref="ByteVector" /> object containing the
        ///    physical representation of the tags stored in the current
        ///    instance.
        /// </returns>
        /// <remarks>
        ///    The tags are rendered in the order that they are stored
        ///    in the current instance.
        /// </remarks>
        public ByteVector Render()
        {
            ByteVector data = new ByteVector ();
            foreach (TagLib.Tag t in Tags) {
                if (t is TagLib.Ape.Tag)
                    data.Add ((t as TagLib.Ape.Tag).Render ());
                else if (t is TagLib.Id3v2.Tag)
                    data.Add ((t as TagLib.Id3v2.Tag).Render ());
                else if (t is TagLib.Id3v1.Tag)
                    data.Add ((t as TagLib.Id3v1.Tag).Render ());
            }

            return data;
        }
예제 #33
0
		/// <summary>
		///    Renders the current instance as a raw ID3v1 tag.
		/// </summary>
		/// <returns>
		///    A <see cref="ByteVector" /> object containing the
		///    rendered tag.
		/// </returns>
		public ByteVector Render ()
		{
			ByteVector data = new ByteVector ();
			
			data.Add (FileIdentifier);
			data.Add (string_handler.Render (title  ).Resize (30));
			data.Add (string_handler.Render (artist ).Resize (30));
			data.Add (string_handler.Render (album  ).Resize (30));
			data.Add (string_handler.Render (year   ).Resize ( 4));
			data.Add (string_handler.Render (comment).Resize (28));
			data.Add ((byte) 0);
			data.Add (track);
			data.Add (genre);
			
			return data;
		}
예제 #34
0
        /// <summary>
        ///    Renders the current instance as a raw Flac picture.
        /// </summary>
        /// <returns>
        ///    A <see cref="ByteVector" /> object containing the
        ///    rendered version of the current instance.
        /// </returns>
        public ByteVector Render()
        {
            ByteVector data = new ByteVector ();

            data.Add (ByteVector.FromUInt ((uint) Type));

            ByteVector mime_data = ByteVector.FromString (MimeType,
                StringType.Latin1);
            data.Add (ByteVector.FromUInt ((uint) mime_data.Count));
            data.Add (mime_data);

            ByteVector decription_data = ByteVector.FromString (
                Description, StringType.UTF8);
            data.Add (ByteVector.FromUInt ((uint)
                decription_data.Count));
            data.Add (decription_data);

            data.Add (ByteVector.FromUInt ((uint) Width));
            data.Add (ByteVector.FromUInt ((uint) Height));
            data.Add (ByteVector.FromUInt ((uint) ColorDepth));
            data.Add (ByteVector.FromUInt ((uint) IndexedColors));

            data.Add (ByteVector.FromUInt ((uint) Data.Count));
            data.Add (Data);

            return data;
        }
예제 #35
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            Mode = AccessMode.Write;
            try {
                ByteVector data = new ByteVector ();

                // Enclose the Id3v2 tag in an "ID32" item and
                // embed it as the first tag.
                if (id32_tag != null) {
                    ByteVector tag_data = id32_tag.Render ();
                    if (tag_data.Count > 10) {
                        if (tag_data.Count % 2 == 1)
                            tag_data.Add (0);
                        data.Add ("ID32");
                        data.Add (ByteVector.FromUInt (
                            (uint) tag_data.Count,
                            false));
                        data.Add (tag_data);
                    }
                }

                // Embed "INFO" as the second tag.
                if (info_tag != null)
                    data.Add (info_tag.RenderEnclosed ());

                // Embed "MID " as the third tag.
                if (mid_tag != null)
                    data.Add (mid_tag.RenderEnclosed ());

                // Embed the DivX tag in "IDVX and embed it as
                // the fourth tag.
                if (divx_tag != null && !divx_tag.IsEmpty) {
                    ByteVector tag_data = divx_tag.Render ();
                    data.Add ("IDVX");
                    data.Add (ByteVector.FromUInt (
                        (uint) tag_data.Count, false));
                    data.Add (tag_data);
                }

                // Read the file to determine the current RIFF
                // size and the area tagging does in.
                uint riff_size;
                long tag_start, tag_end;
                Read (false, ReadStyle.None, out riff_size,
                    out tag_start, out tag_end);

                // If tagging info cannot be found, place it at
                // the end of the file.
                if (tag_start < 12 || tag_end < tag_start)
                    tag_start = tag_end = Length;

                int length = (int)(tag_end - tag_start);

                // If the tag isn't at the end of the file,
                // try appending using padding to improve
                // write time now or for subsequent writes.
                if (tag_end != Length) {
                    int padding_size = length - data.Count - 8;
                    if (padding_size < 0)
                        padding_size = 1024;

                    data.Add ("JUNK");
                    data.Add (ByteVector.FromUInt (
                        (uint)padding_size, false));
                    data.Add (new ByteVector (padding_size));
                }

                // Insert the tagging data.
                Insert (data, tag_start, length);

                // If the data size changed, and the tagging
                // data is within the RIFF portion of the file,
                // update the riff size.
                if (data.Count - length != 0 &&
                    tag_start <= riff_size)
                    Insert (ByteVector.FromUInt ((uint)
                        (riff_size + data.Count - length),
                        false), 4, 4);

                // Update the tag types.
                TagTypesOnDisk = TagTypes;
            } finally {
                Mode = AccessMode.Closed;
            }
        }
예제 #36
0
 public ByteVector Render()
 {
     ByteVector vector = new ByteVector();
     foreach (TagLib.Tag tag in this.Tags)
     {
         if (tag is TagLib.Ape.Tag)
         {
             vector.Add((tag as TagLib.Ape.Tag).Render());
         }
         else if (tag is TagLib.Id3v2.Tag)
         {
             vector.Add((tag as TagLib.Id3v2.Tag).Render());
         }
         else if (tag is TagLib.Id3v1.Tag)
         {
             vector.Add((tag as TagLib.Id3v1.Tag).Render());
         }
     }
     return vector;
 }
예제 #37
0
		/// <summary>
		///    Finds the previous marker of a specified type, starting
		///    at a specified position.
		/// </summary>
		/// <param name="position">
		///    A <see cref="long" /> value reference specifying the
		///    position at which to start searching. This value
		///    is updated to the position of the found marker.
		/// </param>
		/// <param name="marker">
		///    A <see cref="Marker" /> value specifying the type of
		///    marker to search for.
		/// </param>
		/// <returns>
		///    A <see cref="Marker" /> value containing the type of
		///    marker found at the specified position. This value will
		///    be identical to <paramref name="marker" />.
		/// </returns>
		/// <exception cref="CorruptFileException">
		///    A valid marker could not be found.
		/// </exception>
		protected Marker RFindMarker (ref long position, Marker marker)
		{
			ByteVector packet = new ByteVector (MarkerStart);
			packet.Add ((byte) marker);
			position = RFind (packet, position);
			
			if (position < 0)
				throw new CorruptFileException (
					"Marker not found");
			
			return GetMarker (position);
		}
예제 #38
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            Mode = AccessMode.Write;
            try {
                long        end;
                List <Page> pages = new List <Page> ();
                Dictionary <uint, Bitstream> streams =
                    ReadStreams(pages, out end);
                Dictionary <uint, Paginator> paginators =
                    new Dictionary <uint, Paginator> ();
                List <List <Page> > new_pages =
                    new List <List <Page> > ();
                Dictionary <uint, int> shifts =
                    new Dictionary <uint, int> ();

                foreach (Page page in pages)
                {
                    uint id = page.Header.StreamSerialNumber;
                    if (!paginators.ContainsKey(id))
                    {
                        paginators.Add(id,
                                       new Paginator(
                                           streams [id].Codec));
                    }

                    paginators [id].AddPage(page);
                }

                foreach (uint id in paginators.Keys)
                {
                    paginators [id].SetComment(
                        tag.GetComment(id));
                    int shift;
                    new_pages.Add(new List <Page> (
                                      paginators [id]
                                      .Paginate(out shift)));
                    shifts.Add(id, shift);
                }

                ByteVector output = new ByteVector();
                bool       empty;
                do
                {
                    empty = true;
                    foreach (List <Page> stream_pages in new_pages)
                    {
                        if (stream_pages.Count == 0)
                        {
                            continue;
                        }

                        output.Add(stream_pages [0].Render());
                        stream_pages.RemoveAt(0);

                        if (stream_pages.Count != 0)
                        {
                            empty = false;
                        }
                    }
                } while (!empty);

                Insert(output, 0, end);
                InvariantStartPosition = output.Count;
                InvariantEndPosition   = Length;

                TagTypesOnDisk = TagTypes;

                Page.OverwriteSequenceNumbers(this,
                                              output.Count, shifts);
            } finally {
                Mode = AccessMode.Closed;
            }
        }