Closed soe78 closed 4 years ago
this works, but it feels so wrong...
public static void codepageHack() {
try {
Charset cp273 = Charset.forName("Cp273");
Field field = CodepageHelper.class.getDeclaredField("CHARSET_IBM500");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, cp273);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Does your TLE have a CGCSGID Triplet in front of the FullyQualifiedName and AttributeValue? If so, what is the value of CPGID?
No, the TLEs only got 2 Triplets, FullyQualifiedName and AttributeValue. When I break into CodepageHelper, I get a BRG and a BDT with cpgid=500 and gcsgid=65535
Well this is odd. Normally you would have a CGCSGID defining the code page. If there is none it defaults to EBCDIC. Now your CHARs are encoded in CP273 which is EBCDIC with latin-1 chars (used in Germany and Austria). But again if your AFP does not specify the code page using CGCSGID then I am not sure what to do. In any case afplib currently wouldn't know CP273 - the appropriate switch is missing in CodepageHelper:
else if(cpgid == 273) result = Charset.forName("CP273");
If in fact your AFP is wrong then maybe you can work around this by getting the bytes of the TLE value using CP500, which should give you the original bytes and then create a String using CP273 - essentially recoding the chars.
new String("abc".getBytes(Charset.forName("ibm500")), Charset.forName("CP273"));
The Charset conversions gives me the correct results, and I´m perfectly fine with that solution. Thank you very much! I´ll try to figure out, why there is no CGCSGID=273 Triplet, would you add the missing else if anyway? I can create a PR.
done
So I had a long call with a zOS/Afp Guy, and he agrees with you that there should be a Triplet for CP273, if ibm500 shoud not be used. I use your workaround. Issue can be closed, I just added a pull request with a small test + refactoring. Thanks again, Sören
Hi Yan, I´m trying to parse TLE Information from an afp created on zOS. It works perfectly until it comes to TLEs with eMail adresses inside, where the '@' is turned to '§'. As the Charset ist static final in CodepageHelper, I used the old dirty reflection hack to set CodepageHelper.CHARSET_IBM500 to Cp273 and then all TLEs where parsed correctly. The CodepageHelper.getCharset Method is called with parametes cpgid=500 and gcsgid=65535, so the ibm500 is not from the last else statement (with the fixme on it). My question is, would it be possible to turn the CodepageHelper into some kind of CodepageConfiguration and inject it to the AfpInputStream? Thanks, Sören