Mercurial > pub > ImplabNet
comparison Implab/JSON/StringTranslator.cs @ 55:c0bf853aa04f
Added initial JSON support
+JSONParser
+JSONWriter
| author | cin |
|---|---|
| date | Sun, 15 Jun 2014 19:39:11 +0400 |
| parents | |
| children | 130781364799 |
comparison
equal
deleted
inserted
replaced
| 51:2c332a9c64c0 | 55:c0bf853aa04f |
|---|---|
| 1 using Implab; | |
| 2 using Implab.Parsing; | |
| 3 using System; | |
| 4 using System.Collections.Generic; | |
| 5 using System.Diagnostics; | |
| 6 using System.Linq; | |
| 7 using System.Text; | |
| 8 using System.Threading.Tasks; | |
| 9 | |
| 10 namespace Implab.JSON { | |
| 11 /// <summary> | |
| 12 /// Класс для преобразования экранированной строки JSON | |
| 13 /// </summary> | |
| 14 public class StringTranslator : Scanner { | |
| 15 static readonly char[] _escMap; | |
| 16 static readonly int[] _hexMap; | |
| 17 | |
| 18 static StringTranslator() { | |
| 19 var chars = new char[] { 'b', 'f', 't', 'r', 'n', '\\', '/' }; | |
| 20 var vals = new char[] { '\b', '\f', '\t', '\r', '\n', '\\', '/' }; | |
| 21 | |
| 22 _escMap = new char[chars.Max() + 1]; | |
| 23 | |
| 24 for (int i = 0; i < chars.Length; i++) | |
| 25 _escMap[chars[i]] = vals[i]; | |
| 26 | |
| 27 var hexs = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F' }; | |
| 28 var ints = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15 }; | |
| 29 | |
| 30 _hexMap = new int[hexs.Max() + 1]; | |
| 31 | |
| 32 for (int i = 0; i < hexs.Length; i++) | |
| 33 _hexMap[hexs[i]] = ints[i]; | |
| 34 | |
| 35 } | |
| 36 | |
| 37 public StringTranslator() | |
| 38 : base(JSONGrammar.Instance.JsonStringDFA) { | |
| 39 } | |
| 40 | |
| 41 public string Translate(string data) { | |
| 42 Safe.ArgumentNotNull(data, "data"); | |
| 43 return Translate(data.ToCharArray()); | |
| 44 } | |
| 45 | |
| 46 public string Translate(char[] data) { | |
| 47 Safe.ArgumentNotNull(data, "data"); | |
| 48 return Translate(data, data.Length); | |
| 49 } | |
| 50 | |
| 51 public string Translate(char[] data, int length) { | |
| 52 Safe.ArgumentNotNull(data, "data"); | |
| 53 Safe.ArgumentInRange(length, 0, data.Length, "length"); | |
| 54 | |
| 55 var translated = new char[length]; | |
| 56 | |
| 57 Feed(data,length); | |
| 58 | |
| 59 int pos = 0; | |
| 60 | |
| 61 while (ReadTokenInternal()) { | |
| 62 switch ((JSONGrammar.TokenType)TokenTags[0]) { | |
| 63 case JSONGrammar.TokenType.UnescapedChar: | |
| 64 Array.Copy(m_buffer,m_tokenOffset,translated,pos,m_tokenLen); | |
| 65 pos += m_tokenLen; | |
| 66 break; | |
| 67 case JSONGrammar.TokenType.EscapedChar: | |
| 68 translated[pos] = _escMap[m_buffer[m_tokenOffset + 1]]; | |
| 69 pos++; | |
| 70 break; | |
| 71 case JSONGrammar.TokenType.EscapedUnicode: | |
| 72 translated[pos] = TranslateHexUnicode(m_buffer,m_tokenOffset + 2); | |
| 73 pos++; | |
| 74 break; | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 return new String(translated, 0, pos); | |
| 79 } | |
| 80 | |
| 81 internal static char TranslateEscapedChar(char symbol) { | |
| 82 return _escMap[symbol]; | |
| 83 } | |
| 84 | |
| 85 internal static char TranslateHexUnicode(char[] symbols, int offset) { | |
| 86 Debug.Assert(symbols != null); | |
| 87 Debug.Assert(symbols.Length - offset >= 4); | |
| 88 | |
| 89 int value = (_hexMap[symbols[offset]] << 12) | |
| 90 | (_hexMap[symbols[offset + 1]] << 8) | |
| 91 | (_hexMap[symbols[offset + 2]] << 4) | |
| 92 | (_hexMap[symbols[offset + 3]]); | |
| 93 return (char)value; | |
| 94 } | |
| 95 } | |
| 96 } |
