dart-app-core/lib/charset/euc_kr.dart
2023-03-26 01:48:46 +09:00

90 lines
2.4 KiB
Dart

import 'dart:convert';
import 'euc_kr_table.dart';
const eucKr = EucKRCodec(true);
class EucKRCodec extends Encoding {
final bool _allowInvalid;
const EucKRCodec([this._allowInvalid = false]) : super();
@override
String get name => "euc-kr";
@override
EucKREncoder get encoder => const EucKREncoder();
@override
EucKRDecoder get decoder =>
_allowInvalid ? const EucKRDecoder(true) : const EucKRDecoder();
}
class EucKREncoder extends Converter<String, List<int>> {
const EucKREncoder();
@override
List<int> convert(String input) {
List<int> bits = [];
for (var i in input.codeUnits) {
if (i < 0x80) {
bits.add(i);
} else {
int code = utf8ToEucKr[i] ?? 0;
if (code > 0) {
// bits.add(code ~/ 190 + 0x81);
// bits.add(code % 190 + 0x41);
bits.add(code >> 8);
bits.add(code & 0xff);
}
}
}
return bits;
}
}
class EucKRDecoder extends Converter<List<int>, String> {
final bool _allowInvalid;
const EucKRDecoder([this._allowInvalid = false]);
@override
String convert(List<int> input) {
int leadPointer = 0;
StringBuffer sb = StringBuffer();
for (int i = 0; i < input.length; i++) {
int pointer = input[i];
if (leadPointer != 0) {
if (pointer >= 0x41 && pointer <= 0xfe) {
//int code = (leadPointer - 0x81) * 190 + (pointer - 0x41);
int code = (leadPointer << 8) + pointer;
final charCode = code < 0x80 ? code : utf8ToEucKr[code];
if (charCode == null && !_allowInvalid) {
throw FormatException('Unfinished Euc-KR octet sequence', input, i);
} else {
sb.writeCharCode(charCode ?? unicodeReplacementCharacterRune);
}
}
leadPointer = 0;
} else if (pointer < 0x80) {
sb.writeCharCode(pointer);
} else if (pointer >= 0x81 && pointer <= 0xfe) {
leadPointer = pointer;
} else {
if (!_allowInvalid) {
throw FormatException('Unfinished Euc-KR octet sequence', input, i);
}
sb.writeCharCode(unicodeReplacementCharacterRune);
}
}
if (leadPointer != 0) {
if (!_allowInvalid) {
throw FormatException(
'Unfinished Euc-KR octet sequence',
input,
leadPointer,
);
}
}
return sb.toString();
}
}