DecoderRegistry.cs 3.56 KB
Newer Older
Anders Blomdell's avatar
Anders Blomdell committed
1
namespace se.lth.control.labcomm2014 {
Anders Nilsson's avatar
Anders Nilsson committed
2
3
4
5

  using System;
  using System.Collections.Generic;

Anders Blomdell's avatar
Anders Blomdell committed
6
  public class DecoderRegistry {
Anders Nilsson's avatar
Anders Nilsson committed
7
8
9

    public class Entry {
    
Anders Blomdell's avatar
Anders Blomdell committed
10
11
      private SampleDispatcher dispatcher;
      private SampleHandler handler;
Anders Nilsson's avatar
Anders Nilsson committed
12
13
14
15
      private int index;
      private String name;
      private byte[] signature;

Anders Blomdell's avatar
Anders Blomdell committed
16
17
      public Entry(SampleDispatcher dispatcher,
		   SampleHandler handler) {
Anders Nilsson's avatar
Anders Nilsson committed
18
19
20
21
22
23
24
25
26
27
28
29
	this.dispatcher = dispatcher;
	this.name = dispatcher.getName();
	this.signature = dispatcher.getSignature();
	this.handler = handler;
      }

      public Entry(int index, String name, byte[] signature) {
	this.index = index;
	this.name = name;
	this.signature = signature;
      }

Anders Blomdell's avatar
Anders Blomdell committed
30
      public SampleDispatcher getSampleDispatcher() {
Anders Nilsson's avatar
Anders Nilsson committed
31
32
33
	return dispatcher;
      }

Anders Blomdell's avatar
Anders Blomdell committed
34
      public void setSampleDispatcher(SampleDispatcher dispatcher) {
Anders Nilsson's avatar
Anders Nilsson committed
35
36
37
	this.dispatcher = dispatcher;
      }

Anders Blomdell's avatar
Anders Blomdell committed
38
      public SampleHandler getHandler() {
Anders Nilsson's avatar
Anders Nilsson committed
39
40
41
	return handler;
      }

Anders Blomdell's avatar
Anders Blomdell committed
42
      public void setHandler(SampleHandler handler) {
Anders Nilsson's avatar
Anders Nilsson committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
	this.handler = handler;
      }

      public String getName() {
	return name;
      }

      public int getIndex() {
	return index;
      }

      public String getSignature() {
	return BitConverter.ToString(signature);
      }

      public void setIndex(int index) {
	if (this.index != 0 && this.index != index) {
	  throw new Exception("Index mismatch " + 
			      this.index + " != " + index);
	}
	this.index = index;
      }

      public bool matchName(String name) {
	return this.name.Equals(name);
      }

      public bool matchSignature(byte[] signature) {
	bool result = this.signature.Length == signature.Length;
	for (int i = 0 ; result && i < signature.Length ; i++) {
	  result = this.signature[i] == signature[i];
	}
	return result;
      }

      public bool match(String name, byte[] signature) {
	return matchName(name) && matchSignature(signature);
      }

      public void check(String name, byte[] signature) {
	if (!matchName(name)) {
	  throw new Exception("Name mismatch '" + 
				this.name + "' != '" + name + "'");
	} 
	if (!matchSignature(signature)) {
	  throw new Exception("Signature mismatch");
	} 
      }
    }

Anders Blomdell's avatar
Anders Blomdell committed
93
    private Dictionary<SampleDispatcher, Entry> byDispatcher;
Anders Nilsson's avatar
Anders Nilsson committed
94
95
    private Dictionary<int, Entry> byIndex;

Anders Blomdell's avatar
Anders Blomdell committed
96
    public DecoderRegistry() {
Anders Blomdell's avatar
Anders Blomdell committed
97
      byDispatcher = new Dictionary<SampleDispatcher, Entry>();
Anders Nilsson's avatar
Anders Nilsson committed
98
99
100
      byIndex = new Dictionary<int, Entry>();
    }

Anders Blomdell's avatar
Anders Blomdell committed
101
102
    public void add(SampleDispatcher dispatcher,
		    SampleHandler handler) {
Anders Nilsson's avatar
Anders Nilsson committed
103
104
      lock(this) {
	Entry e;
Anders Blomdell's avatar
Anders Blomdell committed
105
	byDispatcher.TryGetValue(dispatcher, out e);
Anders Nilsson's avatar
Anders Nilsson committed
106
107
108
109
110
111
	if (e != null) {
	  e.check(dispatcher.getName(), dispatcher.getSignature());
	  e.setHandler(handler);
	} else {
	  foreach (Entry e2 in byIndex.Values) {
	    if (e2.match(dispatcher.getName(), dispatcher.getSignature())) {
Anders Blomdell's avatar
Anders Blomdell committed
112
	      e2.setSampleDispatcher(dispatcher);
Anders Nilsson's avatar
Anders Nilsson committed
113
114
115
116
117
118
119
	      e2.setHandler(handler);
	      e = e2;
	      break;
	    }
	  }
	  if (e == null) {
	    e = new Entry(dispatcher, handler);
Anders Blomdell's avatar
Anders Blomdell committed
120
	    byDispatcher.Add(dispatcher, e);
Anders Nilsson's avatar
Anders Nilsson committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
	  }
	}
      }
    }

    public void add(int index, 
		    String name,
		    byte[] signature) {
      lock(this) {
	Entry e;
	byIndex.TryGetValue(index, out e);
	if (e != null) {
	  e.check(name, signature);
	} else {
Anders Blomdell's avatar
Anders Blomdell committed
135
	  foreach (Entry e2 in byDispatcher.Values) {
Anders Nilsson's avatar
Anders Nilsson committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	    if (e2.match(name, signature)) {
	      e2.setIndex(index);
	      e = e2;
	      break;
	    }
	  }
	  if (e == null) {
	    e = new Entry(index, name, signature);
	  }
	  byIndex.Add(index, e);
	}
      }
    }
    
    public Entry get(int index) {
      lock(this) {
	Entry result;
	byIndex.TryGetValue(index, out result);
	return result;
      }
    }

  }

}