2 // This file is part of the LWES .NET Binding (LWES.net)
4 // COPYRIGHT (C) 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 // 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
;
29 /// Template for an event type.
32 public struct EventTemplate
37 /// Empty event template.
39 public static readonly EventTemplate Empty
= new EventTemplate();
41 AttributeTemplate
[] _attributes
;
42 Dictionary
<string, int> _attributesByName
;
51 /// Creates a new template.
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
)
59 _attributes
= new AttributeTemplate
[0];
60 _attributesByName
= null;
63 #endregion Constructors
68 /// Gets the tempate's attributes.
70 public IEnumerable
<AttributeTemplate
> Attributes
72 get { return _attributes; }
75 if (value == null) throw new ArgumentNullException("Attributes");
77 // When the attributes are set we calculate the ordinal positions
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
);
90 /// Gets the attribute count.
94 get { return _attributes.Length; }
98 /// Indicates the template is from ESF
102 get { return _fromEsf; }
106 /// The event template's name.
110 get { return _name; }
113 #endregion Properties
118 /// Gets an attribute's template.
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
]
128 if (TryGetOrdinal(name
, out ord
))
130 return _attributes
[ord
];
132 throw new ArgumentOutOfRangeException("name");
137 /// Gets an attribute's template at the ordinal position given.
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
];
155 /// Parses a character array for an event tempate.
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.
194 /// Indicates whether there is an attribute defined with the given name.
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
);
204 /// Tries to get the ordinal position of the attribute given.
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)
216 return _attributesByName
.TryGetValue(name
, out ord
);
219 internal EventTemplate
AppendAttributes(params AttributeTemplate
[] append
)
221 EventTemplate ev
= new EventTemplate(false, Name
);
223 ev
.Attributes
= from a
in Enumerable
.Concat(_attributes
, append
)
224 select new AttributeTemplate(a
.TypeToken
, a
.Name
, ord
++);
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
);
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
);
249 ev
.Attributes
= from a
in Enumerable
.Concat(prepend
, _attributes
)
250 select new AttributeTemplate(a
.TypeToken
, a
.Name
, ord
++);