Fixed the licensing statements - I had erroneously marked the files as covered by...
[lwes-dotnet/github-mirror.git] / Org.Lwes / ESF / EventTemplate.cs
blob14aa40a47225a3418bbd72bb410d47315041bb0f
1 //
2 // This file is part of the LWES .NET Binding (LWES.net)
3 //
4 // COPYRIGHT (C) 2009, Phillip Clark (cerebralkungfu[at*g mail[dot*com)
5 // original .NET implementation
6 //
7 // LWES.net is free software: you can redistribute it and/or modify
8 // it under the terms of the Lesser GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
12 // LWES.net is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the Lesser GNU General Public License
18 // along with LWES.net. If not, see <http://www.gnu.org/licenses/>.
20 namespace Org.Lwes.ESF
22 using System;
23 using System.Collections.Generic;
24 using System.Linq;
26 using Org.Lwes.DB;
28 /// <summary>
29 /// Template for an event type.
30 /// </summary>
31 [Serializable]
32 public struct EventTemplate
34 #region Fields
36 /// <summary>
37 /// Empty event template.
38 /// </summary>
39 public static readonly EventTemplate Empty = new EventTemplate();
41 AttributeTemplate[] _attributes;
42 Dictionary<string, int> _attributesByName;
43 bool _fromEsf;
44 string _name;
46 #endregion Fields
48 #region Constructors
50 /// <summary>
51 /// Creates a new template.
52 /// </summary>
53 /// <param name="fromEsf">Indicates whether the tempate is from an ESF definition.</param>
54 /// <param name="eventName">Name of the event.</param>
55 public EventTemplate(bool fromEsf, string eventName)
57 _fromEsf = fromEsf;
58 _name = eventName;
59 _attributes = new AttributeTemplate[0];
60 _attributesByName = null;
63 #endregion Constructors
65 #region Properties
67 /// <summary>
68 /// Gets the tempate's attributes.
69 /// </summary>
70 public IEnumerable<AttributeTemplate> Attributes
72 get { return _attributes; }
73 private set
75 if (value == null) throw new ArgumentNullException("Attributes");
77 // When the attributes are set we calculate the ordinal positions
78 int ordinal = 0;
79 _attributes = (from a in value
80 select new AttributeTemplate(a.TypeToken, a.Name, ordinal++)).ToArray();
81 _attributesByName = new Dictionary<string, int>();
82 foreach (var a in _attributes)
84 _attributesByName.Add(a.Name, a.Ordinal);
89 /// <summary>
90 /// Gets the attribute count.
91 /// </summary>
92 public int Count
94 get { return _attributes.Length; }
97 /// <summary>
98 /// Indicates the template is from ESF
99 /// </summary>
100 public bool FromEsf
102 get { return _fromEsf; }
105 /// <summary>
106 /// The event template's name.
107 /// </summary>
108 public string Name
110 get { return _name; }
113 #endregion Properties
115 #region Indexers
117 /// <summary>
118 /// Gets an attribute's template.
119 /// </summary>
120 /// <param name="name">attribute name</param>
121 /// <returns>the attribute's template</returns>
122 /// <exception cref="ArgumentOutOfRangeException">thrown if the attribute does not exist</exception>
123 public AttributeTemplate this[string name]
127 int ord;
128 if (TryGetOrdinal(name, out ord))
130 return _attributes[ord];
132 throw new ArgumentOutOfRangeException("name");
136 /// <summary>
137 /// Gets an attribute's template at the ordinal position given.
138 /// </summary>
139 /// <param name="ordinal">the attribute's position</param>
140 /// <returns>the attribute's template</returns>
141 /// <exception cref="ArgumentOutOfRangeException">thrown if the ordinal position is out of range</exception>
142 public AttributeTemplate this[int ordinal]
146 return _attributes[ordinal];
150 #endregion Indexers
152 #region Methods
154 /// <summary>
155 /// Parses a character array for an event tempate.
156 /// </summary>
157 /// <param name="input">character input</param>
158 /// <param name="cursor">reference to a position within the input; upon success
159 /// this variable is advanced by the number of characters taken while parsing</param>
160 /// <returns>the event template</returns>
161 public static EventTemplate ExpectEvent(char[] input, ref Cursor cursor)
163 Cursor c = new Cursor(cursor);
164 EsfParser.SkipWhitespaceAndComments(input, ref c);
166 // parse the event name
167 string eventName = EsfParser.ExpectWord(input, ref c);
168 EventTemplate evt = new EventTemplate(false, eventName);
170 EsfParser.SkipWhitespaceAndComments(input, ref c);
171 EsfParser.ExpectChar(input, ref c, EsfParser.LeftCurlyBracket);
173 // read the attribute list
174 List<AttributeTemplate> attributes = new List<AttributeTemplate>();
175 while (c < input.Length && input[c] != EsfParser.RightCurlyBracket)
177 EsfParser.SkipWhitespaceAndComments(input, ref c);
178 if (c < input.Length && input[c] != EsfParser.RightCurlyBracket)
180 attributes.Add(AttributeTemplate.ExpectAttribute(input, ref c));
183 evt.Attributes = attributes;
185 EsfParser.SkipWhitespaceAndComments(input, ref c);
186 EsfParser.ExpectChar(input, ref c, EsfParser.RightCurlyBracket);
188 // Advance the cursor upon success.
189 cursor = c;
190 return evt;
193 /// <summary>
194 /// Indicates whether there is an attribute defined with the given name.
195 /// </summary>
196 /// <param name="name">attribute's name</param>
197 /// <returns><em>true</em> if the attribute exists; otherwise <em>false</em></returns>
198 public bool HasAttribute(string name)
200 return _attributesByName != null && _attributesByName.ContainsKey(name);
203 /// <summary>
204 /// Tries to get the ordinal position of the attribute given.
205 /// </summary>
206 /// <param name="name">attribute's name</param>
207 /// <param name="ord">reference to a variable that will hold the ordinal position of the attribute upon success</param>
208 /// <returns><em>true</em> if the attribute exists; otherwise <em>false</em></returns>
209 public bool TryGetOrdinal(string name, out int ord)
211 if (_attributesByName == null)
213 ord = -1;
214 return false;
216 return _attributesByName.TryGetValue(name, out ord);
219 internal EventTemplate AppendAttributes(params AttributeTemplate[] append)
221 EventTemplate ev = new EventTemplate(false, Name);
222 int ord = 0;
223 ev.Attributes = from a in Enumerable.Concat(_attributes, append)
224 select new AttributeTemplate(a.TypeToken, a.Name, ord++);
225 return ev;
228 internal int BinaryEncode(byte[] buffer, ref int offset)
230 int count = 0, ofs = offset;
232 count += LwesSerializer.WriteEVENTWORD(buffer, ref ofs, _name, Constants.DefaultEncoding.GetEncoder());
233 count += LwesSerializer.Write(buffer, ref ofs, (UInt16)_attributes.Length);
235 offset = ofs;
236 return count;
239 internal int GetByteCount()
241 // [1-byte-length-prefix][1-255-byte-eventword][2-byte-attribute-count]
242 return Constants.DefaultEncoding.GetByteCount(_name) + 3;
245 internal EventTemplate PrependAttributes(params AttributeTemplate[] prepend)
247 EventTemplate ev = new EventTemplate(false, Name);
248 int ord = 0;
249 ev.Attributes = from a in Enumerable.Concat(prepend, _attributes)
250 select new AttributeTemplate(a.TypeToken, a.Name, ord++);
251 return ev;
254 #endregion Methods