ConsoleEncoding.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace XUnity.AutoTranslator.Plugin.Core.Debugging
  6. {
  7. internal class ConsoleEncoding : Encoding
  8. {
  9. private byte[] _byteBuffer = new byte[ 256 ];
  10. private char[] _charBuffer = new char[ 256 ];
  11. private byte[] _zeroByte = new byte[ 0 ];
  12. private char[] _zeroChar = new char[ 0 ];
  13. private readonly uint _codePage;
  14. public override int CodePage => (int)_codePage;
  15. private ConsoleEncoding( uint codePage )
  16. {
  17. _codePage = codePage;
  18. }
  19. public static ConsoleEncoding GetEncoding( uint codePage )
  20. {
  21. return new ConsoleEncoding( codePage );
  22. }
  23. public override int GetByteCount( char[] chars, int index, int count )
  24. {
  25. WriteCharBuffer( chars, index, count );
  26. int result = Kernel32.WideCharToMultiByte( _codePage, 0, _charBuffer, count, _zeroByte, 0, IntPtr.Zero, IntPtr.Zero );
  27. return result;
  28. }
  29. public override int GetBytes( char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex )
  30. {
  31. var byteCount = GetMaxByteCount( charCount );
  32. WriteCharBuffer( chars, charIndex, charCount );
  33. ExpandByteBuffer( byteCount );
  34. int result = Kernel32.WideCharToMultiByte( _codePage, 0, chars, charCount, _byteBuffer, byteCount, IntPtr.Zero, IntPtr.Zero );
  35. ReadByteBuffer( bytes, byteIndex, byteCount );
  36. return result;
  37. }
  38. public override int GetCharCount( byte[] bytes, int index, int count )
  39. {
  40. WriteByteBuffer( bytes, index, count );
  41. int result = Kernel32.MultiByteToWideChar( _codePage, 0, bytes, count, _zeroChar, 0 );
  42. return result;
  43. }
  44. public override int GetChars( byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex )
  45. {
  46. var charCount = GetMaxCharCount( byteCount );
  47. WriteByteBuffer( bytes, byteIndex, byteCount );
  48. ExpandCharBuffer( charCount );
  49. int result = Kernel32.MultiByteToWideChar( _codePage, 0, bytes, byteCount, _charBuffer, charCount );
  50. ReadCharBuffer( chars, charIndex, charCount );
  51. return result;
  52. }
  53. public override int GetMaxByteCount( int charCount ) => charCount * 2;
  54. public override int GetMaxCharCount( int byteCount ) => byteCount;
  55. private void ExpandByteBuffer( int count )
  56. {
  57. if( _byteBuffer.Length < count )
  58. _byteBuffer = new byte[ count ];
  59. }
  60. private void ExpandCharBuffer( int count )
  61. {
  62. if( _charBuffer.Length < count )
  63. _charBuffer = new char[ count ];
  64. }
  65. private void ReadByteBuffer( byte[] bytes, int index, int count )
  66. {
  67. for( int i = 0 ; i < count ; i++ )
  68. bytes[ index + i ] = _byteBuffer[ i ];
  69. }
  70. private void ReadCharBuffer( char[] chars, int index, int count )
  71. {
  72. for( int i = 0 ; i < count ; i++ )
  73. chars[ index + i ] = _charBuffer[ i ];
  74. }
  75. private void WriteByteBuffer( byte[] bytes, int index, int count )
  76. {
  77. ExpandByteBuffer( count );
  78. for( int i = 0 ; i < count ; i++ )
  79. _byteBuffer[ i ] = bytes[ index + i ];
  80. }
  81. private void WriteCharBuffer( char[] chars, int index, int count )
  82. {
  83. ExpandCharBuffer( count );
  84. for( int i = 0 ; i < count ; i++ )
  85. _charBuffer[ i ] = chars[ index + i ];
  86. }
  87. }
  88. }