/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024, 2026 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии 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 EightBitCharsetDecoder(this); }
public final CharEncoder newEncoder() { return new EightBitCharsetEncoder(this); }
public final String characters { read = fldCharacters }
}
class EightBitCharsetDecoder(CharDecoder)
{
private final EightBitCharset fldCharset;
public (EightBitCharset charset): super(charset) { fldCharset = charset; }
protected void decode(ByteReader src, int length, CharWriter dst) throws CharDecodingException, 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 CharDecodingException {
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 EightBitCharsetCharDecodingException(package.getResourceString("char-decoding.eight-bit-charset")) { byteData = src, charset = charset };
}
if(action == ErrorAction.ignore)
{
return -2;
}
if(action == ErrorAction.report)
{
report();
return -1;
}
return 0x003f;
}
}
class EightBitCharsetEncoder(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 CharEncodingException, 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 CharEncodingException {
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 EightBitCharsetCharEncodingException(package.getResourceString("char-encoding.eight-bit-charset")) { charData = src, charset = charset };
}
if(action == ErrorAction.ignore)
{
return -2;
}
if(action == ErrorAction.report)
{
report();
return -1;
}
return 0x3f;
}
}