EightBitCharset.avt

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

/*
    Исходный код среды исполнения ПВТ-ОО.

    Этот исходный код является частью проекта ПВТ-ОО.

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

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

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

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

package avt.io.charset.rtlang;

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

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

    protected (String name, String[] aliases, String chars): super(name, aliases) { fldChars = chars; }

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

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

    public final String chars { read = fldChars }
}

final 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.chars[src - 0x80];
        if(result > 0) return result;
        ErrorAction action = errorAction;
        if(action == ErrorAction.exception)
        {
            throw new EightBitCharsetCharacterDecodingException("ошибка декодирования байта") { byteData = src, charset = charset };
        }
        if(action == ErrorAction.ignore)
        {
            return -2;
        }
        if(action == ErrorAction.report)
        {
            report();
            return -1;
        }
        return 0x003f;
    }
}

final class EightBitCharEncoder(CharEncoder)
{
    private final EightBitCharset fldCharset;

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

    public boolean canEncode(char src) { return src < 0x0080 || fldCharset.chars.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.chars.indexOf(src);
        if(result >= 0) return result + 0x80;
        ErrorAction action = errorAction;
        if(action == ErrorAction.exception)
        {
            throw new EightBitCharsetCharacterEncodingException("ошибка кодирования символа") { charData = src, charset = charset };
        }
        if(action == ErrorAction.ignore)
        {
            return -2;
        }
        if(action == ErrorAction.report)
        {
            report();
            return -1;
        }
        return 0x3f;
    }
}