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

List.cs

//
// List.cs:
//
// Author:
//   Brian Nickel (brian.nickel@gmail.com)
//
// Copyright (C) 2007 Brian Nickel
//
// This library is free software; you can redistribute it and/or modify
// it  under the terms of the GNU Lesser General Public License version
// 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Runtime.Serialization;

namespace TagLib.Riff {
      /// <summary>
      ///    This class extends <see
      ///    cref="T:System.Collections.Generic.Dictionary`2" /> to provide
      ///    support for reading and writing RIFF lists.
      /// </summary>
      [Serializable]
      [ComVisible(false)]
00038       public class List : Dictionary <ByteVector,ByteVectorCollection>
      {
#region Constructors
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="List" /> with no contents.
            /// </summary>
00046             public List ()
            {
            }
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="List" /> by reading the contents of a raw RIFF
            ///    list stored in a <see cref="ByteVector" /> object.
            /// </summary>
            /// <param name="data">
            ///    A <see cref="ByteVector"/> containing a raw RIFF list to
            ///    read into the new instance.
            /// </param>
00059             public List (ByteVector data)
            {
                  if (data == null)
                        throw new ArgumentNullException ("data");
                  
                  Parse (data);
            }
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="List" /> by reading the contents of a raw RIFF list
            ///    from a specified position in a <see cref="TagLib.File"/>.
            /// </summary>
            /// <param name="file">
            ///    A <see cref="TagLib.File" /> object containing the file
            ///    from which the contents of the new instance is to be
            ///    read.
            /// </param>
            /// <param name="position">
            ///    A <see cref="long" /> value specify at what position to
            ///    read the list.
            /// </param>
            /// <param name="length">
            ///    A <see cref="int" /> value specifying the number of bytes
            ///    to read.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="file" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentOutOfRangeException">
            ///    <paramref name="position" /> is less than zero or greater
            ///    than the size of the file.
            /// </exception>
00092             public List (TagLib.File file, long position, int length)
            {
                  if (file == null)
                        throw new ArgumentNullException ("file");
                  
                  if (length < 0)
                        throw new ArgumentOutOfRangeException (
                              "length");
                  
                  if (position < 0 || position > file.Length - length)
                        throw new ArgumentOutOfRangeException (
                              "position");
                  
                  file.Seek (position);
                  Parse (file.ReadBlock (length));
            }
            
            /// <summary>
            ///    Constructs and initializes a new instance of <see
            ///    cref="List" /> from a specified serialization info and
            ///    streaming context.
            /// </summary>
            /// <param name="info">
            ///    A <see cref="SerializationInfo" /> object containing the
            ///    serialized data to be used for the new instance.
            /// </param>
            /// <param name="context">
            ///    A <see cref="StreamingContext" /> object containing the
            ///    streaming context information for the new instance.
            /// </param>
            /// <remarks>
            ///    This constructor is implemented because <see
            ///    cref="List" /> implements the <see cref="ISerializable"
            ///    /> interface.
            /// </remarks>
00127             protected List (SerializationInfo info,
                            StreamingContext context)
                  : base (info, context)
            {
            }
#endregion
            
            
            
#region Public Methods
            
            /// <summary>
            ///    Renders the current instance as a raw RIFF list.
            /// </summary>
            /// <returns>
            ///    A <see cref="ByteVector"/> object containing the rendered
            ///    version of the current instance.
            /// </returns>
00145             public ByteVector Render ()
            {
                  ByteVector data = new ByteVector ();
                  
                  foreach (ByteVector id in Keys)
                        foreach (ByteVector value in this [id]) {
                              if (value.Count == 0)
                                    continue;
                              
                              data.Add (id);
                              data.Add (ByteVector.FromUInt (
                                    (uint) value.Count, false));
                              data.Add (value);
                              
                              if (value.Count % 2 == 1)
                                    data.Add (0);
                        }
                  
                  return data;
            }
            
            /// <summary>
            ///    Renders the current instance enclosed in an item with a
            ///    specified ID.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector"/> object containing the ID of
            ///    the item to enclose the current instance in.
            /// </param>
            /// <returns>
            ///    A <see cref="ByteVector"/> object containing the rendered
            ///    version of the current instance.
            /// </returns>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00184             public ByteVector RenderEnclosed (ByteVector id)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  ByteVector data = Render ();
                  
                  if (data.Count <= 8)
                        return new ByteVector ();
                  
                  ByteVector header = new ByteVector ("LIST");
                  header.Add (ByteVector.FromUInt (
                        (uint) (data.Count + 4), false));
                  header.Add (id);
                  data.Insert (0, header);
                  return data;
            }
            
