#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved //----------------------------------------------------------------------------- // Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved // Web: https://www.technosoftware.com // // The source code in this file is covered under a dual-license scenario: // - Owner of a purchased license: SCLA 1.0 // - GPL V3: everybody else // // SCLA license terms accompanied with this source code. // See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf // // GNU General Public License as published by the Free Software Foundation; // version 3 of the License are accompanied with this source code. // See https://technosoftware.com/license/GPLv3License.txt // // This source code 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. //----------------------------------------------------------------------------- #endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved #region Using Directives using System; using System.Text; using System.Collections; #endregion namespace Technosoftware.DaAeHdaClient.Hda { /// /// A collection of time offsets used in a relative time. /// [Serializable] public class TsCHdaTimeOffsetCollection : ArrayList { #region Properties /// /// Accessor for elements in the time offset collection. /// public new TsCHdaTimeOffset this[int index] { get => this[index]; set => this[index] = value; } #endregion #region Public Methods /// /// Adds a new offset to the collection. /// /// The offset value. /// The offset type. public int Add(int value, TsCHdaRelativeTime type) { var offset = new TsCHdaTimeOffset { Value = value, Type = type }; return base.Add(offset); } /// /// Returns a String that represents the current Object. /// /// A String that represents the current Object. public override string ToString() { var buffer = new StringBuilder(256); foreach (TsCHdaTimeOffset offset in (ICollection)this) { if (offset.Value >= 0) { buffer.Append("+"); } buffer.AppendFormat("{0}", offset.Value); buffer.Append(TsCHdaTimeOffset.OffsetTypeToString(offset.Type)); } return buffer.ToString(); } /// /// Initializes the collection from a set of offsets contained in a string. /// /// A string containing the time offset fields. public void Parse(string buffer) { // clear existing offsets. Clear(); // parse the offsets. var positive = true; var magnitude = 0; var units = ""; var state = 0; // state = 0 - looking for start of next offset field. // state = 1 - looking for beginning of offset value. // state = 2 - reading offset value. // state = 3 - reading offset type. for (var ii = 0; ii < buffer.Length; ii++) { // check for sign part of the offset field. if (buffer[ii] == '+' || buffer[ii] == '-') { if (state == 3) { Add(CreateOffset(positive, magnitude, units)); magnitude = 0; units = ""; state = 0; } if (state != 0) { throw new FormatException("Unexpected token encountered while parsing relative time string."); } positive = buffer[ii] == '+'; state = 1; } // check for integer part of the offset field. else if (char.IsDigit(buffer, ii)) { if (state == 3) { Add(CreateOffset(positive, magnitude, units)); magnitude = 0; units = ""; state = 0; } if (state != 0 && state != 1 && state != 2) { throw new FormatException("Unexpected token encountered while parsing relative time string."); } magnitude *= 10; magnitude += Convert.ToInt32(buffer[ii] - '0'); state = 2; } // check for units part of the offset field. else if (!char.IsWhiteSpace(buffer, ii)) { if (state != 2 && state != 3) { throw new FormatException("Unexpected token encountered while parsing relative time string."); } units += buffer[ii]; state = 3; } } // process final field. if (state == 3) { Add(CreateOffset(positive, magnitude, units)); state = 0; } // check final state. if (state != 0) { throw new FormatException("Unexpected end of string encountered while parsing relative time string."); } } #endregion #region ICollection Members /// /// Copies the objects to an Array, starting at a the specified index. /// /// The one-dimensional Array that is the destination for the objects. /// The zero-based index in the Array at which copying begins. public void CopyTo(TsCHdaTimeOffset[] array, int index) { CopyTo((Array)array, index); } #endregion #region IList Members /// /// Inserts an item to the IList at the specified position. /// /// The zero-based index at which value should be inserted. /// The Object to insert into the IList. public void Insert(int index, TsCHdaTimeOffset value) { Insert(index, (object)value); } /// /// Removes the first occurrence of a specific object from the IList. /// /// The Object to remove from the IList. public void Remove(TsCHdaTimeOffset value) { Remove((object)value); } /// /// Determines whether the IList contains a specific value. /// /// The Object to locate in the IList. /// true if the Object is found in the IList; otherwise, false. public bool Contains(TsCHdaTimeOffset value) { return Contains((object)value); } /// /// Determines the index of a specific item in the IList. /// /// The Object to locate in the IList. /// The index of value if found in the list; otherwise, -1. public int IndexOf(TsCHdaTimeOffset value) { return IndexOf((object)value); } /// /// Adds an item to the IList. /// /// The Object to add to the IList. /// The position into which the new element was inserted. public int Add(TsCHdaTimeOffset value) { return Add((object)value); } #endregion #region Private Methods /// /// Creates a new offset object from the components extracted from a string. /// private static TsCHdaTimeOffset CreateOffset(bool positive, int magnitude, string units) { foreach (TsCHdaRelativeTime offsetType in Enum.GetValues(typeof(TsCHdaRelativeTime))) { if (offsetType == TsCHdaRelativeTime.Now) { continue; } if (units == TsCHdaTimeOffset.OffsetTypeToString(offsetType)) { var offset = new TsCHdaTimeOffset { Value = (positive) ? magnitude : -magnitude, Type = offsetType }; return offset; } } throw new ArgumentOutOfRangeException(nameof(units), units, @"String is not a valid offset time type."); } #endregion } }