All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.java.truevfs.comp.ibm437.OctetCharset Maven / Gradle / Ivy

/*
 * Copyright (C) 2005-2015 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package net.java.truevfs.comp.ibm437;

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.util.Arrays;
import javax.annotation.concurrent.Immutable;

/**
 * A memory efficient base class for simple 8 bit (octet) character sets.
 *
 * @author Christian Schlichtherle
 */
@Immutable
public abstract class OctetCharset extends Charset {

    /**
     * Use this character in the lookup table provided to the constructor for
     * every character that does not have a replacement in 16 bit Unicode.
     */
    protected static final char REPLACEMENT = 0xFFFD;

    private final char[] byte2char;
    private final char[][] char2byte;

    protected OctetCharset( final String cname,
                            String[] aliases,
                            char[] byte2char) {
        super(cname, aliases = aliases.clone());
        byte2char = byte2char.clone();

        // Construct sparse inverse lookup table.
        final char[][] char2byte = new char[256][];
        for (char i = 0; i < 256; i++) {
            final char c = byte2char[i];
            if (c == REPLACEMENT)
                continue;

            final int hi = c >>> 8;
            final int lo = c & 0xFF;
            char[] table = char2byte[hi];
            if (table == null) {
                table = new char[256];
                Arrays.fill(table, REPLACEMENT);
                char2byte[hi] = table;
            }
            table[lo] = i;
        }

        this.byte2char = byte2char;
        this.char2byte = char2byte;
    }

    @Override
    public boolean contains(Charset cs) {
        return this.getClass().isInstance(cs);
    }

    @Override
    public CharsetEncoder newEncoder() {
        return new Encoder();
    }

    private class Encoder extends CharsetEncoder {
        Encoder() {
            super(OctetCharset.this, 1, 1);
        }

        @Override
        protected CoderResult encodeLoop(   final CharBuffer in,
                                            final ByteBuffer out) {
            final char[][] c2b = char2byte;
            while (in.hasRemaining()) {
                if (!out.hasRemaining())
                    return CoderResult.OVERFLOW;
                final char c = in.get();
                final int hi = c >>> 8;
                final int lo = c & 0xFF;
                final char[] table = c2b[hi];
                final char b;
                if (table == null || (b = table[lo]) == REPLACEMENT) { // char is unsigned!
                    in.position(in.position() - 1); // push back
                    return CoderResult.unmappableForLength(1);
                }
                out.put((byte) b); // char is unsigned!
            }
            return CoderResult.UNDERFLOW;
        }
    }

    @Override
    public CharsetDecoder newDecoder() {
        return new Decoder();
    }

    private class Decoder extends CharsetDecoder {
        Decoder() {
            super(OctetCharset.this, 1, 1);
        }

        @Override
        protected CoderResult decodeLoop(   final ByteBuffer in,
                                            final CharBuffer out) {
            final char[] b2c = byte2char;
            while (in.hasRemaining()) {
                if (!out.hasRemaining())
                    return CoderResult.OVERFLOW;
                final char c = b2c[in.get() & 0xFF];
                if (c == REPLACEMENT) {
                    in.position(in.position() - 1); // push back
                    return CoderResult.unmappableForLength(1);
                }
                out.put(c);
            }
            return CoderResult.UNDERFLOW;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy