Logo Search packages:      
Sourcecode: taglib-sharp version File versions  Download package

File.cs

//
// File.cs: Provides tagging and properties for files that contain an
// indeterminite  number of tags at their beginning or end.
//
// Author:
//   Brian Nickel (brian.nickel@gmail.com)
//
// Copyright (C) 2007 Brian Nickel
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;

namespace TagLib.NonContainer {
      /// <summary>
      ///    This abstract class extends <see cref="TagLib.File" /> to provide
      ///    tagging and properties for files that contain an indeterminite
      ///    number of tags at their beginning or end.
      /// </summary>
      /// <remarks>
      ///    <para>When extending this class, <see cref="ReadStart" />, <see
      ///    cref="ReadEnd" />, and <see cref="ReadProperties" /> should be
      ///    overrided methods that read the format specific information from
      ///    the file.</para>
      ///    <para>The file is read upon construction in the following
      ///    manner:</para>
      ///    <list type="number">
      ///       <item><term>The file is opened for reading.</term></item>
      ///       <item><term>The tags at the start of the file are
      ///       read.</term></item>
      ///       <item><term><see cref="ReadStart" /> is called.</term></item>
      ///       <item><term>The tags at the end of the file are
      ///       read.</term></item>
      ///       <item><term><see cref="ReadEnd" /> is called.</term></item>
      ///       <item><term>If reading with a style other than <see
      ///       cref="ReadStyle.None" />, <see cref="ReadProperties" /> is
      ///       called.</term></item>
      ///       <item><term>The file is closed.</term></item>
      ///    </list>
      /// </remarks>
00059       public abstract class File : TagLib.File
      {
            #region Private Fields
            
            /// <summary>
            ///    Contains the tags.
            /// </summary>
00066             private TagLib.NonContainer.Tag tag;
            
            /// <summary>
            ///    Contains the media properties.
            /// </summary>
00071             private Properties properties;
            
            #endregion
            
            
            
            #region Constructors
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="File" /> for a specified path in the local file
            ///    system and specified read style.
            /// </summary>
            /// <param name="path">
            ///    A <see cref="string" /> object containing the path of the
            ///    file to use in the new instance.
            /// </param>
            /// <param name="propertiesStyle">
            ///    A <see cref="ReadStyle" /> value specifying at what level
            ///    of accuracy to read the media properties, or <see
            ///    cref="ReadStyle.None" /> to ignore the properties.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="path" /> is <see langword="null" />.
            /// </exception>
00096             protected File (string path, ReadStyle propertiesStyle)
                  : base (path)
            {
                  Read (propertiesStyle);
            }
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="File" /> for a specified path in the local file
            ///    system with an average read style.
            /// </summary>
            /// <param name="path">
            ///    A <see cref="string" /> object containing the path of the
            ///    file to use in the new instance.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="path" /> is <see langword="null" />.
            /// </exception>
00114             protected File (string path) : this (path, ReadStyle.Average)
            {
            }
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="File" /> for a specified file abstraction and
            ///    specified read style.
            /// </summary>
            /// <param name="abstraction">
            ///    A <see cref="IFileAbstraction" /> object to use when
            ///    reading from and writing to the file.
            /// </param>
            /// <param name="propertiesStyle">
            ///    A <see cref="ReadStyle" /> value specifying at what level
            ///    of accuracy to read the media properties, or <see
            ///    cref="ReadStyle.None" /> to ignore the properties.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="abstraction" /> is <see langword="null"
            ///    />.
            /// </exception>
00136             protected File (File.IFileAbstraction abstraction,
                            ReadStyle propertiesStyle)
            : base (abstraction)
            {
                  Read (propertiesStyle);
            }
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="File" /> for a specified file abstraction with an
            ///    average read style.
            /// </summary>
            /// <param name="abstraction">
            ///    A <see cref="IFileAbstraction" /> object to use when
            ///    reading from and writing to the file.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="abstraction" /> is <see langword="null"
            ///    />.
            /// </exception>
00156             protected File (File.IFileAbstraction abstraction)
                  : this (abstraction, ReadStyle.Average)
            {
            }
            
            #endregion
            
            
            
            #region Public Properties
            
            /// <summary>
            ///    Gets a abstract representation of all tags stored in the
            ///    current instance.
            /// </summary>
            /// <value>
            ///    A <see cref="TagLib.Tag" /> object representing all tags
            ///    stored in the current instance.
            /// </value>
00175             public override TagLib.Tag Tag {
                  get {return tag;}
            }
            
            /// <summary>
            ///    Gets the media properties of the file represented by the
            ///    current instance.
            /// </summary>
            /// <value>
            ///    A <see cref="TagLib.Properties" /> object containing the
            ///    media properties of the file represented by the current
            ///    instance.
            /// </value>
00188             public override TagLib.Properties Properties {
                  get {return properties;}
            }
            
            #endregion
            
            
            
            #region Public Methods
            
            /// <summary>
            ///    Saves the changes made in the current instance to the
            ///    file it represents.
            /// </summary>
00202             public override void Save ()
            {
                  long start, end;
                  Mode = AccessMode.Write;
                  try {
                        tag.Write (out start, out end);
                        InvariantStartPosition = start;
                        InvariantEndPosition = end;
                        TagTypesOnDisk = TagTypes;
                  } finally {
                        Mode = AccessMode.Closed;
                  }
            }
            
            /// <summary>
            ///    Removes a set of tag types from the current instance.
            /// </summary>
            /// <param name="types">
            ///    A bitwise combined <see cref="TagLib.TagTypes" /> value
            ///    containing tag types to be removed from the file.
            /// </param>
            /// <remarks>
            ///    In order to remove all tags from a file, pass <see
            ///    cref="TagTypes.AllTags" /> as <paramref name="types" />.
            /// </remarks>
00227             public override void RemoveTags (TagTypes types)
            {
                  tag.RemoveTags (types);
            }
            
            #endregion
            
            
            
            #region Protected Properties
            
            /// <summary>
            ///    Gets the collection of tags appearing at the start of the
            ///    file.
            /// </summary>
            /// <value>
            ///    A <see cref="TagLib.NonContainer.StartTag" /> storing the
            ///    tags for the start of the file.
            /// </value>
00246             protected StartTag StartTag {
                  get {return tag.StartTag;}
            }
            
            /// <summary>
            ///    Gets the collection of tags appearing at the end of the
            ///    file.
            /// </summary>
            /// <value>
            ///    A <see cref="TagLib.NonContainer.EndTag" /> storing the
            ///    tags for the end of the file.
            /// </value>
00258             protected EndTag EndTag {
                  get {return tag.EndTag;}
            }
            
            #endregion
            
            
            
            #region Protected Methods
            
            /// <summary>
            ///    Reads format specific information at the start of the
            ///    file.
            /// </summary>
            /// <param name="start">
            ///    A <see cref="long" /> value containing the seek position
            ///    at which the tags end and the media data begins.
            /// </param>
            /// <param name="propertiesStyle">
            ///    A <see cref="ReadStyle" /> value specifying at what level
            ///    of accuracy to read the media properties, or <see
            ///    cref="ReadStyle.None" /> to ignore the properties.
            /// </param>
            /// <remarks>
            ///    This method is called by the constructor immediately
            ///    after the tags at the start of the file have been read
            ///    and as such (so the internal seek mechanism is close to
            ///    the start). It should be used for reading any content
            ///    specific information, such as an audio header from the
            ///    start of the file.
            /// </remarks>
00289             protected virtual void ReadStart (long start,
                                              ReadStyle propertiesStyle)
            {
            }
            
            /// <summary>
            ///    Reads format specific information at the end of the
            ///    file.
            /// </summary>
            /// <param name="end">
            ///    A <see cref="long" /> value containing the seek position
            ///    at which the media data ends and the tags begin.
            /// </param>
            /// <param name="propertiesStyle">
            ///    A <see cref="ReadStyle" /> value specifying at what level
            ///    of accuracy to read the media properties, or <see
            ///    cref="ReadStyle.None" /> to ignore the properties.
            /// </param>
            /// <remarks>
            ///    This method is called by the constructor immediately
            ///    after the tags at the end of the file have been read
            ///    and as such (so the internal seek mechanism is close to
            ///    the end). It should be used for reading any content
            ///    specific information, such as an audio header from the
            ///    end of the file.
            /// </remarks>
00315             protected virtual void ReadEnd (long end,
                                            ReadStyle propertiesStyle)
            {
            }
            
            /// <summary>
            ///    Reads the audio properties from the file represented by
            ///    the current instance.
            /// </summary>
            /// <param name="start">
            ///    A <see cref="long" /> value containing the seek position
            ///    at which the tags end and the media data begins.
            /// </param>
            /// <param name="end">
            ///    A <see cref="long" /> value containing the seek position
            ///    at which the media data ends and the tags begin.
            /// </param>
            /// <param name="propertiesStyle">
            ///    A <see cref="ReadStyle" /> value specifying at what level
            ///    of accuracy to read the media properties, or <see
            ///    cref="ReadStyle.None" /> to ignore the properties.
            /// </param>
            /// <returns>
            ///    A <see cref="TagLib.Properties" /> object describing the
            ///    media properties of the file represented by the current
            ///    instance.
            /// </returns>
            /// <remarks>
            ///    This method is called ONLY IF the file is constructed
            ///    with a read style other than <see cref="ReadStyle.None"
            ///    />, and as such MUST NOT return <see langword="null" />.
            ///    It is guaranteed that <see cref="ReadStart" /> and <see
            ///    cref="ReadEnd" /> will have been called first and this
            ///    method should be strictly used to perform final
            ///    processing on already read data.
            /// </remarks>
            protected abstract Properties ReadProperties (long start,
                                                          long end,
                                                          ReadStyle propertiesStyle);
            
            #endregion
            
            
            
            #region Private Methods
            
            /// <summary>
            ///    Reads the file with a specified read style.
            /// </summary>
            /// <param name="propertiesStyle">
            ///    A <see cref="ReadStyle" /> value specifying at what level
            ///    of accuracy to read the media properties, or <see
            ///    cref="ReadStyle.None" /> to ignore the properties.
            /// </param>
00369             private void Read (ReadStyle propertiesStyle)
            {
                  Mode = AccessMode.Read;
                  try {
                        tag = new Tag (this);
                        
                        // Read the tags and property data at the beginning of
                        // the file.
                        InvariantStartPosition = tag.ReadStart ();
                        TagTypesOnDisk |= StartTag.TagTypes;
                        ReadStart (InvariantStartPosition, propertiesStyle);
                        
                        // Read the tags and property data at the end of the
                        // file.
                        InvariantEndPosition =
                              (InvariantStartPosition == Length) ?
                              Length : tag.ReadEnd ();
                        TagTypesOnDisk |= EndTag.TagTypes;
                        ReadEnd (InvariantEndPosition, propertiesStyle);
                        
                        // Read the audio properties.
                        properties = (propertiesStyle != ReadStyle.None) ?
                              ReadProperties (InvariantStartPosition,
                                    InvariantEndPosition, propertiesStyle) :
                              null;
                  } finally {
                        Mode = AccessMode.Closed;
                  }
            }
            
            #endregion
      }
}

Generated by  Doxygen 1.6.0   Back to index