Пример #1
0
		/// <summary>
		///    Saves the changes made in the current instance to the
		///    file it represents.
		/// </summary>
		public override void Save ()
		{
			if (udta_box == null)
				udta_box = new IsoUserDataBox ();
			
			// Try to get into write mode.
			Mode = File.AccessMode.Write;
			try {
				FileParser parser = new FileParser (this);
				parser.ParseBoxHeaders ();
				
				InvariantStartPosition = parser.MdatStartPosition;
				InvariantEndPosition = parser.MdatEndPosition;
				
				long size_change = 0;
				long write_position = 0;
				
				ByteVector tag_data = udta_box.Render ();
				
				// If we don't have a "udta" box to overwrite...
				if (parser.UdtaTree == null ||
					parser.UdtaTree.Length == 0 ||
					parser.UdtaTree [parser.UdtaTree.Length - 1
					].BoxType != BoxType.Udta) {
					
					// Stick the box at the end of the moov box.
					BoxHeader moov_header = parser.MoovTree [
						parser.MoovTree.Length - 1];
					size_change = tag_data.Count;
					write_position = moov_header.Position +
						moov_header.TotalBoxSize;
					Insert (tag_data, write_position, 0);
					
					// Overwrite the parent box sizes.
					for (int i = parser.MoovTree.Length - 1; i >= 0;
						i --)
						size_change = parser.MoovTree [i
							].Overwrite (this, size_change);
				} else {
					// Overwrite the old box.
					BoxHeader udta_header = parser.UdtaTree [
						parser.UdtaTree.Length - 1];
					size_change = tag_data.Count -
						udta_header.TotalBoxSize;
					write_position = udta_header.Position;
					Insert (tag_data, write_position,
						udta_header.TotalBoxSize);
					
					// Overwrite the parent box sizes.
					for (int i = parser.UdtaTree.Length - 2; i >= 0;
						i --)
						size_change = parser.UdtaTree [i
							].Overwrite (this, size_change);
				}
				
				// If we've had a size change, we may need to adjust
				// chunk offsets.
				if (size_change != 0) {
					// We may have moved the offset boxes, so we
					// need to reread.
					parser.ParseChunkOffsets ();
					InvariantStartPosition = parser.MdatStartPosition;
					InvariantEndPosition = parser.MdatEndPosition;
					
					foreach (Box box in parser.ChunkOffsetBoxes) {
						IsoChunkLargeOffsetBox co64 = 
							box as IsoChunkLargeOffsetBox;
						
						if (co64 != null) {
							co64.Overwrite (this,
								size_change,
								write_position);
							continue;
						}
						
						IsoChunkOffsetBox stco = 
							box as IsoChunkOffsetBox;
						
						if (stco != null) {
							stco.Overwrite (this,
								size_change,
								write_position);
							continue;
						}
					}
				}
				
				TagTypesOnDisk = TagTypes;
			} finally {
				Mode = File.AccessMode.Closed;
			}
		}