            /// <summary>
            ///    Gets the values for a specified item in the current
            ///    instance as a <see cref="ByteVectorCollection" />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <returns>
            ///    A <see cref="ByteVectorCollection" /> object containing
            ///    the values of the specified item.
            /// </returns>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00224             public ByteVectorCollection GetValues (ByteVector id)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  ByteVectorCollection value;
                  
                  return TryGetValue (id, out value) ?
                        value : new ByteVectorCollection ();
            }
            
            /// <summary>
            ///    Gets the values for a specified item in the current
            ///    instance as a <see cref="string[]" />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <returns>
            ///    A <see cref="string[]" /> containing the values of the
            ///    specified item.
            /// </returns>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00257             public string [] GetValuesAsStrings (ByteVector id)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  ByteVectorCollection values = GetValues (id);
                  
                  string [] result = new string [values.Count];
                  
                  for (int i = 0; i < result.Length; i ++) {
                        ByteVector data = values [i];
                        
                        if (data == null) {
                              result [i] = string.Empty;
                              continue;
                        }
                        
                        int length = data.Count;
                        while (length > 0 && data [length - 1] == 0)
                              length --;
                        
                        result [i] = data
                              .ToString (StringType.UTF8, 0, length);
                  }
                  
                  return result;
            }
            
            /// <summary>
            ///    Gets the values for a specified item in the current
            ///    instance as a <see cref="StringCollection" />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <returns>
            ///    A <see cref="StringCollection" /> object containing the
            ///    values of the specified item.
            /// </returns>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
            [Obsolete("Use GetValuesAsStrings(ByteVector)")]
