79 lines
2.2 KiB
Dart
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();
|