| File: Recognition\SrgsGrammar\SrgsDocument.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.CodeAnalysis; using System.Globalization; using System.Speech.Internal; using System.Speech.Internal.SrgsCompiler; using System.Speech.Internal.SrgsParser; using System.Xml; namespace System.Speech.Recognition.SrgsGrammar { /// <summary> /// This class allows a _grammar to be specified in SRGS form. /// APITODO: needs programmatic access to SRGS DOM; PACOG /// APITODO: needs rule activation/deactivation methods /// </summary> [Serializable] public class SrgsDocument { #region Constructors / Destructors /// <summary> /// The default constructor - creates an empty SrgsGrammar object /// </summary> public SrgsDocument() { _grammar = new SrgsGrammar(); } public SrgsDocument(string path) { Helpers.ThrowIfEmptyOrNull(path, nameof(path)); using (XmlTextReader reader = new(path)) { Load(reader); } } public SrgsDocument(XmlReader srgsGrammar) { ArgumentNullException.ThrowIfNull(srgsGrammar); Load(srgsGrammar); } public SrgsDocument(GrammarBuilder builder) { ArgumentNullException.ThrowIfNull(builder); // New grammar _grammar = new SrgsGrammar { #pragma warning disable 56504 // The Culture property is the Grammar builder is already checked. Culture = builder.Culture }; #pragma warning restore 56504 // Creates SrgsDocument elements IElementFactory elementFactory = new SrgsElementFactory(_grammar); // Do it builder.CreateGrammar(elementFactory); } public SrgsDocument(SrgsRule grammarRootRule) : this() { ArgumentNullException.ThrowIfNull(grammarRootRule); Root = grammarRootRule; Rules.Add(grammarRootRule); } #endregion #region public methods public void WriteSrgs(XmlWriter srgsGrammar) { ArgumentNullException.ThrowIfNull(srgsGrammar); // Make sure the grammar is ok _grammar.Validate(); // Write the data. _grammar.WriteSrgs(srgsGrammar); } #endregion #region Public Properties /// <summary> /// Base URI of _grammar (xml:base). /// </summary> public Uri? XmlBase { get { return _grammar.XmlBase; } set { // base value can be null #pragma warning disable 56526 _grammar.XmlBase = value; #pragma warning restore 56526 } } /// <summary> /// Grammar language (xml:lang) /// </summary> public CultureInfo Culture { get { return _grammar.Culture; } set { ArgumentNullException.ThrowIfNull(value); if (value.Equals(CultureInfo.InvariantCulture)) { throw new ArgumentException(SR.Get(SRID.InvariantCultureInfo), nameof(value)); } _grammar.Culture = value; } } /// <summary> /// Root rule (srgs:root) /// </summary> public SrgsRule? Root { get { return _grammar.Root; } set { // base value can be null #pragma warning disable 56526 _grammar.Root = value; #pragma warning restore 56526 } } /// <summary> /// Grammar mode (srgs:mode) - voice, dtmf /// </summary> public SrgsGrammarMode Mode { get { return _grammar.Mode == GrammarType.VoiceGrammar ? SrgsGrammarMode.Voice : SrgsGrammarMode.Dtmf; } set { _grammar.Mode = value == SrgsGrammarMode.Voice ? GrammarType.VoiceGrammar : GrammarType.DtmfGrammar; } } /// <summary> /// Grammar mode (srgs:mode) - voice, dtmf /// </summary> public SrgsPhoneticAlphabet PhoneticAlphabet { get { return (SrgsPhoneticAlphabet)_grammar.PhoneticAlphabet; } set { _grammar.PhoneticAlphabet = (AlphabetType)value; _grammar.HasPhoneticAlphabetBeenSet = true; } } /// <summary> /// A collection of rules that this _grammar houses. /// </summary> // APITODO: Implementations of Rules and all other SRGS objects not here for now public SrgsRulesCollection Rules { get { return _grammar.Rules; } } /// <summary> /// Programming Language used for the inline code; C#, VB or JScript /// </summary> public string? Language { get { return _grammar.Language; } set { // Language can be set to null #pragma warning disable 56526 _grammar.Language = value; #pragma warning restore 56526 } } /// <summary> /// namespace /// </summary> public string? Namespace { get { return _grammar.Namespace; } set { // namespace can be set to null #pragma warning disable 56526 _grammar.Namespace = value; #pragma warning restore 56526 } } /// <summary> /// CodeBehind /// </summary> public Collection<string> CodeBehind { get { return _grammar.CodeBehind; } } /// <summary> /// Add #line statements to the inline scripts if set /// </summary> public bool Debug { get { return _grammar.Debug; } set { _grammar.Debug = value; } } /// <summary> /// language /// </summary> public string Script { get { return _grammar.Script; } set { Helpers.ThrowIfEmptyOrNull(value, nameof(value)); _grammar.Script = value; } } /// <summary> /// ImportNameSpaces /// </summary> public Collection<string> ImportNamespaces { get { return _grammar.ImportNamespaces; } } /// <summary> /// ImportNameSpaces /// </summary> public Collection<string> AssemblyReferences { get { return _grammar.AssemblyReferences; } } #endregion #region Internal methods // Initialize an SrgsDocument from an Srgs text source. [MemberNotNull(nameof(_grammar))] internal void Load(XmlReader srgsGrammar) { // New grammar _grammar = new SrgsGrammar { // For SrgsGrammar, the default is IPA, for xml grammars, it is sapi. PhoneticAlphabet = AlphabetType.Sapi }; // create an XMl Parser XmlParser srgsParser = new(srgsGrammar, null); // Creates SrgsDocument elements srgsParser.ElementFactory = new SrgsElementFactory(_grammar); // Do it srgsParser.Parse(); // This provides the path the XML was loaded from. // {Note potentially this may also be overridden by an xml:base attribute in the XML itself. // But for this scenario that doesn't matter since this is used to calculate the correct base path.} if (!string.IsNullOrEmpty(srgsGrammar.BaseURI)) { _baseUri = new Uri(srgsGrammar.BaseURI); } } internal static GrammarOptions TagFormat2GrammarOptions(SrgsTagFormat value) { GrammarOptions newValue = 0; switch (value) { case SrgsTagFormat.KeyValuePairs: newValue = GrammarOptions.KeyValuePairSrgs; break; case SrgsTagFormat.MssV1: newValue = GrammarOptions.MssV1; break; case SrgsTagFormat.W3cV1: newValue = GrammarOptions.W3cV1; break; } return newValue; } internal static SrgsTagFormat GrammarOptions2TagFormat(GrammarOptions value) { SrgsTagFormat tagFormat = SrgsTagFormat.Default; switch (value & GrammarOptions.TagFormat) { case GrammarOptions.MssV1: tagFormat = SrgsTagFormat.MssV1; break; case GrammarOptions.W3cV1: tagFormat = SrgsTagFormat.W3cV1; break; case GrammarOptions.KeyValuePairSrgs: case GrammarOptions.KeyValuePairs: tagFormat = SrgsTagFormat.KeyValuePairs; break; } return tagFormat; } #endregion #region Internal Properties /// <summary> /// Tag format (srgs:tag-format) /// </summary>summary> internal SrgsTagFormat TagFormat { set { _grammar.TagFormat = value; } } internal Uri? BaseUri { get { return _baseUri; } } internal SrgsGrammar Grammar { get { return _grammar; } } #endregion #region Private Fields private SrgsGrammar _grammar; // Path the grammar was actually loaded from, if this exists. // Note this is different to SrgsGrammar.XmlBase which is the value of the xml:base attribute in the document itself. private Uri? _baseUri; #endregion Fields } #region Enumerations // Grammar mode. Voice, Dtmf public enum SrgsGrammarMode { Voice, Dtmf } // Grammar mode. Voice, Dtmf public enum SrgsPhoneticAlphabet { Sapi, Ipa, Ups } #endregion Enumerations }