History

Added GSF.Unity code subset and sample graph lines application for targeting Unity platform applications.

ritchiecarroll committed 13 years ago

Commit 3fd128f1 parent 750ba5e275 files · +129151 −-26Browse files

Showing the changes to Source/Libraries/GSF.Unity/GSF.Core/Parsing/MultiSourceFrameImageParserBase.cs (1 of 275 files). Show all

Unified · Split

Source/Libraries/GSF.Unity/GSF.Core/Parsing/MultiSourceFrameImageParserBase.cs+805−0
@@ -0,0 +1,805 @@
1+//*******************************************************************************************************
2+// MultiSourceFrameImageParserBase.cs - Gbtc
3+//
4+// Tennessee Valley Authority, 2011
5+// No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
6+//
7+// This software is made freely available under the TVA Open Source Agreement (see below).
8+// Code in this file licensed to GSF under one or more contributor license agreements listed below.
9+//
10+// Code Modification History:
11+// -----------------------------------------------------------------------------------------------------
12+// 12/03/2008 - J. Ritchie Carroll
13+// Generated original version of source code.
14+// 06/19/2009 - Pinal C. Patel
15+// Parsed output is now being delivered in a new collection instead of reusing a single collection.
16+// 08/07/2009 - Josh L. Patterson
17+// Edited Comments.
18+// 09/14/2009 - Stephen C. Wills
19+// Added new header and license agreement.
20+// 11/01/2012 - J. Ritchie Carroll
21+// Updated to use concurrent dictionaries and new recreate parsed output list.
22+//
23+//*******************************************************************************************************
24+
25+#region [ TVA Open Source Agreement ]
26+/*
27+
28+ THIS OPEN SOURCE AGREEMENT ("AGREEMENT") DEFINES THE RIGHTS OF USE,REPRODUCTION, DISTRIBUTION,
29+ MODIFICATION AND REDISTRIBUTION OF CERTAIN COMPUTER SOFTWARE ORIGINALLY RELEASED BY THE
30+ TENNESSEE VALLEY AUTHORITY, A CORPORATE AGENCY AND INSTRUMENTALITY OF THE UNITED STATES GOVERNMENT
31+ ("GOVERNMENT AGENCY"). GOVERNMENT AGENCY IS AN INTENDED THIRD-PARTY BENEFICIARY OF ALL SUBSEQUENT
32+ DISTRIBUTIONS OR REDISTRIBUTIONS OF THE SUBJECT SOFTWARE. ANYONE WHO USES, REPRODUCES, DISTRIBUTES,
33+ MODIFIES OR REDISTRIBUTES THE SUBJECT SOFTWARE, AS DEFINED HEREIN, OR ANY PART THEREOF, IS, BY THAT
34+ ACTION, ACCEPTING IN FULL THE RESPONSIBILITIES AND OBLIGATIONS CONTAINED IN THIS AGREEMENT.
35+
36+ Original Software Designation: openPDC
37+ Original Software Title: The GSF Open Source Phasor Data Concentrator
38+ User Registration Requested. Please Visit https://naspi.tva.com/Registration/
39+ Point of Contact for Original Software: J. Ritchie Carroll <mailto:jrcarrol@tva.gov>
40+
41+ 1. DEFINITIONS
42+
43+ A. "Contributor" means Government Agency, as the developer of the Original Software, and any entity
44+ that makes a Modification.
45+
46+ B. "Covered Patents" mean patent claims licensable by a Contributor that are necessarily infringed by
47+ the use or sale of its Modification alone or when combined with the Subject Software.
48+
49+ C. "Display" means the showing of a copy of the Subject Software, either directly or by means of an
50+ image, or any other device.
51+
52+ D. "Distribution" means conveyance or transfer of the Subject Software, regardless of means, to
53+ another.
54+
55+ E. "Larger Work" means computer software that combines Subject Software, or portions thereof, with
56+ software separate from the Subject Software that is not governed by the terms of this Agreement.
57+
58+ F. "Modification" means any alteration of, including addition to or deletion from, the substance or
59+ structure of either the Original Software or Subject Software, and includes derivative works, as that
60+ term is defined in the Copyright Statute, 17 USC § 101. However, the act of including Subject Software
61+ as part of a Larger Work does not in and of itself constitute a Modification.
62+
63+ G. "Original Software" means the computer software first released under this Agreement by Government
64+ Agency entitled openPDC, including source code, object code and accompanying documentation, if any.
65+
66+ H. "Recipient" means anyone who acquires the Subject Software under this Agreement, including all
67+ Contributors.
68+
69+ I. "Redistribution" means Distribution of the Subject Software after a Modification has been made.
70+
71+ J. "Reproduction" means the making of a counterpart, image or copy of the Subject Software.
72+
73+ K. "Sale" means the exchange of the Subject Software for money or equivalent value.
74+
75+ L. "Subject Software" means the Original Software, Modifications, or any respective parts thereof.
76+
77+ M. "Use" means the application or employment of the Subject Software for any purpose.
78+
79+ 2. GRANT OF RIGHTS
80+
81+ A. Under Non-Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor,
82+ with respect to its own contribution to the Subject Software, hereby grants to each Recipient a
83+ non-exclusive, world-wide, royalty-free license to engage in the following activities pertaining to
84+ the Subject Software:
85+
86+ 1. Use
87+
88+ 2. Distribution
89+
90+ 3. Reproduction
91+
92+ 4. Modification
93+
94+ 5. Redistribution
95+
96+ 6. Display
97+
98+ B. Under Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor, with
99+ respect to its own contribution to the Subject Software, hereby grants to each Recipient under Covered
100+ Patents a non-exclusive, world-wide, royalty-free license to engage in the following activities
101+ pertaining to the Subject Software:
102+
103+ 1. Use
104+
105+ 2. Distribution
106+
107+ 3. Reproduction
108+
109+ 4. Sale
110+
111+ 5. Offer for Sale
112+
113+ C. The rights granted under Paragraph B. also apply to the combination of a Contributor's Modification
114+ and the Subject Software if, at the time the Modification is added by the Contributor, the addition of
115+ such Modification causes the combination to be covered by the Covered Patents. It does not apply to
116+ any other combinations that include a Modification.
117+
118+ D. The rights granted in Paragraphs A. and B. allow the Recipient to sublicense those same rights.
119+ Such sublicense must be under the same terms and conditions of this Agreement.
120+
121+ 3. OBLIGATIONS OF RECIPIENT
122+
123+ A. Distribution or Redistribution of the Subject Software must be made under this Agreement except for
124+ additions covered under paragraph 3H.
125+
126+ 1. Whenever a Recipient distributes or redistributes the Subject Software, a copy of this Agreement
127+ must be included with each copy of the Subject Software; and
128+
129+ 2. If Recipient distributes or redistributes the Subject Software in any form other than source code,
130+ Recipient must also make the source code freely available, and must provide with each copy of the
131+ Subject Software information on how to obtain the source code in a reasonable manner on or through a
132+ medium customarily used for software exchange.
133+
134+ B. Each Recipient must ensure that the following copyright notice appears prominently in the Subject
135+ Software:
136+
137+ No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
138+
139+ C. Each Contributor must characterize its alteration of the Subject Software as a Modification and
140+ must identify itself as the originator of its Modification in a manner that reasonably allows
141+ subsequent Recipients to identify the originator of the Modification. In fulfillment of these
142+ requirements, Contributor must include a file (e.g., a change log file) that describes the alterations
143+ made and the date of the alterations, identifies Contributor as originator of the alterations, and
144+ consents to characterization of the alterations as a Modification, for example, by including a
145+ statement that the Modification is derived, directly or indirectly, from Original Software provided by
146+ Government Agency. Once consent is granted, it may not thereafter be revoked.
147+
148+ D. A Contributor may add its own copyright notice to the Subject Software. Once a copyright notice has
149+ been added to the Subject Software, a Recipient may not remove it without the express permission of
150+ the Contributor who added the notice.
151+
152+ E. A Recipient may not make any representation in the Subject Software or in any promotional,
153+ advertising or other material that may be construed as an endorsement by Government Agency or by any
154+ prior Recipient of any product or service provided by Recipient, or that may seek to obtain commercial
155+ advantage by the fact of Government Agency's or a prior Recipient's participation in this Agreement.
156+
157+ F. In an effort to track usage and maintain accurate records of the Subject Software, each Recipient,
158+ upon receipt of the Subject Software, is requested to register with Government Agency by visiting the
159+ following website: https://naspi.tva.com/Registration/. Recipient's name and personal information
160+ shall be used for statistical purposes only. Once a Recipient makes a Modification available, it is
161+ requested that the Recipient inform Government Agency at the web site provided above how to access the
162+ Modification.
163+
164+ G. Each Contributor represents that that its Modification does not violate any existing agreements,
165+ regulations, statutes or rules, and further that Contributor has sufficient rights to grant the rights
166+ conveyed by this Agreement.
167+
168+ H. A Recipient may choose to offer, and to charge a fee for, warranty, support, indemnity and/or
169+ liability obligations to one or more other Recipients of the Subject Software. A Recipient may do so,
170+ however, only on its own behalf and not on behalf of Government Agency or any other Recipient. Such a
171+ Recipient must make it absolutely clear that any such warranty, support, indemnity and/or liability
172+ obligation is offered by that Recipient alone. Further, such Recipient agrees to indemnify Government
173+ Agency and every other Recipient for any liability incurred by them as a result of warranty, support,
174+ indemnity and/or liability offered by such Recipient.
175+
176+ I. A Recipient may create a Larger Work by combining Subject Software with separate software not
177+ governed by the terms of this agreement and distribute the Larger Work as a single product. In such
178+ case, the Recipient must make sure Subject Software, or portions thereof, included in the Larger Work
179+ is subject to this Agreement.
180+
181+ J. Notwithstanding any provisions contained herein, Recipient is hereby put on notice that export of
182+ any goods or technical data from the United States may require some form of export license from the
183+ U.S. Government. Failure to obtain necessary export licenses may result in criminal liability under
184+ U.S. laws. Government Agency neither represents that a license shall not be required nor that, if
185+ required, it shall be issued. Nothing granted herein provides any such export license.
186+
187+ 4. DISCLAIMER OF WARRANTIES AND LIABILITIES; WAIVER AND INDEMNIFICATION
188+
189+ A. No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND, EITHER
190+ EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT
191+ SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
192+ PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR
193+ FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS
194+ AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR
195+ RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS
196+ RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND
197+ LIABILITIES REGARDING THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT
198+ "AS IS."
199+
200+ B. Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST GOVERNMENT AGENCY, ITS
201+ AGENTS, EMPLOYEES, CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE
202+ OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM
203+ SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S USE OF THE
204+ SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS GOVERNMENT AGENCY, ITS AGENTS,
205+ EMPLOYEES, CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY
206+ LAW. THE FOREGOING RELEASE AND INDEMNIFICATION SHALL APPLY EVEN IF THE LIABILITIES, DEMANDS, DAMAGES,
207+ EXPENSES OR LOSSES ARE CAUSED, OCCASIONED, OR CONTRIBUTED TO BY THE NEGLIGENCE, SOLE OR CONCURRENT, OF
208+ GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER SHALL BE THE
209+ IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT.
210+
211+ 5. GENERAL TERMS
212+
213+ A. Termination: This Agreement and the rights granted hereunder will terminate automatically if a
214+ Recipient fails to comply with these terms and conditions, and fails to cure such noncompliance within
215+ thirty (30) days of becoming aware of such noncompliance. Upon termination, a Recipient agrees to
216+ immediately cease use and distribution of the Subject Software. All sublicenses to the Subject
217+ Software properly granted by the breaching Recipient shall survive any such termination of this
218+ Agreement.
219+
220+ B. Severability: If any provision of this Agreement is invalid or unenforceable under applicable law,
221+ it shall not affect the validity or enforceability of the remainder of the terms of this Agreement.
222+
223+ C. Applicable Law: This Agreement shall be subject to United States federal law only for all purposes,
224+ including, but not limited to, determining the validity of this Agreement, the meaning of its
225+ provisions and the rights, obligations and remedies of the parties.
226+
227+ D. Entire Understanding: This Agreement constitutes the entire understanding and agreement of the
228+ parties relating to release of the Subject Software and may not be superseded, modified or amended
229+ except by further written agreement duly executed by the parties.
230+
231+ E. Binding Authority: By accepting and using the Subject Software under this Agreement, a Recipient
232+ affirms its authority to bind the Recipient to all terms and conditions of this Agreement and that
233+ Recipient hereby agrees to all terms and conditions herein.
234+
235+ F. Point of Contact: Any Recipient contact with Government Agency is to be directed to the designated
236+ representative as follows: J. Ritchie Carroll <mailto:jrcarrol@tva.gov>.
237+
238+*/
239+#endregion
240+
241+#region [ Contributor License Agreements ]
242+
243+//******************************************************************************************************
244+//
245+// Copyright © 2011, Grid Protection Alliance. All Rights Reserved.
246+//
247+// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
248+// not use this file except in compliance with the License. You may obtain a copy of the License at:
249+//
250+// http://www.opensource.org/licenses/eclipse-1.0.php
251+//
252+// Unless agreed to in writing, the subject software distributed under the License is distributed on an
253+// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
254+// License for the specific language governing permissions and limitations.
255+//
256+//******************************************************************************************************
257+
258+#endregion
259+
260+#pragma warning disable 0809
261+
262+using GSF.Collections;
263+using System;
264+using System.Collections.Concurrent;
265+using System.Collections.Generic;
266+using System.ComponentModel;
267+using System.Text;
268+using System.Threading;
269+
270+namespace GSF.Parsing
271+{
272+ /// <summary>
273+ /// This class defines a basic implementation of parsing functionality suitable for automating the parsing of multiple
274+ /// binary data streams, each represented as frames with common headers and returning the parsed data via an event.
275+ /// </summary>
276+ /// <remarks>
277+ /// <para>
278+ /// This parser is designed as a write-only stream such that data can come from any source.
279+ /// </para>
280+ /// <para>
281+ /// This class is more specific than the <see cref="BinaryImageParserBase"/> in that it can automate the parsing of a
282+ /// particular protocol that is formatted as a series of frames that have a common method of identification.
283+ /// Automation of type creation occurs by loading implementations of common types that implement the
284+ /// <see cref="ISupportSourceIdentifiableFrameImage{TSourceIdentifier,TTypeIdentifier}"/> interface. The common method of
285+ /// identification is handled by creating a class derived from the <see cref="ICommonHeader{TTypeIdentifier}"/> which primarily
286+ /// includes a TypeID property, but also should include any state information needed to parse a particular frame if necessary.
287+ /// Derived classes override the <see cref="FrameImageParserBase{TTypeIdentifier, TOutputType}.ParseCommonHeader"/>
288+ /// method in order to parse the <see cref="ICommonHeader{TTypeIdentifier}"/> from a provided binary image.
289+ /// </para>
290+ /// </remarks>
291+ /// <typeparam name="TSourceIdentifier">Type of identifier for the data source.</typeparam>
292+ /// <typeparam name="TTypeIdentifier">Type of identifier used to distinguish output types.</typeparam>
293+ /// <typeparam name="TOutputType">Type of the interface or class used to represent outputs.</typeparam>
294+ public abstract class MultiSourceFrameImageParserBase<TSourceIdentifier, TTypeIdentifier, TOutputType> : FrameImageParserBase<TTypeIdentifier, TOutputType> where TOutputType : ISupportSourceIdentifiableFrameImage<TSourceIdentifier, TTypeIdentifier>
295+ {
296+ #region [ Members ]
297+
298+ // Nested Types
299+
300+ /// <summary>
301+ /// Represents a source identifiable buffer.
302+ /// </summary>
303+ /// <remarks>
304+ /// This class implements <see cref="ISupportLifecycle"/> such that it will support
305+ /// automatic object pool handling, e.g., returning object to pool when disposed.
306+ /// </remarks>
307+ public class SourceIdentifiableBuffer : ISupportLifecycle
308+ {
309+ #region [ Members ]
310+
311+ // Events
312+
313+ /// <summary>
314+ /// Occurs when <see cref="SourceIdentifiableBuffer"/> is disposed.
315+ /// </summary>
316+ public event EventHandler Disposed;
317+
318+ // Fields
319+
320+ /// <summary>
321+ /// Defines the source identifier of the <see cref="Buffer"/>.
322+ /// </summary>
323+ public TSourceIdentifier Source;
324+
325+ /// <summary>
326+ /// Defines the buffer which is identifiable by its associated <see cref="Source"/>.
327+ /// </summary>
328+ public byte[] Buffer;
329+
330+ private int m_count;
331+ private bool m_disposed;
332+
333+ #endregion
334+
335+ #region [ Constructors ]
336+
337+ /// <summary>
338+ /// Releases the unmanaged resources before the <see cref="SourceIdentifiableBuffer"/> object is reclaimed by <see cref="GC"/>.
339+ /// </summary>
340+ ~SourceIdentifiableBuffer()
341+ {
342+ Dispose(false);
343+ }
344+
345+ #endregion
346+
347+ #region [ Properties ]
348+
349+ /// <summary>
350+ /// Gets or sets enabled state of <see cref="SourceIdentifiableBuffer"/>.
351+ /// </summary>
352+ public bool Enabled
353+ {
354+ get;
355+ set;
356+ }
357+
358+ /// <summary>
359+ /// Gets or sets valid number of bytes within the <see cref="Buffer"/>.
360+ /// </summary>
361+ /// <remarks>
362+ /// This property will automatically initialize buffer. Set to zero to release buffer.
363+ /// </remarks>
364+ public int Count
365+ {
366+ get
367+ {
368+ return m_count;
369+ }
370+ set
371+ {
372+ m_count = value;
373+
374+ if ((object)Buffer != null)
375+ BufferPool.ReturnBuffer(Buffer);
376+
377+ if (m_count > 0)
378+ Buffer = BufferPool.TakeBuffer(m_count);
379+ else
380+ Buffer = null;
381+ }
382+ }
383+
384+ #endregion
385+
386+ #region [ Methods ]
387+
388+ /// <summary>
389+ /// Releases all the resources used by the <see cref="SourceIdentifiableBuffer"/> object.
390+ /// </summary>
391+ public void Dispose()
392+ {
393+ Dispose(true);
394+ GC.SuppressFinalize(this);
395+ }
396+
397+ /// <summary>
398+ /// Releases the unmanaged resources used by the <see cref="SourceIdentifiableBuffer"/> object and optionally releases the managed resources.
399+ /// </summary>
400+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
401+ protected virtual void Dispose(bool disposing)
402+ {
403+ if (!m_disposed)
404+ {
405+ try
406+ {
407+ // Return any existing buffer to the pool
408+ Count = 0;
409+ }
410+ finally
411+ {
412+ m_disposed = true; // Prevent duplicate dispose.
413+
414+ if (Disposed != null)
415+ Disposed(this, EventArgs.Empty);
416+ }
417+ }
418+ }
419+
420+ /// <summary>
421+ /// Initializes (or reinitializes) <see cref="SourceIdentifiableBuffer"/> state.
422+ /// </summary>
423+ public void Initialize()
424+ {
425+ // Undispose class instance if it is being reused
426+ if (m_disposed)
427+ {
428+ m_disposed = false;
429+ GC.ReRegisterForFinalize(this);
430+ }
431+ }
432+
433+ #endregion
434+ }
435+
436+ // Fields
437+ private ProcessQueue<SourceIdentifiableBuffer> m_bufferQueue;
438+ private readonly ConcurrentDictionary<TSourceIdentifier, bool> m_sourceInitialized;
439+ private readonly ConcurrentDictionary<TSourceIdentifier, byte[]> m_unparsedBuffers;
440+ private TSourceIdentifier m_source;
441+ private bool m_disposed;
442+
443+ #endregion
444+
445+ #region [ Constructors ]
446+
447+ /// <summary>
448+ /// Creates a new instance of the <see cref="MultiSourceFrameImageParserBase{TSourceIdentifier,TTypeIdentifier,TOutputType}"/> class.
449+ /// </summary>
450+ protected MultiSourceFrameImageParserBase()
451+ {
452+ m_bufferQueue = CreateBufferQueue();
453+ m_bufferQueue.ProcessException += ProcessExceptionHandler;
454+
455+ if (ProtocolUsesSyncBytes)
456+ m_sourceInitialized = new ConcurrentDictionary<TSourceIdentifier, bool>();
457+
458+ m_unparsedBuffers = new ConcurrentDictionary<TSourceIdentifier, byte[]>();
459+ }
460+
461+ #endregion
462+
463+ #region [ Properties ]
464+
465+ /// <summary>
466+ /// Gets the total number of buffers that are currently queued for processing, if any.
467+ /// </summary>
468+ public virtual int QueuedBuffers
469+ {
470+ get
471+ {
472+ if ((object)m_bufferQueue != null)
473+ return m_bufferQueue.Count;
474+
475+ return 0;
476+ }
477+ }
478+
479+ /// <summary>
480+ /// Gets the current run-time statistics of the <see cref="MultiSourceFrameImageParserBase{TSourceIdentifier,TTypeIdentifier,TOutputType}"/>.
481+ /// </summary>
482+ public virtual ProcessQueueStatistics CurrentStatistics
483+ {
484+ get
485+ {
486+ return m_bufferQueue.CurrentStatistics;
487+ }
488+ }
489+
490+ /// <summary>
491+ /// Gets current status of <see cref="MultiSourceFrameImageParserBase{TSourceIdentifier,TTypeIdentifier,TOutputType}"/>.
492+ /// </summary>
493+ public override string Status
494+ {
495+ get
496+ {
497+ StringBuilder status = new StringBuilder();
498+
499+ status.Append(base.Status);
500+ status.Append(m_bufferQueue.Status);
501+
502+ return status.ToString();
503+ }
504+ }
505+
506+ #endregion
507+
508+ #region [ Methods ]
509+
510+ /// <summary>
511+ /// Releases the unmanaged resources used by the <see cref="MultiSourceFrameImageParserBase{TSourceIdentifier,TTypeIdentifier,TOutputType}"/> object and optionally releases the managed resources.
512+ /// </summary>
513+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
514+ protected override void Dispose(bool disposing)
515+ {
516+ if (!m_disposed)
517+ {
518+ try
519+ {
520+ if (disposing)
521+ {
522+ if ((object)m_bufferQueue != null)
523+ {
524+ m_bufferQueue.ProcessException -= ProcessExceptionHandler;
525+ m_bufferQueue.Dispose();
526+ }
527+ m_bufferQueue = null;
528+ }
529+ }
530+ finally
531+ {
532+ m_disposed = true; // Prevent duplicate dispose.
533+ base.Dispose(disposing); // Call base class Dispose().
534+ }
535+ }
536+ }
537+
538+ /// <summary>
539+ /// Start the streaming data parser.
540+ /// </summary>
541+ public override void Start()
542+ {
543+ base.Start();
544+
545+ if ((object)m_sourceInitialized != null)
546+ m_sourceInitialized.Clear();
547+
548+ m_unparsedBuffers.Clear();
549+ m_bufferQueue.Start();
550+ }
551+
552+ /// <summary>
553+ /// Starts the data parser given the specified type implementations.
554+ /// </summary>
555+ /// <param name="implementations">Output type implementations to establish for the parser.</param>
556+ public override void Start(IEnumerable<Type> implementations)
557+ {
558+ base.Start(implementations);
559+
560+ if ((object)m_sourceInitialized != null)
561+ m_sourceInitialized.Clear();
562+
563+ m_unparsedBuffers.Clear();
564+ m_bufferQueue.Start();
565+ }
566+
567+ /// <summary>
568+ /// Stops the streaming data parser.
569+ /// </summary>
570+ public override void Stop()
571+ {
572+ m_bufferQueue.Stop();
573+ base.Stop();
574+ }
575+
576+ /// <summary>
577+ /// Queues a sequence of bytes, from the specified data source, onto the stream for parsing.
578+ /// </summary>
579+ /// <param name="source">Identifier of the data source.</param>
580+ /// <param name="buffer">An array of bytes to queue for parsing</param>
581+ public virtual void Parse(TSourceIdentifier source, byte[] buffer)
582+ {
583+ if ((object)buffer == null)
584+ throw new ArgumentNullException("buffer");
585+
586+ Parse(source, buffer, 0, buffer.Length);
587+ }
588+
589+ /// <summary>
590+ /// Queues a sequence of bytes, from the specified data source, onto the stream for parsing.
591+ /// </summary>
592+ /// <param name="source">Identifier of the data source.</param>
593+ /// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the queue.</param>
594+ /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
595+ /// <param name="count">The number of bytes to be written to the current stream.</param>
596+ /// <remarks>
597+ /// This method associates a buffer with its data source identifier.
598+ /// </remarks>
599+ public virtual void Parse(TSourceIdentifier source, byte[] buffer, int offset, int count)
600+ {
601+ SourceIdentifiableBuffer identifiableBuffer = null;
602+
603+ buffer.ValidateParameters(offset, count);
604+
605+ try
606+ {
607+ // Get an identifiable buffer object
608+ identifiableBuffer = ReusableObjectPool<SourceIdentifiableBuffer>.Default.TakeObject();
609+ identifiableBuffer.Source = source;
610+ identifiableBuffer.Count = count;
611+
612+ // Copy buffer data for processing (destination buffer preallocated from buffer pool)
613+ Buffer.BlockCopy(buffer, offset, identifiableBuffer.Buffer, 0, count);
614+
615+ // Add buffer to the queue for parsing
616+ m_bufferQueue.Add(identifiableBuffer);
617+ }
618+ catch
619+ {
620+ // Return source buffer to object pool if we failed to queue it for processing
621+ if ((object)identifiableBuffer != null)
622+ identifiableBuffer.Dispose();
623+
624+ throw;
625+ }
626+ }
627+
628+ /// <summary>
629+ /// Queues the object implementing the <see cref="ISupportBinaryImage"/> interface, from the specified data source, onto the stream for parsing.
630+ /// </summary>
631+ /// <param name="source">Identifier of the data source.</param>
632+ /// <param name="image">Object to be parsed that implements the <see cref="ISupportBinaryImage"/> interface.</param>
633+ /// <remarks>
634+ /// This method takes the binary image from <see cref="ISupportBinaryImage"/> and writes the buffer to the <see cref="BinaryImageParserBase"/> stream for parsing.
635+ /// </remarks>
636+ public virtual void Parse(TSourceIdentifier source, ISupportBinaryImage image)
637+ {
638+ Parse(source, image.BinaryImage());
639+ }
640+
641+ /// <summary>
642+ /// Clears the internal buffer of unparsed data received from the specified <paramref name="source"/>.
643+ /// </summary>
644+ /// <param name="source">Identifier of the data source.</param>
645+ /// <remarks>
646+ /// This method can be used to ensure that partial data received from the <paramref name="source"/> is not kept in memory indefinitely.
647+ /// </remarks>
648+ public virtual void PurgeBuffer(TSourceIdentifier source)
649+ {
650+ byte[] buffer;
651+ m_unparsedBuffers.TryRemove(source, out buffer);
652+ }
653+
654+ /// <summary>
655+ /// Not implemented. Consumers should call the <see cref="Parse(TSourceIdentifier,ISupportBinaryImage)"/> method instead to make sure data source source ID gets tracked with data buffer.
656+ /// </summary>
657+ /// <exception cref="NotImplementedException">This method should not be called directly.</exception>
658+ /// <param name="image">A <see cref="ISupportBinaryImage"/>.</param>
659+ [EditorBrowsable(EditorBrowsableState.Never), Obsolete("MultiSourceFrameImageParserBase requires consumers call Parse overload that takes data source identifier as an argument", true)]
660+ public override void Parse(ISupportBinaryImage image)
661+ {
662+ throw new NotImplementedException("This method should not be called directly, call the Parse(TSourceIdentifier,ISupportBinaryImage) method to queue data for parsing instead.");
663+ }
664+
665+ /// <summary>
666+ /// Not implemented. Consumers should call the <see cref="Parse(TSourceIdentifier,byte[],int,int)"/> method instead to make sure data source source ID gets tracked with data buffer.
667+ /// </summary>
668+ /// <exception cref="NotImplementedException">This method should not be called directly.</exception>
669+ /// <param name="buffer">A <see cref="Byte"/> array.</param>
670+ /// <param name="count">An <see cref="Int32"/> for the offset.</param>
671+ /// <param name="offset">An <see cref="Int32"/> for the count.</param>
672+ [EditorBrowsable(EditorBrowsableState.Never), Obsolete("MultiSourceFrameImageParserBase requires consumers call Parse overload that takes data source identifier as an argument", true)]
673+ public override void Write(byte[] buffer, int offset, int count)
674+ {
675+ throw new NotImplementedException("This method should not be called directly, call the Parse(TSourceIdentifier,byte[],int,int) method to queue data for parsing instead.");
676+ }
677+
678+ /// <summary>
679+ /// Clears all buffers for this stream and causes any buffered data to be parsed immediately.
680+ /// </summary>
681+ /// <remarks>
682+ /// <para>
683+ /// If the user has called <see cref="Start()"/> method, this method will process all remaining buffers on the calling thread until all
684+ /// queued buffers have been parsed - the <see cref="MultiSourceFrameImageParserBase{TSourceIdentifier,TTypeIdentifier,TOutputType}"/>
685+ /// will then be automatically stopped. This method is typically called on shutdown to make sure any remaining queued buffers get
686+ /// parsed before the class instance is destructed.
687+ /// </para>
688+ /// <para>
689+ /// It is possible for items to be queued while the flush is executing. The flush will continue to parse buffers as quickly
690+ /// as possible until the internal buffer queue is empty. Unless the user stops queueing data to be parsed (i.e. calling the
691+ /// <see cref="Parse(TSourceIdentifier,byte[])"/> method), the flush call may never return (not a happy situtation on shutdown).
692+ /// </para>
693+ /// <para>
694+ /// The <see cref="MultiSourceFrameImageParserBase{TSourceIdentifier,TTypeIdentifier,TOutputType}"/> does not clear queue prior to destruction.
695+ /// If the user fails to call this method before the class is destructed, there may be data that remains unparsed in the internal buffer.
696+ /// </para>
697+ /// </remarks>
698+ public override void Flush()
699+ {
700+ m_bufferQueue.Flush();
701+ }
702+
703+ /// <summary>
704+ /// Creates the internal buffer queue.
705+ /// </summary>
706+ /// <remarks>
707+ /// <para>
708+ /// This method is virtual to allow derived classes to customize the style of processing queue used when consumers
709+ /// choose to implement an internal buffer queue. Default type is a real-time queue with the default settings.
710+ /// When overriding, use the <see cref="ParseQueuedBuffers"/> method for the <see cref="ProcessQueue{T}"/>) item
711+ /// processing delegate.
712+ /// </para>
713+ /// <para>
714+ /// Note that current design only supports serial processing - consumer overriding this method to return an asynchronous
715+ /// process queue to process multiple items at once on separate threads will need to redesign the processing delegate.
716+ /// </para>
717+ /// </remarks>
718+ /// <returns>New internal buffer processing queue (i.e., a new <see cref="ProcessQueue{T}"/>).</returns>
719+ protected virtual ProcessQueue<SourceIdentifiableBuffer> CreateBufferQueue()
720+ {
721+ return ProcessQueue<SourceIdentifiableBuffer>.CreateRealTimeQueue(ParseQueuedBuffers);
722+ }
723+
724+ /// <summary>
725+ /// This method is used by the internal <see cref="ProcessQueue{T}"/> to process all queued data buffers.
726+ /// </summary>
727+ /// <param name="buffers">Identifiable buffers to process.</param>
728+ /// <remarks>
729+ /// This is the <see cref="SourceIdentifiableBuffer"/> processing delegate to use when overriding the <see cref="CreateBufferQueue"/> method.
730+ /// </remarks>
731+ protected virtual void ParseQueuedBuffers(SourceIdentifiableBuffer[] buffers)
732+ {
733+ // Process all queued data buffers...
734+ foreach (SourceIdentifiableBuffer buffer in buffers)
735+ {
736+ // Track current buffer source
737+ m_source = buffer.Source;
738+
739+ // Check to see if this data source has been initialized
740+ if ((object)m_sourceInitialized != null)
741+ StreamInitialized = m_sourceInitialized.GetOrAdd(m_source, true);
742+
743+ // Restore any unparsed buffers for this data source, if any
744+ UnparsedBuffer = m_unparsedBuffers.GetOrAdd(m_source, (byte[])null);
745+
746+ // Start parsing sequence for this buffer - this will begin publication of new parsed outputs
747+ base.Write(buffer.Buffer, 0, buffer.Count);
748+
749+ // Track last unparsed buffer for this data source
750+ m_unparsedBuffers[m_source] = UnparsedBuffer;
751+ }
752+
753+ // Dispose of source buffers - no rush
754+ ThreadPool.QueueUserWorkItem(DisposeSourceBuffers, buffers);
755+ }
756+
757+ // Handle disposing of source buffers (this will return items to the resuable object pool)
758+ private void DisposeSourceBuffers(object state)
759+ {
760+ SourceIdentifiableBuffer[] buffers = state as SourceIdentifiableBuffer[];
761+
762+ if ((object)buffers != null)
763+ {
764+ foreach (SourceIdentifiableBuffer buffer in buffers)
765+ {
766+ if ((object)buffer != null)
767+ buffer.Dispose();
768+ }
769+ }
770+ }
771+
772+ /// <summary>
773+ /// Raises the <see cref="FrameImageParserBase{TTypeIdentifier, TOutputType}.DataParsed"/> event.
774+ /// </summary>
775+ /// <param name="output">The object that was deserialized from binary image.</param>
776+ protected override void OnDataParsed(TOutputType output)
777+ {
778+ // Make sure output gets associated with its data source prior to publication
779+ output.Source = m_source;
780+
781+ base.OnDataParsed(output);
782+ }
783+
784+ /// <summary>
785+ /// Raises the <see cref="BinaryImageParserBase.DataDiscarded"/> event.
786+ /// </summary>
787+ /// <param name="buffer">Source buffer that contains output that failed to parse.</param>
788+ protected override void OnDataDiscarded(byte[] buffer)
789+ {
790+ // If an error occurs during parsing from a data source, we reset its initialization state
791+ if ((object)m_sourceInitialized != null)
792+ m_sourceInitialized[m_source] = false;
793+
794+ base.OnDataDiscarded(buffer);
795+ }
796+
797+ // We just bubble any exceptions captured in process queue out to parsing exception event...
798+ private void ProcessExceptionHandler(object sender, EventArgs<Exception> e)
799+ {
800+ OnParsingException(e.Argument);
801+ }
802+
803+ #endregion
804+ }
805+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t