I found a way to work around this, but how do I make h3270 recognize ISO 8859-15 characters?
If the s3270 screen is sending a character that is not in ASCII it causes array out of bounds errors.
This is due to ISO 8859-15 being 4 hex length characters instead of 2.
(The letter "A" is hex 0041 or 41.)
Currently, the 4 length characters are interpreted as 2 different characters instead of 1 character.
This causes the range to be out of bounds. (81 characters in an 80 character array.)
Example: The unicode character 'Broken Bar' (U+00A6) is UTF-8 hex "c2a6". This is interpreted as two characters (c2 "Â" and a6 “¦” gives you “¦”).
At least something will display with this character but if the hex code is "0178" it fails with NULL. ("01" is not a valid character)
My current workaround is not perfect but it works. I replace hex 4 character length characters with a "?" and one particular character with a "|".
Modified src/org/h3270/host/S3270.java
/**
* Perform an s3270 command. All communication with s3270 should go via this
* method.
*/
private Result doCommand (String command) {
try {
out.println (command);
out.flush();
if (logger.isDebugEnabled()) {
logger.debug("---> " + command);
}
List lines = new ArrayList();
while (true) {
String line = in.readLine();
line = doExtChar(line);
if (line == null) {
checkS3270Process(); // will throw appropriate exception
// if we get here, it's a more obscure error
throw new RuntimeException("s3270 process not responding");
}
if (logger.isDebugEnabled()) {
logger.debug("<--- " + line);
}
if (line.equals("ok")) {
break;
}
lines.add(line);
}
int size = lines.size();
if (size > 0) {
return new Result (lines.subList(0, size - 1),
(String) lines.get(size - 1));
} else {
throw new RuntimeException("no status received in command: " + command);
}
} catch (IOException ex) {
throw new RuntimeException("IOException during command: " + command, ex);
}
}
private static final Pattern CHAR_PATTERN =
Pattern.compile(" ([0-9a-zA-Z]{3,})");
private static final Pattern CHAR_DATA_PATTERN =
Pattern.compile("data\\: ");
public String doExtChar (String line) {
Matcher mm = CHAR_DATA_PATTERN.matcher(line);
while (mm.find()) {
Matcher m = CHAR_PATTERN.matcher(line);
while (m.find()) {
String mgroup = m.group();
if (mgroup.matches(".*c2a6.*")){
line = line.replaceAll("c2a6", "7c");
}else{
line = line.replaceAll(mgroup, "3f");
}
}
}
return line;
}