Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ChunkCounter.cs
1using System;
2using System.Text;
3using System.Text.RegularExpressions;
4using System.Threading.Tasks;
7
9{
10 internal class ChunkCounter : IDisposable
11 {
12 private readonly Cache<string, Rec> streams;
13 private readonly CommunicationLayer comLayer;
14 private readonly bool receiving;
15 private readonly bool cacheE2e;
16
17 public ChunkCounter(bool Receiving, CommunicationLayer ComLayer, bool CacheE2e)
18 {
19 this.receiving = Receiving;
20 this.comLayer = ComLayer;
21 this.cacheE2e = CacheE2e;
22
23 this.streams = new Cache<string, Rec>(int.MaxValue, new TimeSpan(0, 0, 10), new TimeSpan(0, 0, 2), true);
24 this.streams.Removed += this.Streams_Removed;
25 }
26
27 public Task Client_OnDisposed(object Sender, EventArgs e)
28 {
29 this.Dispose();
30 return Task.CompletedTask;
31 }
32
33 public void Dispose()
34 {
35 }
36
37 private class Rec
38 {
39 public string StreamId;
40 public int NrChunks = 0;
41 public long NrBytes = 0;
42 public bool Complete = false;
43 public bool E2e;
44
45 public Rec(string StreamId, bool E2e)
46 {
47 this.StreamId = StreamId;
48 this.E2e = E2e;
49 }
50 }
51
52 private static readonly Regex chunk = new Regex("<(?'Tag'chunk)\\s+(((nr=['\"](?'Nr'\\d+)['\"])|(streamId=['\"](?'StreamId'[^'\"]+)['\"])|(last=['\"](?'Last'(true|false))['\"])|(xmlns=['\"](?'Namespace'[^'\"]+)['\"]))\\s*)+>(?'Base64'[^<]*)</chunk>", RegexOptions.Compiled | RegexOptions.Singleline);
53
54 public Task<string> RemoveChunkMessage(string Text)
55 {
56 if (Text == "ChunkReceived")
57 Text = string.Empty;
58
59 return Task.FromResult(Text);
60 }
61
62 public Task<string> ShortenChunks(string Text)
63 {
64 Match M;
65
66 if (Text.IndexOf("<chunk") >= 0 && (M = chunk.Match(Text)).Success)
67 {
68 string Tag = M.Groups["Tag"].Value;
69 string Namespace = M.Groups["Namespace"].Value;
70
71 if (Tag == "chunk")
72 {
73 if (Namespace != "urn:xmpp:http")
74 return Task.FromResult(Text);
75 }
76 else
77 return Task.FromResult(Text);
78
79 string StreamId = M.Groups["StreamId"].Value;
80 bool Last = M.Groups["Last"].Value == "true";
81 string Base64 = M.Groups["Base64"].Value;
82 byte[] Data;
83
84 try
85 {
86 Data = Convert.FromBase64String(Base64);
87 }
88 catch (Exception)
89 {
90 return Task.FromResult(Text);
91 }
92
93 int NrBytes = Data.Length;
94
95 if (!this.streams.TryGetValue(StreamId, out Rec Rec))
96 {
97 Rec = new Rec(StreamId, false);
98 this.streams.Add(StreamId, Rec);
99 }
100
101 Rec.NrChunks++;
102 Rec.NrBytes += NrBytes;
103
104 if (Last)
105 {
106 Rec.Complete = true;
107 this.streams.Remove(StreamId);
108 }
109
110 Text = string.Empty;
111 return Task.FromResult(Text);
112 }
113
114 int i = Text.IndexOf("<resp ");
115 if (i >= 0)
116 {
117 i = Text.IndexOf("<data><base64>", i + 6);
118 if (i < 0)
119 return Task.FromResult(Text);
120
121 i += 14;
122
123 int j = Text.IndexOf("</base64></data>", i);
124 if (j < 0)
125 return Task.FromResult(Text);
126
127 string Base64 = Text.Substring(i, j - i);
128 byte[] Data;
129
130 try
131 {
132 Data = Convert.FromBase64String(Base64);
133 }
134 catch (Exception)
135 {
136 return Task.FromResult(Text);
137 }
138
139 Text = Text.Substring(0, i) + "(" + Data.Length.ToString() + " bytes)" + Text.Substring(j);
140 }
141
142 return Task.FromResult(Text);
143 }
144
145 private async Task Streams_Removed(object Sender, CacheItemEventArgs<string, Rec> e)
146 {
147 if (this.comLayer.HasSniffers)
148 {
149 StringBuilder sb = new StringBuilder();
150 Rec Rec = e.Value;
151
152 if (Rec.E2e)
153 {
154 sb.Append("(");
155 sb.Append(Rec.NrChunks.ToString());
156 sb.Append(" stanzas containing ");
157 sb.Append(Rec.NrBytes.ToString());
158 sb.Append(" cipher bytes");
159
160 if (this.receiving)
161 sb.Append(" received from ");
162 else
163 sb.Append(" transmitted to ");
164
165 sb.Append(Rec.StreamId);
166 sb.Append(".)");
167 }
168 else
169 {
170 sb.Append("(");
171 sb.Append(Rec.NrChunks.ToString());
172 sb.Append(" chunks containing ");
173 sb.Append(Rec.NrBytes.ToString());
174 sb.Append(" bytes pertaining to stream ");
175 sb.Append(Rec.StreamId);
176
177 if (this.receiving)
178 sb.Append(" received.");
179 else
180 sb.Append(" transmitted.");
181
182 if (e.Value.Complete)
183 sb.Append(" Transfer completed.");
184
185 sb.Append(")");
186 }
187
188 if (this.comLayer.HasSniffers)
189 await this.comLayer.Information(sb.ToString());
190 }
191 }
192
193 }
194}
Simple base class for classes implementing communication protocols.
Implements an in-memory cache.
Definition: Cache.cs:15
Event arguments for cache item removal events.
ValueType Value
Value of item that was removed.