context: //
  // Tag.cs: Provide support for reading and writing ID3v1 tags.
  //
  // Author:
  //   Brian Nickel (brian.nickel@gmail.com)
  //
  // Original Source:
  //   id3v1tag.cpp from TagLib
  //
  // Copyright (C) 2005-2007 Brian Nickel
  // Copyright (C) 2002,2003 Scott Wheeler (Original Implementation)
  // 
  // 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.Globalization;
  
  namespace TagLib.Id3v1
  {
  	/// <summary>
  	///    This class extends <see cref="Tag" /> to provide support for
  	///    reading and writing tags stored in the ID3v1.1 format.
  	/// </summary>
  	public class Tag : TagLib.Tag
  	{
  
  		#region Private Fields
  
  		/// <summary>
  		///    Contains the title.
  		/// </summary>
  		string title;
  
  		/// <summary>
  		///    Contains the semicolon separated performers.
  		/// </summary>
  		string artist;
  
  		/// <summary>
  		///    Contains the album name.
  		/// </summary>
  		string album;
  
  		/// <summary>
  		///    Contains the 4 digit year.
  		/// </summary>
  		string year;
  
  		/// <summary>
  		///    Contains a comment on track.
  		/// </summary>
  		string comment;
  
  		/// <summary>
  		///    Contains the track number in the album.
  		/// </summary>
  		byte track;
  
  		/// <summary>
  		///    Contains the genre index.
  		/// </summary>
  		byte genre;
  
  		#endregion
  
  
  
  
  		#region Public Static Fields
  
  		/// <summary>
  		///    The size of a ID3v1 tag.
  		/// </summary>
  		public const uint Size = 128;
  
  		/// <summary>
  		///    The identifier used to recognize a ID3v1 tags.
  		/// </summary>
  		/// <value>
  		///    "TAG"
  		/// </value>
  		public static readonly ReadOnlyByteVector FileIdentifier = "TAG";
  
  		#endregion
  
  
  
  		#region Constructors
  
  		/// <summary>
  		///    Constructs and initializes a new instance of <see
  		///    cref="Tag" /> with no contents.
  		/// </summary>
  		public Tag ()
  		{
  			Clear ();
  		}
  
  		/// <summary>
  		///    Constructs and initializes a new instance of <see
  		///    cref="Tag" /> by reading the contents from a specified
  		///    position in a specified file.
  		/// </summary>
  		/// <param name="file">
  		///    A <see cref="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 tag.
  		/// </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>
  		/// <exception cref="CorruptFileException">
  		///    The file does not contain <see cref="FileIdentifier" />
  		///    at the given position.
  		/// </exception>
  		public Tag (File file, long position)
  		{
  			if (file == null)
  				throw new ArgumentNullException (nameof (file));
  
  			file.Mode = File.AccessMode.Read;
  
  			if (position < 0 || position > file.Length - Size)
  				throw new ArgumentOutOfRangeException (nameof (position));
  
  			file.Seek (position);
  
  			// read the tag -- always 128 bytes
  
  			ByteVector data = file.ReadBlock ((int)Size);
  
  			// some initial sanity checking
  
  			if (!data.StartsWith (FileIdentifier))
  				throw new CorruptFileException ("ID3v1 data does not start with identifier.");
  
  			Parse (data);
  		}
  
  		/// <summary>
  		///    Constructs and initializes a new instance of <see
  		///    cref="Tag" /> by reading the contents from a specified
  		///    <see cref="ByteVector" /> object.
  		/// </summary>
  		/// <param name="data">
  		///    A <see cref="ByteVector" /> object to read the tag from.
  		/// </param>
  		/// <exception cref="ArgumentNullException">
  		///    <paramref name="data" /> is <see langword="null" />.
  		/// </exception>
  		/// <exception cref="CorruptFileException">
  		///    <paramref name="data" /> is less than 128 bytes or does
  		///    not start with <see cref="FileIdentifier" />.
  		/// </exception>
  		public Tag (ByteVector data)
  		{
  			if (data == null)
  				throw new ArgumentNullException (nameof (data));
  
  			if (data.Count < Size)
  				throw new CorruptFileException ("ID3v1 data is less than 128 bytes long.");
  
  			if (!data.StartsWith (FileIdentifier))
  				throw new CorruptFileException ("ID3v1 data does not start with identifier.");
  
  			Parse (data);
  		}
  
  		#endregion
  
  
  
  		#region Public Methods
  
  		/// <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 ()
  		{
  			var data = new ByteVector {
  				FileIdentifier,
  				DefaultStringHandler.Render (title).Resize (30),
  				DefaultStringHandler.Render (artist).Resize (30),
  				DefaultStringHandler.Render (album).Resize (30),
  				DefaultStringHandler.Render (year).Resize (4),
  				DefaultStringHandler.Render (comment).Resize (28),
  				0,
  				track,
  				genre
  			};
  
  			return data;
  		}
  
  		#endregion
  
  
  
  		#region Public Static Properties
  
  		/// <summary>
  		///    Gets and sets the <see cref="StringHandler" /> object
  		///    to use when reading and writing ID3v1 fields.
  		/// </summary>
  		/// <value>
  		///    A <see cref="StringHandler" /> object to use when
  		///    processing fields.
  		/// </value>
  		public static StringHandler DefaultStringHandler { get; set; } = new StringHandler ();
  
  		#endregion
  
  
  		#region Private Methods
  
  		/// <summary>
  		///    Populates the current instance by parsing the contents of
  		///    a raw ID3v1 tag.
  		/// </summary>
  		/// <param name="data">
  		///    A <see cref="ByteVector" /> object containing the
  		///    starting with an ID3v1 tag.
  		/// </param>
  		void Parse (ByteVector data)
  		{
  			title = DefaultStringHandler.Parse (data.Mid (3, 30));
  			artist = DefaultStringHandler.Parse (data.Mid (33, 30));
  			album = DefaultStringHandler.Parse (data.Mid (63, 30));
  			year = DefaultStringHandler.Parse (data.Mid (93, 4));
  
  			// Check for ID3v1.1 -- Note that ID3v1 *does not*
  			// support "track zero" -- this is not a bug in TagLib.
  			// Since a zeroed byte is what we would expect to
  			// indicate the end of a C-String, specifically the
  			// comment string, a value of zero must be assumed to be
  			// just that.
  
  
gt: 			if (data[125] == 0 && data[126] != 0) {