/*
Исходный код среды исполнения ПВТ-ОО.
Этот исходный код является частью проекта ПВТ-ОО.
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;
}
}