TerminalInput.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:8k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2. * Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3. * $Id: TerminalInput.cs,v 1.2 2005/04/20 08:45:47 okajima Exp $
  4. */
  5. using System;
  6. using System.Resources;
  7. using System.Collections;
  8. using System.IO;
  9. using System.Text;
  10. using System.Diagnostics;
  11. using System.Drawing;
  12. using System.Windows.Forms;
  13. using Poderosa.Log;
  14. using Poderosa.Forms;
  15. using Poderosa.Config;
  16. using Poderosa.Text;
  17. using Poderosa.Communication;
  18. namespace Poderosa.Terminal
  19. {
  20. public interface ITerminal {
  21. /// <summary>
  22. /// 儂僗僩偐傜偺擖椡張棟
  23. /// </summary>
  24. void Input(byte[] data, int offset, int length);
  25. /// <summary>
  26. /// 儂僗僩偐傜偺擖椡張棟(僨僐乕僪嵪傒)
  27. /// </summary>
  28. void Input(char[] data, int offset, int length);
  29. /// <summary>
  30. /// 侾暥帤傪張棟乮傆偮偆偼Input撪偱Decoder宱桼偱張棟偝傟傞乯
  31. /// </summary>
  32. void ProcessChar(char ch);
  33. ProcessCharResult State { get; }
  34. void Reset();
  35. void FullReset();
  36. /// <summary>
  37. /// 庡偵ISO2022偵偍偄偰丄枹僒億乕僩偺僉儍儔僋僞僙僢僩偑巜掕偝傟偨
  38. /// </summary>
  39. void UnsupportedCharSetDetected(char code);
  40. /// <summary>
  41. /// byte->char曄姺偵幐攕偟偨偲偒偺捠抦
  42. /// </summary>
  43. void InvalidCharDetected(Encoding enc, byte[] data);
  44. /// <summary>
  45. /// 僇乕僜儖僉乕偵懳墳偡傞憲怣僨乕僞傪庢摼
  46. /// </summary>
  47. byte[] SequenceKeyData(Keys modifier, Keys body);
  48. /// <summary>
  49. /// 尰嵼偺儌乕僪
  50. /// </summary>
  51. TerminalMode TerminalMode { get; }
  52. void   ClearMacroBuffer();
  53. void   SignalData();
  54. string ReadLineFromMacroBuffer();
  55. string ReadAllFromMacroBuffer();
  56. ITerminalTextLogger Logger { get; }
  57. /// <summary>
  58. /// for debug
  59. /// </summary>
  60. void DumpCurrentText();
  61. }
  62. internal interface ICharDecoder {
  63. void Input(ITerminal terminal, byte[] data, int offset, int length);
  64. void Reset(EncodingProfile enc);
  65. EncodingProfile Encoding { get; }
  66. }
  67. public enum ProcessCharResult {
  68. Processed,
  69. Unsupported,
  70. Escaping
  71. }
  72. /// <summary>
  73. /// 
  74. /// </summary>
  75. internal class JapaneseCharDecoder : ICharDecoder {
  76. private static Encoding JIS = System.Text.Encoding.GetEncoding("iso-2022-jp"); //塸岅娐嫬偱偼偙傟偼幐攕偡傞偐傕
  77. //師偺擖椡偵宷偘傞偨傔偺忬懺
  78. private enum State {
  79. Normal, //昗弨
  80. ESC,    //ESC偑棃偨偲偙傠
  81. ESC_DOLLAR,    //ESC $偑棃偨偲偙傠
  82. ESC_BRACKET,   //ESC (偑棃偨偲偙傠
  83. ESC_ENDBRACKET    //ESC )偑棃偨偲偙傠
  84. }
  85. private State _state;
  86. //憓擖偝傟偨擔杮岅(JIS僄儞僐乕僨傿儞僌)偺偨傔偺僶僢僼傽
  87. private MemoryStream _jisbuf;
  88. //MBCS偺忬懺娗棟
  89. private EncodingProfile _encoding;
  90. private static char[] DEC_SPECIAL_LINES;
  91. //尰嵼宷偑偭偰偄傞僐僱僋僔儑儞
  92. private TerminalConnection _connection;
  93. //暥帤傪張棟偡傞僞乕儈僫儖
  94. private ITerminal _terminal;
  95. public JapaneseCharDecoder(TerminalConnection con) {
  96. _jisbuf = new MemoryStream(0x1000);
  97. _state = State.Normal;
  98. _connection = con;
  99. _encoding = con.Param.EncodingProfile;
  100. _iso2022jpByteProcessor   = new ByteProcessor(this.ProcessByteAsISO2022JP);
  101. _DECLineByteProcessor     = new ByteProcessor(this.ProcessByteAsDECLine);
  102. _currentByteProcessor = null;
  103. _G0ByteProcessor = null;
  104. _G1ByteProcessor = null;
  105. }
  106. public EncodingProfile Encoding {
  107. get {
  108. return _encoding;
  109. }
  110. }
  111. private delegate void ByteProcessor(byte b);
  112. private ByteProcessor _currentByteProcessor;
  113. private ByteProcessor _G0ByteProcessor; //iso2022偺G0,G1
  114. private ByteProcessor _G1ByteProcessor;
  115. private ByteProcessor _iso2022jpByteProcessor; 
  116. private ByteProcessor _DECLineByteProcessor;
  117. public void Input(ITerminal terminal, byte[] data, int offset, int count) {
  118. _terminal = terminal;
  119. //張棟杮懱
  120. int last = offset+count;
  121. while(offset < last) {
  122. byte b = data[offset++];
  123. ProcessByte(b);
  124. }
  125. }
  126. private void ProcessByte(byte b) {
  127. if(_terminal.State==ProcessCharResult.Escaping)
  128. _terminal.ProcessChar((char)b);
  129. else {
  130. if(_state==State.Normal && !IsControlChar(b) && _encoding.IsInterestingByte(b)) {
  131. PutMBCSByte(b);
  132. }
  133. else {
  134. switch(_state) {
  135. case State.Normal:
  136. if(b==0x1B) //ESC
  137. _state = State.ESC;
  138. else if(b==14) //SO
  139. ChangeProcessor(_G1ByteProcessor);
  140. else if(b==15) //SI
  141. ChangeProcessor(_G0ByteProcessor);
  142. else
  143. ConsumeByte(b);
  144. break;
  145. case State.ESC:
  146. if(b==(byte)'$')
  147. _state = State.ESC_DOLLAR;
  148. else if(b==(byte)'(')
  149. _state=State.ESC_BRACKET;
  150. else if(b==(byte)')')
  151. _state=State.ESC_ENDBRACKET;
  152. else {
  153. ConsumeByte(0x1B);
  154. ConsumeByte(b);
  155. _state = State.Normal;
  156. }
  157. break;
  158. case State.ESC_BRACKET:
  159. if(b==(byte)'0')
  160. _G0ByteProcessor = _DECLineByteProcessor;
  161. else if(b==(byte)'B' || b==(byte)'J' || b==(byte)'~') //!!less偱ssh2architecture.txt傪尒偰偄偨傜棃偨丅徻嵶偼傑偩挷傋偰偄側偄丅
  162. _G0ByteProcessor = null;
  163. else
  164. _terminal.UnsupportedCharSetDetected((char)b);
  165. ChangeProcessor(_G0ByteProcessor);
  166. break;
  167. case State.ESC_ENDBRACKET:
  168. if(b==(byte)'0')
  169. _G1ByteProcessor = _DECLineByteProcessor;
  170. else if(b==(byte)'B' || b==(byte)'J' || b==(byte)'~') //!!less偱ssh2architecture.txt傪尒偰偄偨傜棃偨丅徻嵶偼傑偩挷傋偰偄側偄丅
  171. _G1ByteProcessor = null;
  172. _state = State.Normal;
  173. break;
  174. case State.ESC_DOLLAR:
  175. if(b==(byte)'B' || b==(byte)'@') {
  176. ChangeProcessor(_iso2022jpByteProcessor);
  177. }
  178. else {
  179. _terminal.ProcessChar((char)0x1B);
  180. _terminal.ProcessChar('$');
  181. _terminal.ProcessChar((char)b);
  182. _state = State.Normal;
  183. }
  184. break;
  185. default:
  186. Debug.Assert(false, "unexpected state transition");
  187. break;
  188. }
  189. }
  190. }
  191. }
  192. private void ProcessByteAsISO2022JP(byte b) {
  193. _jisbuf.WriteByte(b);
  194. }
  195. private void ProcessByteAsDECLine(byte b) {
  196. char ch = (char)b;
  197. if(0x60<=ch && ch<=0x7F) {
  198. if(DEC_SPECIAL_LINES==null) {
  199. ResourceManager m = new ResourceManager("Poderosa.Terminal.rulechars", typeof(GEnv).Assembly);
  200. DEC_SPECIAL_LINES = m.GetString("DECLineChars").ToCharArray();
  201. //儕僜乕僗偱?偵側偭偰偄偨偲偙傠傪杽傔傞
  202. DEC_SPECIAL_LINES[2] = (char)0x09;
  203. DEC_SPECIAL_LINES[3] = (char)0x0C;
  204. DEC_SPECIAL_LINES[4] = (char)0x0D;
  205. DEC_SPECIAL_LINES[5] = (char)0x0A;
  206. DEC_SPECIAL_LINES[8] = (char)0x0A; //NL偲偁傞偑傛偔傢偐傜側偄丅LF偵偟偰偍偔丅
  207. DEC_SPECIAL_LINES[9] = (char)0x0B;
  208. DEC_SPECIAL_LINES[31] = (char)0x7F;
  209. }
  210. char linechar = DEC_SPECIAL_LINES[(int)(ch - 0x60)];
  211. _terminal.ProcessChar(linechar);
  212. }
  213. else
  214. _terminal.ProcessChar(ch);
  215. }
  216. private void ChangeProcessor(ByteProcessor newprocessor) {
  217. //婛懚偺傗偮偑偁傟偽儕僙僢僩
  218. if(_currentByteProcessor==_iso2022jpByteProcessor) {
  219. FlushJISBuffer();
  220. }
  221. if(newprocessor==_iso2022jpByteProcessor) {
  222. InitJISBuffer();
  223. }
  224. _currentByteProcessor = newprocessor;
  225. _state = State.Normal;
  226. }
  227. private void ConsumeByte(byte b) {
  228. if(_currentByteProcessor==null)
  229. _terminal.ProcessChar((char)b);
  230. else
  231. _currentByteProcessor(b);
  232. }
  233. public void Reset(EncodingProfile enc) {
  234. _encoding.Reset();
  235. _encoding = enc;
  236. _encoding.Reset();
  237. }
  238. private static bool IsControlChar(byte b) {
  239. return b<=0x1F;
  240. }
  241. private void InitJISBuffer() {
  242. _jisbuf.SetLength(0);
  243. _jisbuf.WriteByte(0x1B);
  244. _jisbuf.WriteByte((byte)'$');
  245. _jisbuf.WriteByte((byte)'B');
  246. }
  247. private void FlushJISBuffer() {
  248. _jisbuf.WriteByte(0x1B);
  249. _jisbuf.WriteByte((byte)'(');
  250. _jisbuf.WriteByte((byte)'B');
  251. char[] x = JIS.GetString(_jisbuf.ToArray()).ToCharArray();
  252. for(int i=0; i<x.Length; i++)
  253. _terminal.ProcessChar(x[i]);
  254. _jisbuf.SetLength(0);
  255. }
  256. private void PutMBCSByte(byte b) {
  257. char[] t = new char[2];
  258. try {
  259. char ch = _encoding.PutByte(b);
  260. if(ch!='')
  261. _terminal.ProcessChar(ch);
  262. }
  263. catch(Exception) {
  264. _terminal.InvalidCharDetected(_encoding.Encoding, _encoding.Buffer);
  265. _encoding.Reset();
  266. }
  267. }
  268. }
  269. internal class UnknownEscapeSequenceException : Exception {
  270. public UnknownEscapeSequenceException(string msg) : base(msg) {}
  271. }
  272. internal struct IntPair {
  273. public int first;
  274. public int second;
  275. public IntPair(int f, int s) {
  276. first = f;
  277. second = s;
  278. }
  279. }
  280. }