Пример #2
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            if (udta_boxes.Count == 0)
            {
                IsoUserDataBox udtaBox = new IsoUserDataBox();
                udta_boxes.Add(udtaBox);
            }

            // Try to get into write mode.
            Mode = File.AccessMode.Write;
            try {
                FileParser parser = new FileParser(this);
                parser.ParseBoxHeaders();

                InvariantStartPosition = parser.MdatStartPosition;
                InvariantEndPosition   = parser.MdatEndPosition;

                long size_change    = 0;
                long write_position = 0;

                // To avoid rewriting udta blocks which might not have been modified,
                // the code here will work correctly if:
                // 1. There is a single udta for the entire file
                //   - OR -
                // 2. There are multiple utdtas, but only 1 of them contains the Apple ILST box.
                // We should be OK in the vast majority of cases
                IsoUserDataBox udtaBox = FindAppleTagUdta();
                if (null == udtaBox)
                {
                    udtaBox = new IsoUserDataBox();
                }
                ByteVector tag_data = udtaBox.Render();

                // If we don't have a "udta" box to overwrite...
                if (udtaBox.ParentTree == null ||
                    udtaBox.ParentTree.Length == 0)
                {
                    // Stick the box at the end of the moov box.
                    BoxHeader moov_header = parser.MoovTree [
                        parser.MoovTree.Length - 1];
                    size_change    = tag_data.Count;
                    write_position = moov_header.Position +
                                     moov_header.TotalBoxSize;
                    Insert(tag_data, write_position, 0);

                    // Overwrite the parent box sizes.
                    for (int i = parser.MoovTree.Length - 1; i >= 0;
                         i--)
                    {
                        size_change = parser.MoovTree [i
                                      ].Overwrite(this, size_change);
                    }
                }
                else
                {
                    // Overwrite the old box.
                    BoxHeader udta_header = udtaBox.ParentTree[udtaBox.ParentTree.Length - 1];
                    size_change = tag_data.Count -
                                  udta_header.TotalBoxSize;
                    write_position = udta_header.Position;
                    Insert(tag_data, write_position,
                           udta_header.TotalBoxSize);

                    // Overwrite the parent box sizes.
                    for (int i = udtaBox.ParentTree.Length - 2; i >= 0;
                         i--)
                    {
                        size_change = udtaBox.ParentTree [i
                                      ].Overwrite(this, size_change);
                    }
                }

                // If we've had a size change, we may need to adjust
                // chunk offsets.
                if (size_change != 0)
                {
                    // We may have moved the offset boxes, so we
                    // need to reread.
                    parser.ParseChunkOffsets();
                    InvariantStartPosition = parser.MdatStartPosition;
                    InvariantEndPosition   = parser.MdatEndPosition;

                    foreach (Box box in parser.ChunkOffsetBoxes)
                    {
                        IsoChunkLargeOffsetBox co64 =
                            box as IsoChunkLargeOffsetBox;

                        if (co64 != null)
                        {
                            co64.Overwrite(this,
                                           size_change,
                                           write_position);
                            continue;
                        }

                        IsoChunkOffsetBox stco =
                            box as IsoChunkOffsetBox;

                        if (stco != null)
                        {
                            stco.Overwrite(this,
                                           size_change,
                                           write_position);
                            continue;
                        }
                    }
                }

                TagTypesOnDisk = TagTypes;
            } finally {
                Mode = File.AccessMode.Closed;
            }
        }
Пример #3
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            if (udta_boxes.Count == 0) {
                IsoUserDataBox udtaBox = new IsoUserDataBox ();
                udta_boxes.Add(udtaBox);
            }

            // Try to get into write mode.
            Mode = File.AccessMode.Write;
            try {
                FileParser parser = new FileParser (this);
                parser.ParseBoxHeaders ();

                InvariantStartPosition = parser.MdatStartPosition;
                InvariantEndPosition = parser.MdatEndPosition;

                long size_change = 0;
                long write_position = 0;

                // To avoid rewriting udta blocks which might not have been modified,
                // the code here will work correctly if:
                // 1. There is a single udta for the entire file
                //   - OR -
                // 2. There are multiple utdtas, but only 1 of them contains the Apple ILST box.
                // We should be OK in the vast majority of cases
                IsoUserDataBox udtaBox = FindAppleTagUdta();
                if (null == udtaBox)
                    udtaBox = new IsoUserDataBox ();
                ByteVector tag_data = udtaBox.Render ();

                // If we don't have a "udta" box to overwrite...
                if (udtaBox.ParentTree == null ||
                    udtaBox.ParentTree.Length == 0) {

                    // Stick the box at the end of the moov box.
                    BoxHeader moov_header = parser.MoovTree [
                        parser.MoovTree.Length - 1];
                    size_change = tag_data.Count;
                    write_position = moov_header.Position +
                        moov_header.TotalBoxSize;
                    Insert (tag_data, write_position, 0);

                    // Overwrite the parent box sizes.
                    for (int i = parser.MoovTree.Length - 1; i >= 0;
                        i --)
                        size_change = parser.MoovTree [i
                            ].Overwrite (this, size_change);
                } else {
                    // Overwrite the old box.
                    BoxHeader udta_header = udtaBox.ParentTree[udtaBox.ParentTree.Length - 1];
                    size_change = tag_data.Count -
                        udta_header.TotalBoxSize;
                    write_position = udta_header.Position;
                    Insert (tag_data, write_position,
                        udta_header.TotalBoxSize);

                    // Overwrite the parent box sizes.
                    for (int i = udtaBox.ParentTree.Length - 2; i >= 0;
                        i --)
                        size_change = udtaBox.ParentTree [i
                            ].Overwrite (this, size_change);
                }

                // If we've had a size change, we may need to adjust
                // chunk offsets.
                if (size_change != 0) {
                    // We may have moved the offset boxes, so we
                    // need to reread.
                    parser.ParseChunkOffsets ();
                    InvariantStartPosition = parser.MdatStartPosition;
                    InvariantEndPosition = parser.MdatEndPosition;

                    foreach (Box box in parser.ChunkOffsetBoxes) {
                        IsoChunkLargeOffsetBox co64 =
                            box as IsoChunkLargeOffsetBox;

                        if (co64 != null) {
                            co64.Overwrite (this,
                                size_change,
                                write_position);
                            continue;
                        }

                        IsoChunkOffsetBox stco =
                            box as IsoChunkOffsetBox;

                        if (stco != null) {
                            stco.Overwrite (this,
                                size_change,
                                write_position);
                            continue;
                        }
                    }
                }

                TagTypesOnDisk = TagTypes;
            } finally {
                Mode = File.AccessMode.Closed;
            }
        }
