| File: Recognition\SrgsGrammar\SrgsItem.cs | Web Access |
| Project: src\runtime\src\libraries\System.Speech\src\System.Speech.csproj (System.Speech) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Speech.Internal; using System.Speech.Internal.SrgsParser; using System.Text; using System.Xml; namespace System.Speech.Recognition.SrgsGrammar { [Serializable] [DebuggerDisplay("{DebuggerDisplayString ()}")] [DebuggerTypeProxy(typeof(SrgsItemDebugDisplay))] public class SrgsItem : SrgsElement, IItem { #region Constructors public SrgsItem() { _elements = new SrgsElementList(); } public SrgsItem(string text) : this() { Helpers.ThrowIfEmptyOrNull(text, nameof(text)); _elements.Add(new SrgsText(text)); } public SrgsItem(params SrgsElement[] elements) : this() { ArgumentNullException.ThrowIfNull(elements); for (int iElement = 0; iElement < elements.Length; iElement++) { if (elements[iElement] == null) { throw new ArgumentNullException(nameof(elements), SR.Get(SRID.ParamsEntryNullIllegal)); } _elements.Add(elements[iElement]); } } public SrgsItem(int repeatCount) : this() { SetRepeat(repeatCount); } public SrgsItem(int min, int max) : this() { SetRepeat(min, max); } //overloads with setting the repeat. public SrgsItem(int min, int max, string text) : this(text) { SetRepeat(min, max); } public SrgsItem(int min, int max, params SrgsElement[] elements) : this(elements) { SetRepeat(min, max); } #endregion #region Public Method public void SetRepeat(int count) { // Negative values are not allowed if (count < 0 || count > 255) { throw new ArgumentOutOfRangeException(nameof(count)); } _minRepeat = _maxRepeat = count; } public void SetRepeat(int minRepeat, int maxRepeat) { // Negative values are not allowed if (minRepeat < 0 || minRepeat > 255) { throw new ArgumentOutOfRangeException(nameof(minRepeat), SR.Get(SRID.InvalidMinRepeat, minRepeat)); } if (maxRepeat != int.MaxValue && (maxRepeat < 0 || maxRepeat > 255)) { throw new ArgumentOutOfRangeException(nameof(maxRepeat), SR.Get(SRID.InvalidMinRepeat, maxRepeat)); } // Max be greater or equal to min if (minRepeat > maxRepeat) { throw new ArgumentException(SR.Get(SRID.MinGreaterThanMax)); } _minRepeat = minRepeat; _maxRepeat = maxRepeat; } public void Add(SrgsElement element) { ArgumentNullException.ThrowIfNull(element); Elements.Add(element); } #endregion #region Public Properties public Collection<SrgsElement> Elements { get { return _elements; } } // The probability that this item will be repeated. public float RepeatProbability { get { return _repeatProbability; } set { if (value < 0.0f || value > 1.0f) { throw new ArgumentOutOfRangeException(nameof(value), SR.Get(SRID.InvalidRepeatProbability, value)); } _repeatProbability = value; } } // The minimum number of occurrences this item can/must be repeated. public int MinRepeat { get { return _minRepeat == NotSet ? 1 : _minRepeat; } } // The maximum number of occurrences this item can/must be repeated. public int MaxRepeat { get { return _maxRepeat == NotSet ? 1 : _maxRepeat; } } public float Weight { get { return _weight; } set { if (value <= 0.0f) { throw new ArgumentOutOfRangeException(nameof(value), SR.Get(SRID.InvalidWeight, value)); } _weight = value; } } #endregion #region Internal Methods /// <summary> /// Write the XML fragment describing the object. /// </summary> internal override void WriteSrgs(XmlWriter writer) { // Write <item weight="1.0" repeat-prob="0.5" repeat="m-n"> writer.WriteStartElement("item"); if (!_weight.Equals(1.0f)) { writer.WriteAttributeString("weight", _weight.ToString("0.########", CultureInfo.InvariantCulture)); } if (!_repeatProbability.Equals(0.5f)) { writer.WriteAttributeString("repeat-prob", _repeatProbability.ToString("0.########", CultureInfo.InvariantCulture)); } if (_minRepeat == _maxRepeat) { // could be because both value are NotSet of equal if (_minRepeat != NotSet) { writer.WriteAttributeString("repeat", string.Format(CultureInfo.InvariantCulture, "{0}", _minRepeat)); } } else if (_maxRepeat == int.MaxValue || _maxRepeat == NotSet) { // MinValue Set but not Max Value writer.WriteAttributeString("repeat", string.Format(CultureInfo.InvariantCulture, "{0}-", _minRepeat)); } else { // Max Value Set and maybe MinValue int minRepeat = _minRepeat == NotSet ? 1 : _minRepeat; writer.WriteAttributeString("repeat", string.Format(CultureInfo.InvariantCulture, "{0}-{1}", minRepeat, _maxRepeat)); } // Write <item> body and footer. Type? previousElementType = null; foreach (SrgsElement element in _elements) { // Insert space between consecutive SrgsText _elements. Type elementType = element.GetType(); if ((elementType == typeof(SrgsText)) && (elementType == previousElementType)) { writer.WriteString(" "); } previousElementType = elementType; element.WriteSrgs(writer); } writer.WriteEndElement(); } internal override string DebuggerDisplayString() { StringBuilder sb = new(); if (_elements.Count > 7) { sb.Append("SrgsItem Count = "); sb.Append(_elements.Count.ToString(CultureInfo.InvariantCulture)); } else { if (_minRepeat != _maxRepeat || _maxRepeat != NotSet) { sb.Append('['); if (_minRepeat == _maxRepeat) { sb.Append(_minRepeat.ToString(CultureInfo.InvariantCulture)); } else if (_maxRepeat == int.MaxValue || _maxRepeat == NotSet) { // MinValue Set but not Max Value sb.Append(string.Format(CultureInfo.InvariantCulture, "{0},-", _minRepeat)); } else { // Max Value Set and maybe MinValue int minRepeat = _minRepeat == NotSet ? 1 : _minRepeat; sb.Append(string.Format(CultureInfo.InvariantCulture, "{0},{1}", minRepeat, _maxRepeat)); } sb.Append("] "); } bool first = true; foreach (SrgsElement element in _elements) { if (!first) { sb.Append(' '); } sb.Append('{'); sb.Append(element.DebuggerDisplayString()); sb.Append('}'); first = false; } } return sb.ToString(); } #endregion #region Protected Properties /// <summary> /// Allows the Srgs Element base class to implement /// features requiring recursion in the elements tree. /// </summary> internal override SrgsElement[] Children { get { SrgsElement[] elements = new SrgsElement[_elements.Count]; int i = 0; foreach (SrgsElement element in _elements) { elements[i++] = element; } return elements; } } #endregion #region Private Methods #endregion #region Private Fields private float _weight = 1.0f; private float _repeatProbability = 0.5f; private int _minRepeat = NotSet; private int _maxRepeat = NotSet; private SrgsElementList _elements; private const int NotSet = -1; #endregion #region Private Types // Used by the debugger display attribute internal class SrgsItemDebugDisplay { public SrgsItemDebugDisplay(SrgsItem item) { _weight = item._weight; _repeatProbability = item._repeatProbability; _minRepeat = item._minRepeat; _maxRepeat = item._maxRepeat; _elements = item._elements; } public object Weight { get { return _weight; } } public object MinRepeat { get { return _minRepeat; } } public object MaxRepeat { get { return _maxRepeat; } } public object RepeatProbability { get { return _repeatProbability; } } public object Count { get { return _elements.Count; } } [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public SrgsElement[] AKeys { get { SrgsElement[] elements = new SrgsElement[_elements.Count]; for (int i = 0; i < _elements.Count; i++) { elements[i] = _elements[i]; } return elements; } } private float _weight = 1.0f; private float _repeatProbability = 0.5f; private int _minRepeat = NotSet; private int _maxRepeat = NotSet; private SrgsElementList _elements; } #endregion } }