EightBitCharset.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Реализация среды исполнения языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package avt.io.charset.eightbit;

import avt.io.*;
import avt.io.charset.*;

public abstract class EightBitCharset(Charset)
{
    private final String fldCharacters;

    protected (String name, String[] aliases, String characters): super(name, aliases) { fldCharacters = characters; }

    public final CharDecoder newDecoder() { return new EightBitCharDecoder(this); }

    public final CharEncoder newEncoder() { return new EightBitCharEncoder(this); }

    public final String characters { read = fldCharacters }
}

class EightBitCharDecoder(CharDecoder)
{
    private final EightBitCharset fldCharset;

    public (EightBitCharset charset): super(charset) { fldCharset = charset; }

    protected void decode(ByteReader src, int length, CharWriter dst) throws CharacterDecodingException, IOException {
        while(length-- > 0)
        {
            int byteData = src.read();
            if(byteData < 0 || byteData > 0xff) break;
            int charData = decode(byteData);
            if(charData == -1) break;
            if(charData >= 0) dst.write(charData);
        }
    }

    private int decode(int src) throws CharacterDecodingException {
        if(src < 0x80) return src;
        EightBitCharset charset = fldCharset;
        int result = charset.characters[src - 0x80];
        if(result > 0) return result;
        ErrorAction action = errorAction;
        if(action == ErrorAction.exception)
        {
            throw new EightBitCharsetCharacterDecodingException(package.getResourceString("character-decoding.eight-bit-charset")) { byteData = src, charset = charset };
        }
        if(action == ErrorAction.ignore)
        {
            return -2;
        }
        if(action == ErrorAction.report)
        {
            report();
            return -1;
        }
        return 0x003f;
    }
}

class EightBitCharEncoder(CharEncoder)
{
    private final EightBitCharset fldCharset;

    public (EightBitCharset charset): super(charset) { fldCharset = charset; }

    public boolean canEncode(char src) { return src < 0x0080 || fldCharset.characters.indexOf(src) >= 0; }

    protected void encode(CharReader src, int length, ByteWriter dst) throws CharacterEncodingException, IOException {
        while(length-- > 0)
        {
            int charData = src.read();
            if(charData < 0 || charData > 0xffff) break;
            int byteData = encode(charData);
            if(byteData == -1) break;
            if(byteData >= 0) dst.write(byteData);
        }
    }

    private int encode(int src) throws CharacterEncodingException {
        if(src < 0x0080) return src;
        EightBitCharset charset = fldCharset;
        int result = charset.characters.indexOf(src);
        if(result >= 0) return result + 0x80;
        ErrorAction action = errorAction;
        if(action == ErrorAction.exception)
        {
            throw new EightBitCharsetCharacterEncodingException(package.getResourceString("character-encoding.eight-bit-charset")) { charData = src, charset = charset };
        }
        if(action == ErrorAction.ignore)
        {
            return -2;
        }
        if(action == ErrorAction.report)
        {
            report();
            return -1;
        }
        return 0x3f;
    }
}