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

79 lines
2.2 KiB
Dart

import 'dart:convert';
import 'dart:math';
import 'shift_jis_table.dart';
class ShiftJISDecoder extends Converter<List<int>, String> {
final bool _allowMalformed;
const ShiftJISDecoder({bool allowMalformed = false})
: _allowMalformed = allowMalformed;
@override
convert(input) {
List<int> result = [];
for (int i = 0; i < input.length; i++) {
final c1 = input[i];
List<int>? c2;
if (c1 <= 0x7F) {
// ASCII Compatible (partially)
c2 = JIS_TABLE[c1];
} else if (c1 >= 0xa1 && c1 <= 0xdf) {
// Half-width Hiragana
c2 = JIS_TABLE[c1];
} else if (c1 >= 0x81 && c1 <= 0x9f) {
// JIS X 0208
c2 = JIS_TABLE[(c1 << 8) + input[++i]];
} else if (c1 >= 0xe0 && c1 <= 0xef) {
// JIS X 0208
c2 = JIS_TABLE[(c1 << 8) + input[++i]];
} else {
// Unknown
}
if (c2 != null) {
result.addAll(c2);
} else if (_allowMalformed) {
result.add(unicodeReplacementCharacterRune);
} else {
throw FormatException('Unfinished Shift-JIS octet sequence', input, i);
}
}
return utf8.decode(result, allowMalformed: _allowMalformed);
}
}
class ShiftJISEncoder extends Converter<String, List<int>> {
const ShiftJISEncoder();
@override
List<int> convert(String input) {
List<int> result = [];
for (int i = 0; i < input.length; i++) {
var bytes = utf8.encode(input[i]);
var value = 0;
for (var i = 0, length = bytes.length; i < length; i++) {
value += bytes[i] * (pow(256, (bytes.length - i - 1)) as int);
}
result.addAll(UTF_TABLE[value] ?? [0xFFFD]);
}
return result;
}
}
class ShiftJISCodec extends Encoding {
final bool _allowMalformed;
const ShiftJISCodec({bool allowMalformed = false})
: _allowMalformed = allowMalformed;
@override
Converter<List<int>, String> get decoder => _allowMalformed
? const ShiftJISDecoder(allowMalformed: true)
: const ShiftJISDecoder(allowMalformed: false);
@override
Converter<String, List<int>> get encoder => const ShiftJISEncoder();
@override
String get name => 'shift-jis';
}
const shiftJis = ShiftJISCodec();