History

Renamed folders and separated GSF.Media and GSF.Net into separate projects.

StephenCWills committed 14 years ago

Commit ac1ef661 parent 45bce55628 files · +733 −461Browse files

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

Unified · Split

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

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