##// END OF EJS Templates
component model refactoring
cin -
r152:240aa6994018 v2
parent child
Show More
@@ -0,0 +1,20
1 using System;
2 using System.Collections.Generic;
3
4 namespace Implab.Components {
5 /// <summary>
6 /// Global application components and services.
7 /// </summary>
8 public static class App {
9 readonly static ComponentContainer<object> _root = new ComponentContainer<object>();
10
11 public static ICollection<object> RootContainer {
12 get { return _root; }
13 }
14
15 static App() {
16 AppDomain.CurrentDomain.ProcessExit += (sender, e) => _root.Dispose();
17 }
18 }
19 }
20
@@ -0,0 +1,84
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4
5 namespace Implab.Components {
6 /// <summary>
7 /// Component container.
8 /// </summary>
9 /// <remarks>Instanses of this class are thread safe.</remarks>
10 public class ComponentContainer<T> : Disposable, ICollection<T> {
11 readonly HashSet<T> m_components = new HashSet<T>();
12
13 public void Clear() {
14 T[] removed;
15
16 lock (m_components) {
17 removed = new T[m_components.Count];
18 m_components.CopyTo(removed);
19 m_components.Clear();
20 }
21
22 foreach (var item in removed.OfType<IDisposable>())
23 item.Dispose();
24 }
25
26 public bool Contains(T item) {
27 lock (m_components)
28 return m_components.Contains(item);
29 }
30
31 public void CopyTo(T[] array, int arrayIndex) {
32 lock (m_components)
33 m_components.CopyTo(array, arrayIndex);
34 }
35
36 public bool Remove(T item) {
37 lock (m_components)
38 return m_components.Remove(item);
39 }
40
41 public int Count {
42 get {
43 lock (m_components)
44 return m_components.Count;
45 }
46 }
47
48 public bool IsReadOnly {
49 get {
50 return false;
51 }
52 }
53
54 public IEnumerator<T> GetEnumerator() {
55 T[] items;
56 lock (m_components) {
57 items = new T[m_components.Count];
58 m_components.CopyTo(items);
59 return (IEnumerator<T>)items.GetEnumerator();
60 }
61 }
62
63 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
64 return GetEnumerator();
65 }
66
67 public void Add(T item) {
68 Safe.ArgumentNotNull(item, "item");
69
70 lock (m_components) {
71 if (IsDisposed)
72 Safe.Dispose(item);
73 else
74 m_components.Add(item);
75 }
76 }
77
78 protected override void Dispose(bool disposing) {
79 base.Dispose(disposing);
80 Clear();
81 }
82 }
83 }
84
@@ -0,0 +1,103
1 using Implab.Diagnostics;
2 using System;
3 using System.Threading;
4
5 namespace Implab.Components {
6 /// <summary>
7 /// Base class the objects which support disposing.
8 /// </summary>
9 public class Disposable : IDisposable {
10
11 int m_disposed;
12
13 public event EventHandler Disposed;
14
15 public bool IsDisposed {
16 get {
17 Thread.MemoryBarrier();
18 return m_disposed != 0;
19 }
20 }
21
22 /// <summary>
23 /// Asserts the object is not disposed.
24 /// </summary>
25 /// <exception cref="ObjectDisposedException">The object is disposed</exception>
26 /// <remarks>
27 /// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не
28 /// будет освобожден сразу после нее, поэтому методы использующие проверку должны
29 /// учитывать, что объект может быть освобожден из параллельного потока.
30 /// Данны метод служит для упрощения отладки ошибок при использовании объекта после его
31 /// освобождения.
32 /// </remarks>
33 /// <example>
34 /// // пример синхронизированного освобождения ресурсов
35 /// class FileStore : Disposable {
36 /// readonly TextWriter m_file;
37 /// readonly obejct m_sync = new object();
38 ///
39 /// public FileStore(string file) {
40 /// m_file = new TextWriter(File.OpenWrite(file));
41 /// }
42 ///
43 /// public void Write(string text) {
44 /// lock(m_sync) {
45 /// AssertNotDisposed();
46 /// m_file.Write(text);
47 /// }
48 /// }
49 ///
50 /// protected override void Dispose(bool disposing) {
51 /// if (disposing)
52 /// lock(m_sync) {
53 /// m_file.Dipose();
54 /// base.Dispose(true);
55 /// }
56 /// else
57 /// base.Dispose(false);
58 /// }
59 /// }
60 /// <example>
61 protected void AssertNotDisposed() {
62 Thread.MemoryBarrier();
63 if (m_disposed != 0)
64 throw new ObjectDisposedException(ToString());
65 }
66 /// <summary>
67 /// Вызывает событие <see cref="Disposed"/>
68 /// </summary>
69 /// <param name="disposing">Признак того, что нужно освободить ресурсы, иначе данный метод
70 /// вызван сборщиком мусора и нужно освобождать ТОЛЬКО неуправляемые ресурсы ТОЛЬКО этого
71 /// объекта.</param>
72 /// <remarks>
73 /// Данный метод вызывается гарантированно один раз даже при одновременном вызове <see cref="Dispose()"/>
74 /// из нескольких потоков.
75 /// </remarks>
76 protected virtual void Dispose(bool disposing) {
77 if (disposing) {
78 EventHandler temp = Disposed;
79 if (temp != null)
80 temp(this, EventArgs.Empty);
81 }
82 }
83
84 public void Dispose() {
85 if (Interlocked.Increment(ref m_disposed) == 1) {
86 Dispose(true);
87 GC.SuppressFinalize(this);
88 }
89 }
90
91 /// <summary>
92 /// Записывает сообщение об утечке объекта.
93 /// </summary>
94 protected virtual void ReportObjectLeaks() {
95 TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
96 }
97
98 ~Disposable() {
99 Dispose(false);
100 ReportObjectLeaks();
101 }
102 }
103 } No newline at end of file
@@ -0,0 +1,90
1 using System;
2 using Implab.Parallels;
3 using System.Threading;
4 using System.Diagnostics;
5 using System.Diagnostics.CodeAnalysis;
6
7 namespace Implab {
8 public abstract class DisposablePool<T> : IDisposable {
9 readonly int m_size;
10 readonly AsyncQueue<T> m_queue = new AsyncQueue<T>();
11
12 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
13 static readonly bool _isValueType = typeof(T).IsValueType;
14
15 bool m_disposed;
16
17 int m_count;
18
19 protected DisposablePool(int size) {
20 m_size = size;
21 }
22
23 protected DisposablePool() : this(Environment.ProcessorCount+1) {
24 }
25
26 public T Allocate() {
27 if (m_disposed)
28 throw new ObjectDisposedException(ToString());
29
30 T instance;
31 if (m_queue.TryDequeue(out instance)) {
32 Interlocked.Decrement(ref m_count);
33 } else {
34 instance = CreateInstance();
35 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
36 }
37 return instance;
38 }
39
40 protected abstract T CreateInstance();
41
42 protected virtual void CleanupInstance(T instance) {
43 }
44
45 public void Release(T instance) {
46 if ( Object.Equals(instance,default(T)) && !_isValueType)
47 return;
48
49 Thread.MemoryBarrier();
50 if (m_count < m_size && !m_disposed) {
51 Interlocked.Increment(ref m_count);
52
53 CleanupInstance(instance);
54
55 m_queue.Enqueue(instance);
56
57 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
58 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
59 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
60 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
61 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
62 ((IDisposable)instance).Dispose() ;
63
64 } else {
65 if (instance is IDisposable)
66 ((IDisposable)instance).Dispose();
67 }
68 }
69
70 protected virtual void Dispose(bool disposing) {
71 if (disposing) {
72 m_disposed = true;
73 T instance;
74 while (m_queue.TryDequeue(out instance))
75 if (instance is IDisposable)
76 ((IDisposable)instance).Dispose();
77 }
78 }
79
80 #region IDisposable implementation
81
82 public void Dispose() {
83 Dispose(true);
84 GC.SuppressFinalize(this);
85 }
86
87 #endregion
88 }
89 }
90
@@ -0,0 +1,12
1 namespace Implab.Components {
2 public enum ExecutionState {
3 Uninitialized,
4 Initial,
5 Starting,
6 Running,
7 Stopping,
8 Stopped,
9 Disposed,
10 Failed
11 }
12 } No newline at end of file
@@ -0,0 +1,21
1 using System;
2
3 namespace Implab.Components {
4 /// <summary>
5 /// Initializable components are created and initialized in two steps, first we have create the component,
6 /// then we have to complete it's creation by calling an <see cref="Init()"/> method. All parameters needed
7 /// to complete the initialization must be passed before the calling <see cref="Init()"/>
8 /// </summary>
9 public interface IInitializable {
10 /// <summary>
11 /// Completes initialization.
12 /// </summary>
13 /// <remarks>
14 /// Normally virtual shouldn't be called from the constructor, due to the incomplete object state, but
15 /// they can be called from this method. This method is also usefull when we constructing a complex grpah
16 /// of components where cyclic references may take place.
17 /// </remarks>
18 void Init();
19 }
20 }
21
@@ -0,0 +1,14
1 using System;
2
3 namespace Implab.Components {
4 public interface IRunnable {
5 IPromise Start();
6
7 IPromise Stop();
8
9 ExecutionState State { get; }
10
11 Exception LastError { get; }
12 }
13 }
14
@@ -0,0 +1,60
1 using Implab.Parallels;
2 using System;
3 using System.Threading;
4
5 namespace Implab.Components {
6 /// <summary>
7 /// Базовый класс для создания пулов объектов.
8 /// </summary>
9 /// <remarks>
10 /// <para>Пул объектов позволяет многократно использовать один и тотже объект,
11 /// что актуально для объектов, создание которых требует существенных ресурсов.
12 /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению
13 /// ресурсов и создает новые объекты при необходимости.</para>
14 /// <para>
15 /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания
16 /// новых экземпляров.
17 /// </para>
18 /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para>
19 /// </remarks>
20 public abstract class ObjectPool<T> where T : class {
21 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
22 readonly int m_size;
23 int m_count = 0;
24
25 protected ObjectPool() : this(Environment.ProcessorCount+1) {
26
27 }
28
29 protected ObjectPool(int size) {
30 Safe.ArgumentInRange(size,1,size,"size");
31
32 m_size = size;
33 }
34
35 protected abstract T CreateInstance();
36
37 protected virtual void CleanupInstance(T instance) {
38 }
39
40 public T Allocate() {
41 WeakReference reference;
42 while (m_queue.TryDequeue(out reference)) {
43 Interlocked.Decrement(ref m_count);
44 object instance = reference.Target;
45 if (instance == null)
46 continue;
47 return (T)instance;
48 }
49 return CreateInstance();
50 }
51
52 public void Release(T instance) {
53 if (m_count < m_size && instance != null) {
54 Interlocked.Increment(ref m_count);
55 CleanupInstance(instance);
56 m_queue.Enqueue(new WeakReference(instance));
57 }
58 }
59 }
60 }
@@ -0,0 +1,248
1 using System;
2 using System.Collections.Generic;
3
4 namespace Implab.Components {
5 /// <summary>
6 /// Коллекция сервисов, позволяет регистрировать и получать сервисы.
7 /// </summary>
8 public class ServiceLocator: Disposable, IServiceLocator, IServiceProvider {
9 // запись о сервисе
10 struct ServiceEntry : IDisposable {
11 public object service; // сервис
12 public bool shared; // признак того, что сервис НЕ нужно освобождать
13 public Func<object> activator; // активатор сервиса при первом обращении
14 public Action<object> cleanup; // функция для очистки сервиса
15 public List<Type> associated; // ссылки на текущую запись
16 public Type origin; // ссылка на оригинальную запись о сервисе
17
18 #region IDisposable implementation
19
20 public void Dispose() {
21 if (shared)
22 return;
23 if (cleanup != null) {
24 if (service != null)
25 cleanup(service);
26 } else
27 Safe.Dispose(service);
28 }
29
30 #endregion
31 }
32
33 // словарь существующих сервисов
34 readonly Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
35
36 /// <summary>
37 /// Получает объект предоставляющий сервис <typeparamref name="T"/>.
38 /// </summary>
39 /// <typeparam name="T">Тип запрашиваемого сервиса</typeparam>
40 /// <returns>Объект, реализующий сервис</returns>
41 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
42 public T GetService<T>() {
43 object result;
44 if (TryGetService(typeof(T), out result))
45 return (T)result;
46 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, typeof(T)));
47 }
48
49
50 /// <summary>
51 /// Пытается получить указанный сервис, в случае, если компонента не предоставляет требуемый сервис
52 /// не возникает исключений.
53 /// </summary>
54 /// <typeparam name="T">Тип требуемого сервиса.</typeparam>
55 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param>
56 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns>
57 public bool TryGetService<T>(out T service) {
58 object result;
59 if (TryGetService(typeof(T), out result)) {
60 service = (T)result;
61 return true;
62 }
63 service = default(T);
64 return false;
65 }
66
67 /// <summary>
68 /// Получает объект предоставляющий сервис <paramref name="serviceType"/>
69 /// </summary>
70 /// <param name="serviceType">Тип запрашиваемого сервиса</param>
71 /// <returns>Объект, реализующий сервис</returns>
72 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
73 public object GetService(Type serviceType) {
74 object result;
75 if (TryGetService(serviceType, out result))
76 return result;
77 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, serviceType));
78 }
79
80 /// <summary>
81 /// Пытается получить требуемый сервис или совместимый с ним.
82 /// </summary>
83 /// <returns><c>true</c>, если сервис был найден, <c>false</c> в противном случае..</returns>
84 /// <param name="serviceType">Тип запрашиваемого сервиса.</param>
85 /// <param name="service">Искомый сервис.</param>
86 public virtual bool TryGetService(Type serviceType, out object service) {
87 Safe.ArgumentNotNull(serviceType, "serviceType");
88 AssertNotDisposed();
89
90 ServiceEntry se;
91 if (!m_services.TryGetValue(serviceType, out se)) {
92 // ищем ближайщий объект, реализующий нужный сервис
93 Type pt = null;
94 foreach (var t in m_services.Keys)
95 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt)))
96 pt = t;
97
98 if (pt == null) {
99 // нет нужного сервиса
100 service = null;
101 return false;
102 }
103
104 var pe = m_services[pt];
105
106 // найденная запись может ссылаться на оригинальную запись с сервисом
107 if(pe.origin != null) {
108 pt = pe.origin;
109 pe = m_services[pt];
110 }
111
112 // добавляем список с обратными ссылками
113 if (pe.associated == null)
114 pe.associated = new List<Type>();
115
116 pe.associated.Add(serviceType);
117
118 // обновляем родительскую запись
119 m_services[pt] = pe;
120
121 // создаем запись со ссылкой
122 se = new ServiceEntry {
123 service = pe.service,
124 origin = pt,
125 shared = true // предотвращаем множественные попытки освобождения
126 };
127
128 m_services[serviceType] = se;
129 }
130
131 // запись содержит в себе информацию о сервисе
132 if (se.service != null) {
133 service = se.service;
134 return true;
135 }
136
137 // текущая запись является ссылкой
138 if (se.origin != null) {
139 se.service = GetService(se.origin);
140 m_services[serviceType] = se;
141 service = se.service;
142 return true;
143 }
144
145 // текущая запись не является ссылкой и не имеет информации о сервисе
146 // она должна сожержать информацию об активации
147 if (se.activator != null) {
148 se.service = se.activator();
149
150 m_services[serviceType] = se;
151
152 service = se.service;
153 return true;
154 }
155
156 service = null;
157 return false;
158 }
159
160 /// <summary>
161 /// Регистрирует фабрику для активации сервиса по первому требованию.
162 /// </summary>
163 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
164 /// <param name="activator">Фабрика для создания/получения объекта, предоставляющего сервис.</param>
165 /// <param name = "cleanup">Метод для освобождения экземпляра сервиса, будет вызыван при освобождении сервис-локатора.</param>
166 /// <remarks>При освобождении сервис-локатора, сервисы полученные в результате активации также будут освобождены.</remarks>
167 public void Register<T>(Func<T> activator, Action<T> cleanup) {
168 Safe.ArgumentNotNull(activator, "activator");
169
170 AssertNotDisposed();
171
172 Unregister(typeof(T));
173
174 var serviceEntry = new ServiceEntry();
175 serviceEntry.activator = () => activator();
176 if (cleanup != null)
177 serviceEntry.cleanup = instance => cleanup((T)instance);
178 m_services[typeof(T)] = serviceEntry;
179 }
180
181 public void Register<T>(Func<T> activator) {
182 Register(activator, null);
183 }
184
185 /// <summary>
186 /// Регистрирует объект, предоставляющий сервис.
187 /// </summary>
188 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
189 /// <param name="service">Объект, предоставляющий сервис.</param>
190 /// <exception cref="InvalidOperationException">Указанный сервис уже зарегистрирован.</exception>
191 /// <remarks>Сервис-локатором не управляет временем жизни объекта для зарегистрированного сервиса.</remarks>
192 public void Register<T>(T service) {
193 Register(service, true);
194 }
195
196 /// <summary>
197 /// Регистрирует объект, предоставляющий сервис. Повторная регистрация отменяет уже существующую.
198 /// </summary>
199 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
200 /// <param name="service">Объект, предоставляющий сервис.</param>
201 /// <param name="shared">Признак того, что объект является разделяемым и сервис-локатор не должен его освобождать.</param>
202 public void Register<T>(T service, bool shared) {
203 Safe.ArgumentNotNull(service, "service");
204
205 AssertNotDisposed();
206
207 Unregister(typeof(T));
208
209 m_services[typeof(T)] = new ServiceEntry { service = service, shared = shared };
210 }
211
212 public void Unregister(Type serviceType) {
213 Safe.ArgumentNotNull(serviceType, "serviceType");
214
215 AssertNotDisposed();
216
217 ServiceEntry se;
218 if (m_services.TryGetValue(serviceType, out se)) {
219 if (se.origin != null) {
220 var pe = m_services[se.origin];
221 pe.associated.Remove(serviceType);
222 }
223 // освобождаем ресурсы
224 se.Dispose();
225 m_services.Remove(serviceType);
226
227 // убираем связанные записи
228 if (se.associated != null)
229 foreach (var item in se.associated)
230 m_services.Remove(item);
231 }
232 }
233
234 /// <summary>
235 /// Освобождает зарегистрированные сервисы (которые требуется освобоить).
236 /// </summary>
237 /// <param name="disposing">Призанак того, что нужно освободить ресурсы.</param>
238 protected override void Dispose(bool disposing) {
239 if (disposing) {
240
241 foreach (var entry in m_services.Values)
242 entry.Dispose();
243
244 }
245 base.Dispose(disposing);
246 }
247 }
248 } No newline at end of file
@@ -1,87 +1,86
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using Implab.Components;
4 using System.Text;
5
4
6 namespace Implab.Diagnostics {
5 namespace Implab.Diagnostics {
7 public abstract class ListenerBase : ServiceLocator, ILogWriter<object>, ILogWriter<TraceEvent> {
6 public abstract class ListenerBase : ServiceLocator, ILogWriter<object>, ILogWriter<TraceEvent> {
8
7
9 readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>();
8 readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>();
10
9
11 protected ListenerBase() {
10 protected ListenerBase() {
12 Register(this);
11 Register(this);
13 }
12 }
14
13
15 public void Subscribe(Type eventType) {
14 public void Subscribe(Type eventType) {
16 if (eventType == null)
15 if (eventType == null)
17 throw new ArgumentNullException("eventType");
16 throw new ArgumentNullException("eventType");
18 GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null);
17 GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null);
19 }
18 }
20
19
21 public void Subscribe<TEvent>() {
20 public void Subscribe<TEvent>() {
22 Subscribe<TEvent>(LogChannel<TEvent>.Default);
21 Subscribe<TEvent>(LogChannel<TEvent>.Default);
23 }
22 }
24
23
25 public void Subscribe<TEvent>(LogChannel<TEvent> channel) {
24 public void Subscribe<TEvent>(LogChannel<TEvent> channel) {
26 if (channel == null)
25 if (channel == null)
27 throw new ArgumentNullException("channel");
26 throw new ArgumentNullException("channel");
28
27
29 lock (m_subscriptions) {
28 lock (m_subscriptions) {
30 AssertNotDisposed();
29 AssertNotDisposed();
31 if (m_subscriptions.ContainsKey(channel))
30 if (m_subscriptions.ContainsKey(channel))
32 return;
31 return;
33
32
34 var writer = GetService<ILogWriter<TEvent>>();
33 var writer = GetService<ILogWriter<TEvent>>();
35
34
36 EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => writer.Write(args,args.Value);
35 EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => writer.Write(args,args.Value);
37
36
38 channel.Events += handler;
37 channel.Events += handler;
39
38
40 Action unsubscribe = () => {
39 Action unsubscribe = () => {
41 channel.Events -= handler;
40 channel.Events -= handler;
42 };
41 };
43
42
44 m_subscriptions.Add(channel, unsubscribe);
43 m_subscriptions.Add(channel, unsubscribe);
45 }
44 }
46 }
45 }
47
46
48 public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) {
47 public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) {
49 if (channel == null)
48 if (channel == null)
50 throw new ArgumentNullException("channel");
49 throw new ArgumentNullException("channel");
51
50
52 lock (m_subscriptions) {
51 lock (m_subscriptions) {
53 Action subscription;
52 Action subscription;
54 if (m_subscriptions.TryGetValue(channel, out subscription)) {
53 if (m_subscriptions.TryGetValue(channel, out subscription)) {
55 subscription();
54 subscription();
56 m_subscriptions.Remove(channel);
55 m_subscriptions.Remove(channel);
57 }
56 }
58 }
57 }
59 }
58 }
60
59
61 public void UnsubscribeAll() {
60 public void UnsubscribeAll() {
62 lock (m_subscriptions) {
61 lock (m_subscriptions) {
63 foreach (var subscription in m_subscriptions.Values)
62 foreach (var subscription in m_subscriptions.Values)
64 subscription();
63 subscription();
65 m_subscriptions.Clear();
64 m_subscriptions.Clear();
66 }
65 }
67 }
66 }
68
67
69 #region ILogWriter implementation
68 #region ILogWriter implementation
70 public abstract void Write(LogEventArgs args, object entry);
69 public abstract void Write(LogEventArgs args, object entry);
71 #endregion
70 #endregion
72
71
73 #region ILogWriter implementation
72 #region ILogWriter implementation
74 public virtual void Write(LogEventArgs args, TraceEvent entry) {
73 public virtual void Write(LogEventArgs args, TraceEvent entry) {
75 Write(args, (object)entry);
74 Write(args, (object)entry);
76 }
75 }
77 #endregion
76 #endregion
78
77
79
78
80 protected override void Dispose(bool disposing) {
79 protected override void Dispose(bool disposing) {
81 base.Dispose(disposing);
80 base.Dispose(disposing);
82 if (disposing) {
81 if (disposing) {
83 UnsubscribeAll();
82 UnsubscribeAll();
84 }
83 }
85 }
84 }
86 }
85 }
87 }
86 }
@@ -1,255 +1,260
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 <ProductVersion>8.0.30703</ProductVersion>
10 <ProductVersion>8.0.30703</ProductVersion>
11 <SchemaVersion>2.0</SchemaVersion>
11 <SchemaVersion>2.0</SchemaVersion>
12 <ReleaseVersion>0.2</ReleaseVersion>
12 <ReleaseVersion>0.2</ReleaseVersion>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
14 </PropertyGroup>
14 </PropertyGroup>
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
17 <DebugType>full</DebugType>
17 <DebugType>full</DebugType>
18 <Optimize>false</Optimize>
18 <Optimize>false</Optimize>
19 <OutputPath>bin\Debug</OutputPath>
19 <OutputPath>bin\Debug</OutputPath>
20 <DefineConstants>TRACE;DEBUG;</DefineConstants>
20 <DefineConstants>TRACE;DEBUG;</DefineConstants>
21 <ErrorReport>prompt</ErrorReport>
21 <ErrorReport>prompt</ErrorReport>
22 <WarningLevel>4</WarningLevel>
22 <WarningLevel>4</WarningLevel>
23 <ConsolePause>false</ConsolePause>
23 <ConsolePause>false</ConsolePause>
24 <RunCodeAnalysis>true</RunCodeAnalysis>
24 <RunCodeAnalysis>true</RunCodeAnalysis>
25 </PropertyGroup>
25 </PropertyGroup>
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27 <DebugType>full</DebugType>
27 <DebugType>full</DebugType>
28 <Optimize>true</Optimize>
28 <Optimize>true</Optimize>
29 <OutputPath>bin\Release</OutputPath>
29 <OutputPath>bin\Release</OutputPath>
30 <ErrorReport>prompt</ErrorReport>
30 <ErrorReport>prompt</ErrorReport>
31 <WarningLevel>4</WarningLevel>
31 <WarningLevel>4</WarningLevel>
32 <ConsolePause>false</ConsolePause>
32 <ConsolePause>false</ConsolePause>
33 </PropertyGroup>
33 </PropertyGroup>
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
35 <DebugSymbols>true</DebugSymbols>
35 <DebugSymbols>true</DebugSymbols>
36 <DebugType>full</DebugType>
36 <DebugType>full</DebugType>
37 <Optimize>false</Optimize>
37 <Optimize>false</Optimize>
38 <OutputPath>bin\Debug</OutputPath>
38 <OutputPath>bin\Debug</OutputPath>
39 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
39 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
40 <ErrorReport>prompt</ErrorReport>
40 <ErrorReport>prompt</ErrorReport>
41 <WarningLevel>4</WarningLevel>
41 <WarningLevel>4</WarningLevel>
42 <RunCodeAnalysis>true</RunCodeAnalysis>
42 <RunCodeAnalysis>true</RunCodeAnalysis>
43 <ConsolePause>false</ConsolePause>
43 <ConsolePause>false</ConsolePause>
44 </PropertyGroup>
44 </PropertyGroup>
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
46 <Optimize>true</Optimize>
46 <Optimize>true</Optimize>
47 <OutputPath>bin\Release</OutputPath>
47 <OutputPath>bin\Release</OutputPath>
48 <ErrorReport>prompt</ErrorReport>
48 <ErrorReport>prompt</ErrorReport>
49 <WarningLevel>4</WarningLevel>
49 <WarningLevel>4</WarningLevel>
50 <ConsolePause>false</ConsolePause>
50 <ConsolePause>false</ConsolePause>
51 <DefineConstants>NET_4_5</DefineConstants>
51 <DefineConstants>NET_4_5</DefineConstants>
52 </PropertyGroup>
52 </PropertyGroup>
53 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
53 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
54 <DebugSymbols>true</DebugSymbols>
54 <DebugSymbols>true</DebugSymbols>
55 <DebugType>full</DebugType>
55 <DebugType>full</DebugType>
56 <Optimize>false</Optimize>
56 <Optimize>false</Optimize>
57 <OutputPath>bin\Debug</OutputPath>
57 <OutputPath>bin\Debug</OutputPath>
58 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
58 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
59 <ErrorReport>prompt</ErrorReport>
59 <ErrorReport>prompt</ErrorReport>
60 <WarningLevel>4</WarningLevel>
60 <WarningLevel>4</WarningLevel>
61 <RunCodeAnalysis>true</RunCodeAnalysis>
61 <RunCodeAnalysis>true</RunCodeAnalysis>
62 <ConsolePause>false</ConsolePause>
62 <ConsolePause>false</ConsolePause>
63 </PropertyGroup>
63 </PropertyGroup>
64 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
64 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
65 <Optimize>true</Optimize>
65 <Optimize>true</Optimize>
66 <OutputPath>bin\Release</OutputPath>
66 <OutputPath>bin\Release</OutputPath>
67 <DefineConstants>NET_4_5;MONO;</DefineConstants>
67 <DefineConstants>NET_4_5;MONO;</DefineConstants>
68 <ErrorReport>prompt</ErrorReport>
68 <ErrorReport>prompt</ErrorReport>
69 <WarningLevel>4</WarningLevel>
69 <WarningLevel>4</WarningLevel>
70 <ConsolePause>false</ConsolePause>
70 <ConsolePause>false</ConsolePause>
71 </PropertyGroup>
71 </PropertyGroup>
72 <ItemGroup>
72 <ItemGroup>
73 <Reference Include="System" />
73 <Reference Include="System" />
74 <Reference Include="System.Xml" />
74 <Reference Include="System.Xml" />
75 <Reference Include="mscorlib" />
75 <Reference Include="mscorlib" />
76 </ItemGroup>
76 </ItemGroup>
77 <ItemGroup>
77 <ItemGroup>
78 <Compile Include="Component.cs" />
79 <Compile Include="CustomEqualityComparer.cs" />
78 <Compile Include="CustomEqualityComparer.cs" />
80 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
79 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
81 <Compile Include="Diagnostics\EventText.cs" />
80 <Compile Include="Diagnostics\EventText.cs" />
82 <Compile Include="Diagnostics\LogChannel.cs" />
81 <Compile Include="Diagnostics\LogChannel.cs" />
83 <Compile Include="Diagnostics\LogicalOperation.cs" />
82 <Compile Include="Diagnostics\LogicalOperation.cs" />
84 <Compile Include="Diagnostics\TextFileListener.cs" />
83 <Compile Include="Diagnostics\TextFileListener.cs" />
85 <Compile Include="Diagnostics\TraceLog.cs" />
84 <Compile Include="Diagnostics\TraceLog.cs" />
86 <Compile Include="Diagnostics\TraceEvent.cs" />
85 <Compile Include="Diagnostics\TraceEvent.cs" />
87 <Compile Include="Diagnostics\TraceEventType.cs" />
86 <Compile Include="Diagnostics\TraceEventType.cs" />
88 <Compile Include="Disposable.cs" />
89 <Compile Include="ICancellable.cs" />
87 <Compile Include="ICancellable.cs" />
90 <Compile Include="IProgressHandler.cs" />
88 <Compile Include="IProgressHandler.cs" />
91 <Compile Include="IProgressNotifier.cs" />
89 <Compile Include="IProgressNotifier.cs" />
92 <Compile Include="IPromiseT.cs" />
90 <Compile Include="IPromiseT.cs" />
93 <Compile Include="IPromise.cs" />
91 <Compile Include="IPromise.cs" />
94 <Compile Include="IServiceLocator.cs" />
92 <Compile Include="IServiceLocator.cs" />
95 <Compile Include="ITaskController.cs" />
93 <Compile Include="ITaskController.cs" />
96 <Compile Include="JSON\JSONElementContext.cs" />
94 <Compile Include="JSON\JSONElementContext.cs" />
97 <Compile Include="JSON\JSONElementType.cs" />
95 <Compile Include="JSON\JSONElementType.cs" />
98 <Compile Include="JSON\JSONGrammar.cs" />
96 <Compile Include="JSON\JSONGrammar.cs" />
99 <Compile Include="JSON\JSONParser.cs" />
97 <Compile Include="JSON\JSONParser.cs" />
100 <Compile Include="JSON\JSONScanner.cs" />
98 <Compile Include="JSON\JSONScanner.cs" />
101 <Compile Include="JSON\JsonTokenType.cs" />
99 <Compile Include="JSON\JsonTokenType.cs" />
102 <Compile Include="JSON\JSONWriter.cs" />
100 <Compile Include="JSON\JSONWriter.cs" />
103 <Compile Include="JSON\JSONXmlReader.cs" />
101 <Compile Include="JSON\JSONXmlReader.cs" />
104 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
102 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
105 <Compile Include="JSON\StringTranslator.cs" />
103 <Compile Include="JSON\StringTranslator.cs" />
106 <Compile Include="Parallels\DispatchPool.cs" />
104 <Compile Include="Parallels\DispatchPool.cs" />
107 <Compile Include="Parallels\ArrayTraits.cs" />
105 <Compile Include="Parallels\ArrayTraits.cs" />
108 <Compile Include="Parallels\MTQueue.cs" />
106 <Compile Include="Parallels\MTQueue.cs" />
109 <Compile Include="Parallels\WorkerPool.cs" />
107 <Compile Include="Parallels\WorkerPool.cs" />
110 <Compile Include="Parsing\Alphabet.cs" />
108 <Compile Include="Parsing\Alphabet.cs" />
111 <Compile Include="Parsing\AlphabetBase.cs" />
109 <Compile Include="Parsing\AlphabetBase.cs" />
112 <Compile Include="Parsing\AltToken.cs" />
110 <Compile Include="Parsing\AltToken.cs" />
113 <Compile Include="Parsing\BinaryToken.cs" />
111 <Compile Include="Parsing\BinaryToken.cs" />
114 <Compile Include="Parsing\CatToken.cs" />
112 <Compile Include="Parsing\CatToken.cs" />
115 <Compile Include="Parsing\CDFADefinition.cs" />
113 <Compile Include="Parsing\CDFADefinition.cs" />
116 <Compile Include="Parsing\DFABuilder.cs" />
114 <Compile Include="Parsing\DFABuilder.cs" />
117 <Compile Include="Parsing\DFADefinitionBase.cs" />
115 <Compile Include="Parsing\DFADefinitionBase.cs" />
118 <Compile Include="Parsing\DFAStateDescriptor.cs" />
116 <Compile Include="Parsing\DFAStateDescriptor.cs" />
119 <Compile Include="Parsing\DFAutomaton.cs" />
117 <Compile Include="Parsing\DFAutomaton.cs" />
120 <Compile Include="Parsing\EDFADefinition.cs" />
118 <Compile Include="Parsing\EDFADefinition.cs" />
121 <Compile Include="Parsing\EmptyToken.cs" />
119 <Compile Include="Parsing\EmptyToken.cs" />
122 <Compile Include="Parsing\EndToken.cs" />
120 <Compile Include="Parsing\EndToken.cs" />
123 <Compile Include="Parsing\EnumAlphabet.cs" />
121 <Compile Include="Parsing\EnumAlphabet.cs" />
124 <Compile Include="Parsing\Grammar.cs" />
122 <Compile Include="Parsing\Grammar.cs" />
125 <Compile Include="Parsing\IAlphabet.cs" />
123 <Compile Include="Parsing\IAlphabet.cs" />
126 <Compile Include="Parsing\IDFADefinition.cs" />
124 <Compile Include="Parsing\IDFADefinition.cs" />
127 <Compile Include="Parsing\IVisitor.cs" />
125 <Compile Include="Parsing\IVisitor.cs" />
128 <Compile Include="Parsing\ParserException.cs" />
126 <Compile Include="Parsing\ParserException.cs" />
129 <Compile Include="Parsing\Scanner.cs" />
127 <Compile Include="Parsing\Scanner.cs" />
130 <Compile Include="Parsing\StarToken.cs" />
128 <Compile Include="Parsing\StarToken.cs" />
131 <Compile Include="Parsing\SymbolToken.cs" />
129 <Compile Include="Parsing\SymbolToken.cs" />
132 <Compile Include="Parsing\Token.cs" />
130 <Compile Include="Parsing\Token.cs" />
133 <Compile Include="ServiceLocator.cs" />
134 <Compile Include="TaskController.cs" />
135 <Compile Include="ProgressInitEventArgs.cs" />
131 <Compile Include="ProgressInitEventArgs.cs" />
136 <Compile Include="Properties\AssemblyInfo.cs" />
132 <Compile Include="Properties\AssemblyInfo.cs" />
137 <Compile Include="Parallels\AsyncPool.cs" />
133 <Compile Include="Parallels\AsyncPool.cs" />
138 <Compile Include="Safe.cs" />
134 <Compile Include="Safe.cs" />
139 <Compile Include="ValueEventArgs.cs" />
135 <Compile Include="ValueEventArgs.cs" />
140 <Compile Include="PromiseExtensions.cs" />
136 <Compile Include="PromiseExtensions.cs" />
141 <Compile Include="SyncContextPromise.cs" />
137 <Compile Include="SyncContextPromise.cs" />
142 <Compile Include="Diagnostics\OperationContext.cs" />
138 <Compile Include="Diagnostics\OperationContext.cs" />
143 <Compile Include="Diagnostics\TraceContext.cs" />
139 <Compile Include="Diagnostics\TraceContext.cs" />
144 <Compile Include="Diagnostics\LogEventArgs.cs" />
140 <Compile Include="Diagnostics\LogEventArgs.cs" />
145 <Compile Include="Diagnostics\LogEventArgsT.cs" />
141 <Compile Include="Diagnostics\LogEventArgsT.cs" />
146 <Compile Include="Diagnostics\Extensions.cs" />
142 <Compile Include="Diagnostics\Extensions.cs" />
147 <Compile Include="IComponentContainer.cs" />
148 <Compile Include="PromiseEventType.cs" />
143 <Compile Include="PromiseEventType.cs" />
149 <Compile Include="ComponentContainer.cs" />
150 <Compile Include="DisposablePool.cs" />
151 <Compile Include="ObjectPool.cs" />
152 <Compile Include="Parallels\AsyncQueue.cs" />
144 <Compile Include="Parallels\AsyncQueue.cs" />
153 <Compile Include="PromiseT.cs" />
145 <Compile Include="PromiseT.cs" />
154 <Compile Include="IDeferred.cs" />
146 <Compile Include="IDeferred.cs" />
155 <Compile Include="IDeferredT.cs" />
147 <Compile Include="IDeferredT.cs" />
156 <Compile Include="Promise.cs" />
148 <Compile Include="Promise.cs" />
157 <Compile Include="PromiseTransientException.cs" />
149 <Compile Include="PromiseTransientException.cs" />
158 <Compile Include="Parallels\Signal.cs" />
150 <Compile Include="Parallels\Signal.cs" />
159 <Compile Include="Parallels\SharedLock.cs" />
151 <Compile Include="Parallels\SharedLock.cs" />
160 <Compile Include="Diagnostics\ILogWriter.cs" />
152 <Compile Include="Diagnostics\ILogWriter.cs" />
161 <Compile Include="Diagnostics\ListenerBase.cs" />
153 <Compile Include="Diagnostics\ListenerBase.cs" />
162 <Compile Include="Parallels\BlockingQueue.cs" />
154 <Compile Include="Parallels\BlockingQueue.cs" />
163 <Compile Include="AbstractEvent.cs" />
155 <Compile Include="AbstractEvent.cs" />
164 <Compile Include="AbstractPromise.cs" />
156 <Compile Include="AbstractPromise.cs" />
165 <Compile Include="AbstractPromiseT.cs" />
157 <Compile Include="AbstractPromiseT.cs" />
166 <Compile Include="FuncTask.cs" />
158 <Compile Include="FuncTask.cs" />
167 <Compile Include="FuncTaskBase.cs" />
159 <Compile Include="FuncTaskBase.cs" />
168 <Compile Include="FuncTaskT.cs" />
160 <Compile Include="FuncTaskT.cs" />
169 <Compile Include="ActionChainTaskBase.cs" />
161 <Compile Include="ActionChainTaskBase.cs" />
170 <Compile Include="ActionChainTask.cs" />
162 <Compile Include="ActionChainTask.cs" />
171 <Compile Include="ActionChainTaskT.cs" />
163 <Compile Include="ActionChainTaskT.cs" />
172 <Compile Include="FuncChainTaskBase.cs" />
164 <Compile Include="FuncChainTaskBase.cs" />
173 <Compile Include="FuncChainTask.cs" />
165 <Compile Include="FuncChainTask.cs" />
174 <Compile Include="FuncChainTaskT.cs" />
166 <Compile Include="FuncChainTaskT.cs" />
175 <Compile Include="ActionTaskBase.cs" />
167 <Compile Include="ActionTaskBase.cs" />
176 <Compile Include="ActionTask.cs" />
168 <Compile Include="ActionTask.cs" />
177 <Compile Include="ActionTaskT.cs" />
169 <Compile Include="ActionTaskT.cs" />
178 <Compile Include="ICancellationToken.cs" />
170 <Compile Include="ICancellationToken.cs" />
179 <Compile Include="SuccessPromise.cs" />
171 <Compile Include="SuccessPromise.cs" />
180 <Compile Include="SuccessPromiseT.cs" />
172 <Compile Include="SuccessPromiseT.cs" />
181 <Compile Include="PromiseAwaiterT.cs" />
173 <Compile Include="PromiseAwaiterT.cs" />
182 <Compile Include="PromiseAwaiter.cs" />
174 <Compile Include="PromiseAwaiter.cs" />
175 <Compile Include="Components\ComponentContainer.cs" />
176 <Compile Include="Components\Disposable.cs" />
177 <Compile Include="Components\DisposablePool.cs" />
178 <Compile Include="Components\ObjectPool.cs" />
179 <Compile Include="Components\ServiceLocator.cs" />
180 <Compile Include="Components\IInitializable.cs" />
181 <Compile Include="TaskController.cs" />
182 <Compile Include="Components\App.cs" />
183 <Compile Include="Components\IRunnable.cs" />
184 <Compile Include="Components\ExecutionState.cs" />
183 </ItemGroup>
185 </ItemGroup>
184 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
186 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
185 <ItemGroup />
187 <ItemGroup />
186 <ProjectExtensions>
188 <ProjectExtensions>
187 <MonoDevelop>
189 <MonoDevelop>
188 <Properties>
190 <Properties>
189 <Policies>
191 <Policies>
190 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
192 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
191 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
193 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
192 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
194 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
193 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
195 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
194 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
196 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
195 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
197 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
196 <NameConventionPolicy>
198 <NameConventionPolicy>
197 <Rules>
199 <Rules>
198 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
200 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
199 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
201 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
200 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
202 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
201 <RequiredPrefixes>
203 <RequiredPrefixes>
202 <String>I</String>
204 <String>I</String>
203 </RequiredPrefixes>
205 </RequiredPrefixes>
204 </NamingRule>
206 </NamingRule>
205 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
207 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
206 <RequiredSuffixes>
208 <RequiredSuffixes>
207 <String>Attribute</String>
209 <String>Attribute</String>
208 </RequiredSuffixes>
210 </RequiredSuffixes>
209 </NamingRule>
211 </NamingRule>
210 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
212 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
211 <RequiredSuffixes>
213 <RequiredSuffixes>
212 <String>EventArgs</String>
214 <String>EventArgs</String>
213 </RequiredSuffixes>
215 </RequiredSuffixes>
214 </NamingRule>
216 </NamingRule>
215 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
217 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
216 <RequiredSuffixes>
218 <RequiredSuffixes>
217 <String>Exception</String>
219 <String>Exception</String>
218 </RequiredSuffixes>
220 </RequiredSuffixes>
219 </NamingRule>
221 </NamingRule>
220 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
222 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
221 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
223 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
222 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
224 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
223 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
225 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
224 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
226 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
225 <RequiredPrefixes>
227 <RequiredPrefixes>
226 <String>m_</String>
228 <String>m_</String>
227 </RequiredPrefixes>
229 </RequiredPrefixes>
228 </NamingRule>
230 </NamingRule>
229 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
231 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
230 <RequiredPrefixes>
232 <RequiredPrefixes>
231 <String>_</String>
233 <String>_</String>
232 </RequiredPrefixes>
234 </RequiredPrefixes>
233 </NamingRule>
235 </NamingRule>
234 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
236 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
235 <RequiredPrefixes>
237 <RequiredPrefixes>
236 <String>m_</String>
238 <String>m_</String>
237 </RequiredPrefixes>
239 </RequiredPrefixes>
238 </NamingRule>
240 </NamingRule>
239 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
241 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
240 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
242 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
241 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
243 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
242 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
244 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
243 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
245 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
244 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
246 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
245 <RequiredPrefixes>
247 <RequiredPrefixes>
246 <String>T</String>
248 <String>T</String>
247 </RequiredPrefixes>
249 </RequiredPrefixes>
248 </NamingRule>
250 </NamingRule>
249 </Rules>
251 </Rules>
250 </NameConventionPolicy>
252 </NameConventionPolicy>
251 </Policies>
253 </Policies>
252 </Properties>
254 </Properties>
253 </MonoDevelop>
255 </MonoDevelop>
254 </ProjectExtensions>
256 </ProjectExtensions>
257 <ItemGroup>
258 <Folder Include="Components\" />
259 </ItemGroup>
255 </Project> No newline at end of file
260 </Project>
@@ -1,260 +1,258
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.IO;
4 using System.IO;
5 using System.Linq;
5 using Implab.Components;
6 using System.Text;
7 using System.Threading.Tasks;
8
6
9 namespace Implab.Parsing {
7 namespace Implab.Parsing {
10 /// <summary>
8 /// <summary>
11 /// Базовый класс для разбора потока входных символов на токены.
9 /// Базовый класс для разбора потока входных символов на токены.
12 /// </summary>
10 /// </summary>
13 /// <remarks>
11 /// <remarks>
14 /// Сканнер имеет внутри буффер с симолами входного текста, по которому перемещаются два
12 /// Сканнер имеет внутри буффер с симолами входного текста, по которому перемещаются два
15 /// указателя, начала и конца токена, при перемещении искользуется ДКА для определения
13 /// указателя, начала и конца токена, при перемещении искользуется ДКА для определения
16 /// конца токена и допустимости текущего символа.
14 /// конца токена и допустимости текущего символа.
17 /// </remarks>
15 /// </remarks>
18 public abstract class Scanner : Disposable {
16 public abstract class Scanner : Disposable {
19 struct ScannerConfig {
17 struct ScannerConfig {
20 public DFAStateDescriptior[] states;
18 public DFAStateDescriptior[] states;
21 public int[] alphabetMap;
19 public int[] alphabetMap;
22 }
20 }
23
21
24 Stack<ScannerConfig> m_defs = new Stack<ScannerConfig>();
22 Stack<ScannerConfig> m_defs = new Stack<ScannerConfig>();
25
23
26 DFAStateDescriptior[] m_states;
24 DFAStateDescriptior[] m_states;
27 int[] m_alphabetMap;
25 int[] m_alphabetMap;
28
26
29 protected DFAStateDescriptior m_currentState;
27 protected DFAStateDescriptior m_currentState;
30 int m_previewCode;
28 int m_previewCode;
31
29
32 protected int m_tokenLen = 0;
30 protected int m_tokenLen = 0;
33 protected int m_tokenOffset;
31 protected int m_tokenOffset;
34
32
35 protected char[] m_buffer;
33 protected char[] m_buffer;
36 protected int m_bufferSize;
34 protected int m_bufferSize;
37 protected int m_pointer;
35 protected int m_pointer;
38
36
39 TextReader m_reader;
37 TextReader m_reader;
40 bool m_disposeReader;
38 bool m_disposeReader;
41 int m_chunkSize = 1024; // 1k
39 int m_chunkSize = 1024; // 1k
42 int m_limit = 10 * 1024 * 1024; // 10Mb
40 int m_limit = 10 * 1024 * 1024; // 10Mb
43
41
44 protected Scanner(CDFADefinition definition) {
42 protected Scanner(CDFADefinition definition) {
45 Safe.ArgumentNotNull(definition, "definition");
43 Safe.ArgumentNotNull(definition, "definition");
46
44
47 m_states = definition.States;
45 m_states = definition.States;
48 m_alphabetMap = definition.Alphabet.GetTranslationMap();
46 m_alphabetMap = definition.Alphabet.GetTranslationMap();
49
47
50 Feed(new char[0]);
48 Feed(new char[0]);
51 }
49 }
52
50
53 /// <summary>
51 /// <summary>
54 /// Заполняет входными данными буффер.
52 /// Заполняет входными данными буффер.
55 /// </summary>
53 /// </summary>
56 /// <param name="data">Данные для обработки.</param>
54 /// <param name="data">Данные для обработки.</param>
57 /// <remarks>Копирование данных не происходит, переданный массив используется в
55 /// <remarks>Копирование данных не происходит, переданный массив используется в
58 /// качестве входного буффера.</remarks>
56 /// качестве входного буффера.</remarks>
59 public void Feed(char[] data) {
57 public void Feed(char[] data) {
60 Safe.ArgumentNotNull(data, "data");
58 Safe.ArgumentNotNull(data, "data");
61
59
62 Feed(data, data.Length);
60 Feed(data, data.Length);
63 }
61 }
64
62
65 /// <summary>
63 /// <summary>
66 /// Заполняет буффур чтения входными данными.
64 /// Заполняет буффур чтения входными данными.
67 /// </summary>
65 /// </summary>
68 /// <param name="data">Данные для обработки.</param>
66 /// <param name="data">Данные для обработки.</param>
69 /// <param name="length">Длина данных для обработки.</param>
67 /// <param name="length">Длина данных для обработки.</param>
70 /// <remarks>Копирование данных не происходит, переданный массив используется в
68 /// <remarks>Копирование данных не происходит, переданный массив используется в
71 /// качестве входного буффера.</remarks>
69 /// качестве входного буффера.</remarks>
72 public void Feed(char[] data, int length) {
70 public void Feed(char[] data, int length) {
73 Safe.ArgumentNotNull(data, "data");
71 Safe.ArgumentNotNull(data, "data");
74 Safe.ArgumentInRange(length, 0, data.Length, "length");
72 Safe.ArgumentInRange(length, 0, data.Length, "length");
75 AssertNotDisposed();
73 AssertNotDisposed();
76
74
77 m_pointer = -1;
75 m_pointer = -1;
78 m_buffer = data;
76 m_buffer = data;
79 m_bufferSize = length;
77 m_bufferSize = length;
80 Shift();
78 Shift();
81 }
79 }
82
80
83 public void Feed(TextReader reader, bool dispose) {
81 public void Feed(TextReader reader, bool dispose) {
84 Safe.ArgumentNotNull(reader, "reader");
82 Safe.ArgumentNotNull(reader, "reader");
85 AssertNotDisposed();
83 AssertNotDisposed();
86
84
87 if (m_reader != null && m_disposeReader)
85 if (m_reader != null && m_disposeReader)
88 m_reader.Dispose();
86 m_reader.Dispose();
89
87
90 m_reader = reader;
88 m_reader = reader;
91 m_disposeReader = dispose;
89 m_disposeReader = dispose;
92 m_pointer = -1;
90 m_pointer = -1;
93 m_buffer = new char[m_chunkSize];
91 m_buffer = new char[m_chunkSize];
94 m_bufferSize = 0;
92 m_bufferSize = 0;
95 Shift();
93 Shift();
96 }
94 }
97
95
98 /// <summary>
96 /// <summary>
99 /// Получает текущий токен в виде строки.
97 /// Получает текущий токен в виде строки.
100 /// </summary>
98 /// </summary>
101 /// <returns></returns>
99 /// <returns></returns>
102 protected string GetTokenValue() {
100 protected string GetTokenValue() {
103 return new String(m_buffer, m_tokenOffset, m_tokenLen);
101 return new String(m_buffer, m_tokenOffset, m_tokenLen);
104 }
102 }
105
103
106 /// <summary>
104 /// <summary>
107 /// Метки текущего токена, которые были назначены в регулярном выражении.
105 /// Метки текущего токена, которые были назначены в регулярном выражении.
108 /// </summary>
106 /// </summary>
109 protected int[] TokenTags {
107 protected int[] TokenTags {
110 get {
108 get {
111 return m_currentState.tag;
109 return m_currentState.tag;
112 }
110 }
113 }
111 }
114
112
115 /// <summary>
113 /// <summary>
116 /// Признак конца данных
114 /// Признак конца данных
117 /// </summary>
115 /// </summary>
118 public bool EOF {
116 public bool EOF {
119 get {
117 get {
120 return m_pointer >= m_bufferSize;
118 return m_pointer >= m_bufferSize;
121 }
119 }
122 }
120 }
123
121
124 /// <summary>
122 /// <summary>
125 /// Читает следующий токен, при этом <see cref="m_tokenOffset"/> указывает на начало токена,
123 /// Читает следующий токен, при этом <see cref="m_tokenOffset"/> указывает на начало токена,
126 /// <see cref="m_tokenLen"/> на длину токена, <see cref="m_buffer"/> - массив символов, в
124 /// <see cref="m_tokenLen"/> на длину токена, <see cref="m_buffer"/> - массив символов, в
127 /// котором находится токен.
125 /// котором находится токен.
128 /// </summary>
126 /// </summary>
129 /// <returns><c>false</c> - достигнут конец данных, токен не прочитан.</returns>
127 /// <returns><c>false</c> - достигнут конец данных, токен не прочитан.</returns>
130 protected bool ReadTokenInternal() {
128 protected bool ReadTokenInternal() {
131 if (m_pointer >= m_bufferSize)
129 if (m_pointer >= m_bufferSize)
132 return false;
130 return false;
133
131
134 m_currentState = m_states[CDFADefinition.INITIAL_STATE];
132 m_currentState = m_states[CDFADefinition.INITIAL_STATE];
135 m_tokenLen = 0;
133 m_tokenLen = 0;
136 m_tokenOffset = m_pointer;
134 m_tokenOffset = m_pointer;
137 int nextState = CDFADefinition.UNREACHEBLE_STATE;
135 int nextState = CDFADefinition.UNREACHEBLE_STATE;
138 do {
136 do {
139 nextState = m_currentState.transitions[m_previewCode];
137 nextState = m_currentState.transitions[m_previewCode];
140 if (nextState == CDFADefinition.UNREACHEBLE_STATE) {
138 if (nextState == CDFADefinition.UNREACHEBLE_STATE) {
141 if (m_currentState.final)
139 if (m_currentState.final)
142 return true;
140 return true;
143 else
141 else
144 throw new ParserException(
142 throw new ParserException(
145 String.Format(
143 String.Format(
146 "Unexpected symbol '{0}', at pos {1}",
144 "Unexpected symbol '{0}', at pos {1}",
147 m_buffer[m_pointer],
145 m_buffer[m_pointer],
148 Position
146 Position
149 )
147 )
150 );
148 );
151 } else {
149 } else {
152 m_currentState = m_states[nextState];
150 m_currentState = m_states[nextState];
153 m_tokenLen++;
151 m_tokenLen++;
154 }
152 }
155
153
156 } while (Shift());
154 } while (Shift());
157
155
158 // END OF DATA
156 // END OF DATA
159 if (!m_currentState.final)
157 if (!m_currentState.final)
160 throw new ParserException("Unexpected end of data");
158 throw new ParserException("Unexpected end of data");
161
159
162 return true;
160 return true;
163 }
161 }
164
162
165
163
166 bool Shift() {
164 bool Shift() {
167 m_pointer++;
165 m_pointer++;
168
166
169 if (m_pointer >= m_bufferSize) {
167 if (m_pointer >= m_bufferSize) {
170 if (!ReadNextChunk())
168 if (!ReadNextChunk())
171 return false;
169 return false;
172 }
170 }
173
171
174 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
172 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
175
173
176 return true;
174 return true;
177 }
175 }
178
176
179 bool ReadNextChunk() {
177 bool ReadNextChunk() {
180 if (m_reader == null)
178 if (m_reader == null)
181 return false;
179 return false;
182
180
183 // extend buffer if nesessary
181 // extend buffer if nesessary
184 if (m_pointer + m_chunkSize > m_buffer.Length) {
182 if (m_pointer + m_chunkSize > m_buffer.Length) {
185 // trim unused buffer head
183 // trim unused buffer head
186 var size = m_tokenLen + m_chunkSize;
184 var size = m_tokenLen + m_chunkSize;
187 if (size >= m_limit)
185 if (size >= m_limit)
188 throw new ParserException(String.Format("Input buffer {0} bytes limit exceeded", m_limit));
186 throw new ParserException(String.Format("Input buffer {0} bytes limit exceeded", m_limit));
189 var temp = new char[size];
187 var temp = new char[size];
190 Array.Copy(m_buffer, m_tokenOffset, temp, 0, m_tokenLen);
188 Array.Copy(m_buffer, m_tokenOffset, temp, 0, m_tokenLen);
191 m_pointer -= m_tokenOffset;
189 m_pointer -= m_tokenOffset;
192 m_bufferSize -= m_tokenOffset;
190 m_bufferSize -= m_tokenOffset;
193 m_tokenOffset = 0;
191 m_tokenOffset = 0;
194 m_buffer = temp;
192 m_buffer = temp;
195 }
193 }
196
194
197 var read = m_reader.Read(m_buffer, m_tokenLen, m_chunkSize);
195 var read = m_reader.Read(m_buffer, m_tokenLen, m_chunkSize);
198 if (read == 0)
196 if (read == 0)
199 return false;
197 return false;
200
198
201 m_bufferSize += read;
199 m_bufferSize += read;
202
200
203 return true;
201 return true;
204 }
202 }
205
203
206 /// <summary>
204 /// <summary>
207 /// Позиция сканнера во входном буфере
205 /// Позиция сканнера во входном буфере
208 /// </summary>
206 /// </summary>
209 public int Position {
207 public int Position {
210 get {
208 get {
211 return m_pointer + 1;
209 return m_pointer + 1;
212 }
210 }
213 }
211 }
214
212
215 /// <summary>
213 /// <summary>
216 /// Преключает внутренний ДКА на указанный, позволяет реализовать подобие захватывающей
214 /// Преключает внутренний ДКА на указанный, позволяет реализовать подобие захватывающей
217 /// группировки.
215 /// группировки.
218 /// </summary>
216 /// </summary>
219 /// <param name="states">Таблица состояний нового ДКА</param>
217 /// <param name="states">Таблица состояний нового ДКА</param>
220 /// <param name="alphabet">Таблица входных символов для нового ДКА</param>
218 /// <param name="alphabet">Таблица входных символов для нового ДКА</param>
221 protected void Switch(DFAStateDescriptior[] states, int[] alphabet) {
219 protected void Switch(DFAStateDescriptior[] states, int[] alphabet) {
222 Safe.ArgumentNotNull(states, "dfa");
220 Safe.ArgumentNotNull(states, "dfa");
223
221
224 m_defs.Push(new ScannerConfig {
222 m_defs.Push(new ScannerConfig {
225 states = m_states,
223 states = m_states,
226 alphabetMap = m_alphabetMap
224 alphabetMap = m_alphabetMap
227 });
225 });
228
226
229 m_states = states;
227 m_states = states;
230 m_alphabetMap = alphabet;
228 m_alphabetMap = alphabet;
231
229
232 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
230 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
233 }
231 }
234
232
235 /// <summary>
233 /// <summary>
236 /// Восстанавливает предыдущей ДКА сканнера.
234 /// Восстанавливает предыдущей ДКА сканнера.
237 /// </summary>
235 /// </summary>
238 protected void Restore() {
236 protected void Restore() {
239 if (m_defs.Count == 0)
237 if (m_defs.Count == 0)
240 throw new InvalidOperationException();
238 throw new InvalidOperationException();
241 var prev = m_defs.Pop();
239 var prev = m_defs.Pop();
242 m_states = prev.states;
240 m_states = prev.states;
243 m_alphabetMap = prev.alphabetMap;
241 m_alphabetMap = prev.alphabetMap;
244 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
242 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
245 }
243 }
246
244
247 protected override void Dispose(bool disposing) {
245 protected override void Dispose(bool disposing) {
248 if (disposing) {
246 if (disposing) {
249 if (m_reader != null && m_disposeReader)
247 if (m_reader != null && m_disposeReader)
250 m_reader.Dispose();
248 m_reader.Dispose();
251 m_buffer = null;
249 m_buffer = null;
252 m_bufferSize = 0;
250 m_bufferSize = 0;
253 m_pointer = 0;
251 m_pointer = 0;
254 m_tokenLen = 0;
252 m_tokenLen = 0;
255 m_tokenOffset = 0;
253 m_tokenOffset = 0;
256 }
254 }
257 base.Dispose(disposing);
255 base.Dispose(disposing);
258 }
256 }
259 }
257 }
260 }
258 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now