Пример #4
0
        /// <summary>
        ///    Saves the changes made in the current instance to the
        ///    file it represents.
        /// </summary>
        public override void Save()
        {
            if (udta_box == null)
            {
                udta_box = new IsoUserDataBox();
            }

            // Try to get into write mode.
            Mode = File.AccessMode.Write;
            try {
                FileParser parser = new FileParser(this);
                parser.ParseBoxHeaders();

                InvariantStartPosition = parser.MdatStartPosition;
                InvariantEndPosition   = parser.MdatEndPosition;

                long size_change    = 0;
                long write_position = 0;

                ByteVector tag_data = udta_box.Render();

                // If we don't have a "udta" box to overwrite...
                if (parser.UdtaTree == null ||
                    parser.UdtaTree.Length == 0 ||
                    parser.UdtaTree [parser.UdtaTree.Length - 1
                    ].BoxType != BoxType.Udta)
                {
                    // Stick the box at the end of the moov box.
                    BoxHeader moov_header = parser.MoovTree [
                        parser.MoovTree.Length - 1];
                    size_change    = tag_data.Count;
                    write_position = moov_header.Position +
                                     moov_header.TotalBoxSize;
                    Insert(tag_data, write_position, 0);

                    // Overwrite the parent box sizes.
                    for (int i = parser.MoovTree.Length - 1; i >= 0;
                         i--)
                    {
                        size_change = parser.MoovTree [i
                                      ].Overwrite(this, size_change);
                    }
                }
                else
                {
                    // Overwrite the old box.
                    BoxHeader udta_header = parser.UdtaTree [
                        parser.UdtaTree.Length - 1];
                    size_change = tag_data.Count -
                                  udta_header.TotalBoxSize;
                    write_position = udta_header.Position;
                    Insert(tag_data, write_position,
                           udta_header.TotalBoxSize);

                    // Overwrite the parent box sizes.
                    for (int i = parser.UdtaTree.Length - 2; i >= 0;
                         i--)
                    {
                        size_change = parser.UdtaTree [i
                                      ].Overwrite(this, size_change);
                    }
                }

                // If we've had a size change, we may need to adjust
                // chunk offsets.
                if (size_change != 0)
                {
                    // We may have moved the offset boxes, so we
                    // need to reread.
                    parser.ParseChunkOffsets();
                    InvariantStartPosition = parser.MdatStartPosition;
                    InvariantEndPosition   = parser.MdatEndPosition;

                    foreach (Box box in parser.ChunkOffsetBoxes)
                    {
                        IsoChunkLargeOffsetBox co64 =
                            box as IsoChunkLargeOffsetBox;

                        if (co64 != null)
                        {
                            co64.Overwrite(this,
                                           size_change,
                                           write_position);
                            continue;
                        }

                        IsoChunkOffsetBox stco =
                            box as IsoChunkOffsetBox;

                        if (stco != null)
                        {
                            stco.Overwrite(this,
                                           size_change,
                                           write_position);
                            continue;
                        }
                    }
                }

                TagTypesOnDisk = TagTypes;
            } finally {
                Mode = File.AccessMode.Closed;
            }
        }
