source: uKadecot/trunk/tools/EcnlControllerUI/EcnlControllerUI/ValueRange.cs@ 108

Last change on this file since 108 was 108, checked in by coas-nagasima, 9 years ago

MIMEプロパティの変更

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 20.2 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2015 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id: ValueRange.cs 108 2015-06-11 09:15:46Z coas-nagasima $
36 */
37
38using System;
39using System.Collections.Generic;
40using System.Text.RegularExpressions;
41
42namespace ctrlui
43{
44 enum TokenType
45 {
46 Separetor,
47 HexValue,
48 Numeric,
49 String,
50 End,
51 };
52
53 class TokenInfo
54 {
55 public string Token;
56 public TokenType Type;
57 public static string Separetor = @"[=,:\(\)\[\]~]";
58 public static string HexValue = "^0x[0-9A-Fa-f]+";
59 public static string Numeric = @"^[\-\+]?[\.]?[0-9]+[0-9,\.]*";
60
61 public TokenInfo(string token, TokenType type)
62 {
63 Token = token;
64 Type = type;
65 }
66
67 public override string ToString()
68 {
69 return Token;
70 }
71
72 public int ToInt32()
73 {
74 switch (Type) {
75 case TokenType.HexValue:
76 return Int32.Parse(Token.Substring(2)/*0xの削除*/, 16);
77 case TokenType.Numeric:
78 return Int32.Parse(Token);
79 default:
80 return 0;
81 }
82 }
83
84 public long ToInt64(string typeName)
85 {
86 string temp;
87
88 switch (Type) {
89 case TokenType.HexValue:
90 temp = Token.Substring(2)/*0xの削除*/;
91 return Int32.Parse(temp, 16);
92 case TokenType.Numeric:
93 return Int32.Parse(Token);
94 default:
95 return 0;
96 }
97 }
98 }
99
100 enum State
101 {
102 Value,
103 EqualOrRange,
104 Description,
105 UnitOrCommaOrEnd,
106 RengeMax,
107 StartParenthesis,
108 RangeDescription,
109 MinDescription,
110 RangeSeparetor,
111 MaxDescription,
112 EndParenthesis,
113 CommaOrEnd,
114 BitFieldLSB,
115 BitRange,
116 BitFieldMSB,
117 BitFieldDescription,
118 BitRangeEnd,
119 Colon,
120 }
121
122 public abstract class Value
123 {
124 public abstract string Disp { get; }
125 public abstract string GetInitialValue();
126 }
127
128 public class Option : Value
129 {
130 private long _Val;
131 private string _Disp;
132
133 public Option(long val, string disp)
134 {
135 _Val = val;
136 _Disp = disp;
137 }
138
139 public long Val { get { return _Val; } }
140 public override string Disp { get { return _Disp; } }
141
142 public override string GetInitialValue()
143 {
144 return _Val.ToString(16).ToUpper();
145 }
146 }
147
148 public class Range : Value
149 {
150 private long _Min;
151 private long _Max;
152 private string _Disp;
153 private string _MinDisp;
154 private string _MaxDisp;
155 private string _Unit;
156 private long _InitialValue;
157
158 public Range(long min, long max, string disp)
159 {
160 _Min = min;
161 _Max = max;
162 _Disp = disp;
163 _MinDisp = "";
164 _MaxDisp = "";
165 _Unit = "";
166 _InitialValue = min;
167 }
168
169 public Range(long min, long max, string disp, string minDisp, string maxDisp, string unit)
170 {
171 _Min = min;
172 _Max = max;
173 _Disp = disp;
174 _MinDisp = minDisp;
175 _MaxDisp = maxDisp;
176 _Unit = unit;
177 _InitialValue = min;
178 }
179
180 public long Min { get { return _Min; } }
181 public long Max { get { return _Max; } }
182 public override string Disp { get { return _Disp; } }
183 public string MinDisp { get { return _MinDisp; } }
184 public string MaxDisp { get { return _MaxDisp; } }
185 public string Unit { get { return _Unit; } }
186 public long InitialValue
187 {
188 get { return _InitialValue; }
189 set { _InitialValue = value; }
190 }
191
192 public override string GetInitialValue()
193 {
194 return _InitialValue.ToString(16).ToUpper();
195 }
196
197 public string GetDisp(long value)
198 {
199 return _Disp + value.ToString() + _Unit;
200 }
201 }
202
203 public class InRangeValue : Value
204 {
205 private Range _Range;
206 private long _Value;
207
208 public InRangeValue(Range range, long value)
209 {
210 _Range = range;
211 _Value = value;
212 }
213
214 public Range Range { get { return _Range; } }
215 public long Value { get { return _Value; } }
216 public override string Disp { get { return _Range.GetDisp(_Value); } }
217
218 public override string GetInitialValue()
219 {
220 return _Value.ToString(16).ToUpper();
221 }
222 }
223
224 public class BitField : Value
225 {
226 private int _Least;
227 private int _Most;
228 private string _Disp;
229 private List<Option> _Values = new List<Option>();
230 private List<Range> _Ranges = new List<Range>();
231 private Value _InitailValue;
232
233 public BitField(int least, int most, string disp)
234 {
235 _Least = least;
236 _Most = most;
237 _Disp = disp;
238 }
239
240 public int Least { get { return _Least; } }
241 public int Most { get { return _Most; } }
242 public override string Disp { get { return _Disp; } }
243 public List<Option> Values { get { return _Values; } }
244 public List<Range> Ranges { get { return _Ranges; } }
245 public Value InitailValue { get { return _InitailValue; } }
246
247 public override string GetInitialValue()
248 {
249 if (_InitailValue == null)
250 return "";
251 return _InitailValue.GetInitialValue();
252 }
253
254 internal void AddValue(Option option)
255 {
256 if (_InitailValue == null)
257 _InitailValue = option;
258 _Values.Add(option);
259 }
260
261 internal void AddRange(Range range)
262 {
263 if (_InitailValue == null)
264 _InitailValue = range;
265 _Ranges.Add(range);
266 }
267
268 internal bool IsInRange(long val64)
269 {
270 foreach (var val in _Values) {
271 if (val.Val != val64)
272 continue;
273
274 return true;
275 }
276
277 foreach (var rng in _Ranges) {
278 if ((rng.Min > val64) || (rng.Max < val64))
279 continue;
280
281 return true;
282 }
283
284 return false;
285 }
286
287 internal Value GetInRangeValue(long val64)
288 {
289 foreach (var val in _Values) {
290 if (val.Val != val64)
291 continue;
292
293 return val;
294 }
295
296 foreach (var rng in _Ranges) {
297 if ((rng.Min > val64) || (rng.Max < val64))
298 continue;
299
300 return new InRangeValue(rng, val64);
301 }
302
303 return null;
304 }
305 }
306
307 public class BitFiledsValue : Value
308 {
309 private BitField[] _BitFields;
310 private Value[] _BitFieldValues;
311 private long _Value;
312
313 public BitFiledsValue(BitField[] bitFlds, Value[] bitFldVals, long value)
314 {
315 _BitFields = bitFlds;
316 _BitFieldValues = bitFldVals;
317 _Value = value;
318 }
319
320 public override string Disp
321 {
322 get { return ""; }
323 }
324
325 public override string GetInitialValue()
326 {
327 return _Value.ToString(16).ToUpper();
328 }
329 }
330
331 class ValueSet
332 {
333 public List<Option> values;
334 public List<Range> ranges;
335 public BitField bitField;
336 public Value initialValue;
337
338 public ValueSet(List<Option> values, List<Range> ranges, BitField bitField, Value initialValue)
339 {
340 this.values = values;
341 this.ranges = ranges;
342 this.bitField = bitField;
343 this.initialValue = initialValue;
344 }
345 }
346
347 public class ValueRange
348 {
349 private List<Option> _Values = new List<Option>();
350 private List<Range> _Ranges = new List<Range>();
351 private List<BitField> _BitFields = new List<BitField>();
352 private List<ValueRange> _MemberFields = new List<ValueRange>();
353 private Value _InitailValue;
354 static Dictionary<string, ValueSet> _ParsedText = new Dictionary<string, ValueSet>();
355
356 public List<Option> Values { get { return _Values; } }
357 public List<Range> Ranges { get { return _Ranges; } }
358 public List<BitField> BitFields { get { return _BitFields; } }
359 public List<ValueRange> MemberFields { get { return _MemberFields; } }
360
361 public string InitailValue
362 {
363 get
364 {
365 if (_InitailValue == null)
366 return "";
367 return _InitailValue.GetInitialValue();
368 }
369 set
370 {
371 int val64 = Int32.Parse(value);
372 foreach (var val in _Values) {
373 if (val.Val != val64)
374 continue;
375
376 _InitailValue = val;
377 return;
378 }
379
380 foreach (var rng in _Ranges) {
381 if ((rng.Min > val64) || (rng.Max < val64))
382 continue;
383
384 _InitailValue = new InRangeValue(rng, val64);
385 return;
386 }
387
388 if (_BitFields.Count > 0) {
389 bool ok = true;
390 List<Value> bitFlds = new List<Value>();
391 foreach (var bit in _BitFields) {
392 if (!bit.IsInRange(val64)) {
393 ok = false;
394 break;
395 }
396
397 bitFlds.Add(bit.GetInRangeValue(val64));
398 }
399
400 if (ok) {
401 _InitailValue = new BitFiledsValue(_BitFields.ToArray(), bitFlds.ToArray(), val64);
402 return;
403 }
404 }
405 }
406 }
407
408 private static bool ParseValueRange(string input, string type, List<Option> values, List<Range> ranges,
409 out BitField bitFeild, out Value initialValue)
410 {
411 bitFeild = null;
412 initialValue = null;
413
414 List<TokenInfo> tokens = new List<TokenInfo>();
415 int pos = 0;
416 while (pos < input.Length) {
417 Regex ms;
418 RegexMatch m;
419 if ((m = (ms = new Regex(TokenInfo.HexValue)).Exec(input.Substring(pos))) != null) {
420 tokens.Add(new TokenInfo(m[0], TokenType.HexValue));
421 pos += m[0].Length;
422 }
423 else if ((m = (ms = new Regex(TokenInfo.Numeric)).Exec(input.Substring(pos))) != null) {
424 tokens.Add(new TokenInfo(m[0], TokenType.Numeric));
425 pos += m[0].Length;
426 }
427 else {
428 if ((m = (ms = new Regex(TokenInfo.Separetor)).Exec(input.Substring(pos))) == null) {
429 tokens.Add(new TokenInfo(input.Substring(pos), TokenType.String));
430 break;
431 }
432 int index = pos + m.Index;
433 if (index == pos) {
434 tokens.Add(new TokenInfo(m[0], TokenType.Separetor));
435 pos += 1;
436 }
437 else {
438 tokens.Add(new TokenInfo(input.Substring(pos, index - pos), TokenType.String));
439 tokens.Add(new TokenInfo(m[0], TokenType.Separetor));
440 pos = index + 1;
441 }
442 }
443 }
444 tokens.Add(new TokenInfo("", TokenType.End));
445
446 bool OK = false;
447 List<TokenInfo> sentence = new List<TokenInfo>();
448 State state = State.Value;
449 foreach (TokenInfo token in tokens) {
450 switch (state) {
451 case State.Value:
452 if ((token.Type == TokenType.HexValue)
453 || (token.Type == TokenType.Numeric)) {
454 sentence.Add(token);
455 state = State.EqualOrRange;
456 continue;
457 }
458 else if ((token.Type == TokenType.Separetor)
459 && (token.Token == "[")) {
460 if (bitFeild != null)
461 break;
462 state = State.BitFieldLSB;
463 continue;
464 }
465 break;
466 case State.EqualOrRange:
467 if (token.Type == TokenType.Separetor) {
468 switch (token.Token) {
469 case "=":
470 state = State.Description;
471 continue;
472 case "~":
473 state = State.RengeMax;
474 continue;
475 }
476 }
477 else if (token.Type == TokenType.End) {
478 Option option = new Option(sentence[0].ToInt64(type), "固定");
479 if (bitFeild != null)
480 bitFeild.AddValue(option);
481 else {
482 if (initialValue == null)
483 initialValue = option;
484 values.Add(option);
485 }
486 sentence.Clear();
487 state = State.CommaOrEnd;
488 continue;
489 }
490 break;
491 case State.Description:
492 if (token.Type == TokenType.String) {
493 Option option = new Option(sentence[0].ToInt64(type), token.Token);
494 if (bitFeild != null)
495 bitFeild.AddValue(option);
496 else {
497 if (initialValue == null)
498 initialValue = option;
499 values.Add(option);
500 }
501 sentence.Clear();
502 state = State.CommaOrEnd;
503 continue;
504 }
505 else if (token.Type == TokenType.Numeric) {
506 sentence.Add(token);
507 state = State.UnitOrCommaOrEnd;
508 continue;
509 }
510 break;
511 case State.UnitOrCommaOrEnd:
512 if (token.Type == TokenType.String) {
513 Option option = new Option(sentence[0].ToInt64(type), sentence[1].Token + token.Token);
514 if (bitFeild != null)
515 bitFeild.AddValue(option);
516 else {
517 if (initialValue == null)
518 initialValue = option;
519 values.Add(option);
520 }
521 sentence.Clear();
522 state = State.CommaOrEnd;
523 continue;
524 }
525 else if ((token.Type == TokenType.Separetor)
526 && (token.Token == ",")) {
527 Option option = new Option(sentence[0].ToInt64(type), sentence[1].Token);
528 if (bitFeild != null)
529 bitFeild.AddValue(option);
530 else {
531 if (initialValue == null)
532 initialValue = option;
533 values.Add(option);
534 }
535 sentence.Clear();
536 state = State.Value;
537 continue;
538 }
539 else if (token.Type == TokenType.End) {
540 Option option = new Option(sentence[0].ToInt64(type), sentence[1].Token);
541 if (bitFeild != null)
542 bitFeild.AddValue(option);
543 else {
544 if (initialValue == null)
545 initialValue = option;
546 values.Add(option);
547 }
548 sentence.Clear();
549 OK = true;
550 }
551 break;
552 case State.RengeMax:
553 if ((token.Type == TokenType.HexValue)
554 || (token.Type == TokenType.Numeric)) {
555 sentence.Add(token);
556 state = State.StartParenthesis;
557 continue;
558 }
559 else if ((token.Type == TokenType.Separetor)
560 && (token.Token == "=")) {
561 string max = "0x";
562 for (int i = sentence[0].Token.Length - 2; i > 0; i--) {
563 max += "F";
564 }
565 sentence.Add(new TokenInfo(max, TokenType.HexValue));
566 state = State.RangeDescription;
567 continue;
568 }
569 break;
570 case State.StartParenthesis:
571 if (token.Type == TokenType.Separetor) {
572 switch (token.Token) {
573 case "=":
574 if (sentence.Count == 2) {
575 state = State.RangeDescription;
576 continue;
577 }
578 break;
579 case "(":
580 sentence.Add(new TokenInfo("", TokenType.String));
581 state = State.MinDescription;
582 continue;
583 case ",":
584 Range range = new Range(sentence[0].ToInt64(type), sentence[1].ToInt64(type), (sentence.Count > 2) ? sentence[2].Token : "");
585 if (bitFeild != null) {
586 bitFeild.AddRange(range);
587 }
588 else {
589 if (initialValue == null)
590 initialValue = range;
591 ranges.Add(range);
592 }
593 sentence.Clear();
594 state = State.Value;
595 continue;
596 }
597 }
598 else if (token.Type == TokenType.End) {
599 Range range = new Range(sentence[0].ToInt64(type), sentence[1].ToInt64(type), (sentence.Count > 2) ? sentence[2].Token : "");
600 if (bitFeild != null) {
601 bitFeild.AddRange(range);
602 }
603 else {
604 if (initialValue == null)
605 initialValue = range;
606 ranges.Add(range);
607 }
608 sentence.Clear();
609 OK = true;
610 }
611 break;
612 case State.RangeDescription:
613 if (token.Type == TokenType.String) {
614 sentence.Add(token);
615 state = State.StartParenthesis;
616 continue;
617 }
618 break;
619 case State.MinDescription:
620 if ((token.Type == TokenType.Numeric)
621 || (token.Type == TokenType.String)) {
622 sentence.Add(token);
623 state = State.RangeSeparetor;
624 continue;
625 }
626 break;
627 case State.RangeSeparetor:
628 if ((token.Type == TokenType.Separetor)
629 && (token.Token == "~")) {
630 state = State.MaxDescription;
631 continue;
632 }
633 break;
634 case State.MaxDescription:
635 if ((token.Type == TokenType.Numeric)
636 || (token.Type == TokenType.String)) {
637 sentence.Add(token);
638 state = State.EndParenthesis;
639 continue;
640 }
641 break;
642 case State.EndParenthesis:
643 if ((token.Type == TokenType.Separetor)
644 && (token.Token == ")")) {
645 Range range = new Range(
646 sentence[0].ToInt64(type),
647 sentence[1].ToInt64(type),
648 sentence[2].Token,
649 sentence[3].Token,
650 sentence[4].Token,
651 (sentence.Count > 5) ? sentence[5].Token : "");
652 if (bitFeild != null) {
653 bitFeild.AddRange(range);
654 }
655 else {
656 if (initialValue == null)
657 initialValue = range;
658 ranges.Add(range);
659 }
660 sentence.Clear();
661 state = State.CommaOrEnd;
662 continue;
663 }
664 else if (token.Type == TokenType.String) {
665 sentence.Add(token);
666 state = State.EndParenthesis;
667 continue;
668 }
669 break;
670 case State.BitFieldLSB:
671 if (token.Type == TokenType.Numeric) {
672 sentence.Add(token);
673 state = State.BitRange;
674 continue;
675 }
676 break;
677 case State.BitRange:
678 if (token.Type == TokenType.Separetor) {
679 switch (token.Token) {
680 case "~":
681 state = State.BitFieldMSB;
682 continue;
683 case "]":
684 sentence.Add(sentence[0]);
685 state = State.BitFieldDescription;
686 continue;
687 }
688 }
689 break;
690 case State.BitFieldMSB:
691 if (token.Type == TokenType.Numeric) {
692 sentence.Add(token);
693 state = State.BitRangeEnd;
694 continue;
695 }
696 break;
697 case State.BitRangeEnd:
698 if ((token.Type == TokenType.Separetor)
699 && (token.Token == "]")) {
700 state = State.BitFieldDescription;
701 continue;
702 }
703 break;
704 case State.BitFieldDescription:
705 if (token.Type == TokenType.String) {
706 sentence.Add(token);
707 state = State.Colon;
708 continue;
709 }
710 break;
711 case State.Colon:
712 if ((token.Type == TokenType.Separetor)
713 && (token.Token == ":")) {
714 bitFeild = new BitField(sentence[0].ToInt32(), sentence[1].ToInt32(), sentence[2].Token);
715 if (initialValue == null)
716 initialValue = bitFeild;
717 sentence.Clear();
718 state = State.Value;
719 continue;
720 }
721 else if (token.Type == TokenType.End) {
722 bitFeild = new BitField(sentence[0].ToInt32(), sentence[1].ToInt32(), sentence[2].Token);
723 if (initialValue == null)
724 initialValue = bitFeild;
725 sentence.Clear();
726 OK = true;
727 break;
728 }
729 break;
730 case State.CommaOrEnd:
731 if (token.Type == TokenType.End) {
732 OK = true;
733 }
734 else if ((token.Type == TokenType.Separetor)
735 && (token.Token == ",")) {
736 state = State.Value;
737 continue;
738 }
739 break;
740 }
741 break;
742 }
743
744 return OK;
745 }
746
747 public static ValueRange Parse(string valrng, JsonFieldInfo emti)
748 {
749 ValueRange valueRange = new ValueRange();
750
751 if (emti.primitive) {
752 string[] lines = valrng.Split(new Regex("\r\n"));
753 foreach (string line in lines) {
754 if (new Regex("^<(.+)>$").Test(line))
755 continue;
756
757 List<Option> values;
758 List<Range> ranges;
759 BitField bitField;
760 Value initialValue;
761
762 ValueSet pair;
763 if (_ParsedText.TryGetValue(line, out pair)) {
764 values = pair.values;
765 ranges = pair.ranges;
766 bitField = pair.bitField;
767 initialValue = pair.initialValue;
768 }
769 else {
770 values = new List<Option>();
771 ranges = new List<Range>();
772
773 ParseValueRange(line, emti.type, values, ranges, out bitField, out initialValue);
774
775 _ParsedText.Add(line, new ValueSet(values, ranges, bitField, initialValue));
776 }
777
778 valueRange._Values.AddRange(values);
779 valueRange._Ranges.AddRange(ranges);
780 if (bitField != null)
781 valueRange._BitFields.Add(bitField);
782 if (valueRange._InitailValue == null)
783 valueRange._InitailValue = initialValue;
784 }
785 }
786 else {
787 foreach (JsonFieldInfo efi in emti.fields) {
788 ValueRange member = Parse(efi.valueDescription, efi);
789 valueRange._MemberFields.Add(member);
790 }
791 }
792
793 return valueRange;
794 }
795 }
796}
Note: See TracBrowser for help on using the repository browser.