Merge pull request #2107 from kasthack/system.web.sr
[mono.git] / mcs / class / System.Xaml / System.Xaml / XamlBackgroundReader.cs
1 //
2 // Copyright (C) 2011 Novell Inc. http://novell.com
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 using System;
24 using System.Collections.Generic;
25 using System.Threading;
26
27 namespace System.Xaml
28 {
29         public class XamlBackgroundReader : XamlReader, IXamlLineInfo
30         {
31                 public XamlBackgroundReader (XamlReader wrappedReader)
32                 {
33                         if (wrappedReader == null)
34                                 throw new ArgumentNullException ("wrappedReader");
35                         r = wrappedReader;
36                         q = new XamlNodeQueue (r.SchemaContext) { LineInfoProvider = r as IXamlLineInfo };
37                 }
38                 
39                 Thread thread;
40                 XamlReader r;
41                 XamlNodeQueue q;
42                 bool read_all_done, do_work = true;
43                 ManualResetEvent wait = new ManualResetEvent (true);
44
45                 public bool HasLineInfo {
46                         get { return ((IXamlLineInfo) q.Reader).HasLineInfo; }
47                 }
48                 
49                 public override bool IsEof {
50                         get { return read_all_done && q.IsEmpty; }
51                 }
52                 
53                 public int LineNumber {
54                         get { return ((IXamlLineInfo) q.Reader).LineNumber; }
55                 }
56                 
57                 [MonoTODO ("always returns 0")]
58                 public int LinePosition {
59                         get { return ((IXamlLineInfo) q.Reader).LinePosition; }
60                 }
61                 
62                 public override XamlMember Member {
63                         get { return q.Reader.Member; }
64                 }
65                 
66                 public override NamespaceDeclaration Namespace {
67                         get { return q.Reader.Namespace; }
68                 }
69                 
70                 public override XamlNodeType NodeType {
71                         get { return q.Reader.NodeType; }
72                 }
73                 
74                 public override XamlSchemaContext SchemaContext {
75                         get { return q.Reader.SchemaContext; }
76                 }
77                 
78                 public override XamlType Type {
79                         get { return q.Reader.Type; }
80                 }
81                 
82                 public override object Value {
83                         get { return q.Reader.Value; }
84                 }
85
86                 protected override void Dispose (bool disposing)
87                 {
88                         do_work = false;
89                 }
90                 
91                 public override bool Read ()
92                 {
93                         if (q.IsEmpty)
94                                 wait.WaitOne ();
95                         return q.Reader.Read ();
96                 }
97                 
98                 public void StartThread ()
99                 {
100                         StartThread ("XAML reader thread"); // documented name
101                 }
102                 
103                 public void StartThread (string threadName)
104                 {
105                         if (thread != null)
106                                 throw new InvalidOperationException ("Thread has already started");
107                         thread = new Thread (new ParameterizedThreadStart (delegate {
108                                 while (do_work && r.Read ()) {
109                                         q.Writer.WriteNode (r);
110                                         wait.Set ();
111                                 }
112                                 read_all_done = true;
113                         })) { Name = threadName };
114                         thread.Start ();
115                 }
116         }
117 }