|
|
@@ -0,0 +1,142 @@
|
|
|
+package net.ranides.assira.text;
|
|
|
+
|
|
|
+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.CoderResult;
|
|
|
+import java.nio.charset.spi.CharsetProvider;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Locale;
|
|
|
+import java.util.Set;
|
|
|
+import net.ranides.assira.collection.sets.HashSet;
|
|
|
+
|
|
|
+public class MazoviaCharset extends CharsetProvider {
|
|
|
+
|
|
|
+ public static final String CS_NAME = "mazovia";
|
|
|
+
|
|
|
+ public final static String[] NAMES = new String[]{
|
|
|
+ "cp-896",
|
|
|
+ "cp896",
|
|
|
+ "cp620",
|
|
|
+ "cp-620",
|
|
|
+ "cp790",
|
|
|
+ "cp-790"
|
|
|
+ };
|
|
|
+
|
|
|
+ private static final Set<String> NAMES_SET = new HashSet<>(NAMES);
|
|
|
+
|
|
|
+ private static final List<Charset> CHARSETS = Arrays.asList(new MCharset());
|
|
|
+
|
|
|
+ private static final char[][] CHARMAP = new char[][]{
|
|
|
+ {'\u0104', 143}//Ą
|
|
|
+ , {'\u0105', 134}//ą
|
|
|
+ , {'\u0106', 149}//Ć
|
|
|
+ , {'\u0107', 141}//ć
|
|
|
+ , {'\u0118', 144}//Ę
|
|
|
+ , {'\u0119', 145}//ę
|
|
|
+ , {'\u0141', 156}//Ł
|
|
|
+ , {'\u0142', 146}//ł
|
|
|
+ , {'\u0143', 165}//Ń
|
|
|
+ , {'\u0144', 164}//ń
|
|
|
+ , {'\u00D3', 163}//Ó
|
|
|
+ , {'\u00F3', 162}//ó
|
|
|
+ , {'\u015A', 152}//Ś
|
|
|
+ , {'\u015B', 158}//ś
|
|
|
+ , {'\u0179', 160}//Ź
|
|
|
+ , {'\u017A', 166}//ź
|
|
|
+ , {'\u017B', 161}//Ż
|
|
|
+ , {'\u017C', 167}//ż
|
|
|
+ };
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Iterator<Charset> charsets() {
|
|
|
+ return CHARSETS.iterator();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Charset charsetForName(String charsetName) {
|
|
|
+ if(CS_NAME.equalsIgnoreCase(charsetName)){
|
|
|
+ return CHARSETS.get(0);
|
|
|
+ }
|
|
|
+ if (NAMES_SET.contains(charsetName.toLowerCase(Locale.ROOT).trim())) {
|
|
|
+ return CHARSETS.get(0);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class MCharset extends Charset {
|
|
|
+
|
|
|
+ public MCharset() {
|
|
|
+ super(CS_NAME, NAMES);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean contains(Charset cs) {
|
|
|
+ return cs.equals(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CharsetEncoder newEncoder() {
|
|
|
+ return new MEncoder(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CharsetDecoder newDecoder() {
|
|
|
+ return new MDecoder(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class MEncoder extends CharsetEncoder {
|
|
|
+
|
|
|
+ public MEncoder(Charset cs) {
|
|
|
+ super(cs, 1, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
|
|
|
+ while (in.hasRemaining()) {
|
|
|
+ out.put((byte) (encodeChar(in.get()) & 0xFF));
|
|
|
+ }
|
|
|
+ return CoderResult.UNDERFLOW;
|
|
|
+ }
|
|
|
+
|
|
|
+ private char encodeChar(char c) {
|
|
|
+ for (char[] m : CHARMAP) {
|
|
|
+ if (c == m[0]) {
|
|
|
+ return m[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class MDecoder extends CharsetDecoder {
|
|
|
+
|
|
|
+ public MDecoder(Charset cs) {
|
|
|
+ super(cs, 1, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
|
|
|
+ while (in.hasRemaining()) {
|
|
|
+ out.put(decodeChar((char) (in.get() & 0x00FF)));
|
|
|
+ }
|
|
|
+ return CoderResult.UNDERFLOW;
|
|
|
+ }
|
|
|
+
|
|
|
+ private char decodeChar(char c) {
|
|
|
+ for (char[] m : CHARMAP) {
|
|
|
+ if (c == m[1]) {
|
|
|
+ return m[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|