Phase 4
This commit is contained in:
@@ -26,6 +26,7 @@ public class ConnectionConfig {
|
||||
private int dynamicRows = 24;
|
||||
private int dynamicCols = 80;
|
||||
private haus.nightmare.lib3270j.graphics.GraphicsMode graphicsMode = haus.nightmare.lib3270j.graphics.GraphicsMode.BOTH;
|
||||
private String codePage = "037";
|
||||
|
||||
public ConnectionConfig() {}
|
||||
|
||||
@@ -94,6 +95,11 @@ public class ConnectionConfig {
|
||||
this.graphicsMode = (mode != null) ? mode : haus.nightmare.lib3270j.graphics.GraphicsMode.NONE;
|
||||
}
|
||||
|
||||
public String getCodePage() { return codePage; }
|
||||
public void setCodePage(String codePage) {
|
||||
this.codePage = (codePage != null && !codePage.trim().isEmpty()) ? codePage.trim() : "037";
|
||||
}
|
||||
|
||||
public String getTerminalName() { return terminalName; }
|
||||
public void setTerminalName(String name) { this.terminalName = name; }
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public class Telnet3270Client {
|
||||
|
||||
public Telnet3270Client(ConnectionConfig config) {
|
||||
this.config = config;
|
||||
this.translator = new EbcdicTranslator();
|
||||
this.translator = new EbcdicTranslator(config.getCodePage());
|
||||
this.screenBuffer = new ScreenBuffer(config.getModel(), translator);
|
||||
this.dsProcessor = new DataStreamProcessor(screenBuffer, translator);
|
||||
this.dsProcessor.getQueryReplyBuilder().setGraphicsMode(config.getGraphicsMode());
|
||||
@@ -126,6 +126,12 @@ public class Telnet3270Client {
|
||||
/** Get the EBCDIC translator. */
|
||||
public EbcdicTranslator getTranslator() { return translator; }
|
||||
|
||||
/** Get the active Code Page identifier. */
|
||||
public String getCodePage() { return translator.getCodePageId(); }
|
||||
|
||||
/** Set the active Code Page identifier. */
|
||||
public void setCodePage(String codePageId) { translator.setCodePage(codePageId); }
|
||||
|
||||
/** Get the current connection state. */
|
||||
public ConnectionState getConnectionState() { return fsm.getConnectionState(); }
|
||||
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base implementation for Single-Byte Character Set (SBCS) EBCDIC Code Pages.
|
||||
*/
|
||||
public abstract class AbstractCodePage implements CodePage {
|
||||
|
||||
protected final String id;
|
||||
protected final String description;
|
||||
protected final int cpgid;
|
||||
protected final int cgcsgid;
|
||||
|
||||
protected final int[] toUnicode = new int[256];
|
||||
protected final int[] toEbcdic = new int[256];
|
||||
protected final Map<Character, Integer> extendedToEbcdic = new HashMap<>();
|
||||
|
||||
public AbstractCodePage(String id, String description, int cpgid, int cgcsgid, int[] unicodeMapping) {
|
||||
this(id, description, cpgid, cgcsgid, null, unicodeMapping);
|
||||
}
|
||||
|
||||
public AbstractCodePage(String id, String description, int cpgid, int cgcsgid, String javaCharsetName, int[] unicodeMapping) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.cpgid = cpgid;
|
||||
this.cgcsgid = cgcsgid;
|
||||
|
||||
int[] map = loadMapping(javaCharsetName, unicodeMapping);
|
||||
System.arraycopy(map, 0, this.toUnicode, 0, 256);
|
||||
initReverseMapping();
|
||||
}
|
||||
|
||||
public static int[] loadMapping(String charsetName, int[] fallback) {
|
||||
if (charsetName != null) {
|
||||
String[] candidates = {
|
||||
charsetName,
|
||||
"IBM" + charsetName,
|
||||
"Cp" + charsetName,
|
||||
"IBM-" + charsetName,
|
||||
"x-IBM" + charsetName
|
||||
};
|
||||
for (String name : candidates) {
|
||||
try {
|
||||
if (Charset.isSupported(name)) {
|
||||
Charset cs = Charset.forName(name);
|
||||
int[] map = new int[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
byte[] b = new byte[]{(byte) i};
|
||||
String s = new String(b, cs);
|
||||
map[i] = (!s.isEmpty() && s.charAt(0) != '\uFFFD') ? s.charAt(0) : (fallback != null ? fallback[i] : 0);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
return fallback != null ? fallback : new int[256];
|
||||
}
|
||||
|
||||
protected void initReverseMapping() {
|
||||
Arrays.fill(toEbcdic, -1);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int uc = toUnicode[i];
|
||||
if (uc >= 0 && uc < 256) {
|
||||
if (toEbcdic[uc] == -1) {
|
||||
toEbcdic[uc] = i;
|
||||
}
|
||||
} else if (uc >= 256) {
|
||||
extendedToEbcdic.putIfAbsent((char) uc, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodePageId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCpgid() {
|
||||
return cpgid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCgcsgid() {
|
||||
return cgcsgid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDBCS() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char ebcdicToUnicode(int ebc) {
|
||||
return (char) toUnicode[ebc & 0xFF];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int unicodeToEbcdic(char unicode) {
|
||||
int u = unicode;
|
||||
if (u >= 0 && u < 256) {
|
||||
return toEbcdic[u];
|
||||
}
|
||||
Integer val = extendedToEbcdic.get(unicode);
|
||||
return val != null ? val : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte unicodeToEbcdicSafe(char unicode) {
|
||||
int ebc = unicodeToEbcdic(unicode);
|
||||
return (byte) (ebc >= 0 ? ebc : 0x40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char dbcsToUnicode(int b1, int b2) {
|
||||
return '\uFFFD';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int unicodeToDbcs(char unicode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String ebcdicToString(byte[] ebcdic, int offset, int length) {
|
||||
if (ebcdic == null || length <= 0) return "";
|
||||
char[] chars = new char[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
chars[i] = ebcdicToUnicode(ebcdic[offset + i]);
|
||||
}
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] stringToEbcdic(String s) {
|
||||
if (s == null || s.isEmpty()) return new byte[0];
|
||||
byte[] bytes = new byte[s.length()];
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
bytes[i] = unicodeToEbcdicSafe(s.charAt(i));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id + " (" + description + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base implementation for Mixed Double-Byte Character Set (DBCS) EBCDIC Code Pages
|
||||
* (e.g. Japanese Katakana 930, Japanese Latin 939, Chinese 935/937/1388, Korean 933).
|
||||
*/
|
||||
public abstract class AbstractDBCSCodePage extends AbstractCodePage {
|
||||
|
||||
public static final int SO = 0x0E; // Shift Out (enter DBCS mode)
|
||||
public static final int SI = 0x0F; // Shift In (enter SBCS mode)
|
||||
|
||||
protected final Map<Integer, Character> dbcsToUnicodeMap = new HashMap<>();
|
||||
protected final Map<Character, Integer> unicodeToDbcsMap = new HashMap<>();
|
||||
protected Charset nioCharset;
|
||||
|
||||
public AbstractDBCSCodePage(String id, String description, int cpgid, int cgcsgid,
|
||||
int[] sbcsMapping, String nioCharsetName) {
|
||||
super(id, description, cpgid, cgcsgid, sbcsMapping);
|
||||
if (nioCharsetName != null) {
|
||||
try {
|
||||
if (Charset.isSupported(nioCharsetName)) {
|
||||
this.nioCharset = Charset.forName(nioCharsetName);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
// Initialize ideographic space (0x4040 <-> \u3000)
|
||||
registerDbcsPair(0x4040, '\u3000');
|
||||
}
|
||||
|
||||
public void registerDbcsPair(int ebcdicDBCS, char unicodeChar) {
|
||||
dbcsToUnicodeMap.put(ebcdicDBCS, unicodeChar);
|
||||
unicodeToDbcsMap.put(unicodeChar, ebcdicDBCS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDBCS() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char dbcsToUnicode(int b1, int b2) {
|
||||
int key = ((b1 & 0xFF) << 8) | (b2 & 0xFF);
|
||||
Character c = dbcsToUnicodeMap.get(key);
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
|
||||
if (nioCharset != null) {
|
||||
try {
|
||||
byte[] raw = new byte[] { (byte) SO, (byte) b1, (byte) b2, (byte) SI };
|
||||
CharBuffer cb = nioCharset.decode(ByteBuffer.wrap(raw));
|
||||
if (cb.hasRemaining()) {
|
||||
char decoded = cb.get();
|
||||
if (decoded != '\uFFFD' && decoded != 0) {
|
||||
registerDbcsPair(key, decoded);
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
return '?';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int unicodeToDbcs(char unicode) {
|
||||
Integer val = unicodeToDbcsMap.get(unicode);
|
||||
if (val != null) {
|
||||
return val;
|
||||
}
|
||||
|
||||
if (nioCharset != null) {
|
||||
try {
|
||||
CharsetEncoder encoder = nioCharset.newEncoder()
|
||||
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||
.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
||||
ByteBuffer bb = encoder.encode(CharBuffer.wrap(new char[]{unicode}));
|
||||
byte[] bytes = new byte[bb.remaining()];
|
||||
bb.get(bytes);
|
||||
|
||||
// Check if encoded as SO + b1 + b2 + SI or b1 + b2
|
||||
if (bytes.length >= 4 && (bytes[0] & 0xFF) == SO) {
|
||||
int key = ((bytes[1] & 0xFF) << 8) | (bytes[2] & 0xFF);
|
||||
registerDbcsPair(key, unicode);
|
||||
return key;
|
||||
} else if (bytes.length == 2) {
|
||||
int key = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
|
||||
registerDbcsPair(key, unicode);
|
||||
return key;
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String ebcdicToString(byte[] ebcdic, int offset, int length) {
|
||||
if (ebcdic == null || length <= 0) return "";
|
||||
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
boolean inDBCS = false;
|
||||
int end = Math.min(ebcdic.length, offset + length);
|
||||
int i = offset;
|
||||
|
||||
while (i < end) {
|
||||
int b = ebcdic[i] & 0xFF;
|
||||
if (b == SO) {
|
||||
inDBCS = true;
|
||||
i++;
|
||||
} else if (b == SI) {
|
||||
inDBCS = false;
|
||||
i++;
|
||||
} else if (inDBCS) {
|
||||
if (i + 1 < end) {
|
||||
int b2 = ebcdic[i + 1] & 0xFF;
|
||||
if (b2 == SI) {
|
||||
// Orphaned single byte before SI
|
||||
inDBCS = false;
|
||||
i += 2;
|
||||
} else {
|
||||
sb.append(dbcsToUnicode(b, b2));
|
||||
i += 2;
|
||||
}
|
||||
} else {
|
||||
// Trailing byte
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
sb.append(ebcdicToUnicode(b));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] stringToEbcdic(String s) {
|
||||
if (s == null || s.isEmpty()) return new byte[0];
|
||||
|
||||
// Manual state machine encoding
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(s.length() * 2);
|
||||
boolean inDBCS = false;
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
int dbcsCode = unicodeToDbcs(c);
|
||||
|
||||
if (dbcsCode >= 0) {
|
||||
// Character is DBCS
|
||||
if (!inDBCS) {
|
||||
out.write(SO);
|
||||
inDBCS = true;
|
||||
}
|
||||
out.write((dbcsCode >> 8) & 0xFF);
|
||||
out.write(dbcsCode & 0xFF);
|
||||
} else {
|
||||
// Character is SBCS
|
||||
if (inDBCS) {
|
||||
out.write(SI);
|
||||
inDBCS = false;
|
||||
}
|
||||
out.write(unicodeToEbcdicSafe(c));
|
||||
}
|
||||
}
|
||||
|
||||
if (inDBCS) {
|
||||
out.write(SI);
|
||||
}
|
||||
|
||||
return out.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* Interface defining character translation and metadata for EBCDIC code pages
|
||||
* conforming to IBM Host On-Demand (HoD v14) converters specification.
|
||||
*/
|
||||
public interface CodePage {
|
||||
|
||||
/**
|
||||
* Get the primary identifier for this code page (e.g. "037", "1047", "500", "273").
|
||||
*/
|
||||
String getCodePageId();
|
||||
|
||||
/**
|
||||
* Get a human-readable description (e.g. "US / Canada - EBCDIC").
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Get the Code Page Global ID (CPGID / CCSID) for 3270 query replies.
|
||||
*/
|
||||
int getCpgid();
|
||||
|
||||
/**
|
||||
* Get the Graphic Character Set Global ID (GCSGID) for 3270 query replies.
|
||||
*/
|
||||
int getCgcsgid();
|
||||
|
||||
/**
|
||||
* Translate an EBCDIC byte (0x00-0xFF) to a Unicode character.
|
||||
*/
|
||||
char ebcdicToUnicode(int ebc);
|
||||
|
||||
/**
|
||||
* Translate a Unicode character to an EBCDIC byte value.
|
||||
* Returns -1 if unmappable.
|
||||
*/
|
||||
int unicodeToEbcdic(char unicode);
|
||||
|
||||
/**
|
||||
* Translate a Unicode character to an EBCDIC byte value, returning a safe
|
||||
* fallback (default EBCDIC space 0x40) if unmappable.
|
||||
*/
|
||||
byte unicodeToEbcdicSafe(char unicode);
|
||||
|
||||
/**
|
||||
* Translate an EBCDIC byte array slice to a Unicode String.
|
||||
*/
|
||||
String ebcdicToString(byte[] ebcdic, int offset, int length);
|
||||
|
||||
/**
|
||||
* Translate a Unicode String to an EBCDIC byte array.
|
||||
*/
|
||||
byte[] stringToEbcdic(String s);
|
||||
|
||||
/**
|
||||
* Check if this code page is a double-byte (DBCS) / mixed SBCS+DBCS code page.
|
||||
*/
|
||||
boolean isDBCS();
|
||||
|
||||
/**
|
||||
* Translate a double-byte EBCDIC pair (b1, b2) to a Unicode character.
|
||||
* Returns '\uFFFD' or '?' if unmappable.
|
||||
*/
|
||||
char dbcsToUnicode(int b1, int b2);
|
||||
|
||||
/**
|
||||
* Translate a Unicode character to a double-byte EBCDIC code ((b1 << 8) | b2).
|
||||
* Returns -1 if unmappable.
|
||||
*/
|
||||
int unicodeToDbcs(char unicode);
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Registry and factory for 3270 EBCDIC Code Pages.
|
||||
* Manages built-in SBCS/DBCS codepages, alias normalization, and dynamic JVM Charset resolution.
|
||||
*/
|
||||
public class CodePageRegistry {
|
||||
|
||||
private static final Logger log = Logger.getLogger(CodePageRegistry.class.getName());
|
||||
|
||||
private static final Map<String, CodePage> CODE_PAGES = new LinkedHashMap<>();
|
||||
private static final Map<String, String> ALIASES = new HashMap<>();
|
||||
|
||||
static {
|
||||
// Register core SBCS codepages
|
||||
register(new Cp037());
|
||||
register(new Cp1047());
|
||||
register(new Cp500());
|
||||
register(new Cp273());
|
||||
register(new Cp277());
|
||||
register(new Cp278());
|
||||
register(new Cp280());
|
||||
register(new Cp284());
|
||||
register(new Cp285());
|
||||
register(new Cp297());
|
||||
register(new Cp870());
|
||||
register(new Cp871());
|
||||
register(new Cp875());
|
||||
register(new Cp1026());
|
||||
|
||||
// Register Euro variants (1140-1149)
|
||||
register(new CpEuroVariants.Cp1140());
|
||||
register(new CpEuroVariants.Cp1141());
|
||||
register(new CpEuroVariants.Cp1142());
|
||||
register(new CpEuroVariants.Cp1143());
|
||||
register(new CpEuroVariants.Cp1144());
|
||||
register(new CpEuroVariants.Cp1145());
|
||||
register(new CpEuroVariants.Cp1146());
|
||||
register(new CpEuroVariants.Cp1147());
|
||||
register(new CpEuroVariants.Cp1148());
|
||||
register(new CpEuroVariants.Cp1149());
|
||||
|
||||
// Register DBCS mixed codepages
|
||||
register(new Cp930());
|
||||
register(new Cp939());
|
||||
register(new Cp935());
|
||||
register(new Cp935.Cp1388());
|
||||
register(new Cp937());
|
||||
register(new Cp937.Cp1371());
|
||||
register(new Cp933());
|
||||
|
||||
// Setup common aliases
|
||||
addAlias("us", "037");
|
||||
addAlias("usa", "037");
|
||||
addAlias("ebcdic-cp-us", "037");
|
||||
addAlias("ebcdic-cp-ca", "037");
|
||||
addAlias("ebcdic-cp-nl", "037");
|
||||
|
||||
addAlias("posix", "1047");
|
||||
addAlias("unix", "1047");
|
||||
addAlias("open-systems", "1047");
|
||||
addAlias("zos-unix", "1047");
|
||||
|
||||
addAlias("intl", "500");
|
||||
addAlias("international", "500");
|
||||
addAlias("ebcdic-cp-ch", "500");
|
||||
|
||||
addAlias("de", "273");
|
||||
addAlias("germany", "273");
|
||||
addAlias("austria", "273");
|
||||
addAlias("ebcdic-cp-de", "273");
|
||||
|
||||
addAlias("dk", "277");
|
||||
addAlias("no", "277");
|
||||
addAlias("denmark", "277");
|
||||
addAlias("norway", "277");
|
||||
addAlias("ebcdic-cp-dk", "277");
|
||||
addAlias("ebcdic-cp-no", "277");
|
||||
|
||||
addAlias("se", "278");
|
||||
addAlias("fi", "278");
|
||||
addAlias("sweden", "278");
|
||||
addAlias("finland", "278");
|
||||
addAlias("ebcdic-cp-se", "278");
|
||||
addAlias("ebcdic-cp-fi", "278");
|
||||
|
||||
addAlias("it", "280");
|
||||
addAlias("italy", "280");
|
||||
addAlias("ebcdic-cp-it", "280");
|
||||
|
||||
addAlias("es", "284");
|
||||
addAlias("spain", "284");
|
||||
addAlias("latin-america", "284");
|
||||
addAlias("ebcdic-cp-es", "284");
|
||||
|
||||
addAlias("uk", "285");
|
||||
addAlias("gb", "285");
|
||||
addAlias("great-britain", "285");
|
||||
addAlias("ebcdic-cp-gb", "285");
|
||||
|
||||
addAlias("fr", "297");
|
||||
addAlias("france", "297");
|
||||
addAlias("ebcdic-cp-fr", "297");
|
||||
|
||||
addAlias("latin2", "870");
|
||||
addAlias("pl", "870");
|
||||
addAlias("cz", "870");
|
||||
addAlias("hu", "870");
|
||||
addAlias("ebcdic-cp-roece", "870");
|
||||
|
||||
addAlias("is", "871");
|
||||
addAlias("iceland", "871");
|
||||
addAlias("ebcdic-cp-is", "871");
|
||||
|
||||
addAlias("gr", "875");
|
||||
addAlias("greece", "875");
|
||||
addAlias("greek", "875");
|
||||
addAlias("ebcdic-cp-gr", "875");
|
||||
|
||||
addAlias("tr", "1026");
|
||||
addAlias("turkey", "1026");
|
||||
addAlias("turkish", "1026");
|
||||
addAlias("ebcdic-cp-tr", "1026");
|
||||
|
||||
addAlias("ja", "930");
|
||||
addAlias("japanese", "930");
|
||||
addAlias("katakana", "930");
|
||||
addAlias("ja-latin", "939");
|
||||
|
||||
addAlias("zh", "935");
|
||||
addAlias("chinese-simplified", "935");
|
||||
addAlias("zh-tw", "937");
|
||||
addAlias("chinese-traditional", "937");
|
||||
|
||||
addAlias("ko", "933");
|
||||
addAlias("korean", "933");
|
||||
}
|
||||
|
||||
public static void register(CodePage cp) {
|
||||
if (cp != null) {
|
||||
CODE_PAGES.put(cp.getCodePageId(), cp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addAlias(String alias, String targetId) {
|
||||
if (alias != null && targetId != null) {
|
||||
ALIASES.put(normalizeKey(alias), targetId);
|
||||
}
|
||||
}
|
||||
|
||||
public static String normalizeKey(String name) {
|
||||
if (name == null) return "";
|
||||
String s = name.trim().toLowerCase();
|
||||
s = s.replace("_", "").replace("-", "");
|
||||
if (s.startsWith("ebcdiccp")) {
|
||||
s = s.substring(8);
|
||||
} else if (s.startsWith("ebcdic")) {
|
||||
s = s.substring(6);
|
||||
} else if (s.startsWith("ibm")) {
|
||||
s = s.substring(3);
|
||||
} else if (s.startsWith("cp")) {
|
||||
s = s.substring(2);
|
||||
} else if (s.startsWith("ccsid")) {
|
||||
s = s.substring(5);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a code page by ID or alias.
|
||||
* If not found in built-ins, attempts to load via java.nio.charset.Charset.
|
||||
* Falls back to CP037 if completely unresolvable.
|
||||
*/
|
||||
public static CodePage getCodePage(String name) {
|
||||
if (name == null || name.trim().isEmpty()) {
|
||||
return CODE_PAGES.get("037");
|
||||
}
|
||||
|
||||
String raw = name.trim();
|
||||
// Direct match
|
||||
CodePage cp = CODE_PAGES.get(raw);
|
||||
if (cp != null) return cp;
|
||||
|
||||
// Normalized key lookup
|
||||
String norm = normalizeKey(raw);
|
||||
cp = CODE_PAGES.get(norm);
|
||||
if (cp != null) return cp;
|
||||
|
||||
// Alias lookup
|
||||
String targetId = ALIASES.get(norm);
|
||||
if (targetId != null) {
|
||||
cp = CODE_PAGES.get(targetId);
|
||||
if (cp != null) return cp;
|
||||
}
|
||||
|
||||
// Try standard NIO Charset dynamic adapter
|
||||
try {
|
||||
if (Charset.isSupported(raw)) {
|
||||
return new NioCodePageAdapter(raw);
|
||||
}
|
||||
String ibmName = "IBM" + norm;
|
||||
if (Charset.isSupported(ibmName)) {
|
||||
return new NioCodePageAdapter(ibmName);
|
||||
}
|
||||
String cpName = "Cp" + norm;
|
||||
if (Charset.isSupported(cpName)) {
|
||||
return new NioCodePageAdapter(cpName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.fine("Dynamic charset loading failed for " + name + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
log.warning("CodePage not recognized: '" + name + "'; falling back to CP037");
|
||||
return CODE_PAGES.get("037");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an unmodifiable list of all registered built-in CodePages.
|
||||
*/
|
||||
public static List<CodePage> getAvailableCodePages() {
|
||||
return Collections.unmodifiableList(new ArrayList<>(CODE_PAGES.values()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all registered built-in CodePage IDs.
|
||||
*/
|
||||
public static String[] getAvailableCodePageIds() {
|
||||
return CODE_PAGES.keySet().toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic fallback adapter wrapping any JVM java.nio.charset.Charset.
|
||||
*/
|
||||
public static class NioCodePageAdapter extends AbstractCodePage {
|
||||
private final Charset charset;
|
||||
|
||||
public NioCodePageAdapter(String charsetName) {
|
||||
this(Charset.forName(charsetName));
|
||||
}
|
||||
|
||||
public NioCodePageAdapter(Charset charset) {
|
||||
super(charset.name(), "JVM Charset: " + charset.displayName(), parseCpgid(charset.name()), 697, buildMappingFromCharset(charset));
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
private static int parseCpgid(String name) {
|
||||
try {
|
||||
String num = name.replaceAll("\\D+", "");
|
||||
if (!num.isEmpty()) {
|
||||
return Integer.parseInt(num);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
return 37;
|
||||
}
|
||||
|
||||
private static int[] buildMappingFromCharset(Charset cs) {
|
||||
int[] map = new int[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
byte[] b = new byte[]{(byte) i};
|
||||
String s = new String(b, cs);
|
||||
map[i] = !s.isEmpty() ? s.charAt(0) : (char) i;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 037 (US / Canada / Netherlands / Portugal / Brazil).
|
||||
* CCSID / CPGID: 37, GCSGID: 697.
|
||||
*/
|
||||
public class Cp037 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "037";
|
||||
public static final String DESCRIPTION = "US / Canada / Brazil - EBCDIC";
|
||||
public static final int CPGID = 37;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F (space, accent chars, punctuation)
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
|
||||
// 80-8F (lowercase a-i)
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F (lowercase j-r)
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF (lowercase s-z)
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF (uppercase A-I)
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF (uppercase J-R)
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF (uppercase S-Z)
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF (digits 0-9)
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp037() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "037", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 1026 (Turkey - Turkish Latin-5 EBCDIC).
|
||||
* CCSID / CPGID: 1026, GCSGID: 1152.
|
||||
*/
|
||||
public class Cp1026 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "1026";
|
||||
public static final String DESCRIPTION = "Turkey - Turkish Latin-5 EBCDIC";
|
||||
public static final int CPGID = 1026;
|
||||
public static final int GCSGID = 1152;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x005B, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x015E, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00D6, 0x00C7, 0x00DC, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x0130, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00F6, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x011E, 0x00F4, 0x0131, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00E7, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x011F, 0x00FB, 0x015F, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x00FC, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00A6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp1026() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1026", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 1047 (IBM Open Systems / z/OS Unix System Services Latin-1).
|
||||
* CCSID / CPGID: 1047, GCSGID: 103.
|
||||
*/
|
||||
public class Cp1047 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "1047";
|
||||
public static final String DESCRIPTION = "IBM Open Systems / z/OS Unix Latin-1";
|
||||
public static final int CPGID = 1047;
|
||||
public static final int GCSGID = 103;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x000A, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x005B, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00AC, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00DD, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp1047() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1047", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 273 (Germany / Austria).
|
||||
* CCSID / CPGID: 273, GCSGID: 697.
|
||||
*/
|
||||
public class Cp273 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "273";
|
||||
public static final String DESCRIPTION = "Germany / Austria - EBCDIC";
|
||||
public static final int CPGID = 273;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x007B, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x005B, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00E4, 0x00F6, 0x00FC, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00E4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00FC, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00DC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp273() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "273", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 277 (Denmark / Norway).
|
||||
* CCSID / CPGID: 277, GCSGID: 697.
|
||||
*/
|
||||
public class Cp277 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "277";
|
||||
public static final String DESCRIPTION = "Denmark / Norway - EBCDIC";
|
||||
public static final int CPGID = 277;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x00A4, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00E6, 0x00F8, 0x00E5, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00C6, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00D8, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x00C5, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp277() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "277", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 278 (Sweden / Finland).
|
||||
* CCSID / CPGID: 278, GCSGID: 697.
|
||||
*/
|
||||
public class Cp278 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "278";
|
||||
public static final String DESCRIPTION = "Sweden / Finland - EBCDIC";
|
||||
public static final int CPGID = 278;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x007B, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x00A4, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x005B, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00E4, 0x00F6, 0x00E5, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00C4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00D6, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x00C5, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp278() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "278", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 280 (Italy).
|
||||
* CCSID / CPGID: 280, GCSGID: 697.
|
||||
*/
|
||||
public class Cp280 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "280";
|
||||
public static final String DESCRIPTION = "Italy - EBCDIC";
|
||||
public static final int CPGID = 280;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x007B, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00B0, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x005B, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00A3, 0x00A7, 0x00E9, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00F2, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00F9, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x00E0, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp280() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "280", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 284 (Spain / Latin America).
|
||||
* CCSID / CPGID: 284, GCSGID: 697.
|
||||
*/
|
||||
public class Cp284 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "284";
|
||||
public static final String DESCRIPTION = "Spain / Latin America - EBCDIC";
|
||||
public static final int CPGID = 284;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00F1, 0x00D1, 0x00E7, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp284() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "284", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 285 (United Kingdom).
|
||||
* CCSID / CPGID: 285, GCSGID: 697.
|
||||
*/
|
||||
public class Cp285 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "285";
|
||||
public static final String DESCRIPTION = "United Kingdom - EBCDIC";
|
||||
public static final int CPGID = 285;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00A3, 0x0040, 0x0027, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp285() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "285", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 297 (France).
|
||||
* CCSID / CPGID: 297, GCSGID: 697.
|
||||
*/
|
||||
public class Cp297 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "297";
|
||||
public static final String DESCRIPTION = "France - EBCDIC";
|
||||
public static final int CPGID = 297;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x007B, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00B0, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x005B, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00E0, 0x00E9, 0x00E8, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00E9, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00E8, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp297() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "297", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 500 (International / Western Europe Latin-1).
|
||||
* CCSID / CPGID: 500, GCSGID: 697.
|
||||
*/
|
||||
public class Cp500 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "500";
|
||||
public static final String DESCRIPTION = "International / Western Europe Latin-1";
|
||||
public static final int CPGID = 500;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x005B, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp500() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "500", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 870 (Latin-2 / Eastern Europe: Polish, Czech, Slovak, Hungarian, etc.).
|
||||
* CCSID / CPGID: 870, GCSGID: 959.
|
||||
*/
|
||||
public class Cp870 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "870";
|
||||
public static final String DESCRIPTION = "Eastern Europe / Latin-2 - EBCDIC";
|
||||
public static final int CPGID = 870;
|
||||
public static final int GCSGID = 959;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x0103, 0x00E4, 0x016F, 0x0165, 0x0105, 0x0155,
|
||||
0x0107, 0x00E9, 0x015B, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x010D, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x016E, 0x0164, 0x0104, 0x0154,
|
||||
0x0106, 0x00C9, 0x015A, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x010C, 0x0060, 0x003A, 0x0161, 0x017C, 0x00FD, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x0160, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x017B, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp870() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "870", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 871 (Iceland).
|
||||
* CCSID / CPGID: 871, GCSGID: 697.
|
||||
*/
|
||||
public class Cp871 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "871";
|
||||
public static final String DESCRIPTION = "Iceland - EBCDIC";
|
||||
public static final int CPGID = 871;
|
||||
public static final int GCSGID = 697;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x00A4, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x00FE, 0x00F0, 0x00FD, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x00DE, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF
|
||||
0x00D0, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF
|
||||
0x00DD, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
|
||||
public Cp871() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "871", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 875 (Greece - Greek EBCDIC).
|
||||
* CCSID / CPGID: 875, GCSGID: 925.
|
||||
*/
|
||||
public class Cp875 extends AbstractCodePage {
|
||||
|
||||
public static final String ID = "875";
|
||||
public static final String DESCRIPTION = "Greece - Greek EBCDIC";
|
||||
public static final int CPGID = 875;
|
||||
public static final int GCSGID = 925;
|
||||
|
||||
public static final int[] MAPPING = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F
|
||||
0x0020, 0x00A0, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CE, 0x00DF, 0x005B, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
|
||||
// 50-5F
|
||||
0x0026, 0x0390, 0x03B0, 0x03CA, 0x03CB, 0x0390, 0x0385, 0x0386,
|
||||
0x0388, 0x0389, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x038A, 0x038C, 0x038E, 0x038F, 0x03AA, 0x03AB,
|
||||
0x00A9, 0x00AE, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
|
||||
// 80-8F
|
||||
0x03B9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
// 90-9F
|
||||
0x03C0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6,
|
||||
// A0-AF
|
||||
0x03C7, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x03C8, 0x03C9, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
|
||||
// D0-DF
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C,
|
||||
// E0-EF
|
||||
0x005C, 0x039D, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4,
|
||||
// F0-FF
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x009F,
|
||||
};
|
||||
|
||||
public Cp875() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "875", MAPPING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 930 (Japanese Katakana Mixed DBCS: host SBCS CP290 / DBCS CP300).
|
||||
* CCSID / CPGID: 930, GCSGID: 1172.
|
||||
*/
|
||||
public class Cp930 extends AbstractDBCSCodePage {
|
||||
|
||||
public static final String ID = "930";
|
||||
public static final String DESCRIPTION = "Japanese Katakana Mixed DBCS";
|
||||
public static final int CPGID = 930;
|
||||
public static final int GCSGID = 1172;
|
||||
|
||||
public Cp930() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM930");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 933 (Korean Mixed DBCS).
|
||||
* CCSID / CPGID: 933, GCSGID: 1173.
|
||||
*/
|
||||
public class Cp933 extends AbstractDBCSCodePage {
|
||||
|
||||
public static final String ID = "933";
|
||||
public static final String DESCRIPTION = "Korean Mixed DBCS";
|
||||
public static final int CPGID = 933;
|
||||
public static final int GCSGID = 1173;
|
||||
|
||||
public Cp933() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM933");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 935 / 1388 (Simplified Chinese Mixed DBCS).
|
||||
* CCSID / CPGID: 935, GCSGID: 1175.
|
||||
*/
|
||||
public class Cp935 extends AbstractDBCSCodePage {
|
||||
|
||||
public static final String ID = "935";
|
||||
public static final String DESCRIPTION = "Simplified Chinese Mixed DBCS";
|
||||
public static final int CPGID = 935;
|
||||
public static final int GCSGID = 1175;
|
||||
|
||||
public Cp935() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM935");
|
||||
}
|
||||
|
||||
public static class Cp1388 extends AbstractDBCSCodePage {
|
||||
public static final String ID = "1388";
|
||||
public static final String DESCRIPTION = "Simplified Chinese Extended Mixed DBCS";
|
||||
public static final int CPGID = 1388;
|
||||
public static final int GCSGID = 1175;
|
||||
|
||||
public Cp1388() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM1388");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 937 / 1371 (Traditional Chinese Mixed DBCS).
|
||||
* CCSID / CPGID: 937, GCSGID: 1174.
|
||||
*/
|
||||
public class Cp937 extends AbstractDBCSCodePage {
|
||||
|
||||
public static final String ID = "937";
|
||||
public static final String DESCRIPTION = "Traditional Chinese Mixed DBCS";
|
||||
public static final int CPGID = 937;
|
||||
public static final int GCSGID = 1174;
|
||||
|
||||
public Cp937() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM937");
|
||||
}
|
||||
|
||||
public static class Cp1371 extends AbstractDBCSCodePage {
|
||||
public static final String ID = "1371";
|
||||
public static final String DESCRIPTION = "Traditional Chinese Extended Mixed DBCS";
|
||||
public static final int CPGID = 1371;
|
||||
public static final int GCSGID = 1174;
|
||||
|
||||
public Cp1371() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM1371");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
/**
|
||||
* IBM Code Page 939 (Japanese Latin Mixed DBCS: host SBCS CP1027 / DBCS CP300).
|
||||
* CCSID / CPGID: 939, GCSGID: 1172.
|
||||
*/
|
||||
public class Cp939 extends AbstractDBCSCodePage {
|
||||
|
||||
public static final String ID = "939";
|
||||
public static final String DESCRIPTION = "Japanese Latin Mixed DBCS";
|
||||
public static final int CPGID = 939;
|
||||
public static final int GCSGID = 1172;
|
||||
|
||||
public Cp939() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, Cp037.MAPPING, "x-IBM939");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Euro currency symbol (€) enabled EBCDIC code pages (CP1140 through CP1149).
|
||||
*/
|
||||
public class CpEuroVariants {
|
||||
|
||||
public static class Cp1140 extends AbstractCodePage {
|
||||
public static final String ID = "1140";
|
||||
public static final String DESCRIPTION = "US / Canada Euro - EBCDIC";
|
||||
public static final int CPGID = 1140;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1140() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1140", modifyEuro(Cp037.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1141 extends AbstractCodePage {
|
||||
public static final String ID = "1141";
|
||||
public static final String DESCRIPTION = "Germany / Austria Euro - EBCDIC";
|
||||
public static final int CPGID = 1141;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1141() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1141", modifyEuro(Cp273.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1142 extends AbstractCodePage {
|
||||
public static final String ID = "1142";
|
||||
public static final String DESCRIPTION = "Denmark / Norway Euro - EBCDIC";
|
||||
public static final int CPGID = 1142;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1142() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1142", modifyEuro(Cp277.MAPPING, 0x5A));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1143 extends AbstractCodePage {
|
||||
public static final String ID = "1143";
|
||||
public static final String DESCRIPTION = "Sweden / Finland Euro - EBCDIC";
|
||||
public static final int CPGID = 1143;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1143() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1143", modifyEuro(Cp278.MAPPING, 0x5A));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1144 extends AbstractCodePage {
|
||||
public static final String ID = "1144";
|
||||
public static final String DESCRIPTION = "Italy Euro - EBCDIC";
|
||||
public static final int CPGID = 1144;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1144() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1144", modifyEuro(Cp280.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1145 extends AbstractCodePage {
|
||||
public static final String ID = "1145";
|
||||
public static final String DESCRIPTION = "Spain / Latin America Euro - EBCDIC";
|
||||
public static final int CPGID = 1145;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1145() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1145", modifyEuro(Cp284.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1146 extends AbstractCodePage {
|
||||
public static final String ID = "1146";
|
||||
public static final String DESCRIPTION = "United Kingdom Euro - EBCDIC";
|
||||
public static final int CPGID = 1146;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1146() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1146", modifyEuro(Cp285.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1147 extends AbstractCodePage {
|
||||
public static final String ID = "1147";
|
||||
public static final String DESCRIPTION = "France Euro - EBCDIC";
|
||||
public static final int CPGID = 1147;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1147() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1147", modifyEuro(Cp297.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1148 extends AbstractCodePage {
|
||||
public static final String ID = "1148";
|
||||
public static final String DESCRIPTION = "International Latin-1 Euro - EBCDIC";
|
||||
public static final int CPGID = 1148;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1148() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1148", modifyEuro(Cp500.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cp1149 extends AbstractCodePage {
|
||||
public static final String ID = "1149";
|
||||
public static final String DESCRIPTION = "Iceland Euro - EBCDIC";
|
||||
public static final int CPGID = 1149;
|
||||
public static final int GCSGID = 695;
|
||||
|
||||
public Cp1149() {
|
||||
super(ID, DESCRIPTION, CPGID, GCSGID, "1149", modifyEuro(Cp871.MAPPING, 0x9F));
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] modifyEuro(int[] baseMapping, int euroPosition) {
|
||||
int[] copy = Arrays.copyOf(baseMapping, 256);
|
||||
copy[euroPosition & 0xFF] = '\u20AC'; // '€'
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@@ -1,142 +1,161 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* EBCDIC ↔ Unicode translator.
|
||||
* EBCDIC ↔ Unicode character translator conforming to IBM Host On-Demand (HoD v14).
|
||||
* Modular architecture delegating to pluggable CodePage implementations (SBCS and DBCS).
|
||||
* Default: Code Page 037 (US/Canada EBCDIC).
|
||||
*/
|
||||
public class EbcdicTranslator {
|
||||
|
||||
/**
|
||||
* EBCDIC Code Page 037 to Unicode mapping.
|
||||
* Index is the EBCDIC byte value (0x00-0xFF), value is the Unicode codepoint.
|
||||
* EBCDIC Code Page 037 to Unicode mapping table preserved for legacy static access.
|
||||
*/
|
||||
private static final int[] CP037_TO_UNICODE = {
|
||||
// 00-0F
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
|
||||
0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
||||
// 10-1F
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
|
||||
0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
|
||||
// 20-2F
|
||||
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
|
||||
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
|
||||
// 30-3F
|
||||
0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
|
||||
0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
|
||||
// 40-4F (space, accent chars, punctuation)
|
||||
0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
|
||||
0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
|
||||
// 50-5F
|
||||
0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
|
||||
// 60-6F
|
||||
0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
|
||||
0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
|
||||
// 70-7F
|
||||
0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
|
||||
// 80-8F (lowercase a-i)
|
||||
0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||
0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
|
||||
// 90-9F (lowercase j-r)
|
||||
0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
|
||||
0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
|
||||
// A0-AF (lowercase s-z)
|
||||
0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
|
||||
0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
|
||||
// B0-BF
|
||||
0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
|
||||
0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
|
||||
// C0-CF (uppercase A-I)
|
||||
0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||
0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
|
||||
// D0-DF (uppercase J-R)
|
||||
0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
|
||||
0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
|
||||
// E0-EF (uppercase S-Z)
|
||||
0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
|
||||
// F0-FF (digits 0-9)
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||
0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
|
||||
};
|
||||
public static final int[] CP037_TO_UNICODE = Cp037.MAPPING;
|
||||
|
||||
private CodePage activeCodePage;
|
||||
|
||||
public EbcdicTranslator() {
|
||||
this("037");
|
||||
}
|
||||
|
||||
public EbcdicTranslator(String codePageId) {
|
||||
setCodePage(codePageId);
|
||||
}
|
||||
|
||||
public EbcdicTranslator(CodePage codePage) {
|
||||
setCodePage(codePage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unicode to EBCDIC Code Page 037 mapping (for basic Latin + Latin-1).
|
||||
* Index is the Unicode codepoint (0x00-0xFF), value is the EBCDIC byte (-1 if unmappable).
|
||||
* Set active code page by identifier or alias (e.g. "037", "1047", "500", "273", "1140", "930").
|
||||
*/
|
||||
private static final int[] UNICODE_TO_CP037 = new int[256];
|
||||
public synchronized void setCodePage(String codePageId) {
|
||||
this.activeCodePage = CodePageRegistry.getCodePage(codePageId);
|
||||
}
|
||||
|
||||
static {
|
||||
// Build reverse mapping
|
||||
java.util.Arrays.fill(UNICODE_TO_CP037, -1);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int unicode = CP037_TO_UNICODE[i];
|
||||
if (unicode < 256) {
|
||||
UNICODE_TO_CP037[unicode] = i;
|
||||
}
|
||||
/**
|
||||
* Set active code page directly.
|
||||
*/
|
||||
public synchronized void setCodePage(CodePage codePage) {
|
||||
if (codePage != null) {
|
||||
this.activeCodePage = codePage;
|
||||
} else {
|
||||
this.activeCodePage = CodePageRegistry.getCodePage("037");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate EBCDIC byte to Unicode character.
|
||||
* Get the active CodePage descriptor and translator.
|
||||
*/
|
||||
public char ebcdicToUnicode(int ebc) {
|
||||
return (char) CP037_TO_UNICODE[ebc & 0xFF];
|
||||
public synchronized CodePage getCodePage() {
|
||||
return activeCodePage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static helper to translate EBCDIC byte to Unicode character.
|
||||
* Get the active code page identifier string.
|
||||
*/
|
||||
public synchronized String getCodePageId() {
|
||||
return activeCodePage.getCodePageId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active Code Page Global ID (CPGID / CCSID) for Query Replies.
|
||||
*/
|
||||
public synchronized int getCpgid() {
|
||||
return activeCodePage.getCpgid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active Graphic Character Set Global ID (GCSGID) for Query Replies.
|
||||
*/
|
||||
public synchronized int getCgcsgid() {
|
||||
return activeCodePage.getCgcsgid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if active code page is Double-Byte / mixed DBCS.
|
||||
*/
|
||||
public synchronized boolean isDBCSCodePage() {
|
||||
return activeCodePage.isDBCS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate double-byte EBCDIC pair (b1, b2) to Unicode.
|
||||
*/
|
||||
public synchronized char dbcsToUnicode(int b1, int b2) {
|
||||
return activeCodePage.dbcsToUnicode(b1, b2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate Unicode character to double-byte EBCDIC ((b1 << 8) | b2).
|
||||
*/
|
||||
public synchronized int unicodeToDbcs(char unicode) {
|
||||
return activeCodePage.unicodeToDbcs(unicode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate EBCDIC byte to Unicode character using active code page.
|
||||
*/
|
||||
public char ebcdicToUnicode(int ebc) {
|
||||
return activeCodePage.ebcdicToUnicode(ebc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static helper to translate EBCDIC byte to Unicode character (using standard CP037).
|
||||
*/
|
||||
public static char toUnicode(int ebc) {
|
||||
return (char) CP037_TO_UNICODE[ebc & 0xFF];
|
||||
}
|
||||
|
||||
/**
|
||||
* Static helper to translate EBCDIC byte to ASCII character.
|
||||
* Static helper to translate EBCDIC byte to ASCII character (using standard CP037).
|
||||
*/
|
||||
public static char ebcdicToAscii(int ebc) {
|
||||
return toUnicode(ebc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate Unicode character to EBCDIC byte.
|
||||
* Translate Unicode character to EBCDIC byte using active code page.
|
||||
* Returns -1 if the character cannot be mapped.
|
||||
*/
|
||||
public int unicodeToEbcdic(char unicode) {
|
||||
if (unicode < 256) {
|
||||
return UNICODE_TO_CP037[unicode];
|
||||
}
|
||||
return -1;
|
||||
return activeCodePage.unicodeToEbcdic(unicode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate Unicode character to EBCDIC, returning EBCDIC space (0x40) if unmappable.
|
||||
*/
|
||||
public byte unicodeToEbcdicSafe(char unicode) {
|
||||
int ebc = unicodeToEbcdic(unicode);
|
||||
return (byte) (ebc >= 0 ? ebc : 0x40);
|
||||
return activeCodePage.unicodeToEbcdicSafe(unicode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a byte array from EBCDIC to a Unicode string.
|
||||
* Translate a byte array from EBCDIC to a Unicode string using active code page.
|
||||
*/
|
||||
public String ebcdicToString(byte[] ebcdic, int offset, int length) {
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(ebcdicToUnicode(ebcdic[offset + i] & 0xFF));
|
||||
}
|
||||
return sb.toString();
|
||||
return activeCodePage.ebcdicToString(ebcdic, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a Unicode string to EBCDIC byte array.
|
||||
* Translate a Unicode string to EBCDIC byte array using active code page.
|
||||
*/
|
||||
public byte[] stringToEbcdic(String s) {
|
||||
byte[] result = new byte[s.length()];
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
result[i] = unicodeToEbcdicSafe(s.charAt(i));
|
||||
}
|
||||
return result;
|
||||
return activeCodePage.stringToEbcdic(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all registered code page ID strings.
|
||||
*/
|
||||
public static String[] getAvailableCodePages() {
|
||||
return CodePageRegistry.getAvailableCodePageIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all registered CodePage instances.
|
||||
*/
|
||||
public static List<CodePage> getAllCodePages() {
|
||||
return CodePageRegistry.getAvailableCodePages();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,6 +337,13 @@ public class QueryReplyBuilder {
|
||||
int charW = getCharWidth();
|
||||
int charH = getCharHeight();
|
||||
|
||||
int cgcsgid = 0x02B9;
|
||||
int cpgid = 0x0025;
|
||||
if (screen != null && screen.getTranslator() != null) {
|
||||
cgcsgid = screen.getTranslator().getCgcsgid();
|
||||
cpgid = screen.getTranslator().getCpgid();
|
||||
}
|
||||
|
||||
if (graphicsMode.isProgrammedSymbolsEnabled()) {
|
||||
// Programmed Symbols mode (3279 PS with LoadPS 0x0A, flags1 = 0xA2 for GE + PS + CGCSGID)
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(65);
|
||||
@@ -349,8 +356,10 @@ public class QueryReplyBuilder {
|
||||
out.write(0x00); // Load PS device type (low)
|
||||
out.write(0x00); // reserved
|
||||
out.write(0x07); // DL = 7 bytes per descriptor
|
||||
// Descriptor 1 (SET 0): default character set (non-loadable, single plane, CP037)
|
||||
out.write(0x00); out.write(0x10); out.write(0x00); out.write(0x02); out.write(0xb9); out.write(0x00); out.write(0x25);
|
||||
// Descriptor 1 (SET 0): default character set (non-loadable, single plane, active codepage)
|
||||
out.write(0x00); out.write(0x10); out.write(0x00);
|
||||
out.write((cgcsgid >> 8) & 0xFF); out.write(cgcsgid & 0xFF);
|
||||
out.write((cpgid >> 8) & 0xFF); out.write(cpgid & 0xFF);
|
||||
// Descriptor 2 (SET 1): APL/GE character set
|
||||
out.write(0x01); out.write(0x00); out.write(0xf1); out.write(0x03); out.write(0xc3); out.write(0x01); out.write(0x36);
|
||||
// Loadable Single-Plane PS Sets (PSA, PSB: Slots 2, 3) - Flags = 0x80 (Loadable, single plane)
|
||||
@@ -375,8 +384,10 @@ public class QueryReplyBuilder {
|
||||
out.write(0x00);
|
||||
out.write(0x00);
|
||||
out.write(0x07); // DL = 7
|
||||
// Set 0 (Base EBCDIC - Non-loadable, single plane, CP037)
|
||||
out.write(0x00); out.write(0x10); out.write(0x00); out.write(0x02); out.write(0xb9); out.write(0x00); out.write(0x25);
|
||||
// Set 0 (Base EBCDIC - Non-loadable, single plane, active codepage)
|
||||
out.write(0x00); out.write(0x10); out.write(0x00);
|
||||
out.write((cgcsgid >> 8) & 0xFF); out.write(cgcsgid & 0xFF);
|
||||
out.write((cpgid >> 8) & 0xFF); out.write(cpgid & 0xFF);
|
||||
// Set 1 (APL/Text)
|
||||
out.write(0x01); out.write(0x00); out.write(0xf1); out.write(0x03); out.write(0xc3); out.write(0x01); out.write(0x36);
|
||||
return out.toByteArray();
|
||||
|
||||
@@ -125,6 +125,9 @@ public class ECLXfer implements FTCut.FTCutListener, FTDft.FTDftListener {
|
||||
*/
|
||||
public void getFile(String hostFile, String localFile, String options, int mode, String codePage, ECLXferListener listener) {
|
||||
if (listener != null) addXferListener(listener);
|
||||
if (codePage != null && !codePage.trim().isEmpty() && translator != null) {
|
||||
translator.setCodePage(codePage);
|
||||
}
|
||||
ReceiveFile(localFile, hostFile, options);
|
||||
}
|
||||
|
||||
@@ -133,6 +136,9 @@ public class ECLXfer implements FTCut.FTCutListener, FTDft.FTDftListener {
|
||||
*/
|
||||
public void putFile(String localFile, String hostFile, String options, int mode, String codePage, ECLXferListener listener) {
|
||||
if (listener != null) addXferListener(listener);
|
||||
if (codePage != null && !codePage.trim().isEmpty() && translator != null) {
|
||||
translator.setCodePage(codePage);
|
||||
}
|
||||
SendFile(localFile, hostFile, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ public class FTConfig {
|
||||
private int avblock = 0;
|
||||
private int dftBufferSize = FTConstants.DFT_BUF;
|
||||
private String otherOptions = null;
|
||||
private String codePage = null;
|
||||
|
||||
// ========== Derived convenience getters ==========
|
||||
|
||||
@@ -142,6 +143,9 @@ public class FTConfig {
|
||||
public void setOverwrite(boolean overwrite) {
|
||||
if (overwrite) this.existAction = ExistAction.REPLACE;
|
||||
}
|
||||
|
||||
public String getCodePage() { return codePage; }
|
||||
public void setCodePage(String codePage) { this.codePage = codePage; }
|
||||
|
||||
public void setReceive(boolean receive) {
|
||||
setDirection(receive ? Direction.RECEIVE : Direction.SEND);
|
||||
|
||||
@@ -1071,6 +1071,167 @@ public class InputProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter a double-byte (DBCS) character at the given screen address (or cursor position if pos < 0).
|
||||
*/
|
||||
public boolean DBCSinputChar(char c, int pos) {
|
||||
if (keyboardLocked || screen == null) return false;
|
||||
int size = screen.getRows() * screen.getCols();
|
||||
if (size <= 0) return false;
|
||||
|
||||
int baddr = (pos >= 0) ? pos : screen.getCursorAddress();
|
||||
baddr = ((baddr % size) + size) % size;
|
||||
|
||||
if (screen.isFormatted()) {
|
||||
byte fa = screen.getFieldAttributeAt(baddr);
|
||||
if (faIsProtected(fa & 0xFF)) return false;
|
||||
}
|
||||
|
||||
int dbcs = translator.unicodeToDbcs(c);
|
||||
if (dbcs < 0) {
|
||||
// Fall back to SBCS typing
|
||||
typeCharacter(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
int b1 = (dbcs >> 8) & 0xFF;
|
||||
int b2 = dbcs & 0xFF;
|
||||
|
||||
int nextAddr = screen.incrementAddress(baddr);
|
||||
if (screen.getCell(baddr).isFieldAttribute() || screen.getCell(nextAddr).isFieldAttribute()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
screen.setCell(baddr, b1);
|
||||
screen.getCell(baddr).ucs4 = c;
|
||||
screen.setCell(nextAddr, b2);
|
||||
screen.getCell(nextAddr).ucs4 = c;
|
||||
|
||||
// Set MDT
|
||||
if (screen.isFormatted()) {
|
||||
int faAddr = screen.findFieldAttribute(baddr);
|
||||
if (faAddr >= 0) {
|
||||
screen.getCell(faAddr).fa |= FA_MODIFY;
|
||||
}
|
||||
}
|
||||
|
||||
screen.setCursorAddress(screen.incrementAddress(nextAddr));
|
||||
screen.markAllChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift characters right within a field by shiftAmount positions.
|
||||
*/
|
||||
public void shiftCharactersRightInField(int baddr, int shiftAmount) {
|
||||
if (screen == null || shiftAmount <= 0) return;
|
||||
int size = screen.getRows() * screen.getCols();
|
||||
if (size <= 0) return;
|
||||
|
||||
baddr = ((baddr % size) + size) % size;
|
||||
|
||||
// Find end of field
|
||||
int endAddr = baddr;
|
||||
int count = 0;
|
||||
while (!screen.getCell(screen.incrementAddress(endAddr)).isFieldAttribute() && count < size) {
|
||||
endAddr = screen.incrementAddress(endAddr);
|
||||
count++;
|
||||
if (endAddr == baddr) break;
|
||||
}
|
||||
|
||||
for (int s = 0; s < shiftAmount; s++) {
|
||||
int dst = endAddr;
|
||||
int shiftCount = 0;
|
||||
while (dst != baddr && shiftCount < size) {
|
||||
int src = screen.decrementAddress(dst);
|
||||
screen.getCell(dst).ec = screen.getCell(src).ec;
|
||||
screen.getCell(dst).ucs4 = screen.getCell(src).ucs4;
|
||||
dst = src;
|
||||
shiftCount++;
|
||||
}
|
||||
screen.getCell(baddr).ec = 0;
|
||||
screen.getCell(baddr).ucs4 = 0;
|
||||
}
|
||||
screen.markAllChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift characters right within the current line by count positions.
|
||||
*/
|
||||
public void shiftCharactersRightInLine(int row, int col, int shiftAmount) {
|
||||
if (screen == null || shiftAmount <= 0) return;
|
||||
int cols = screen.getCols();
|
||||
int baddr = screen.rowColToAddress(row, col);
|
||||
int lineEnd = screen.rowColToAddress(row, cols - 1);
|
||||
|
||||
for (int s = 0; s < shiftAmount; s++) {
|
||||
for (int dst = lineEnd; dst > baddr; dst--) {
|
||||
screen.getCell(dst).ec = screen.getCell(dst - 1).ec;
|
||||
screen.getCell(dst).ucs4 = screen.getCell(dst - 1).ucs4;
|
||||
}
|
||||
screen.getCell(baddr).ec = 0;
|
||||
screen.getCell(baddr).ucs4 = 0;
|
||||
}
|
||||
screen.markAllChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift characters right across the screen by count positions.
|
||||
*/
|
||||
public void shiftCharactersRightInScreen(int pos, int shiftAmount) {
|
||||
if (screen == null || shiftAmount <= 0) return;
|
||||
int size = screen.getRows() * screen.getCols();
|
||||
pos = ((pos % size) + size) % size;
|
||||
|
||||
for (int s = 0; s < shiftAmount; s++) {
|
||||
for (int dst = size - 1; dst > pos; dst--) {
|
||||
screen.getCell(dst).ec = screen.getCell(dst - 1).ec;
|
||||
screen.getCell(dst).ucs4 = screen.getCell(dst - 1).ucs4;
|
||||
}
|
||||
screen.getCell(pos).ec = 0;
|
||||
screen.getCell(pos).ucs4 = 0;
|
||||
}
|
||||
screen.markAllChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a double-byte (DBCS) character with insert-mode shifting (2 positions).
|
||||
*/
|
||||
public boolean DBCSinputCharInsert(char c, int pos) {
|
||||
if (keyboardLocked || screen == null) return false;
|
||||
int baddr = (pos >= 0) ? pos : screen.getCursorAddress();
|
||||
|
||||
// Shift 2 characters right
|
||||
shiftCharactersRightInField(baddr, 2);
|
||||
return DBCSinputChar(c, baddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up orphaned or empty Shift-Out / Shift-In (SO 0x0E followed by SI 0x0F) control codes.
|
||||
*/
|
||||
public void clearUnusedSISO(int pos) {
|
||||
if (screen == null) return;
|
||||
int size = screen.getRows() * screen.getCols();
|
||||
if (size <= 0) return;
|
||||
|
||||
int start = (pos >= 0) ? pos : 0;
|
||||
int end = (pos >= 0) ? Math.min(size, pos + screen.getCols()) : size;
|
||||
|
||||
for (int i = start; i < end - 1; i++) {
|
||||
ExtendedAttribute ea1 = screen.getCell(i);
|
||||
ExtendedAttribute ea2 = screen.getCell(i + 1);
|
||||
if (!ea1.isFieldAttribute() && !ea2.isFieldAttribute()) {
|
||||
if ((ea1.ec & 0xFF) == 0x0E && (ea2.ec & 0xFF) == 0x0F) {
|
||||
ea1.ec = 0;
|
||||
ea1.ucs4 = 0;
|
||||
ea2.ec = 0;
|
||||
ea2.ucs4 = 0;
|
||||
screen.markAllChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get a reference to the TelnetFSM for direct SF operations. */
|
||||
public TelnetFSM getTelnetFSM() {
|
||||
return fsm;
|
||||
|
||||
@@ -46,6 +46,10 @@ public class ScreenBuffer {
|
||||
return renderLock;
|
||||
}
|
||||
|
||||
public EbcdicTranslator getTranslator() {
|
||||
return translator;
|
||||
}
|
||||
|
||||
public ScreenBuffer(TerminalModel model, EbcdicTranslator translator) {
|
||||
this.translator = translator;
|
||||
this.defRows = MODEL_2_ROWS;
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit tests for Single-Byte Character Set (SBCS) and Euro EBCDIC codepages.
|
||||
*/
|
||||
public class CodePageTest {
|
||||
|
||||
@Test
|
||||
public void testCp037USCanada() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("037");
|
||||
assertEquals("037", cp.getCodePageId());
|
||||
assertEquals(37, cp.getCpgid());
|
||||
assertEquals(697, cp.getCgcsgid());
|
||||
assertFalse(cp.isDBCS());
|
||||
|
||||
// Basic ASCII roundtrip
|
||||
assertEquals('A', cp.ebcdicToUnicode(0xC1));
|
||||
assertEquals(0xC1, cp.unicodeToEbcdic('A'));
|
||||
assertEquals('Z', cp.ebcdicToUnicode(0xE9));
|
||||
assertEquals('0', cp.ebcdicToUnicode(0xF0));
|
||||
assertEquals(' ', cp.ebcdicToUnicode(0x40));
|
||||
|
||||
// CP037 special punctuation
|
||||
assertEquals('[', cp.ebcdicToUnicode(0xBA));
|
||||
assertEquals(']', cp.ebcdicToUnicode(0xBB));
|
||||
assertEquals('{', cp.ebcdicToUnicode(0xC0));
|
||||
assertEquals('}', cp.ebcdicToUnicode(0xD0));
|
||||
assertEquals('\\', cp.ebcdicToUnicode(0xE0));
|
||||
assertEquals('~', cp.ebcdicToUnicode(0xA1));
|
||||
assertEquals('^', cp.ebcdicToUnicode(0xB0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp1047OpenSystems() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("1047");
|
||||
assertEquals("1047", cp.getCodePageId());
|
||||
assertEquals(1047, cp.getCpgid());
|
||||
assertEquals(103, cp.getCgcsgid());
|
||||
|
||||
// CP1047 bracket differences
|
||||
assertEquals('[', cp.ebcdicToUnicode(0xAD));
|
||||
assertEquals(']', cp.ebcdicToUnicode(0xBD));
|
||||
assertEquals(0xAD, cp.unicodeToEbcdic('['));
|
||||
assertEquals(0xBD, cp.unicodeToEbcdic(']'));
|
||||
assertEquals('^', cp.ebcdicToUnicode(0x5F));
|
||||
assertEquals(0x5F, cp.unicodeToEbcdic('^'));
|
||||
assertEquals('¬', cp.ebcdicToUnicode(0xB0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp500International() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("500");
|
||||
assertEquals("500", cp.getCodePageId());
|
||||
assertEquals(500, cp.getCpgid());
|
||||
assertEquals(697, cp.getCgcsgid());
|
||||
|
||||
// CP500 bracket & exclamation mappings
|
||||
assertEquals('[', cp.ebcdicToUnicode(0x4A));
|
||||
assertEquals(']', cp.ebcdicToUnicode(0x5A));
|
||||
assertEquals(0x4A, cp.unicodeToEbcdic('['));
|
||||
assertEquals(0x5A, cp.unicodeToEbcdic(']'));
|
||||
assertEquals('!', cp.ebcdicToUnicode(0x4F));
|
||||
assertEquals('$', cp.ebcdicToUnicode(0x5B));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp273GermanyAustria() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("273");
|
||||
assertEquals("273", cp.getCodePageId());
|
||||
assertEquals(273, cp.getCpgid());
|
||||
|
||||
// German umlauts and eszett roundtrip
|
||||
int ebcAe = cp.unicodeToEbcdic('ä');
|
||||
assertTrue(ebcAe >= 0);
|
||||
assertEquals('ä', cp.ebcdicToUnicode(ebcAe));
|
||||
|
||||
int ebcOe = cp.unicodeToEbcdic('ö');
|
||||
assertTrue(ebcOe >= 0);
|
||||
assertEquals('ö', cp.ebcdicToUnicode(ebcOe));
|
||||
|
||||
int ebcUe = cp.unicodeToEbcdic('ü');
|
||||
assertTrue(ebcUe >= 0);
|
||||
assertEquals('ü', cp.ebcdicToUnicode(ebcUe));
|
||||
|
||||
int ebcSs = cp.unicodeToEbcdic('ß');
|
||||
assertTrue(ebcSs >= 0);
|
||||
assertEquals('ß', cp.ebcdicToUnicode(ebcSs));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp277DenmarkNorway() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("277");
|
||||
assertEquals("277", cp.getCodePageId());
|
||||
|
||||
int ebcAe = cp.unicodeToEbcdic('æ');
|
||||
assertTrue(ebcAe >= 0);
|
||||
assertEquals('æ', cp.ebcdicToUnicode(ebcAe));
|
||||
|
||||
int ebcOe = cp.unicodeToEbcdic('ø');
|
||||
assertTrue(ebcOe >= 0);
|
||||
assertEquals('ø', cp.ebcdicToUnicode(ebcOe));
|
||||
|
||||
int ebcAa = cp.unicodeToEbcdic('å');
|
||||
assertTrue(ebcAa >= 0);
|
||||
assertEquals('å', cp.ebcdicToUnicode(ebcAa));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp278SwedenFinland() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("278");
|
||||
assertEquals("278", cp.getCodePageId());
|
||||
|
||||
int ebcAe = cp.unicodeToEbcdic('ä');
|
||||
assertTrue(ebcAe >= 0);
|
||||
assertEquals('ä', cp.ebcdicToUnicode(ebcAe));
|
||||
|
||||
int ebcOe = cp.unicodeToEbcdic('ö');
|
||||
assertTrue(ebcOe >= 0);
|
||||
assertEquals('ö', cp.ebcdicToUnicode(ebcOe));
|
||||
|
||||
int ebcAa = cp.unicodeToEbcdic('å');
|
||||
assertTrue(ebcAa >= 0);
|
||||
assertEquals('å', cp.ebcdicToUnicode(ebcAa));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp280Italy() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("280");
|
||||
assertEquals("280", cp.getCodePageId());
|
||||
|
||||
int ebcA = cp.unicodeToEbcdic('à');
|
||||
assertTrue(ebcA >= 0);
|
||||
assertEquals('à', cp.ebcdicToUnicode(ebcA));
|
||||
|
||||
int ebcE = cp.unicodeToEbcdic('é');
|
||||
assertTrue(ebcE >= 0);
|
||||
assertEquals('é', cp.ebcdicToUnicode(ebcE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp284SpainLatinAmerica() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("284");
|
||||
assertEquals("284", cp.getCodePageId());
|
||||
|
||||
int ebcN = cp.unicodeToEbcdic('ñ');
|
||||
assertTrue(ebcN >= 0);
|
||||
assertEquals('ñ', cp.ebcdicToUnicode(ebcN));
|
||||
|
||||
int ebcNu = cp.unicodeToEbcdic('Ñ');
|
||||
assertTrue(ebcNu >= 0);
|
||||
assertEquals('Ñ', cp.ebcdicToUnicode(ebcNu));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp285UK() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("285");
|
||||
assertEquals("285", cp.getCodePageId());
|
||||
|
||||
int ebcPound = cp.unicodeToEbcdic('£');
|
||||
assertTrue(ebcPound >= 0);
|
||||
assertEquals('£', cp.ebcdicToUnicode(ebcPound));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp297France() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("297");
|
||||
assertEquals("297", cp.getCodePageId());
|
||||
|
||||
int ebcA = cp.unicodeToEbcdic('à');
|
||||
assertTrue(ebcA >= 0);
|
||||
assertEquals('à', cp.ebcdicToUnicode(ebcA));
|
||||
|
||||
int ebcE = cp.unicodeToEbcdic('é');
|
||||
assertTrue(ebcE >= 0);
|
||||
assertEquals('é', cp.ebcdicToUnicode(ebcE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp870Latin2() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("870");
|
||||
assertEquals("870", cp.getCodePageId());
|
||||
assertEquals(870, cp.getCpgid());
|
||||
assertEquals(959, cp.getCgcsgid());
|
||||
|
||||
int ebcS = cp.unicodeToEbcdic('š');
|
||||
assertTrue(ebcS >= 0);
|
||||
assertEquals('š', cp.ebcdicToUnicode(ebcS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp871Iceland() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("871");
|
||||
assertEquals("871", cp.getCodePageId());
|
||||
|
||||
int ebcThorn = cp.unicodeToEbcdic('þ');
|
||||
assertTrue(ebcThorn >= 0);
|
||||
assertEquals('þ', cp.ebcdicToUnicode(ebcThorn));
|
||||
|
||||
int ebcEth = cp.unicodeToEbcdic('ð');
|
||||
assertTrue(ebcEth >= 0);
|
||||
assertEquals('ð', cp.ebcdicToUnicode(ebcEth));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp875Greece() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("875");
|
||||
assertEquals("875", cp.getCodePageId());
|
||||
|
||||
int ebcAlpha = cp.unicodeToEbcdic('α');
|
||||
assertTrue(ebcAlpha >= 0);
|
||||
assertEquals('α', cp.ebcdicToUnicode(ebcAlpha));
|
||||
|
||||
int ebcOmega = cp.unicodeToEbcdic('Ω');
|
||||
assertTrue(ebcOmega >= 0);
|
||||
assertEquals('Ω', cp.ebcdicToUnicode(ebcOmega));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCp1026Turkey() {
|
||||
CodePage cp = CodePageRegistry.getCodePage("1026");
|
||||
assertEquals("1026", cp.getCodePageId());
|
||||
|
||||
int ebcS = cp.unicodeToEbcdic('ş');
|
||||
assertTrue(ebcS >= 0);
|
||||
assertEquals('ş', cp.ebcdicToUnicode(ebcS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEuroVariantsCp1140To1149() {
|
||||
CodePage cp1140 = CodePageRegistry.getCodePage("1140");
|
||||
assertEquals(1140, cp1140.getCpgid());
|
||||
assertEquals(695, cp1140.getCgcsgid());
|
||||
assertEquals(0x9F, cp1140.unicodeToEbcdic('€'));
|
||||
assertEquals('€', cp1140.ebcdicToUnicode(0x9F));
|
||||
|
||||
CodePage cp1141 = CodePageRegistry.getCodePage("1141");
|
||||
assertEquals(0x9F, cp1141.unicodeToEbcdic('€'));
|
||||
assertEquals('€', cp1141.ebcdicToUnicode(0x9F));
|
||||
|
||||
CodePage cp1148 = CodePageRegistry.getCodePage("1148");
|
||||
assertEquals(1148, cp1148.getCpgid());
|
||||
assertEquals(0x9F, cp1148.unicodeToEbcdic('€'));
|
||||
assertEquals('€', cp1148.ebcdicToUnicode(0x9F));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringRoundTrips() {
|
||||
CodePage cp273 = CodePageRegistry.getCodePage("273");
|
||||
String german = "Grüße aus München: Äpfel & Öfen!";
|
||||
byte[] ebcdic = cp273.stringToEbcdic(german);
|
||||
String restored = cp273.ebcdicToString(ebcdic, 0, ebcdic.length);
|
||||
assertEquals(german, restored);
|
||||
|
||||
CodePage cp284 = CodePageRegistry.getCodePage("284");
|
||||
String spanish = "España y México: ¡Hola año nuevo!";
|
||||
byte[] espEbcdic = cp284.stringToEbcdic(spanish);
|
||||
String espRestored = cp284.ebcdicToString(espEbcdic, 0, espEbcdic.length);
|
||||
assertEquals(spanish, espRestored);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import haus.nightmare.lib3270j.TerminalModel;
|
||||
import haus.nightmare.lib3270j.input.InputProcessor;
|
||||
import haus.nightmare.lib3270j.screen.ScreenBuffer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit tests for Mixed Double-Byte Character Set (DBCS) codepages and SO/SI state processing.
|
||||
*/
|
||||
public class DBCSTranslationTest {
|
||||
|
||||
@Test
|
||||
public void testDBCSProperties() {
|
||||
CodePage cp930 = CodePageRegistry.getCodePage("930");
|
||||
assertTrue(cp930.isDBCS());
|
||||
assertEquals("930", cp930.getCodePageId());
|
||||
assertEquals(930, cp930.getCpgid());
|
||||
assertEquals(1172, cp930.getCgcsgid());
|
||||
|
||||
CodePage cp935 = CodePageRegistry.getCodePage("935");
|
||||
assertTrue(cp935.isDBCS());
|
||||
assertEquals(935, cp935.getCpgid());
|
||||
|
||||
CodePage cp937 = CodePageRegistry.getCodePage("937");
|
||||
assertTrue(cp937.isDBCS());
|
||||
assertEquals(937, cp937.getCpgid());
|
||||
|
||||
CodePage cp933 = CodePageRegistry.getCodePage("933");
|
||||
assertTrue(cp933.isDBCS());
|
||||
assertEquals(933, cp933.getCpgid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdeographicSpace() {
|
||||
CodePage cp930 = CodePageRegistry.getCodePage("930");
|
||||
assertEquals('\u3000', cp930.dbcsToUnicode(0x40, 0x40));
|
||||
assertEquals(0x4040, cp930.unicodeToDbcs('\u3000'));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDBCSStreamSOSIProcessing() {
|
||||
AbstractDBCSCodePage cp = (AbstractDBCSCodePage) CodePageRegistry.getCodePage("930");
|
||||
cp.registerDbcsPair(0x4341, '\u6771'); // '東'
|
||||
cp.registerDbcsPair(0x4342, '\u4EAC'); // '京'
|
||||
|
||||
// Mixed byte sequence: "IBM" + SO + 東 + 京 + SI + "123"
|
||||
// 'I'=0xC9, 'B'=0xC2, 'M'=0xD4, SO=0x0E, 0x43, 0x41, 0x43, 0x42, SI=0x0F, '1'=0xF1, '2'=0xF2, '3'=0xF3
|
||||
byte[] mixed = new byte[] {
|
||||
(byte) 0xC9, (byte) 0xC2, (byte) 0xD4,
|
||||
0x0E, (byte) 0x43, (byte) 0x41, (byte) 0x43, (byte) 0x42, 0x0F,
|
||||
(byte) 0xF1, (byte) 0xF2, (byte) 0xF3
|
||||
};
|
||||
|
||||
String translated = cp.ebcdicToString(mixed, 0, mixed.length);
|
||||
assertEquals("IBM東京123", translated);
|
||||
|
||||
// Reverse conversion: stringToEbcdic
|
||||
byte[] reEncoded = cp.stringToEbcdic("IBM東京123");
|
||||
assertArrayEquals(mixed, reEncoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInputProcessorDBCSInput() {
|
||||
EbcdicTranslator translator = new EbcdicTranslator("930");
|
||||
AbstractDBCSCodePage cp = (AbstractDBCSCodePage) translator.getCodePage();
|
||||
cp.registerDbcsPair(0x4545, '\u6771');
|
||||
|
||||
ScreenBuffer screen = new ScreenBuffer(TerminalModel.IBM_3279_2, translator);
|
||||
InputProcessor input = new InputProcessor(screen, translator, null);
|
||||
|
||||
// Enter DBCS character at pos 0
|
||||
boolean ok = input.DBCSinputChar('\u6771', 0);
|
||||
assertTrue(ok);
|
||||
assertEquals(0x45, screen.getCell(0).ec & 0xFF);
|
||||
assertEquals(0x45, screen.getCell(1).ec & 0xFF);
|
||||
assertEquals('\u6771', (char) screen.getCell(0).ucs4);
|
||||
assertEquals(2, screen.getCursorAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearUnusedSISO() {
|
||||
EbcdicTranslator translator = new EbcdicTranslator("930");
|
||||
ScreenBuffer screen = new ScreenBuffer(TerminalModel.IBM_3279_2, translator);
|
||||
InputProcessor input = new InputProcessor(screen, translator, null);
|
||||
|
||||
// Place orphaned SO (0x0E) followed immediately by SI (0x0F)
|
||||
screen.setCell(5, 0x0E);
|
||||
screen.setCell(6, 0x0F);
|
||||
assertEquals(0x0E, screen.getCell(5).ec & 0xFF);
|
||||
assertEquals(0x0F, screen.getCell(6).ec & 0xFF);
|
||||
|
||||
input.clearUnusedSISO(0);
|
||||
assertEquals(0, screen.getCell(5).ec & 0xFF);
|
||||
assertEquals(0, screen.getCell(6).ec & 0xFF);
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
package haus.nightmare.lib3270j.charset;
|
||||
|
||||
import haus.nightmare.lib3270j.ConnectionConfig;
|
||||
import haus.nightmare.lib3270j.Telnet3270Client;
|
||||
import haus.nightmare.lib3270j.TerminalModel;
|
||||
import haus.nightmare.lib3270j.datastream.QueryReplyBuilder;
|
||||
import haus.nightmare.lib3270j.screen.ScreenBuffer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* High-level integration tests for Phase 4 Character Translation & Multi-Codepage subsystem.
|
||||
*/
|
||||
public class EbcdicTranslatorPhase4Test {
|
||||
|
||||
@Test
|
||||
public void testRegistryAliases() {
|
||||
assertEquals("037", CodePageRegistry.getCodePage("cp037").getCodePageId());
|
||||
assertEquals("037", CodePageRegistry.getCodePage("IBM-037").getCodePageId());
|
||||
assertEquals("037", CodePageRegistry.getCodePage("ebcdic-cp-us").getCodePageId());
|
||||
|
||||
assertEquals("1047", CodePageRegistry.getCodePage("posix").getCodePageId());
|
||||
assertEquals("1047", CodePageRegistry.getCodePage("open-systems").getCodePageId());
|
||||
assertEquals("1047", CodePageRegistry.getCodePage("IBM1047").getCodePageId());
|
||||
|
||||
assertEquals("273", CodePageRegistry.getCodePage("de").getCodePageId());
|
||||
assertEquals("273", CodePageRegistry.getCodePage("germany").getCodePageId());
|
||||
|
||||
assertEquals("285", CodePageRegistry.getCodePage("uk").getCodePageId());
|
||||
assertEquals("285", CodePageRegistry.getCodePage("gb").getCodePageId());
|
||||
|
||||
assertEquals("297", CodePageRegistry.getCodePage("fr").getCodePageId());
|
||||
assertEquals("297", CodePageRegistry.getCodePage("france").getCodePageId());
|
||||
|
||||
assertEquals("930", CodePageRegistry.getCodePage("ja").getCodePageId());
|
||||
assertEquals("935", CodePageRegistry.getCodePage("chinese-simplified").getCodePageId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDynamicCodePageSwitching() {
|
||||
EbcdicTranslator translator = new EbcdicTranslator("037");
|
||||
assertEquals("037", translator.getCodePageId());
|
||||
assertEquals(37, translator.getCpgid());
|
||||
assertEquals('[', translator.ebcdicToUnicode(0xBA));
|
||||
|
||||
// Switch to CP1047
|
||||
translator.setCodePage("1047");
|
||||
assertEquals("1047", translator.getCodePageId());
|
||||
assertEquals(1047, translator.getCpgid());
|
||||
assertEquals('[', translator.ebcdicToUnicode(0xAD));
|
||||
|
||||
// Switch to German CP273
|
||||
translator.setCodePage("273");
|
||||
assertEquals("273", translator.getCodePageId());
|
||||
assertEquals(273, translator.getCpgid());
|
||||
int ebcAe = translator.unicodeToEbcdic('ä');
|
||||
assertTrue(ebcAe >= 0);
|
||||
assertEquals('ä', translator.ebcdicToUnicode(ebcAe));
|
||||
|
||||
// Switch to Euro CP1140
|
||||
translator.setCodePage("1140");
|
||||
assertEquals("1140", translator.getCodePageId());
|
||||
assertEquals(1140, translator.getCpgid());
|
||||
assertEquals('€', translator.ebcdicToUnicode(0x9F));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryReplyBuilderCharsetsSynchronization() {
|
||||
ScreenBuffer screen = new ScreenBuffer(TerminalModel.IBM_3279_2, new EbcdicTranslator("273"));
|
||||
QueryReplyBuilder builder = new QueryReplyBuilder(screen);
|
||||
|
||||
byte[] qrs = builder.buildAllQueryReplies(80, 24, 1920);
|
||||
assertNotNull(qrs);
|
||||
assertTrue(qrs.length > 0);
|
||||
|
||||
// Scan for QR_CHARSETS (0x85)
|
||||
int idx = 1; // skip AID_SF
|
||||
boolean foundCharsets = false;
|
||||
while (idx < qrs.length) {
|
||||
int len = ((qrs[idx] & 0xFF) << 8) | (qrs[idx + 1] & 0xFF);
|
||||
int sfid = qrs[idx + 2] & 0xFF;
|
||||
int qrCode = qrs[idx + 3] & 0xFF;
|
||||
|
||||
if (qrCode == 0x85) { // QR_CHARSETS
|
||||
foundCharsets = true;
|
||||
// Check Set 0 Descriptor (CPGID 273 = 0x0111)
|
||||
// Descriptor 1 starts after 9-byte header
|
||||
int descOffset = idx + 4 + 9;
|
||||
int cpgidHigh = qrs[descOffset + 5] & 0xFF;
|
||||
int cpgidLow = qrs[descOffset + 6] & 0xFF;
|
||||
int cpgid = (cpgidHigh << 8) | cpgidLow;
|
||||
assertEquals(273, cpgid, "Query Reply Charsets should advertise active CPGID 273");
|
||||
break;
|
||||
}
|
||||
idx += len;
|
||||
}
|
||||
assertTrue(foundCharsets, "QR_CHARSETS must be present in Query Replies");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScreenBufferTranslateWithActiveCodePage() {
|
||||
EbcdicTranslator translator = new EbcdicTranslator("273");
|
||||
ScreenBuffer screen = new ScreenBuffer(TerminalModel.IBM_3279_2, translator);
|
||||
|
||||
// Put German characters in buffer
|
||||
screen.setCell(0, translator.unicodeToEbcdic('ä'));
|
||||
screen.setCell(1, translator.unicodeToEbcdic('ö'));
|
||||
screen.setCell(2, translator.unicodeToEbcdic('ü'));
|
||||
screen.setCell(3, translator.unicodeToEbcdic('ß'));
|
||||
|
||||
screen.translateToUnicode();
|
||||
|
||||
assertEquals('ä', (char) screen.getCell(0).ucs4);
|
||||
assertEquals('ö', (char) screen.getCell(1).ucs4);
|
||||
assertEquals('ü', (char) screen.getCell(2).ucs4);
|
||||
assertEquals('ß', (char) screen.getCell(3).ucs4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelnet3270ClientWithConfiguredCodePage() {
|
||||
ConnectionConfig config = new ConnectionConfig("mainframe.example.com", 23);
|
||||
config.setCodePage("500");
|
||||
|
||||
Telnet3270Client client = new Telnet3270Client(config);
|
||||
assertEquals("500", client.getCodePage());
|
||||
assertEquals(500, client.getTranslator().getCpgid());
|
||||
|
||||
// Test changing at runtime
|
||||
client.setCodePage("1047");
|
||||
assertEquals("1047", client.getCodePage());
|
||||
assertEquals(1047, client.getTranslator().getCpgid());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user