00308             public StringCollection GetValuesAsStringCollection (ByteVector id)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  return new StringCollection (GetValuesAsStrings (id));
            }
            
            /// <summary>
            ///    Gets the value for a specified item in the current
            ///    instance as a <see cref="uint"/>.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <returns>
            ///    A <see cref="uint" /> value containing the first value
            ///    with the specified ID that could be converted to an
            ///    integer, or zero if none could be found.
            /// </returns>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00339             public uint GetValueAsUInt (ByteVector id)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  foreach (string text in GetValuesAsStrings (id)) {
                        uint value;
                        if (uint.TryParse (text, out value))
                              return value;
                  }
                  
                  return 0;
            }
            
            /// <summary>
            ///    Sets the value for a specified item in the current
            ///    instance to the contents of a <see
            ///    cref="T:System.Collections.Generic.IEnumerable`1" />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <param name="values">
            ///    A <see cref="T:System.Collections.Generic.IEnumerable`1"
            ///    /> containing the <see cref="ByteVector"/> objects to
            ///    store in the specified item.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00377             public void SetValue (ByteVector id,
                                  IEnumerable<ByteVector> values)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  if (values == null)
                        RemoveValue (id);
                  else if (ContainsKey (id))
                        this [id] = new ByteVectorCollection (values);
                  else
                        Add (id, new ByteVectorCollection (values));
            }
            
            /// <summary>
            ///    Sets the value for a specified item in the current
            ///    instance to the contents of a <see cref="ByteVector[]"
            ///    />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <param name="values">
            ///    A <see cref="ByteVector[]" /> containing the values to
            ///    store in the specified item.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00414             public void SetValue (ByteVector id, params ByteVector [] values)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  if (values == null || values.Length == 0)
                        RemoveValue (id);
                  else
                        SetValue (id, values as IEnumerable<ByteVector>);
            }
            
            /// <summary>
            ///    Sets the value for a specified item in the current
            ///    instance to the value of a <see cref="uint"/>.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <param name="value">
            ///    A <see cref="uint" /> value to store in the specified
            ///    item.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00447             public void SetValue (ByteVector id, uint value)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  if (value == 0)
                        RemoveValue (id);
                  else
                        SetValue (id, value.ToString (
                              CultureInfo.InvariantCulture));
            }
            
            /// <summary>
            ///    Sets the value for a specified item in the current
            ///    instance to the contents of a <see
            ///    cref="T:System.Collections.Generic.IEnumerable`1" />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <param name="values">
            ///    A <see cref="T:System.Collections.Generic.IEnumerable`1"
            ///    /> containing the <see cref="string"/> objects to store
            ///    in the specified item.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00483             public void SetValue (ByteVector id, IEnumerable<string> values)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  if (values == null) {
                        RemoveValue (id);
                        return;
                  }
                  
                  ByteVectorCollection l = new ByteVectorCollection ();
                  foreach (string value in values) {
                        if (string.IsNullOrEmpty (value))
                              continue;
                        
                        ByteVector data = ByteVector.FromString (value,
                              StringType.UTF8);
                        data.Add (0);
                        l.Add (data);
                  }
                  
                  if (l.Count == 0)
                        RemoveValue (id);
                  else
                        SetValue (id, l);
            }
            
            /// <summary>
            ///    Sets the value for a specified item in the current
            ///    instance to the contents of a <see cref="string[]" />.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector" /> object containing the ID of
            ///    the item to set.
            /// </param>
            /// <param name="values">
            ///    A <see cref="string[]" /> containing the values to store
            ///    in the specified item.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00532             public void SetValue (ByteVector id, params string [] values)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  if (values == null || values.Length == 0)
                        RemoveValue (id);
                  else
                        SetValue (id, values as IEnumerable<string>);
            }
            
            /// <summary>
            ///    Removes the item with the specified ID from the current
            ///    instance.
            /// </summary>
            /// <param name="id">
            ///    A <see cref="ByteVector"/> object containing the ID of
            ///    the item to remove from the current instance.
            /// </param>
            /// <exception cref="ArgumentNullException">
            ///    <paramref name="id" /> is <see langword="null" />.
            /// </exception>
            /// <exception cref="ArgumentException">
            ///    <paramref name="id" /> isn't exactly four bytes long.
            /// </exception>
00561             public void RemoveValue (ByteVector id)
            {
                  if (id == null)
                        throw new ArgumentNullException ("id");
                  
                  if (id.Count != 4)
                        throw new ArgumentException (
                              "ID must be 4 bytes long.", "id");
                  
                  if (ContainsKey (id))
                        Remove (id);
            }
            
#endregion
            
            
            
#region Private Methods
            
            /// <summary>
            ///    Populates the current instance by reading in the contents
            ///    of a raw RIFF list stored in a <see cref="ByteVector" />
            ///    object.
            /// </summary>
            /// <param name="data">
            ///    A <see cref="ByteVector"/> containing a raw RIFF list to
            ///    read into the current instance.
            /// </param>
00589             private void Parse (ByteVector data)
            {
                  int offset = 0;
                  while (offset + 8 < data.Count) {
                        ByteVector id = data.Mid (offset, 4);
                        int length = (int) data.Mid (offset + 4, 4)
                              .ToUInt (false);
                        
                        if (!ContainsKey (id))
                              Add (id, new ByteVectorCollection ());
                        
                        this [id].Add (data.Mid (offset + 8, length));
                        
                        if (length % 2 == 1)
                              length ++;
                        
                        offset += 8 + length;
                  }
            }
#endregion
      }
}

Generated by  Doxygen 1.6.0   Back to index