package org.jcodings;
import org.jcodings.exception.ErrorMessages;
import org.jcodings.exception.InternalException;
import org.jcodings.util.CaseInsensitiveBytesHash;
public final class EncodingDB {
public static final class Entry {
private static int count;
private final Entry base;
private Encoding encoding;
private final String encodingClass;
private final int index;
private final boolean isDummy;
private final byte[]name;
private Entry (byte[]name, String encodingClass, Entry base, boolean isDummy) {
this.name = name;
this.encodingClass = encodingClass;
this.base = base;
this.isDummy = isDummy;
index = count++;
}
Entry(String encodingClass) {
this(null, encodingClass, null, false);
}
Entry(byte[]name, Entry base) {
this(name, base.encodingClass, base, false);
}
Entry(byte[]name) {
this(name, ascii.encodingClass, ascii, true);
}
Entry(byte[]name, Entry base, boolean dummy) {
this(name, base.encodingClass, base, dummy);
}
@Override
public int hashCode() {
return encodingClass.hashCode();
}
public Entry getBase() {
return base;
}
public Encoding getEncoding() {
if (encoding == null) {
if (name == null) {
encoding = EncodingList.getInstance(encodingClass);
} else {
encoding = EncodingList.getInstance(encodingClass).replicate(name);
if (isDummy) encoding.setDummy();
}
}
return encoding;
}
public String getEncodingClass() {
return encodingClass;
}
public int getIndex() {
return index;
}
public boolean isDummy() {
return isDummy;
}
}
static Entry ascii;
static final CaseInsensitiveBytesHash<Entry> encodings = new CaseInsensitiveBytesHash<Entry>(50);
static final CaseInsensitiveBytesHash<Entry> aliases = new CaseInsensitiveBytesHash<Entry>(150);
public static final CaseInsensitiveBytesHash<Entry> getEncodings() {
return encodings;
}
public static final CaseInsensitiveBytesHash<Entry> getAliases() {
return aliases;
}
public static void declare(String name, String encodingClass) {
byte[]bytes = name.getBytes();
if (encodings.get(bytes) != null) throw new InternalException(ErrorMessages.ERR_ENCODING_ALREADY_REGISTERED, name);
encodings.putDirect(bytes, new Entry(encodingClass));
}
public static void alias(String alias, String original) {
byte[]origBytes = original.getBytes();
Entry originalEntry = encodings.get(origBytes);
if (originalEntry == null) throw new InternalException(ErrorMessages.ERR_NO_SUCH_ENCODNG, original);
byte[]aliasBytes = alias.getBytes();
if (aliases.get(aliasBytes) != null) throw new InternalException(ErrorMessages.ERR_ENCODING_ALIAS_ALREADY_REGISTERED, alias);
aliases.putDirect(aliasBytes, originalEntry);
}
public static void replicate(String replica, String original) {
byte[]origBytes = original.getBytes();
Entry originalEntry = encodings.get(origBytes);
if (originalEntry == null) throw new InternalException(ErrorMessages.ERR_NO_SUCH_ENCODNG, original);
finishReplica(replica, originalEntry.isDummy, originalEntry);
}
private static void replicate(String replica, String original, boolean dummy) {
byte[]origBytes = original.getBytes();
Entry originalEntry = encodings.get(origBytes);
if (originalEntry == null) throw new InternalException(ErrorMessages.ERR_NO_SUCH_ENCODNG, original);
finishReplica(replica, dummy, originalEntry);
}
private static void finishReplica(String replica, boolean dummy, Entry originalEntry) {
byte[]replicaBytes = replica.getBytes();
if (encodings.get(replicaBytes) != null) throw new InternalException(ErrorMessages.ERR_ENCODING_REPLICA_ALREADY_REGISTERED, replica);
encodings.putDirect(replicaBytes, new Entry(replicaBytes, originalEntry, dummy));
}
public static void set_base(String name, String original) {
}
public static Entry dummy(byte[] bytes) {
if (encodings.get(bytes) != null) throw new InternalException(ErrorMessages.ERR_ENCODING_ALREADY_REGISTERED, new String(bytes));
Entry entry = new Entry(bytes);
encodings.putDirect(bytes, entry);
return entry;
}
public static void dummy(String name) {
dummy(name.getBytes());
}
public static void dummy_unicode(String replica) {
replicate(replica, replica + "BE", true);
}
static {
EncodingList.load();
}
}