Проблема кодирования с JLine - PullRequest
0 голосов
/ 24 апреля 2018

Jline - это модуль для перехвата ввода пользователя с консоли до того, как пользователь нажмет Enter.Он использует JNA или подобное волшебство.

Я провожу несколько экспериментов с ним, и у меня возникают проблемы с кодированием, когда я вводлю более «экзотические» символы Юникода.ОС здесь W10, и я использую Cygwin.Также это в Groovy, но должно быть очевидно для Java.

def terminal = org.jline.terminal.TerminalBuilder.builder().jna( true ).system( true ).build()
terminal.enterRawMode()
// NB the Terminal I get is class org.jline.terminal.impl.PosixSysTerminal
def reader = terminal.reader()

def bytes = [] // NB class ArrayList
int readInt = -1
while( readInt != 13 && readInt != 10 ) {
    readInt = reader.read()
    byte convertedByte = (byte)readInt
    // see what the binary looks like:
    String binaryString = String.format("%8s", Integer.toBinaryString( convertedByte & 0xFF)).replace(' ', '0')
    println "binary |$binaryString|"
    bytes << (byte)readInt // NB means "append to list"
    println ">>> read |$readInt| byte |$convertedByte|"
}
// strip final byte (13 or 10)
bytes = bytes[0..-2]
println "z bytes $bytes, class ${bytes.class.name}"
def response = new String( (byte[])bytes.toArray(), 'UTF-8' )
// to get proper out encoding for Cygwin I then need to do this (I have no idea why!)
def psOut = new PrintStream(System.out, true, 'UTF-8' )
psOut.print( "using PrintStream: |$response|" )

Это прекрасно работает с однобайтовым Юникодом, и буквы типа "é" (2 байта) обрабатываются нормально.Но с "ẃ" все идет не так:

ẃ --> Unicode U+1E83 
    UTF-8 HEX: 0xE1 0xBA 0x83 (e1ba83) 
    BINARY: 11100001:10111010:10000011

На самом деле двоичный файл, который он выдает при вводе "ẃ", равен 11100001: 10111010: 10010010 .

Thisпереводится как U + 1E92, который является еще одним польским символом, «Ẓ».И это действительно то, что напечатано в response String.

К сожалению, пакет JLine вручает вам этот reader, который является классом org.jline.utils.NonBlocking$NonBlockingInputStreamReader ... Так что я действительно не знаючто я могу сделать, чтобы исследовать его кодировку (я полагаю, UTF-8) или как-то изменить его ... Может кто-нибудь объяснить, в чем проблема?

1 Ответ

0 голосов
/ 27 апреля 2018

Насколько я могу судить, это относится к специфической для Cygwin проблеме, как меня спросили, а затем ответил мне год назад.

В моем ответе есть решение для вопроса, который я задал непосредственно после этого ... которое корректно работает с вводом Unicode, даже когда вне Базовой многоязычной плоскости, используя JLine, ... и используя консоль Cygwin ... надеюсь.

...