Пример #5
0
 public override void Save()
 {
     if (udta_boxes.Count == 0)
     {
         IsoUserDataBox udtaBox = new IsoUserDataBox();
         udta_boxes.Add(udtaBox);
     }
     Mode = File.AccessMode.Write;
     try
     {
         FileParser parser = new FileParser(this);
         parser.ParseBoxHeaders();
         InvariantStartPosition = parser.MdatStartPosition;
         InvariantEndPosition   = parser.MdatEndPosition;
         long           size_change    = 0;
         long           write_position = 0;
         IsoUserDataBox udtaBox        = FindAppleTagUdta();
         if (null == udtaBox)
         {
             udtaBox = new IsoUserDataBox();
         }
         ByteVector tag_data = udtaBox.Render();
         if (udtaBox.ParentTree == null || udtaBox.ParentTree.Length == 0)
         {
             BoxHeader moov_header = parser.MoovTree[parser.MoovTree.Length - 1];
             size_change    = tag_data.Count;
             write_position = moov_header.Position + moov_header.TotalBoxSize;
             Insert(tag_data, write_position, 0);
             for (int i = parser.MoovTree.Length - 1; i >= 0; i--)
             {
                 size_change = parser.MoovTree[i].Overwrite(this, size_change);
             }
         }
         else
         {
             BoxHeader udta_header = udtaBox.ParentTree[udtaBox.ParentTree.Length - 1];
             size_change    = tag_data.Count - udta_header.TotalBoxSize;
             write_position = udta_header.Position;
             Insert(tag_data, write_position, udta_header.TotalBoxSize);
             for (int i = udtaBox.ParentTree.Length - 2; i >= 0; i--)
             {
                 size_change = udtaBox.ParentTree[i].Overwrite(this, size_change);
             }
         }
         if (size_change != 0)
         {
             parser.ParseChunkOffsets();
             InvariantStartPosition = parser.MdatStartPosition;
             InvariantEndPosition   = parser.MdatEndPosition;
             foreach (Box box in parser.ChunkOffsetBoxes)
             {
                 IsoChunkLargeOffsetBox co64 = box as IsoChunkLargeOffsetBox;
                 if (co64 != null)
                 {
                     co64.Overwrite(this, size_change, write_position);
                     continue;
                 }
                 IsoChunkOffsetBox stco = box as IsoChunkOffsetBox;
                 if (stco != null)
                 {
                     stco.Overwrite(this, size_change, write_position);
                     continue;
                 }
             }
         }
         TagTypesOnDisk = TagTypes;
     }
     finally
     {
         Mode = File.AccessMode.Closed;
     }
 }
Пример #6
0
 public override void Save()
 {
     if (this.udta_box == null)
     {
         this.udta_box = new IsoUserDataBox();
     }
     base.Mode = TagLib.File.AccessMode.Write;
     try
     {
         FileParser parser = new FileParser(this);
         parser.ParseBoxHeaders();
         base.InvariantStartPosition = parser.MdatStartPosition;
         base.InvariantEndPosition = parser.MdatEndPosition;
         long sizeChange = 0L;
         long start = 0L;
         ByteVector data = this.udta_box.Render();
         if (((parser.UdtaTree == null) || (parser.UdtaTree.Length == 0)) || (parser.UdtaTree[parser.UdtaTree.Length - 1].BoxType != BoxType.Udta))
         {
             BoxHeader header = parser.MoovTree[parser.MoovTree.Length - 1];
             sizeChange = data.Count;
             start = header.Position + header.TotalBoxSize;
             base.Insert(data, start, 0L);
             for (int i = parser.MoovTree.Length - 1; i >= 0; i--)
             {
                 sizeChange = parser.MoovTree[i].Overwrite(this, sizeChange);
             }
         }
         else
         {
             BoxHeader header2 = parser.UdtaTree[parser.UdtaTree.Length - 1];
             sizeChange = data.Count - header2.TotalBoxSize;
             start = header2.Position;
             base.Insert(data, start, header2.TotalBoxSize);
             for (int j = parser.UdtaTree.Length - 2; j >= 0; j--)
             {
                 sizeChange = parser.UdtaTree[j].Overwrite(this, sizeChange);
             }
         }
         if (sizeChange != 0)
         {
             parser.ParseChunkOffsets();
             base.InvariantStartPosition = parser.MdatStartPosition;
             base.InvariantEndPosition = parser.MdatEndPosition;
             foreach (Box box in parser.ChunkOffsetBoxes)
             {
                 IsoChunkLargeOffsetBox box2 = box as IsoChunkLargeOffsetBox;
                 if (box2 != null)
                 {
                     box2.Overwrite(this, sizeChange, start);
                 }
                 else
                 {
                     IsoChunkOffsetBox box3 = box as IsoChunkOffsetBox;
                     if (box3 != null)
                     {
                         box3.Overwrite(this, sizeChange, start);
                     }
                 }
             }
         }
         base.TagTypesOnDisk = base.TagTypes;
     }
     finally
     {
         base.Mode = TagLib.File.AccessMode.Closed;
     }
 }