2 // This file is part of the LWES .NET Binding (LWES.net)
4 // COPYRIGHT© 2009, Phillip Clark (cerebralkungfu[at*g mail[dot*com)
5 // original .NET implementation
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 // Lesser 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
23 using System
.Collections
.Generic
;
27 /// Template for an event type.
30 public struct EventTemplate
35 /// Empty event template.
37 public static readonly EventTemplate Empty
= new EventTemplate();
39 AttributeTemplate
[] _attributes
;
40 Dictionary
<string, int> _attributesByName
;
49 /// Creates a new template.
51 /// <param name="fromEsf">Indicates whether the tempate is from an ESF definition.</param>
52 /// <param name="eventName">Name of the event.</param>
53 public EventTemplate(bool fromEsf
, string eventName
)
57 _attributes
= new AttributeTemplate
[0];
58 _attributesByName
= null;
61 #endregion Constructors
66 /// Gets the tempate's attributes.
68 public IEnumerable
<AttributeTemplate
> Attributes
70 get { return _attributes; }
73 if (value == null) throw new ArgumentNullException("Attributes");
75 // When the attributes are set we calculate the ordinal positions
77 _attributes
= (from a
in value
78 select new AttributeTemplate(a
.TypeToken
, a
.Name
, ordinal
++)).ToArray();
79 _attributesByName
= new Dictionary
<string, int>();
80 foreach (var a
in _attributes
)
82 _attributesByName
.Add(a
.Name
, a
.Ordinal
);
88 /// Gets the attribute count.
92 get { return _attributes.Length; }
96 /// Indicates the template is from ESF
100 get { return _fromEsf; }
104 /// The event template's name.
108 get { return _name; }
111 #endregion Properties
116 /// Gets an attribute's template.
118 /// <param name="name">attribute name</param>
119 /// <returns>the attribute's template</returns>
120 /// <exception cref="ArgumentOutOfRangeException">thrown if the attribute does not exist</exception>
121 public AttributeTemplate
this[string name
]
126 if (TryGetOrdinal(name
, out ord
))
128 return _attributes
[ord
];
130 throw new ArgumentOutOfRangeException("name");
135 /// Gets an attribute's template at the ordinal position given.
137 /// <param name="ordinal">the attribute's position</param>
138 /// <returns>the attribute's template</returns>
139 /// <exception cref="ArgumentOutOfRangeException">thrown if the ordinal position is out of range</exception>
140 public AttributeTemplate
this[int ordinal
]
144 return _attributes
[ordinal
];
153 /// Parses a character array for an event tempate.
155 /// <param name="input">character input</param>
156 /// <param name="cursor">reference to a position within the input; upon success
157 /// this variable is advanced by the number of characters taken while parsing</param>
158 /// <returns>the event template</returns>
159 public static EventTemplate
ExpectEvent(char[] input
, ref Cursor cursor
)
161 Cursor c
= new Cursor(cursor
);
162 EsfParser
.SkipWhitespaceAndComments(input
, ref c
);
164 // parse the event name
165 string eventName
= EsfParser
.ExpectWord(input
, ref c
);
166 EventTemplate evt
= new EventTemplate(false, eventName
);
168 EsfParser
.SkipWhitespaceAndComments(input
, ref c
);
169 EsfParser
.ExpectChar(input
, ref c
, EsfParser
.LeftCurlyBracket
);
171 // read the attribute list
172 List
<AttributeTemplate
> attributes
= new List
<AttributeTemplate
>();
173 while (c
< input
.Length
&& input
[c
] != EsfParser
.RightCurlyBracket
)
175 EsfParser
.SkipWhitespaceAndComments(input
, ref c
);
176 if (c
< input
.Length
&& input
[c
] != EsfParser
.RightCurlyBracket
)
178 attributes
.Add(AttributeTemplate
.ExpectAttribute(input
, ref c
));
181 evt
.Attributes
= attributes
;
183 EsfParser
.SkipWhitespaceAndComments(input
, ref c
);
184 EsfParser
.ExpectChar(input
, ref c
, EsfParser
.RightCurlyBracket
);
186 // Advance the cursor upon success.
192 /// Indicates whether there is an attribute defined with the given name.
194 /// <param name="name">attribute's name</param>
195 /// <returns><em>true</em> if the attribute exists; otherwise <em>false</em></returns>
196 public bool HasAttribute(string name
)
198 return _attributesByName
!= null && _attributesByName
.ContainsKey(name
);
202 /// Tries to get the ordinal position of the attribute given.
204 /// <param name="name">attribute's name</param>
205 /// <param name="ord">reference to a variable that will hold the ordinal position of the attribute upon success</param>
206 /// <returns><em>true</em> if the attribute exists; otherwise <em>false</em></returns>
207 public bool TryGetOrdinal(string name
, out int ord
)
209 if (_attributesByName
== null)
214 return _attributesByName
.TryGetValue(name
, out ord
);
217 internal EventTemplate
AppendAttributes(params AttributeTemplate
[] append
)
219 EventTemplate ev
= new EventTemplate(false, Name
);
221 ev
.Attributes
= from a
in Enumerable
.Concat(_attributes
, append
)
222 select new AttributeTemplate(a
.TypeToken
, a
.Name
, ord
++);
226 internal int BinaryEncode(byte[] buffer
, ref int offset
)
228 int count
= 0, ofs
= offset
;
230 count
+= LwesSerializer
.WriteEVENTWORD(buffer
, ref ofs
, _name
, Constants
.DefaultEncoding
.GetEncoder());
231 count
+= LwesSerializer
.Write(buffer
, ref ofs
, (UInt16
)_attributes
.Length
);
237 internal int GetByteCount()
239 // [1-byte-length-prefix][1-255-byte-eventword][2-byte-attribute-count]
240 return Constants
.DefaultEncoding
.GetByteCount(_name
) + 3;
243 internal EventTemplate
PrependAttributes(params AttributeTemplate
[] prepend
)
245 EventTemplate ev
= new EventTemplate(false, Name
);
247 ev
.Attributes
= from a
in Enumerable
.Concat(prepend
, _attributes
)
248 select new AttributeTemplate(a
.TypeToken
, a
.Name
, ord
++);