Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
TSV.cs
1using System;
2using System.Text;
7
8namespace Waher.Content
9{
13 public static class TSV
14 {
15 #region Encoding/Decoding
16
22 public static string[][] Parse(string Tsv)
23 {
24 int Pos = 0;
25 int Len = Tsv.Length;
26 string[][] Result = Parse(Tsv, ref Pos, Len);
27 char ch;
28
29 while (Pos < Len && ((ch = Tsv[Pos]) <= ' ' || ch == 160))
30 Pos++;
31
32 if (Pos < Len)
33 throw new Exception("Unexpected content at end of string.");
34
35 return Result;
36 }
37
38 private static string[][] Parse(string Tsv, ref int Pos, int Len)
39 {
42 StringBuilder sb = new StringBuilder();
43 int State = 0;
44 int i = 0;
45 char ch;
46 bool sbEmpty = true;
47
48 while (Pos < Len)
49 {
50 ch = Tsv[Pos++];
51 switch (State)
52 {
53 case 0:
54 if (ch == '"')
55 State += 2;
56 else if (ch == '\t')
57 Fields.Add(string.Empty);
58 else if (ch == '\r' || ch == '\n')
59 {
60 if (Fields.Count > 0)
61 {
62 Records.Add(Fields.ToArray());
63 Fields.Clear();
64 }
65 }
66 else
67 {
68 sb.Append(ch);
69 sbEmpty = false;
70 State++;
71 }
72 break;
73
74 case 1: // Undelimited string
75 if (ch == '\t')
76 {
77 Fields.Add(sb.ToString());
78 sb.Clear();
79 sbEmpty = true;
80 State = 0;
81 }
82 else if (ch == '\r' || ch == '\n')
83 {
84 Fields.Add(sb.ToString());
85 sb.Clear();
86 sbEmpty = true;
87 State = 0;
88
89 Records.Add(Fields.ToArray());
90 Fields.Clear();
91 }
92 else
93 {
94 sb.Append(ch);
95 sbEmpty = false;
96 }
97 break;
98
99 case 2: // String.
100 if (ch == '\\')
101 State++;
102 else if (ch == '"')
103 State--;
104 else
105 {
106 sb.Append(ch);
107 sbEmpty = false;
108 }
109 break;
110
111 case 3: // String, escaped character.
112 switch (ch)
113 {
114 case 'a':
115 sb.Append('\a');
116 break;
117
118 case 'b':
119 sb.Append('\b');
120 break;
121
122 case 'f':
123 sb.Append('\f');
124 break;
125
126 case 'n':
127 sb.Append('\n');
128 break;
129
130 case 'r':
131 sb.Append('\r');
132 break;
133
134 case 't':
135 sb.Append('\t');
136 break;
137
138 case 'v':
139 sb.Append('\v');
140 break;
141
142 case 'x':
143 i = 0;
144 State += 4;
145 break;
146
147 case 'u':
148 i = 0;
149 State += 2;
150 break;
151
152 default:
153 sb.Append(ch);
154 break;
155 }
156
157 sbEmpty = false;
158 State--;
159 break;
160
161 case 4: // hex digit 1(4)
162 i = JSON.HexDigit(ch);
163 State++;
164 break;
165
166 case 5: // hex digit 2(4)
167 i <<= 4;
168 i |= JSON.HexDigit(ch);
169 State++;
170 break;
171
172 case 6: // hex digit 3(4)
173 i <<= 4;
174 i |= JSON.HexDigit(ch);
175 State++;
176 break;
177
178 case 7: // hex digit 4(4)
179 i <<= 4;
180 i |= JSON.HexDigit(ch);
181 sb.Append((char)i);
182 sbEmpty = false;
183 State -= 5;
184 break;
185 }
186 }
187
188 if (!sbEmpty)
189 Fields.Add(sb.ToString());
190
191 if (Fields.Count > 0)
192 Records.Add(Fields.ToArray());
193
194 return Records.ToArray();
195 }
196
202 public static string Encode(string[][] Records)
203 {
204 return Encode(Records, true);
205 }
206
214 public static string Encode(string[][] Records, bool QuoteIllegalCharacters)
215 {
216 StringBuilder sb = new StringBuilder();
217 bool First;
218
219 foreach (string[] Record in Records)
220 {
221 First = true;
222
223 foreach (string Field in Record)
224 {
225 bool Tab = false;
226 bool Control = false;
227 bool Quote = false;
228
229 if (First)
230 First = false;
231 else
232 sb.Append('\t');
233
234 if (Field is null)
235 continue;
236
237 foreach (char ch in Field)
238 {
239 if (ch == '\t' && QuoteIllegalCharacters)
240 Tab = true;
241 else if (ch == '"' && QuoteIllegalCharacters)
242 Quote = true;
243 else if (ch < ' ')
244 {
245 if (!QuoteIllegalCharacters)
246 throw new InvalidOperationException("String is not properly quoted.");
247
248 Control = true;
249 }
250 }
251
252 if (Tab || Quote || Control)
253 {
254 string Escaped = Field;
255
256 if (Quote)
257 Escaped = Escaped.Replace("\"", "\\\"");
258
259 if (Control)
260 {
261 Escaped = Escaped.
262 Replace("\a", "\\a").
263 Replace("\b", "\\b").
264 Replace("\f", "\\f").
265 Replace("\n", "\\n").
266 Replace("\r", "\\r").
267 Replace("\t", "\\t").
268 Replace("\v", "\\v");
269 }
270
271 sb.Append('"');
272 sb.Append(Escaped);
273 sb.Append('"');
274 }
275 else
276 sb.Append(Field);
277 }
278
279 sb.AppendLine();
280 }
281
282 return sb.ToString();
283 }
284
290 public static string Encode(IMatrix Matrix)
291 {
292 return Encode(Matrix, (E) =>
293 {
294 if (E.AssociatedObjectValue is string s)
295 return s;
296 else if (E.AssociatedObjectValue is double d)
297 return CommonTypes.Encode(d);
298 else
299 return ScriptNode.ToString(E);
300 }, true);
301 }
302
311 public static string Encode(IMatrix Matrix, ToString ElementToString, bool QuoteIllegalCharacters)
312 {
313 if (ElementToString is null)
314 throw new ArgumentNullException(nameof(ElementToString));
315
318
319 if (Matrix is ObjectMatrix M)
320 {
321 if (!(M.ColumnNames is null))
322 Records.Add(M.ColumnNames);
323 }
324
325 int Row, NrRows = Matrix.Rows;
326 int Column, NrColumns = Matrix.Columns;
327
328 for (Row = 0; Row < NrRows; Row++)
329 {
330 for (Column = 0; Column < NrColumns; Column++)
331 Fields.Add(ElementToString(Matrix.GetElement(Column, Row)));
332
333 Records.Add(Fields.ToArray());
334 Fields.Clear();
335 }
336
337 return Encode(Records.ToArray(), QuoteIllegalCharacters);
338 }
339
340 #endregion
341 }
342}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:15
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Definition: CommonTypes.cs:596
Helps with common TSV-related tasks. (TSV=TAB Separated Values)
Definition: TSV.cs:14
static string Encode(string[][] Records)
Encodes records as a Comma-separated values string.
Definition: TSV.cs:202
static string Encode(IMatrix Matrix, ToString ElementToString, bool QuoteIllegalCharacters)
Encodes a matrix as a Comma-separated values string.
Definition: TSV.cs:311
static string Encode(string[][] Records, bool QuoteIllegalCharacters)
Encodes records as a Comma-separated values string.
Definition: TSV.cs:214
static string[][] Parse(string Tsv)
Parses a TSV string.
Definition: TSV.cs:22
static string Encode(IMatrix Matrix)
Encodes a matrix as a Comma-separated values string.
Definition: TSV.cs:290
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
void Clear()
Clears the collection.
Definition: ChunkedList.cs:306
int Count
Number of elements in collection.
Definition: ChunkedList.cs:68
void Add(T Item)
Adds an item to the collection.
Definition: ChunkedList.cs:272
T[] ToArray()
Returns an array containing all elements of the collection.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
override string ToString()
Definition: ScriptNode.cs:359
Basic interface for matrices.
Definition: IMatrix.cs:7
IElement GetElement(int Column, int Row)
Gets an element of the matrix.
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.