9 using Org
.Lwes
.Properties
;
19 IEventAttribute
[] _attributes
;
20 SupportedEncoding _encoding
;
21 EventTemplate _template
;
29 /// Creates a new event with the given name.
31 public Event(string evName
)
32 : this(new EventTemplate(false, evName
), false, Constants
.CDefaultSupportedEncoding
)
37 /// Creates a new instance with an encoding.
39 /// <param name="enc">An encoding for the event.</param>
40 public Event(SupportedEncoding enc
)
41 : this(EventTemplate
.Empty
, false, enc
)
46 /// Creates a new event.
48 /// <param name="evTemplate">the event's template</param>
49 /// <param name="validating"><em>true</em> if validating should be performed on the event;
50 /// otherwise <em>false</em></param>
51 /// <param name="enc">indicates the encoding to use for the event's character data</param>
52 public Event(EventTemplate evTemplate
, bool validating
, SupportedEncoding enc
)
54 _template
= evTemplate
;
55 _validating
= validating
;
57 _attributes
= new IEventAttribute
[evTemplate
.Count
];
61 /// Constructor used by mutators.
63 private Event(EventTemplate t
, bool validating
, SupportedEncoding enc
64 , IEventAttribute
[] attributes
)
67 _validating
= validating
;
69 _attributes
= attributes
;
72 #endregion Constructors
77 /// Gets the attribute count.
79 public int AttributeCount
81 get { return _template.Count; }
85 /// Gets the encoding used when the event is encoded for binary transmission.
87 public SupportedEncoding Encoding
89 get { return _encoding; }
97 get { return _template.Name; }
100 #endregion Properties
105 /// Gets an attribute by name.
107 /// <param name="name">attribute name</param>
108 /// <returns>the attribute if it exists; otherwise an exception is thrown</returns>
109 /// <exception cref="ArgumentOutOfRangeException">thrown if an attribute with the given <paramref name="name"/> doesn't exist</exception>
110 public IEventAttribute
this[string name
]
115 if (!_template
.TryGetOrdinal(name
, out ord
))
116 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
117 return _attributes
[ord
];
122 /// Gets an attribute by ordinal position.
124 /// <param name="ord">ordinal position of the attribute</param>
125 /// <returns>an attribute at the <paramref name="ordinal"/> position given</returns>
126 /// <exception cref="ArgumentOutOfRangeException">thrown if the <paramref name="ordinal"/> is out of range</exception>
127 public IEventAttribute
this[int ord
]
131 if (0 > ord
|| ord
>= _attributes
.Length
)
132 throw new ArgumentOutOfRangeException("ordinal");
133 return _attributes
[ord
];
142 /// Gets an attribute's value.
144 /// <typeparam name="V">value type V</typeparam>
145 /// <param name="name">attribute's name.</param>
146 /// <returns>The value of the attribute, as type V</returns>
147 /// <exception cref="InvalidCastException">if the attribute's value cannot be
148 /// coerced into value type V</exception>
149 /// <exception cref="NoSuchAttributeException">thrown if an attribute with the given name
150 /// does not exist.</exception>
151 public V GetValue
<V
>(string name
)
154 if (_template
.TryGetOrdinal(name
, out ord
))
156 return _attributes
[ord
].GetValue
<V
>();
158 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
162 /// Sets an attribute's value.
164 /// <param name="name">the attribute's name</param>
165 /// <param name="value">the attribute's UInt16 value</param>
166 public Event
SetValue(string name
, UInt16
value)
169 AttributeTemplate attr
;
170 if (_template
.TryGetOrdinal(name
, out ord
))
172 attr
= _template
[ord
];
174 // Validate if necessary
175 if (_validating
&& !attr
.IsAssignable(value))
176 throw new AttributeNotSetException("name");
178 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
183 // Allow for SiteID or SenderPort inherited from MetaInfoEvent
184 if (!String
.Equals(Constants
.MetaEventInfoAttributes
.SiteID
.Name
, name
)
185 && !String
.Equals(Constants
.MetaEventInfoAttributes
.SenderPort
.Name
, name
))
186 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
189 // Adding a new attribute
190 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
194 /// Sets an attribute's value.
196 /// <param name="name">the attribute's name</param>
197 /// <param name="value">the attribute's Int16 value</param>
198 public Event
SetValue(string name
, Int16
value)
201 AttributeTemplate attr
;
202 if (_template
.TryGetOrdinal(name
, out ord
))
204 attr
= _template
[ord
];
206 // Validate if necessary
207 if (_validating
&& !attr
.IsAssignable(value))
208 throw new AttributeNotSetException("name");
210 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
213 // Allow for Encoding inherited from MetaInfoEvent
214 if (String
.Equals(Constants
.MetaEventInfoAttributes
.Encoding
.Name
, name
))
216 // encoding must be the first attribute (when encoded), make it so
217 return PrependAttribute(Constants
.MetaEventInfoAttributes
.Encoding
, value);
221 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
223 // Adding a new attribute
224 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
228 /// Sets an attribute's value.
230 /// <param name="name">the attribute's name</param>
231 /// <param name="value">the attribute's UInt32 value</param>
232 public Event
SetValue(string name
, UInt32
value)
235 AttributeTemplate attr
;
236 if (_template
.TryGetOrdinal(name
, out ord
))
238 attr
= _template
[ord
];
240 // Validate if necessary
241 if (_validating
&& !attr
.IsAssignable(value))
242 throw new AttributeNotSetException("name");
244 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
248 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
250 // Adding a new attribute
251 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
255 /// Sets an attribute's value.
257 /// <param name="name">the attribute's name</param>
258 /// <param name="value">the attribute's Int32 value</param>
259 public Event
SetValue(string name
, Int32
value)
262 AttributeTemplate attr
;
263 if (_template
.TryGetOrdinal(name
, out ord
))
265 attr
= _template
[ord
];
267 // Validate if necessary
268 if (_validating
&& !attr
.IsAssignable(value))
269 throw new AttributeNotSetException("name");
271 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
275 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
277 // Adding a new attribute
278 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
282 /// Sets an attribute's value.
284 /// <param name="name">the attribute's name</param>
285 /// <param name="value">the attribute's String value</param>
286 public Event
SetValue(string name
, String
value)
289 AttributeTemplate attr
;
290 if (_template
.TryGetOrdinal(name
, out ord
))
292 attr
= _template
[ord
];
294 // Validate if necessary
295 if (_validating
&& !attr
.IsAssignable(value))
296 throw new AttributeNotSetException("name");
298 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
302 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
304 // Adding a new attribute
305 return AppendAttribute( AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
309 /// Sets an attribute's value.
311 /// <param name="name">the attribute's name</param>
312 /// <param name="value">the attribute's IPAddress value</param>
313 public Event
SetValue(string name
, IPAddress
value)
316 AttributeTemplate attr
;
317 if (_template
.TryGetOrdinal(name
, out ord
))
319 attr
= _template
[ord
];
321 // Validate if necessary
322 if (_validating
&& !attr
.IsAssignable(value))
323 throw new AttributeNotSetException("name");
325 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
330 // Allow for SenderIP inherited from MetaInfoEvent
331 if (!String
.Equals(Constants
.MetaEventInfoAttributes
.SenderIP
.Name
, name
))
332 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
335 // Adding a new attribute
336 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
340 /// Sets an attribute's value.
342 /// <param name="name">the attribute's name</param>
343 /// <param name="value">the attribute's Int64 value</param>
344 public Event
SetValue(string name
, Int64
value)
347 AttributeTemplate attr
;
348 if (_template
.TryGetOrdinal(name
, out ord
))
350 attr
= _template
[ord
];
352 // Validate if necessary
353 if (_validating
&& !attr
.IsAssignable(value))
354 throw new AttributeNotSetException("name");
356 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
361 // Allow for ReceiptTime inherited from MetaInfoEvent
362 if (!String
.Equals(Constants
.MetaEventInfoAttributes
.ReceiptTime
.Name
, name
))
363 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
366 // Adding a new attribute
367 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
371 /// Sets an attribute's value.
373 /// <param name="name">the attribute's name</param>
374 /// <param name="value">the attribute's UInt64 value</param>
375 public Event
SetValue(string name
, UInt64
value)
378 AttributeTemplate attr
;
379 if (_template
.TryGetOrdinal(name
, out ord
))
381 attr
= _template
[ord
];
383 // Validate if necessary
384 if (_validating
&& !attr
.IsAssignable(value))
385 throw new AttributeNotSetException("name");
387 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
391 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
393 // Adding a new attribute
394 return AppendAttribute(AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
398 /// Sets an attribute's value.
400 /// <param name="name">the attribute's name</param>
401 /// <param name="value">the attribute's Boolean value</param>
402 public Event
SetValue(string name
, Boolean
value)
405 AttributeTemplate attr
;
406 if (_template
.TryGetOrdinal(name
, out ord
))
408 attr
= _template
[ord
];
410 // Validate if necessary
411 if (_validating
&& !attr
.IsAssignable(value))
412 throw new AttributeNotSetException("name");
414 return Mutate(ord
, _attributes
[ord
].Mutate(_template
, value));
418 throw new ArgumentOutOfRangeException("name", String
.Format(Resources
.Error_AttributeNotDefined
, name
));
420 // Adding a new attribute
421 return AppendAttribute( AttributeTemplate
.CreateTemplateForVariable(name
, 0, value), value);
425 /// Converts the event to a string.
427 /// <returns>String containing the event.</returns>
428 public override string ToString()
430 StringBuilder s
= new StringBuilder(400);
431 s
.Append(_template
.Name
).Append(": { Name: '").Append(_template
.Name
)
432 .Append("', FromESF: ").Append(_template
.FromEsf
)
433 .Append(", Attributes: {");
434 if (_attributes
!= null)
437 foreach (var a
in _attributes
)
439 if (i
++ > 0) s
.Append(", ").Append(a
);
443 return s
.Append("}}").ToString();
447 /// Converts the event to a string.
449 /// <param name="humanReadable">Whether the output should be formatted for human readability</param>
450 /// <returns>string contianing the event</returns>
451 public string ToString(bool humanReadable
)
453 if (!humanReadable
) return ToString();
455 string nl
= Environment
.NewLine
;
457 StringBuilder s
= new StringBuilder(400);
458 s
.Append(_template
.Name
).Append(":").Append(nl
).Append(" { Name: '").Append(_template
.Name
)
459 .Append("'").Append(nl
).Append(" , FromESF: ").Append(_template
.FromEsf
)
460 .Append(nl
).Append(" , Attributes: {");
461 if (_attributes
!= null)
464 foreach (var a
in _attributes
)
466 if (i
++ > 0) s
.Append(nl
).Append(" , ").Append(a
);
470 return s
.Append(nl
).Append(" }").Append(nl
).Append(" }").ToString();
474 /// Tries to get an attribute.
476 /// <param name="name">attribute's name</param>
477 /// <param name="value">reference to a variable where the attribute will be stored upon success</param>
478 /// <returns><em>true</em> if the attribute exists; otherwise <em>false</em></returns>
479 public bool TryGetAttribute(string name
, out IEventAttribute
value)
482 if (_template
.TryGetOrdinal(name
, out ord
))
484 value = _attributes
[ord
];
487 value = default(IEventAttribute
);
492 /// Tries to get an attribute's value as a UInt16.
494 /// <param name="attr">the attribute's name</param>
495 /// <param name="value">reference to a variable to hold the value</param>
496 /// <returns><em>true</em> if the value can be retrieved as a UInt16, otherwise <em>false</em></returns>
497 public bool TryGetValue(string attr
, out ushort value)
500 if (_template
.TryGetOrdinal(attr
, out ord
))
502 return _attributes
[ord
].TryGetValue(out value);
504 value = default(ushort);
509 /// Tries to get an attribute's value as a Int16.
511 /// <param name="attr">the attribute's name</param>
512 /// <param name="value">reference to a variable to hold the value</param>
513 /// <returns><em>true</em> if the value can be retrieved as a Int16, otherwise <em>false</em></returns>
514 public bool TryGetValue(string attr
, out short value)
517 if (_template
.TryGetOrdinal(attr
, out ord
))
519 return _attributes
[ord
].TryGetValue(out value);
521 value = default(short);
526 /// Tries to get an attribute's value as a UInt32.
528 /// <param name="attr">the attribute's name</param>
529 /// <param name="value">reference to a variable to hold the value</param>
530 /// <returns><em>true</em> if the value can be retrieved as a UInt32, otherwise <em>false</em></returns>
531 public bool TryGetValue(string attr
, out uint value)
534 if (_template
.TryGetOrdinal(attr
, out ord
))
536 return _attributes
[ord
].TryGetValue(out value);
538 value = default(uint);
543 /// Tries to get an attribute's value as a Int32.
545 /// <param name="attr">the attribute's name</param>
546 /// <param name="value">reference to a variable to hold the value</param>
547 /// <returns><em>true</em> if the value can be retrieved as a Int32, otherwise <em>false</em></returns>
548 public bool TryGetValue(string attr
, out int value)
551 if (_template
.TryGetOrdinal(attr
, out ord
))
553 return _attributes
[ord
].TryGetValue(out value);
555 value = default(int);
560 /// Tries to get an attribute's value as a string.
562 /// <param name="attr">the attribute's name</param>
563 /// <param name="value">reference to a variable to hold the value</param>
564 /// <returns><em>true</em> if the value can be retrieved as a string, otherwise <em>false</em></returns>
565 public bool TryGetValue(string attr
, out string value)
568 if (_template
.TryGetOrdinal(attr
, out ord
))
570 return _attributes
[ord
].TryGetValue(out value);
572 value = default(string);
577 /// Tries to get an attribute's value as a IPAddress.
579 /// <param name="attr">the attribute's name</param>
580 /// <param name="value">reference to a variable to hold the value</param>
581 /// <returns><em>true</em> if the value can be retrieved as a IPAddress, otherwise <em>false</em></returns>
582 public bool TryGetValue(string attr
, out IPAddress
value)
585 if (_template
.TryGetOrdinal(attr
, out ord
))
587 return _attributes
[ord
].TryGetValue(out value);
589 value = default(IPAddress
);
594 /// Tries to get an attribute's value as a UInt16.
596 /// <param name="attr">the attribute's name</param>
597 /// <param name="value">reference to a variable to hold the value</param>
598 /// <returns><em>true</em> if the value can be retrieved as a UInt16, otherwise <em>false</em></returns>
599 public bool TryGetValue(string attr
, out long value)
602 if (_template
.TryGetOrdinal(attr
, out ord
))
604 return _attributes
[ord
].TryGetValue(out value);
606 value = default(long);
611 /// Tries to get an attribute's value as a UInt64.
613 /// <param name="attr">the attribute's name</param>
614 /// <param name="value">reference to a variable to hold the value</param>
615 /// <returns><em>true</em> if the value can be retrieved as a UInt64, otherwise <em>false</em></returns>
616 public bool TryGetValue(string attr
, out ulong value)
619 if (_template
.TryGetOrdinal(attr
, out ord
))
621 return _attributes
[ord
].TryGetValue(out value);
623 value = default(ulong);
628 /// Tries to get an attribute's value as a Boolean.
630 /// <param name="attr">the attribute's name</param>
631 /// <param name="value">reference to a variable to hold the value</param>
632 /// <returns><em>true</em> if the value can be retrieved as a Boolean, otherwise <em>false</em></returns>
633 public bool TryGetValue(string attr
, out bool value)
636 if (_template
.TryGetOrdinal(attr
, out ord
))
638 return _attributes
[ord
].TryGetValue(out value);
640 value = default(bool);
644 internal static Event
BinaryDecode(IEventTemplateDB db
, byte[] buffer
, int offset
, int count
)
646 Decoder dec
= Constants
.DefaultEncoding
.GetDecoder();
647 Decoder bodyDecoder
= dec
;
648 int ofs
= offset
, end_of_input
= offset
+ count
;
650 string eventName
= LwesSerializer
.ReadEVENTWORD(buffer
, ref ofs
, dec
);
651 UInt16 attributeCount
= LwesSerializer
.ReadUInt16(buffer
, ref ofs
);
654 if (!db
.TryCreateEvent(eventName
, out ev
, false, SupportedEncoding
.Default
))
656 ev
= new Event(new EventTemplate(false, eventName
), false, SupportedEncoding
.Default
);
659 for (int i
= 0; i
< attributeCount
&& ofs
< end_of_input
; i
++)
661 string attributeName
= LwesSerializer
.ReadATTRIBUTEWORD(buffer
, ref ofs
, dec
);
662 TypeToken attributeTokenType
= (TypeToken
)LwesSerializer
.ReadByte(buffer
, ref ofs
);
664 // Encoding is in the first attribute position if it is present
666 && String
.Equals(Constants
.MetaEventInfoAttributes
.Encoding
, attributeName
)
667 && attributeTokenType
== TypeToken
.UINT16
)
669 Int16 changeEncoding
= LwesSerializer
.ReadInt16(buffer
, ref ofs
);
670 bodyDecoder
= Constants
.GetEncoding(changeEncoding
).GetDecoder();
671 ev
= ev
.SetValue(Constants
.MetaEventInfoAttributes
.Encoding
.Name
, changeEncoding
);
675 switch (attributeTokenType
)
677 case TypeToken
.UINT16
:
678 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadUInt16(buffer
, ref ofs
));
680 case TypeToken
.INT16
:
681 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadInt16(buffer
, ref ofs
));
683 case TypeToken
.UINT32
:
684 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadUInt32(buffer
, ref ofs
));
686 case TypeToken
.INT32
:
687 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadInt32(buffer
, ref ofs
));
689 case TypeToken
.STRING
:
690 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadString(buffer
, ref ofs
, bodyDecoder
));
692 case TypeToken
.IP_ADDR
:
693 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadIPAddress(buffer
, ref ofs
));
695 case TypeToken
.INT64
:
696 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadInt64(buffer
, ref ofs
));
698 case TypeToken
.UINT64
:
699 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadUInt64(buffer
, ref ofs
));
701 case TypeToken
.BOOLEAN
:
702 ev
= ev
.SetValue(attributeName
, LwesSerializer
.ReadBoolean(buffer
, ref ofs
));
711 internal int BinaryEncode(byte[] buffer
, int offset
)
713 /* Encoded using the following protocol:
715 * EVENTWORD,<number of elements>,ATTRIBUTEWORD,TYPETOKEN,
716 * (UINT16|INT16|UINT32|INT32|UINT64|INT64|BOOLEAN|STRING)
717 * ...ATTRIBUTEWORD,TYPETOKEN(UINT16|INT16|UINT32|INT32|
718 * UINT64|INT64|BOOLEAN|STRING)
720 * The EVENTWORD and ATTRIBUTEWORD(s) are encoded with
721 * the default encoding, the first attribute will be the
722 * encoding for strings if present (may differ from the
723 * encoding used for EVENTWORD and ATTRIBUTEWORD(s)
726 int count
= 0, ofs
= offset
;
727 Encoder utf8
= Constants
.DefaultEncoding
.GetEncoder();
728 Encoder bodyEncoder
= Constants
.GetEncoding((short)_encoding
).GetEncoder();
730 // Encode the EVENTWORD + attribute-count
731 _template
.BinaryEncode(buffer
, ref ofs
);
733 // All of the template and dynamic attributes are encoded...
734 for (int i
= 0; i
< _attributes
.Length
; i
++)
736 count
+= _attributes
[i
].BinaryEncode(buffer
, ref ofs
, bodyEncoder
);
743 internal int CalculateEncodedByteCount()
745 Encoding enc
= Constants
.GetEncoding((short)_encoding
);
746 int count
= _template
.GetByteCount();
748 // All of the template and dynamic attributes are encoded...
749 for(int i
= 0; i
< _attributes
.Length
; i
++)
751 count
+= _attributes
[i
].GetByteCount(enc
);
756 private Event AppendAttribute
<T
>(AttributeTemplate attr
, T
value)
758 EventTemplate et
= _template
.AppendAttributes(attr
);
759 IEventAttribute
[] attributes
= new IEventAttribute
[_attributes
.Length
+ 1];
760 Array
.Copy(_attributes
, attributes
, _attributes
.Length
);
761 attributes
[attributes
.Length
- 1] = new EventAttribute
<T
>(attr
, value);
762 return new Event(et
, _validating
, _encoding
, attributes
);
765 private Event
Mutate(int ord
, IEventAttribute attr
)
767 IEventAttribute
[] copy
= (IEventAttribute
[])_attributes
.Clone();
769 return new Event(_template
, _validating
, _encoding
, copy
);
772 private Event PrependAttribute
<T
>(AttributeTemplate attr
, T
value)
774 EventTemplate et
= _template
.PrependAttributes(attr
);
775 IEventAttribute
[] attributes
= new IEventAttribute
[_attributes
.Length
+ 1];
776 Array
.Copy(_attributes
, 0, attributes
, 1, _attributes
.Length
);
777 attributes
[0] = new EventAttribute
<T
>(attr
, value);
778 return new Event(et
, _validating
, _encoding
, attributes
);