From 7ef121789515071797bfaf4048aee7a9fa58a29b Mon Sep 17 00:00:00 2001 From: Robert Virkus Date: Wed, 9 Dec 2020 15:49:20 +0100 Subject: [PATCH] Initial version with support for ISO 8859 1-16, Windows 1250, 1251 and 1252 character encodings --- .gitignore | 13 ++ CHANGELOG.md | 3 + README.md | 61 +++++++++ analysis_options.yaml | 14 +++ example/enough_convert_example.dart | 109 ++++++++++++++++ lib/base.dart | 121 ++++++++++++++++++ lib/enough_convert.dart | 24 ++++ lib/latin/latin.dart | 25 ++++ lib/latin/latin1.dart | 146 +++++++++++++++++++++ lib/latin/latin10.dart | 156 +++++++++++++++++++++++ lib/latin/latin11.dart | 148 ++++++++++++++++++++++ lib/latin/latin13.dart | 156 +++++++++++++++++++++++ lib/latin/latin14.dart | 156 +++++++++++++++++++++++ lib/latin/latin15.dart | 156 +++++++++++++++++++++++ lib/latin/latin16.dart | 156 +++++++++++++++++++++++ lib/latin/latin2.dart | 156 +++++++++++++++++++++++ lib/latin/latin3.dart | 149 ++++++++++++++++++++++ lib/latin/latin4.dart | 156 +++++++++++++++++++++++ lib/latin/latin5.dart | 156 +++++++++++++++++++++++ lib/latin/latin6.dart | 111 ++++++++++++++++ lib/latin/latin7.dart | 153 ++++++++++++++++++++++ lib/latin/latin8.dart | 120 ++++++++++++++++++ lib/latin/latin9.dart | 156 +++++++++++++++++++++++ lib/windows/windows.dart | 25 ++++ lib/windows/windows1250.dart | 184 +++++++++++++++++++++++++++ lib/windows/windows1251.dart | 188 ++++++++++++++++++++++++++++ lib/windows/windows1252.dart | 184 +++++++++++++++++++++++++++ pubspec.yaml | 14 +++ test/latin/latin10_test.dart | 98 +++++++++++++++ test/latin/latin11_test.dart | 94 ++++++++++++++ test/latin/latin13_test.dart | 98 +++++++++++++++ test/latin/latin14_test.dart | 107 ++++++++++++++++ test/latin/latin15_test.dart | 102 +++++++++++++++ test/latin/latin16_test.dart | 101 +++++++++++++++ test/latin/latin1_test.dart | 58 +++++++++ test/latin/latin2_test.dart | 83 ++++++++++++ test/latin/latin3_test.dart | 84 +++++++++++++ test/latin/latin4_test.dart | 88 +++++++++++++ test/latin/latin5_test.dart | 90 +++++++++++++ test/latin/latin6_test.dart | 87 +++++++++++++ test/latin/latin7_test.dart | 94 ++++++++++++++ test/latin/latin8_test.dart | 102 +++++++++++++++ test/latin/latin9_test.dart | 99 +++++++++++++++ test/windows/windows1250_test.dart | 94 ++++++++++++++ test/windows/windows1251_test.dart | 89 +++++++++++++ test/windows/windows1252_test.dart | 94 ++++++++++++++ 46 files changed, 4858 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 example/enough_convert_example.dart create mode 100644 lib/base.dart create mode 100644 lib/enough_convert.dart create mode 100644 lib/latin/latin.dart create mode 100644 lib/latin/latin1.dart create mode 100644 lib/latin/latin10.dart create mode 100644 lib/latin/latin11.dart create mode 100644 lib/latin/latin13.dart create mode 100644 lib/latin/latin14.dart create mode 100644 lib/latin/latin15.dart create mode 100644 lib/latin/latin16.dart create mode 100644 lib/latin/latin2.dart create mode 100644 lib/latin/latin3.dart create mode 100644 lib/latin/latin4.dart create mode 100644 lib/latin/latin5.dart create mode 100644 lib/latin/latin6.dart create mode 100644 lib/latin/latin7.dart create mode 100644 lib/latin/latin8.dart create mode 100644 lib/latin/latin9.dart create mode 100644 lib/windows/windows.dart create mode 100644 lib/windows/windows1250.dart create mode 100644 lib/windows/windows1251.dart create mode 100644 lib/windows/windows1252.dart create mode 100644 pubspec.yaml create mode 100644 test/latin/latin10_test.dart create mode 100644 test/latin/latin11_test.dart create mode 100644 test/latin/latin13_test.dart create mode 100644 test/latin/latin14_test.dart create mode 100644 test/latin/latin15_test.dart create mode 100644 test/latin/latin16_test.dart create mode 100644 test/latin/latin1_test.dart create mode 100644 test/latin/latin2_test.dart create mode 100644 test/latin/latin3_test.dart create mode 100644 test/latin/latin4_test.dart create mode 100644 test/latin/latin5_test.dart create mode 100644 test/latin/latin6_test.dart create mode 100644 test/latin/latin7_test.dart create mode 100644 test/latin/latin8_test.dart create mode 100644 test/latin/latin9_test.dart create mode 100644 test/windows/windows1250_test.dart create mode 100644 test/windows/windows1251_test.dart create mode 100644 test/windows/windows1252_test.dart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c44ab0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Files and directories created by pub +.dart_tool/ +.packages + +# Omit commiting pubspec.lock for library packages: +# https://dart.dev/guides/libraries/private-files#pubspeclock +pubspec.lock + +# Conventional directory for build outputs +build/ + +# Directory created by dartdoc +doc/api/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d7ad2c4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.9.0 + +- Initial version with support for ISO 8859 1-16, Windows 1250, 1251 and 1252 character encodings diff --git a/README.md b/README.md new file mode 100644 index 0000000..e0ab989 --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +Support for ISO 8859 / Latin and Windows character encodings missing from `dart:convert`. + +Supporting the following encodings: +* Latin / ISO 8859 encodings: + * Latin 1 / ISO 8859-1 + * Latin 2 / ISO 8859-2 + * Latin 3 / ISO 8859-3 + * Latin 4 / ISO 8859-4 + * Latin 5 / ISO 8859-5 + * Latin 6 / ISO 8859-6 + * Latin 7 / ISO 8859-7 + * Latin 8 / ISO 8859-8 + * Latin 9 / ISO 8859-9 + * Latin 10 / ISO 8859-10 + * Latin 11 / ISO 8859-11 + * Latin 13 / ISO 8859-13 + * Latin 14 / ISO 8859-14 + * Latin 15 / ISO 8859-15 + * Latin 16 / ISO 8859-16 +* Windows Codepage Encodings: + * Windows-1250 / cp-1250 + * Windows-1251 / cp-1251 + * Windows-1252 / cp-1252 + + +## Usage + +Using `enough_convert` is pretty straight forward: + +```dart +import 'package:enough_convert/enough_convert.dart'; + +main() { + final codec = const Windows1252Codec(allowInvalid: false); + final input = 'Il faut être bête quand même.'; + final encoded = codec.encode(input); + final decoded = codec.decode([...encoded]); + print('${codec.name}: encode "$input" to "$encoded"'); + print('${codec.name}: decode $encoded to "$decoded"'); + +} +``` + +## Installation +Add this dependency your pubspec.yaml file: + +``` +dependencies: + enough_convert: ^0.9.0 +``` +The latest version or `enough_convert` is [![enough_convert version](https://img.shields.io/pub/v/enough_convert.svg)](https://pub.dartlang.org/packages/enough_convert). + + +## Features and bugs + +Please file feature requests and bugs at the [issue tracker][tracker]. + +[tracker]: https://github.com/Enough-Software/enough_convert/issues + +## License +`enough_convert` is licensed under the commercial friendly [Mozilla Public License 2.0](LICENSE) diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..a686c1b --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,14 @@ +# Defines a default set of lint rules enforced for +# projects at Google. For details and rationale, +# see https://github.com/dart-lang/pedantic#enabled-lints. +include: package:pedantic/analysis_options.yaml + +# For lint rules and documentation, see http://dart-lang.github.io/linter/lints. +# Uncomment to specify additional rules. +# linter: +# rules: +# - camel_case_types + +analyzer: +# exclude: +# - path/to/excluded/files/** diff --git a/example/enough_convert_example.dart b/example/enough_convert_example.dart new file mode 100644 index 0000000..da24be1 --- /dev/null +++ b/example/enough_convert_example.dart @@ -0,0 +1,109 @@ +import 'dart:convert' as cnvrt; + +import 'package:enough_convert/enough_convert.dart'; + +void main() { + latin2(); + latin3(); + latin4(); + latin5(); + latin6(); + latin7(); + latin8(); + latin9(); + latin10(); + latin11(); + latin13(); + latin14(); + latin15(); + latin16(); + windows1250(); + windows1251(); + windows1252(); +} + +void latin2() { + roundtrip( + const Latin2Codec(allowInvalid: false), 'Těší mě, že vás poznávám!'); +} + +void latin3() { + roundtrip( + const Latin3Codec(allowInvalid: false), 'Tanıştığımıza memnun oldum!'); +} + +void latin4() { + roundtrip(const Latin4Codec(allowInvalid: false), 'Priecājos iepazīties!'); +} + +void latin5() { + roundtrip(const Latin5Codec(allowInvalid: false), 'Приятно встретиться!'); +} + +void latin6() { + roundtrip(const Latin6Codec(allowInvalid: false), 'سعدت بلقائك'); +} + +void latin7() { + roundtrip( + const Latin7Codec(allowInvalid: false), 'Χαίρομαι που σας γνωρίζω!'); +} + +void latin8() { + roundtrip(const Latin8Codec(allowInvalid: false), + 'נעים להכיר אותך.נעים להכיר אותך-.'); +} + +void latin9() { + roundtrip( + const Latin9Codec(allowInvalid: false), 'Tanıştığımıza memnun oldum!'); +} + +void latin10() { + roundtrip(const Latin10Codec(allowInvalid: false), 'Hyggelig å møte deg!'); +} + +void latin11() { + roundtrip(const Latin11Codec(allowInvalid: false), 'ยินดีที่ได้พบคุณ!'); +} + +void latin13() { + roundtrip(const Latin13Codec(allowInvalid: false), 'Hyggelig å møte deg!'); +} + +void latin14() { + roundtrip(const Latin14Codec(allowInvalid: false), + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.'); +} + +void latin15() { + roundtrip( + const Latin15Codec(allowInvalid: false), 'Il faut être bête quand même.'); +} + +void latin16() { + roundtrip( + const Latin16Codec(allowInvalid: false), 'Örülök, hogy találkoztunk!'); +} + +void windows1250() { + roundtrip(const Windows1250Codec(allowInvalid: false), + 'Teší ma, že vás spoznávam!'); +} + +void windows1251() { + roundtrip(const Windows1251Codec(allowInvalid: false), + 'Радий познайомитися з Вами!'); +} + +void windows1252() { + roundtrip(const Windows1252Codec(allowInvalid: false), + 'Il faut être bête quand même.'); +} + +void roundtrip(cnvrt.Encoding codec, String input) { + final encoded = codec.encode(input); + final decoded = codec.decode([...encoded]); + print('${codec.name}: encode "$input" to "$encoded"'); + print('${codec.name}: decode $encoded to "$decoded"'); +} diff --git a/lib/base.dart b/lib/base.dart new file mode 100644 index 0000000..1b69a8e --- /dev/null +++ b/lib/base.dart @@ -0,0 +1,121 @@ +import 'dart:convert' as cnvrt; + +/// Contains base classes for latin 2 to latin 16 / iso-8859-XX codecs + +/// Provides a simple, non chunkable iso-8859-XX decoder. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class BaseDecoder extends cnvrt.Converter, String> { + final String symbols; + final int startIndex; + final bool allowInvalid; + + /// Creates a new 8bit decoder. + /// [symbols] contain all symbols different than UTF8 from the specified [startIndex] onwards. + /// The length of the [symbols] need to be `255` / `0xFF` minus the [startIndex]. + /// Set [allowedInvalid] to true in case invalid characters sequences should be at least readable. + const BaseDecoder(this.symbols, this.startIndex, {this.allowInvalid = false}) + : assert(symbols?.length == 255 - startIndex); + + @override + String convert(List bytes, [int start = 0, int end]) { + end = RangeError.checkValidRange(start, end, bytes.length); + if (end == null) { + throw RangeError('Invalid range'); + } + // note: this directly modifies the given data, so decoding the + // same byte array twice will not work + for (var i = start; i < end; i++) { + final byte = bytes[i]; + if ((byte & ~0xFF) != 0) { + if (!allowInvalid) { + throw FormatException('Invalid value in input: $byte at position $i'); + } else { + bytes[i] = 0xFFFD; // unicode � + } + } else if (byte > startIndex) { + final index = byte - (startIndex + 1); + bytes[i] = symbols.codeUnitAt(index); + } + } + return String.fromCharCodes(bytes, start, end); + } +} + +/// Provides a simple, non chunkable 8bit encoder. +class BaseEncoder extends cnvrt.Converter> { + final bool allowInvalid; + final Map encodingMap; + final int startIndex; + + /// Creates a new encoder. + /// Set [allowedInvalid] to true in case invalid characters should be translated to question marks. + const BaseEncoder(this.encodingMap, this.startIndex, + {this.allowInvalid = false}); + + /// Static helper function to generate a conversion map from a symbols string. + static Map createEncodingMap(String symbols, int startIndex) { + final runes = symbols.runes; + final map = {}; + var index = 0; + if (runes.length != 255 - startIndex) { + print( + 'WARNING: there are not ${255 - startIndex} symbols but ${runes.length} runes in the specified map - is the given startIndex $startIndex correct?'); + } + for (final rune in runes) { + if (rune != 0x3F) { + // "?" denote an empty slot in the map + final value = index + startIndex + 1; + if (map.containsValue(value)) { + final symbol = symbols.substring(index, index + 1); + final firstIndex = symbols.indexOf(symbol); + final lastIndex = symbols.lastIndexOf(symbol); + throw FormatException( + 'Duplicate value $value for isoSymbols "$symbol" at index $index - in symbols to found at $firstIndex and $lastIndex'); + } + if (value <= startIndex) { + final symbol = symbols.substring(index, index + 1); + throw FormatException( + 'Invalid value $value for "$symbol" at index $index'); + } + map[rune] = value; + print('\t$rune: $value,'); + } + index++; + } + return map; + } + + @override + List convert(String input, [int start = 0, int end]) { + final runes = input.runes; + end = RangeError.checkValidRange(start, end, runes.length); + if (end == null) { + throw RangeError('Invalid range'); + } + var runesList = runes.toList(growable: false); + if (start > 0 || end < runesList.length) { + runesList = runesList.sublist(start, end); + } + for (var i = 0; i < runesList.length; i++) { + var rune = runesList[i]; + if (rune > startIndex) { + final value = encodingMap[rune]; + if (value == null) { + if (!allowInvalid) { + throw FormatException( + 'Invalid value in input: ${String.fromCharCode(rune)} ($rune) at $i'); + } else { + runesList[i] = 0x3F; // ? + } + } else { + runesList[i] = value; + } + } + } + return runesList; + } +} diff --git a/lib/enough_convert.dart b/lib/enough_convert.dart new file mode 100644 index 0000000..0d91c30 --- /dev/null +++ b/lib/enough_convert.dart @@ -0,0 +1,24 @@ +/// Provides missing common character encoders / decoders / codecs / encodings for Dart. +library enough_convert; + +export 'base.dart'; +export 'latin/latin.dart'; +export 'latin/latin1.dart'; +export 'latin/latin2.dart'; +export 'latin/latin3.dart'; +export 'latin/latin4.dart'; +export 'latin/latin5.dart'; +export 'latin/latin6.dart'; +export 'latin/latin7.dart'; +export 'latin/latin8.dart'; +export 'latin/latin9.dart'; +export 'latin/latin10.dart'; +export 'latin/latin11.dart'; +export 'latin/latin13.dart'; +export 'latin/latin14.dart'; +export 'latin/latin15.dart'; +export 'latin/latin16.dart'; +export 'windows/windows.dart'; +export 'windows/windows1250.dart'; +export 'windows/windows1251.dart'; +export 'windows/windows1252.dart'; diff --git a/lib/latin/latin.dart b/lib/latin/latin.dart new file mode 100644 index 0000000..f781026 --- /dev/null +++ b/lib/latin/latin.dart @@ -0,0 +1,25 @@ +import 'package:enough_convert/base.dart'; + +/// Contains base classes for latin 2 to latin 16 / iso-8859-XX codecs + +/// Provides a simple, non chunkable iso-8859-XX decoder. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class LatinDecoder extends BaseDecoder { + /// Creates a new latin 1 decoder. + /// The [symbols] need to be exactly `95` characters long. + /// Set [allowedInvalid] to true in case invalid characters sequences should be at least readable. + const LatinDecoder(String symbols, {bool allowInvalid = false}) + : super(symbols, 0xA0, allowInvalid: allowInvalid); +} + +/// Provides a simple, non chunkable iso-8859-XX encoder. +class LatinEncoder extends BaseEncoder { + /// Creates a new latin / iso-8859-XX encoder. + /// Set [allowedInvalid] to true in case invalid characters should be translated to question marks. + const LatinEncoder(Map encodingMap, {bool allowInvalid = false}) + : super(encodingMap, 0xA0, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin1.dart b/lib/latin/latin1.dart new file mode 100644 index 0000000..121e11f --- /dev/null +++ b/lib/latin/latin1.dart @@ -0,0 +1,146 @@ +import 'dart:convert' as cnvrt; + +/// Provides simple iso-8859-1 / latin 1 support for dart. +/// Use `dart:convert.Latin1Codec` if in doubt. +class Latin1Codec extends cnvrt.Encoding { + final bool allowInvalid; + + const Latin1Codec({this.allowInvalid = false}); + + @override + cnvrt.Converter, String> get decoder => allowInvalid + ? const Latin1Decoder(allowInvalid: true) + : const Latin1Decoder(allowInvalid: false); + + @override + cnvrt.Converter> get encoder => allowInvalid + ? const Latin1Encoder(allowInvalid: true) + : const Latin1Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-1'; +} + +/// Provides a simple, non chunkable iso-8859-1 / latin1 decoder. +class Latin1Decoder extends cnvrt.Converter, String> { + final bool allowInvalid; + + /// Creates a new latin 1 decoder. + /// Set [allowedInvalid] to true in case invalid characters sequences should be at least readable. + const Latin1Decoder({this.allowInvalid = false}); + + @override + String convert(List bytes, [int start = 0, int end]) { + // values of ISO 8859-1 corresponds to the first 256 characters in UTF8, so conversion is trivial + end = RangeError.checkValidRange(start, end, bytes.length); + if (end == null) { + throw RangeError('Invalid range'); + } + + for (var i = start; i < end; i++) { + var byte = bytes[i]; + if ((byte & ~0xFF) != 0) { + if (!allowInvalid) { + throw FormatException('Invalid value in input: $byte'); + } else { + bytes[i] = 0xFFFD; // unicode � + } + } + } + return String.fromCharCodes(bytes, start, end); + } + + // @override + // cnvrt.ByteConversionSink startChunkedConversion(Sink sink) { + // cnvrt.StringConversionSink stringSink; + // if (sink is cnvrt.StringConversionSink) { + // stringSink = sink; + // } else { + // stringSink = cnvrt.StringConversionSink.from(sink); + // } + // return Latin1DecoderSink(stringSink, allowInvalid); + // } +} + +// class Latin1DecoderSink extends cnvrt.ByteConversionSinkBase { +// final cnvrt.StringConversionSink sink; +// final bool allowInvalid; + +// Latin1DecoderSink(this.sink, this.allowInvalid); + +// @override +// void close() { +// sink.close(); +// } + +// @override +// void add(List chunk) { +// addSlice(chunk, 0, chunk.length, false); +// } + +// @override +// void addSlice(List source, int start, int end, bool isLast) { +// RangeError.checkValidRange(start, end, source.length); +// if (start == end) return; +// if (!allowInvalid && source is! Uint8List) { +// // List may contain value outside of the 0..255 range. If so, throw. +// // Technically, we could excuse Uint8ClampedList as well, but it unlikely +// // to be relevant. +// _checkValidLatin1(source, start, end); +// } +// _addSliceToSink(source, start, end, isLast); +// } + +// void _addSliceToSink(List source, int start, int end, bool isLast) { +// sink.add(String.fromCharCodes(source, start, end)); +// if (isLast) { +// close(); +// } +// } + +// void _checkValidLatin1(List source, int start, int end) { +// for (var i = start; i < end; i++) { +// var char = source[i]; +// if (char < 0 || char > 0xff) { +// throw FormatException( +// 'Source contains non-ISO-8859 character code 0x${char.toRadixString(16)}.', +// source, +// i); +// } +// } +// } +// } + +/// Provides a simple, non chunkable iso-8859-1 / latin1 encoder. +class Latin1Encoder extends cnvrt.Converter> { + final bool allowInvalid; + + /// Creates a new latin 1 encoder. + /// Set [allowedInvalid] to true in case invalid characters should be translated to question marks. + const Latin1Encoder({this.allowInvalid = false}); + + @override + List convert(String input, [int start = 0, int end]) { + // 7bit values of ISO 8859 correspond to their ASCII values: + final runes = input.runes; + end = RangeError.checkValidRange(start, end, runes.length); + if (end == null) { + throw RangeError('Invalid range'); + } + var runesList = runes.toList(growable: false); + if (start > 0 || end < runesList.length) { + runesList = runesList.sublist(start, end); + } + for (var i = 0; i < runesList.length; i++) { + var rune = runesList[i]; + if ((rune & ~0xFF) != 0) { + if (!allowInvalid) { + throw FormatException('Invalid value in input: $rune'); + } else { + runesList[i] = 0x3F; // ? + } + } + } + return runesList; + } +} diff --git a/lib/latin/latin10.dart b/lib/latin/latin10.dart new file mode 100644 index 0000000..575775b --- /dev/null +++ b/lib/latin/latin10.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin10Symbols = + 'ĄĒĢĪĨĶ§ĻĐŠŦŽ\u{00AD}ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ'; +const Map _latin10SymbolMap = { + 260: 161, + 274: 162, + 290: 163, + 298: 164, + 296: 165, + 310: 166, + 167: 167, + 315: 168, + 272: 169, + 352: 170, + 358: 171, + 381: 172, + 173: 173, + 362: 174, + 330: 175, + 176: 176, + 261: 177, + 275: 178, + 291: 179, + 299: 180, + 297: 181, + 311: 182, + 183: 183, + 316: 184, + 273: 185, + 353: 186, + 359: 187, + 382: 188, + 8213: 189, + 363: 190, + 331: 191, + 256: 192, + 193: 193, + 194: 194, + 195: 195, + 196: 196, + 197: 197, + 198: 198, + 302: 199, + 268: 200, + 201: 201, + 280: 202, + 203: 203, + 278: 204, + 205: 205, + 206: 206, + 207: 207, + 208: 208, + 325: 209, + 332: 210, + 211: 211, + 212: 212, + 213: 213, + 214: 214, + 360: 215, + 216: 216, + 370: 217, + 218: 218, + 219: 219, + 220: 220, + 221: 221, + 222: 222, + 223: 223, + 257: 224, + 225: 225, + 226: 226, + 227: 227, + 228: 228, + 229: 229, + 230: 230, + 303: 231, + 269: 232, + 233: 233, + 281: 234, + 235: 235, + 279: 236, + 237: 237, + 238: 238, + 239: 239, + 240: 240, + 326: 241, + 333: 242, + 243: 243, + 244: 244, + 245: 245, + 246: 246, + 361: 247, + 248: 248, + 371: 249, + 250: 250, + 251: 251, + 252: 252, + 253: 253, + 254: 254, + 312: 255, +}; + +/// Provides a latin 10 / iso-8859-10 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin10Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin10Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin10Decoder get decoder => allowInvalid + ? const Latin10Decoder(allowInvalid: true) + : const Latin10Decoder(allowInvalid: false); + + @override + Latin10Encoder get encoder => allowInvalid + ? const Latin10Encoder(allowInvalid: true) + : const Latin10Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-10'; +} + +/// Encodes texts into latin 10 / iso-88510-10 data +class Latin10Encoder extends LatinEncoder { + const Latin10Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin10SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 10 / iso-88510-10 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin10Decoder extends LatinDecoder { + const Latin10Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin10Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin11.dart b/lib/latin/latin11.dart new file mode 100644 index 0000000..e4f7dee --- /dev/null +++ b/lib/latin/latin11.dart @@ -0,0 +1,148 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin11Symbols = + 'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู????฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛????'; +const Map _latin11SymbolMap = { + 3585: 161, + 3586: 162, + 3587: 163, + 3588: 164, + 3589: 165, + 3590: 166, + 3591: 167, + 3592: 168, + 3593: 169, + 3594: 170, + 3595: 171, + 3596: 172, + 3597: 173, + 3598: 174, + 3599: 175, + 3600: 176, + 3601: 177, + 3602: 178, + 3603: 179, + 3604: 180, + 3605: 181, + 3606: 182, + 3607: 183, + 3608: 184, + 3609: 185, + 3610: 186, + 3611: 187, + 3612: 188, + 3613: 189, + 3614: 190, + 3615: 191, + 3616: 192, + 3617: 193, + 3618: 194, + 3619: 195, + 3620: 196, + 3621: 197, + 3622: 198, + 3623: 199, + 3624: 200, + 3625: 201, + 3626: 202, + 3627: 203, + 3628: 204, + 3629: 205, + 3630: 206, + 3631: 207, + 3632: 208, + 3633: 209, + 3634: 210, + 3635: 211, + 3636: 212, + 3637: 213, + 3638: 214, + 3639: 215, + 3640: 216, + 3641: 217, + 3642: 218, + 3647: 223, + 3648: 224, + 3649: 225, + 3650: 226, + 3651: 227, + 3652: 228, + 3653: 229, + 3654: 230, + 3655: 231, + 3656: 232, + 3657: 233, + 3658: 234, + 3659: 235, + 3660: 236, + 3661: 237, + 3662: 238, + 3663: 239, + 3664: 240, + 3665: 241, + 3666: 242, + 3667: 243, + 3668: 244, + 3669: 245, + 3670: 246, + 3671: 247, + 3672: 248, + 3673: 249, + 3674: 250, + 3675: 251, +}; + +/// Provides a latin 11 / iso-8859-11 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin11Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin11Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin11Decoder get decoder => allowInvalid + ? const Latin11Decoder(allowInvalid: true) + : const Latin11Decoder(allowInvalid: false); + + @override + Latin11Encoder get encoder => allowInvalid + ? const Latin11Encoder(allowInvalid: true) + : const Latin11Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-11'; +} + +/// Encodes texts into latin 11 / iso-88511-11 data +class Latin11Encoder extends LatinEncoder { + const Latin11Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin11SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 11 / iso-88511-11 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin11Decoder extends LatinDecoder { + const Latin11Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin11Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin13.dart b/lib/latin/latin13.dart new file mode 100644 index 0000000..ec5af1a --- /dev/null +++ b/lib/latin/latin13.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin13Symbols = + '”¢£¤„¦§Ø©Ŗ«¬\u{00AD}®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’'; +const Map _latin13SymbolMap = { + 8221: 161, + 162: 162, + 163: 163, + 164: 164, + 8222: 165, + 166: 166, + 167: 167, + 216: 168, + 169: 169, + 342: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 198: 175, + 176: 176, + 177: 177, + 178: 178, + 179: 179, + 8220: 180, + 181: 181, + 182: 182, + 183: 183, + 248: 184, + 185: 185, + 343: 186, + 187: 187, + 188: 188, + 189: 189, + 190: 190, + 230: 191, + 260: 192, + 302: 193, + 256: 194, + 262: 195, + 196: 196, + 197: 197, + 280: 198, + 274: 199, + 268: 200, + 201: 201, + 377: 202, + 278: 203, + 290: 204, + 310: 205, + 298: 206, + 315: 207, + 352: 208, + 323: 209, + 325: 210, + 211: 211, + 332: 212, + 213: 213, + 214: 214, + 215: 215, + 370: 216, + 321: 217, + 346: 218, + 362: 219, + 220: 220, + 379: 221, + 381: 222, + 223: 223, + 261: 224, + 303: 225, + 257: 226, + 263: 227, + 228: 228, + 229: 229, + 281: 230, + 275: 231, + 269: 232, + 233: 233, + 378: 234, + 279: 235, + 291: 236, + 311: 237, + 299: 238, + 316: 239, + 353: 240, + 324: 241, + 326: 242, + 243: 243, + 333: 244, + 245: 245, + 246: 246, + 247: 247, + 371: 248, + 322: 249, + 347: 250, + 363: 251, + 252: 252, + 380: 253, + 382: 254, + 8217: 255, +}; + +/// Provides a latin 13 / iso-8859-13 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin13Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin13Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin13Decoder get decoder => allowInvalid + ? const Latin13Decoder(allowInvalid: true) + : const Latin13Decoder(allowInvalid: false); + + @override + Latin13Encoder get encoder => allowInvalid + ? const Latin13Encoder(allowInvalid: true) + : const Latin13Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-13'; +} + +/// Encodes texts into latin 13 / iso-88513-13 data +class Latin13Encoder extends LatinEncoder { + const Latin13Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin13SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 13 / iso-88513-13 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin13Decoder extends LatinDecoder { + const Latin13Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin13Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin14.dart b/lib/latin/latin14.dart new file mode 100644 index 0000000..c7f328b --- /dev/null +++ b/lib/latin/latin14.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin14Symbols = + 'Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ\u{00AD}®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ'; +const Map _latin14SymbolMap = { + 7682: 161, + 7683: 162, + 163: 163, + 266: 164, + 267: 165, + 7690: 166, + 167: 167, + 7808: 168, + 169: 169, + 7810: 170, + 7691: 171, + 7922: 172, + 173: 173, + 174: 174, + 376: 175, + 7710: 176, + 7711: 177, + 288: 178, + 289: 179, + 7744: 180, + 7745: 181, + 182: 182, + 7766: 183, + 7809: 184, + 7767: 185, + 7811: 186, + 7776: 187, + 7923: 188, + 7812: 189, + 7813: 190, + 7777: 191, + 192: 192, + 193: 193, + 194: 194, + 195: 195, + 196: 196, + 197: 197, + 198: 198, + 199: 199, + 200: 200, + 201: 201, + 202: 202, + 203: 203, + 204: 204, + 205: 205, + 206: 206, + 207: 207, + 372: 208, + 209: 209, + 210: 210, + 211: 211, + 212: 212, + 213: 213, + 214: 214, + 7786: 215, + 216: 216, + 217: 217, + 218: 218, + 219: 219, + 220: 220, + 221: 221, + 374: 222, + 223: 223, + 224: 224, + 225: 225, + 226: 226, + 227: 227, + 228: 228, + 229: 229, + 230: 230, + 231: 231, + 232: 232, + 233: 233, + 234: 234, + 235: 235, + 236: 236, + 237: 237, + 238: 238, + 239: 239, + 373: 240, + 241: 241, + 242: 242, + 243: 243, + 244: 244, + 245: 245, + 246: 246, + 7787: 247, + 248: 248, + 249: 249, + 250: 250, + 251: 251, + 252: 252, + 253: 253, + 375: 254, + 255: 255, +}; + +/// Provides a latin 14 / iso-8859-14 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin14Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin14Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin14Decoder get decoder => allowInvalid + ? const Latin14Decoder(allowInvalid: true) + : const Latin14Decoder(allowInvalid: false); + + @override + Latin14Encoder get encoder => allowInvalid + ? const Latin14Encoder(allowInvalid: true) + : const Latin14Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-14'; +} + +/// Encodes texts into latin 14 / iso-88514-14 data +class Latin14Encoder extends LatinEncoder { + const Latin14Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin14SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 14 / iso-88514-14 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin14Decoder extends LatinDecoder { + const Latin14Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin14Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin15.dart b/lib/latin/latin15.dart new file mode 100644 index 0000000..c099b7e --- /dev/null +++ b/lib/latin/latin15.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin15Symbols = + '¡¢£€¥Š§š©ª«¬\u{00AD}®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; +const Map _latin15SymbolMap = { + 161: 161, + 162: 162, + 163: 163, + 8364: 164, + 165: 165, + 352: 166, + 167: 167, + 353: 168, + 169: 169, + 170: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 175: 175, + 176: 176, + 177: 177, + 178: 178, + 179: 179, + 381: 180, + 181: 181, + 182: 182, + 183: 183, + 382: 184, + 185: 185, + 186: 186, + 187: 187, + 338: 188, + 339: 189, + 376: 190, + 191: 191, + 192: 192, + 193: 193, + 194: 194, + 195: 195, + 196: 196, + 197: 197, + 198: 198, + 199: 199, + 200: 200, + 201: 201, + 202: 202, + 203: 203, + 204: 204, + 205: 205, + 206: 206, + 207: 207, + 208: 208, + 209: 209, + 210: 210, + 211: 211, + 212: 212, + 213: 213, + 214: 214, + 215: 215, + 216: 216, + 217: 217, + 218: 218, + 219: 219, + 220: 220, + 221: 221, + 222: 222, + 223: 223, + 224: 224, + 225: 225, + 226: 226, + 227: 227, + 228: 228, + 229: 229, + 230: 230, + 231: 231, + 232: 232, + 233: 233, + 234: 234, + 235: 235, + 236: 236, + 237: 237, + 238: 238, + 239: 239, + 240: 240, + 241: 241, + 242: 242, + 243: 243, + 244: 244, + 245: 245, + 246: 246, + 247: 247, + 248: 248, + 249: 249, + 250: 250, + 251: 251, + 252: 252, + 253: 253, + 254: 254, + 255: 255, +}; + +/// Provides a latin 15 / iso-8859-15 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin15Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin15Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin15Decoder get decoder => allowInvalid + ? const Latin15Decoder(allowInvalid: true) + : const Latin15Decoder(allowInvalid: false); + + @override + Latin15Encoder get encoder => allowInvalid + ? const Latin15Encoder(allowInvalid: true) + : const Latin15Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-15'; +} + +/// Encodes texts into latin 15 / iso-88515-15 data +class Latin15Encoder extends LatinEncoder { + const Latin15Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin15SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 15 / iso-88515-15 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin15Decoder extends LatinDecoder { + const Latin15Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin15Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin16.dart b/lib/latin/latin16.dart new file mode 100644 index 0000000..1e450a1 --- /dev/null +++ b/lib/latin/latin16.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin16Symbols = + 'ĄąŁ€„Š§š©Ș«Ź\u{00AD}źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ'; +const Map _latin16SymbolMap = { + 260: 161, + 261: 162, + 321: 163, + 8364: 164, + 8222: 165, + 352: 166, + 167: 167, + 353: 168, + 169: 169, + 536: 170, + 171: 171, + 377: 172, + 173: 173, + 378: 174, + 379: 175, + 176: 176, + 177: 177, + 268: 178, + 322: 179, + 381: 180, + 8221: 181, + 182: 182, + 183: 183, + 382: 184, + 269: 185, + 537: 186, + 187: 187, + 338: 188, + 339: 189, + 376: 190, + 380: 191, + 192: 192, + 193: 193, + 194: 194, + 258: 195, + 196: 196, + 262: 197, + 198: 198, + 199: 199, + 200: 200, + 201: 201, + 202: 202, + 203: 203, + 204: 204, + 205: 205, + 206: 206, + 207: 207, + 272: 208, + 323: 209, + 210: 210, + 211: 211, + 212: 212, + 336: 213, + 214: 214, + 346: 215, + 368: 216, + 217: 217, + 218: 218, + 219: 219, + 220: 220, + 280: 221, + 538: 222, + 223: 223, + 224: 224, + 225: 225, + 226: 226, + 259: 227, + 228: 228, + 263: 229, + 230: 230, + 231: 231, + 232: 232, + 233: 233, + 234: 234, + 235: 235, + 236: 236, + 237: 237, + 238: 238, + 239: 239, + 273: 240, + 324: 241, + 242: 242, + 243: 243, + 244: 244, + 337: 245, + 246: 246, + 347: 247, + 369: 248, + 249: 249, + 250: 250, + 251: 251, + 252: 252, + 281: 253, + 539: 254, + 255: 255, +}; + +/// Provides a latin 16 / iso-8859-16 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin16Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin16Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin16Decoder get decoder => allowInvalid + ? const Latin16Decoder(allowInvalid: true) + : const Latin16Decoder(allowInvalid: false); + + @override + Latin16Encoder get encoder => allowInvalid + ? const Latin16Encoder(allowInvalid: true) + : const Latin16Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-16'; +} + +/// Encodes texts into latin 16 / iso-88516-16 data +class Latin16Encoder extends LatinEncoder { + const Latin16Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin16SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 16 / iso-88516-16 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin16Decoder extends LatinDecoder { + const Latin16Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin16Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin2.dart b/lib/latin/latin2.dart new file mode 100644 index 0000000..f67c6ab --- /dev/null +++ b/lib/latin/latin2.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin2Symbols = + 'Ą˘Ł¤ĽŚ§¨ŠŞŤŹ\u{00AD}ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙'; +const Map _latin2SymbolMap = { + 260: 161, + 728: 162, + 321: 163, + 164: 164, + 317: 165, + 346: 166, + 167: 167, + 168: 168, + 352: 169, + 350: 170, + 356: 171, + 377: 172, + 173: 173, + 381: 174, + 379: 175, + 176: 176, + 261: 177, + 731: 178, + 322: 179, + 180: 180, + 318: 181, + 347: 182, + 711: 183, + 184: 184, + 353: 185, + 351: 186, + 357: 187, + 378: 188, + 733: 189, + 382: 190, + 380: 191, + 340: 192, + 193: 193, + 194: 194, + 258: 195, + 196: 196, + 313: 197, + 262: 198, + 199: 199, + 268: 200, + 201: 201, + 280: 202, + 203: 203, + 282: 204, + 205: 205, + 206: 206, + 270: 207, + 272: 208, + 323: 209, + 327: 210, + 211: 211, + 212: 212, + 336: 213, + 214: 214, + 215: 215, + 344: 216, + 366: 217, + 218: 218, + 368: 219, + 220: 220, + 221: 221, + 354: 222, + 223: 223, + 341: 224, + 225: 225, + 226: 226, + 259: 227, + 228: 228, + 314: 229, + 263: 230, + 231: 231, + 269: 232, + 233: 233, + 281: 234, + 235: 235, + 283: 236, + 237: 237, + 238: 238, + 271: 239, + 273: 240, + 324: 241, + 328: 242, + 243: 243, + 244: 244, + 337: 245, + 246: 246, + 247: 247, + 345: 248, + 367: 249, + 250: 250, + 369: 251, + 252: 252, + 253: 253, + 355: 254, + 729: 255, +}; + +/// Provides a latin 2 / iso-8859-2 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin2Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin2Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin2Decoder get decoder => allowInvalid + ? const Latin2Decoder(allowInvalid: true) + : const Latin2Decoder(allowInvalid: false); + + @override + Latin2Encoder get encoder => allowInvalid + ? const Latin2Encoder(allowInvalid: true) + : const Latin2Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-2'; +} + +/// Encodes texts into latin 2 / iso-8859-2 data +class Latin2Encoder extends LatinEncoder { + const Latin2Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin2SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 2 / iso-8859-2 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin2Decoder extends LatinDecoder { + const Latin2Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin2Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin3.dart b/lib/latin/latin3.dart new file mode 100644 index 0000000..2e544f2 --- /dev/null +++ b/lib/latin/latin3.dart @@ -0,0 +1,149 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin3Symbols = + 'Ħ˘£¤?Ĥ§¨İŞĞĴ\u{00AD}?Ż°ħ²³´µĥ·¸ışğĵ½?żÀÁÂ?ÄĊĈÇÈÉÊËÌÍÎÏ?ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ?äċĉçèéêëìíîï?ñòóôġö÷ĝùúûüŭŝ˙'; +const Map _latin3SymbolMap = { + 294: 161, + 728: 162, + 163: 163, + 164: 164, + 292: 166, + 167: 167, + 168: 168, + 304: 169, + 350: 170, + 286: 171, + 308: 172, + 173: 173, + 379: 175, + 176: 176, + 295: 177, + 178: 178, + 179: 179, + 180: 180, + 181: 181, + 293: 182, + 183: 183, + 184: 184, + 305: 185, + 351: 186, + 287: 187, + 309: 188, + 189: 189, + 380: 191, + 192: 192, + 193: 193, + 194: 194, + 196: 196, + 266: 197, + 264: 198, + 199: 199, + 200: 200, + 201: 201, + 202: 202, + 203: 203, + 204: 204, + 205: 205, + 206: 206, + 207: 207, + 209: 209, + 210: 210, + 211: 211, + 212: 212, + 288: 213, + 214: 214, + 215: 215, + 284: 216, + 217: 217, + 218: 218, + 219: 219, + 220: 220, + 364: 221, + 348: 222, + 223: 223, + 224: 224, + 225: 225, + 226: 226, + 228: 228, + 267: 229, + 265: 230, + 231: 231, + 232: 232, + 233: 233, + 234: 234, + 235: 235, + 236: 236, + 237: 237, + 238: 238, + 239: 239, + 241: 241, + 242: 242, + 243: 243, + 244: 244, + 289: 245, + 246: 246, + 247: 247, + 285: 248, + 249: 249, + 250: 250, + 251: 251, + 252: 252, + 365: 253, + 349: 254, + 729: 255, +}; + +/// Provides a latin 3 / iso-8859-3 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin3Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin3Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin3Decoder get decoder => allowInvalid + ? const Latin3Decoder(allowInvalid: true) + : const Latin3Decoder(allowInvalid: false); + + @override + Latin3Encoder get encoder => allowInvalid + ? const Latin3Encoder(allowInvalid: true) + : const Latin3Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-3'; +} + +/// Encodes texts into latin 3 / iso-8859-3 data +class Latin3Encoder extends LatinEncoder { + const Latin3Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin3SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 3 / iso-8859-3 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin3Decoder extends LatinDecoder { + const Latin3Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin3Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin4.dart b/lib/latin/latin4.dart new file mode 100644 index 0000000..555084d --- /dev/null +++ b/lib/latin/latin4.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin4Symbols = + 'ĄĸŖ¤ĨĻ§¨ŠĒĢŦ\u{00AD}Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙'; +const Map _latin4SymbolMap = { + 260: 161, + 312: 162, + 342: 163, + 164: 164, + 296: 165, + 315: 166, + 167: 167, + 168: 168, + 352: 169, + 274: 170, + 290: 171, + 358: 172, + 173: 173, + 381: 174, + 175: 175, + 176: 176, + 261: 177, + 731: 178, + 343: 179, + 180: 180, + 297: 181, + 316: 182, + 711: 183, + 184: 184, + 353: 185, + 275: 186, + 291: 187, + 359: 188, + 330: 189, + 382: 190, + 331: 191, + 256: 192, + 193: 193, + 194: 194, + 195: 195, + 196: 196, + 197: 197, + 198: 198, + 302: 199, + 268: 200, + 201: 201, + 280: 202, + 203: 203, + 278: 204, + 205: 205, + 206: 206, + 298: 207, + 272: 208, + 325: 209, + 332: 210, + 310: 211, + 212: 212, + 213: 213, + 214: 214, + 215: 215, + 216: 216, + 370: 217, + 218: 218, + 219: 219, + 220: 220, + 360: 221, + 362: 222, + 223: 223, + 257: 224, + 225: 225, + 226: 226, + 227: 227, + 228: 228, + 229: 229, + 230: 230, + 303: 231, + 269: 232, + 233: 233, + 281: 234, + 235: 235, + 279: 236, + 237: 237, + 238: 238, + 299: 239, + 273: 240, + 326: 241, + 333: 242, + 311: 243, + 244: 244, + 245: 245, + 246: 246, + 247: 247, + 248: 248, + 371: 249, + 250: 250, + 251: 251, + 252: 252, + 361: 253, + 363: 254, + 729: 255, +}; + +/// Provides a latin 4 / iso-8859-4 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin4Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin4Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin4Decoder get decoder => allowInvalid + ? const Latin4Decoder(allowInvalid: true) + : const Latin4Decoder(allowInvalid: false); + + @override + Latin4Encoder get encoder => allowInvalid + ? const Latin4Encoder(allowInvalid: true) + : const Latin4Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-4'; +} + +/// Encodes texts into latin 4 / iso-8859-4 data +class Latin4Encoder extends LatinEncoder { + const Latin4Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin4SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 4 / iso-8859-4 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin4Decoder extends LatinDecoder { + const Latin4Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin4Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin5.dart b/lib/latin/latin5.dart new file mode 100644 index 0000000..1d06c6f --- /dev/null +++ b/lib/latin/latin5.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin5Symbols = + 'ЁЂЃЄЅІЇЈЉЊЋЌ\u{00AD}ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ'; +const Map _latin5SymbolMap = { + 1025: 161, + 1026: 162, + 1027: 163, + 1028: 164, + 1029: 165, + 1030: 166, + 1031: 167, + 1032: 168, + 1033: 169, + 1034: 170, + 1035: 171, + 1036: 172, + 173: 173, + 1038: 174, + 1039: 175, + 1040: 176, + 1041: 177, + 1042: 178, + 1043: 179, + 1044: 180, + 1045: 181, + 1046: 182, + 1047: 183, + 1048: 184, + 1049: 185, + 1050: 186, + 1051: 187, + 1052: 188, + 1053: 189, + 1054: 190, + 1055: 191, + 1056: 192, + 1057: 193, + 1058: 194, + 1059: 195, + 1060: 196, + 1061: 197, + 1062: 198, + 1063: 199, + 1064: 200, + 1065: 201, + 1066: 202, + 1067: 203, + 1068: 204, + 1069: 205, + 1070: 206, + 1071: 207, + 1072: 208, + 1073: 209, + 1074: 210, + 1075: 211, + 1076: 212, + 1077: 213, + 1078: 214, + 1079: 215, + 1080: 216, + 1081: 217, + 1082: 218, + 1083: 219, + 1084: 220, + 1085: 221, + 1086: 222, + 1087: 223, + 1088: 224, + 1089: 225, + 1090: 226, + 1091: 227, + 1092: 228, + 1093: 229, + 1094: 230, + 1095: 231, + 1096: 232, + 1097: 233, + 1098: 234, + 1099: 235, + 1100: 236, + 1101: 237, + 1102: 238, + 1103: 239, + 8470: 240, + 1105: 241, + 1106: 242, + 1107: 243, + 1108: 244, + 1109: 245, + 1110: 246, + 1111: 247, + 1112: 248, + 1113: 249, + 1114: 250, + 1115: 251, + 1116: 252, + 167: 253, + 1118: 254, + 1119: 255, +}; + +/// Provides a latin 5 / iso-8859-5 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin5Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin5Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin5Decoder get decoder => allowInvalid + ? const Latin5Decoder(allowInvalid: true) + : const Latin5Decoder(allowInvalid: false); + + @override + Latin5Encoder get encoder => allowInvalid + ? const Latin5Encoder(allowInvalid: true) + : const Latin5Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-5'; +} + +/// Encodes texts into latin 5 / iso-8859-5 data +class Latin5Encoder extends LatinEncoder { + const Latin5Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin5SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 5 / iso-8859-5 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin5Decoder extends LatinDecoder { + const Latin5Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin5Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin6.dart b/lib/latin/latin6.dart new file mode 100644 index 0000000..06835c2 --- /dev/null +++ b/lib/latin/latin6.dart @@ -0,0 +1,111 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin6Symbols = + '???¤???????،\u{00AD}?????????????؛???؟?ءآأؤإئابةتثجحخدذرزسشصضطظعغ?????ـفقكلمنهوىيًٌٍَُِّْ?????????????'; +const Map _latin6SymbolMap = { + 164: 164, + 1548: 172, + 173: 173, + 1563: 187, + 1567: 191, + 1569: 193, + 1570: 194, + 1571: 195, + 1572: 196, + 1573: 197, + 1574: 198, + 1575: 199, + 1576: 200, + 1577: 201, + 1578: 202, + 1579: 203, + 1580: 204, + 1581: 205, + 1582: 206, + 1583: 207, + 1584: 208, + 1585: 209, + 1586: 210, + 1587: 211, + 1588: 212, + 1589: 213, + 1590: 214, + 1591: 215, + 1592: 216, + 1593: 217, + 1594: 218, + 1600: 224, + 1601: 225, + 1602: 226, + 1603: 227, + 1604: 228, + 1605: 229, + 1606: 230, + 1607: 231, + 1608: 232, + 1609: 233, + 1610: 234, + 1611: 235, + 1612: 236, + 1613: 237, + 1614: 238, + 1615: 239, + 1616: 240, + 1617: 241, + 1618: 242, +}; + +/// Provides a latin 6 / iso-8859-6 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin6Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin6Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin6Decoder get decoder => allowInvalid + ? const Latin6Decoder(allowInvalid: true) + : const Latin6Decoder(allowInvalid: false); + + @override + Latin6Encoder get encoder => allowInvalid + ? const Latin6Encoder(allowInvalid: true) + : const Latin6Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-6'; +} + +/// Encodes texts into latin 6 / iso-8859-6 data +class Latin6Encoder extends LatinEncoder { + const Latin6Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin6SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 6 / iso-8859-6 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin6Decoder extends LatinDecoder { + const Latin6Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin6Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin7.dart b/lib/latin/latin7.dart new file mode 100644 index 0000000..fc540ab --- /dev/null +++ b/lib/latin/latin7.dart @@ -0,0 +1,153 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin7Symbols = + '‘’£€₯¦§¨©ͺ«¬\u{00AD}?―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ?ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ?'; +const Map _latin7SymbolMap = { + 8216: 161, + 8217: 162, + 163: 163, + 8364: 164, + 8367: 165, + 166: 166, + 167: 167, + 168: 168, + 169: 169, + 890: 170, + 171: 171, + 172: 172, + 173: 173, + 8213: 175, + 176: 176, + 177: 177, + 178: 178, + 179: 179, + 900: 180, + 901: 181, + 902: 182, + 183: 183, + 904: 184, + 905: 185, + 906: 186, + 187: 187, + 908: 188, + 189: 189, + 910: 190, + 911: 191, + 912: 192, + 913: 193, + 914: 194, + 915: 195, + 916: 196, + 917: 197, + 918: 198, + 919: 199, + 920: 200, + 921: 201, + 922: 202, + 923: 203, + 924: 204, + 925: 205, + 926: 206, + 927: 207, + 928: 208, + 929: 209, + 931: 211, + 932: 212, + 933: 213, + 934: 214, + 935: 215, + 936: 216, + 937: 217, + 938: 218, + 939: 219, + 940: 220, + 941: 221, + 942: 222, + 943: 223, + 944: 224, + 945: 225, + 946: 226, + 947: 227, + 948: 228, + 949: 229, + 950: 230, + 951: 231, + 952: 232, + 953: 233, + 954: 234, + 955: 235, + 956: 236, + 957: 237, + 958: 238, + 959: 239, + 960: 240, + 961: 241, + 962: 242, + 963: 243, + 964: 244, + 965: 245, + 966: 246, + 967: 247, + 968: 248, + 969: 249, + 970: 250, + 971: 251, + 972: 252, + 973: 253, + 974: 254, +}; + +/// Provides a latin 7 / iso-8859-7 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin7Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin7Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin7Decoder get decoder => allowInvalid + ? const Latin7Decoder(allowInvalid: true) + : const Latin7Decoder(allowInvalid: false); + + @override + Latin7Encoder get encoder => allowInvalid + ? const Latin7Encoder(allowInvalid: true) + : const Latin7Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-7'; +} + +/// Encodes texts into latin 7 / iso-8859-7 data +class Latin7Encoder extends LatinEncoder { + const Latin7Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin7SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 7 / iso-8859-7 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin7Decoder extends LatinDecoder { + const Latin7Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin7Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin8.dart b/lib/latin/latin8.dart new file mode 100644 index 0000000..7e4a39c --- /dev/null +++ b/lib/latin/latin8.dart @@ -0,0 +1,120 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin8Symbols = + '?¢£¤¥¦§¨©×«¬\u{00AD}®¯°±²³´µ¶·¸¹÷»¼½¾????????????????????????????????‗אבגדהוזחטיךכלםמןנסעףפץצקרשת??\u{8206}\u{8207}?'; +const Map _latin8SymbolMap = { + 162: 162, + 163: 163, + 164: 164, + 165: 165, + 166: 166, + 167: 167, + 168: 168, + 169: 169, + 215: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 175: 175, + 176: 176, + 177: 177, + 178: 178, + 179: 179, + 180: 180, + 181: 181, + 182: 182, + 183: 183, + 184: 184, + 185: 185, + 247: 186, + 187: 187, + 188: 188, + 189: 189, + 190: 190, + 8215: 223, + 1488: 224, + 1489: 225, + 1490: 226, + 1491: 227, + 1492: 228, + 1493: 229, + 1494: 230, + 1495: 231, + 1496: 232, + 1497: 233, + 1498: 234, + 1499: 235, + 1500: 236, + 1501: 237, + 1502: 238, + 1503: 239, + 1504: 240, + 1505: 241, + 1506: 242, + 1507: 243, + 1508: 244, + 1509: 245, + 1510: 246, + 1511: 247, + 1512: 248, + 1513: 249, + 1514: 250, + 33286: 253, + 33287: 254, +}; + +/// Provides a latin 8 / iso-8859-8 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin8Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin8Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin8Decoder get decoder => allowInvalid + ? const Latin8Decoder(allowInvalid: true) + : const Latin8Decoder(allowInvalid: false); + + @override + Latin8Encoder get encoder => allowInvalid + ? const Latin8Encoder(allowInvalid: true) + : const Latin8Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-8'; +} + +/// Encodes texts into latin 8 / iso-8859-8 data +class Latin8Encoder extends LatinEncoder { + const Latin8Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin8SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 8 / iso-8859-8 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin8Decoder extends LatinDecoder { + const Latin8Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin8Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/latin/latin9.dart b/lib/latin/latin9.dart new file mode 100644 index 0000000..9f6c3d1 --- /dev/null +++ b/lib/latin/latin9.dart @@ -0,0 +1,156 @@ +import 'dart:convert' as cnvrt; + +import 'latin.dart'; + +const String _latin9Symbols = + '¡¢£¤¥¦§¨©ª«¬\u{00AD}®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ'; +const Map _latin9SymbolMap = { + 161: 161, + 162: 162, + 163: 163, + 164: 164, + 165: 165, + 166: 166, + 167: 167, + 168: 168, + 169: 169, + 170: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 175: 175, + 176: 176, + 177: 177, + 178: 178, + 179: 179, + 180: 180, + 181: 181, + 182: 182, + 183: 183, + 184: 184, + 185: 185, + 186: 186, + 187: 187, + 188: 188, + 189: 189, + 190: 190, + 191: 191, + 192: 192, + 193: 193, + 194: 194, + 195: 195, + 196: 196, + 197: 197, + 198: 198, + 199: 199, + 200: 200, + 201: 201, + 202: 202, + 203: 203, + 204: 204, + 205: 205, + 206: 206, + 207: 207, + 286: 208, + 209: 209, + 210: 210, + 211: 211, + 212: 212, + 213: 213, + 214: 214, + 215: 215, + 216: 216, + 217: 217, + 218: 218, + 219: 219, + 220: 220, + 304: 221, + 350: 222, + 223: 223, + 224: 224, + 225: 225, + 226: 226, + 227: 227, + 228: 228, + 229: 229, + 230: 230, + 231: 231, + 232: 232, + 233: 233, + 234: 234, + 235: 235, + 236: 236, + 237: 237, + 238: 238, + 239: 239, + 287: 240, + 241: 241, + 242: 242, + 243: 243, + 244: 244, + 245: 245, + 246: 246, + 247: 247, + 248: 248, + 249: 249, + 250: 250, + 251: 251, + 252: 252, + 305: 253, + 351: 254, + 255: 255, +}; + +/// Provides a latin 9 / iso-8859-9 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Latin9Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Latin9Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Latin9Decoder get decoder => allowInvalid + ? const Latin9Decoder(allowInvalid: true) + : const Latin9Decoder(allowInvalid: false); + + @override + Latin9Encoder get encoder => allowInvalid + ? const Latin9Encoder(allowInvalid: true) + : const Latin9Encoder(allowInvalid: false); + + @override + String get name => 'iso-8859-9'; +} + +/// Encodes texts into latin 9 / iso-8859-9 data +class Latin9Encoder extends LatinEncoder { + const Latin9Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_latin9SymbolMap, allowInvalid: allowInvalid); +} + +/// Decodes latin 9 / iso-8859-9 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Latin9Decoder extends LatinDecoder { + const Latin9Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_latin9Symbols, allowInvalid: allowInvalid); +} diff --git a/lib/windows/windows.dart b/lib/windows/windows.dart new file mode 100644 index 0000000..32ea015 --- /dev/null +++ b/lib/windows/windows.dart @@ -0,0 +1,25 @@ +import 'package:enough_convert/base.dart'; + +/// Contains base classes for windows codepage codecs + +/// Provides a windows codepage decoder. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class WindowsDecoder extends BaseDecoder { + /// Creates a new windows codepage decoder. + /// The [symbols] need to be exactly `128` characters long. + /// Set [allowedInvalid] to true in case invalid characters sequences should be at least readable. + const WindowsDecoder(String symbols, {bool allowInvalid = false}) + : super(symbols, 0x7F, allowInvalid: allowInvalid); +} + +/// Provides a simple, non chunkable iso-8859-XX encoder. +class WindowsEncoder extends BaseEncoder { + /// Creates a new windows codepage encoder. + /// Set [allowedInvalid] to true in case invalid characters should be translated to question marks. + const WindowsEncoder(Map encodingMap, {bool allowInvalid = false}) + : super(encodingMap, 0x7F, allowInvalid: allowInvalid); +} diff --git a/lib/windows/windows1250.dart b/lib/windows/windows1250.dart new file mode 100644 index 0000000..eee326a --- /dev/null +++ b/lib/windows/windows1250.dart @@ -0,0 +1,184 @@ +import 'dart:convert' as cnvrt; + +import 'package:enough_convert/windows/windows.dart'; + +const String _cp1250Symbols = + '€?‚?„…†‡?‰Š‹ŚŤŽŹ?‘’“”•–—?™š›śťžź\u{00A0}ˇ˘Ł¤Ą¦§¨©Ş«¬\u{00AD}®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙'; +const Map _cp1250Map = { + 8364: 128, + 8218: 130, + 8222: 132, + 8230: 133, + 8224: 134, + 8225: 135, + 8240: 137, + 352: 138, + 8249: 139, + 346: 140, + 356: 141, + 381: 142, + 377: 143, + 8216: 145, + 8217: 146, + 8220: 147, + 8221: 148, + 8226: 149, + 8211: 150, + 8212: 151, + 8482: 153, + 353: 154, + 8250: 155, + 347: 156, + 357: 157, + 382: 158, + 378: 159, + 160: 160, + 711: 161, + 728: 162, + 321: 163, + 164: 164, + 260: 165, + 166: 166, + 167: 167, + 168: 168, + 169: 169, + 350: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 379: 175, + 176: 176, + 177: 177, + 731: 178, + 322: 179, + 180: 180, + 181: 181, + 182: 182, + 183: 183, + 184: 184, + 261: 185, + 351: 186, + 187: 187, + 317: 188, + 733: 189, + 318: 190, + 380: 191, + 340: 192, + 193: 193, + 194: 194, + 258: 195, + 196: 196, + 313: 197, + 262: 198, + 199: 199, + 268: 200, + 201: 201, + 280: 202, + 203: 203, + 282: 204, + 205: 205, + 206: 206, + 270: 207, + 272: 208, + 323: 209, + 327: 210, + 211: 211, + 212: 212, + 336: 213, + 214: 214, + 215: 215, + 344: 216, + 366: 217, + 218: 218, + 368: 219, + 220: 220, + 221: 221, + 354: 222, + 223: 223, + 341: 224, + 225: 225, + 226: 226, + 259: 227, + 228: 228, + 314: 229, + 263: 230, + 231: 231, + 269: 232, + 233: 233, + 281: 234, + 235: 235, + 283: 236, + 237: 237, + 238: 238, + 271: 239, + 273: 240, + 324: 241, + 328: 242, + 243: 243, + 244: 244, + 337: 245, + 246: 246, + 247: 247, + 345: 248, + 367: 249, + 250: 250, + 369: 251, + 252: 252, + 253: 253, + 355: 254, + 729: 255, +}; + +/// Provides a windows 1250 / cp1250 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Windows1250Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Windows1250Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Windows1250Decoder get decoder => allowInvalid + ? const Windows1250Decoder(allowInvalid: true) + : const Windows1250Decoder(allowInvalid: false); + + @override + Windows1250Encoder get encoder => allowInvalid + ? const Windows1250Encoder(allowInvalid: true) + : const Windows1250Encoder(allowInvalid: false); + + @override + String get name => 'windows-1250'; +} + +/// Decodes windows 1250 / cp1250 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Windows1250Decoder extends WindowsDecoder { + const Windows1250Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_cp1250Symbols, allowInvalid: allowInvalid); +} + +/// Encodes texts into windows 1250 data +class Windows1250Encoder extends WindowsEncoder { + const Windows1250Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_cp1250Map, allowInvalid: allowInvalid); +} diff --git a/lib/windows/windows1251.dart b/lib/windows/windows1251.dart new file mode 100644 index 0000000..f5a4a08 --- /dev/null +++ b/lib/windows/windows1251.dart @@ -0,0 +1,188 @@ +import 'dart:convert' as cnvrt; + +import 'package:enough_convert/windows/windows.dart'; + +const String _cp1251Symbols = + 'ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—?™љ›њќћџ\u{00A0}ЎўЈ¤Ґ¦§Ё©Є«¬\u{00AD}®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя'; +const Map _cp1251Map = { + 1026: 128, + 1027: 129, + 8218: 130, + 1107: 131, + 8222: 132, + 8230: 133, + 8224: 134, + 8225: 135, + 8364: 136, + 8240: 137, + 1033: 138, + 8249: 139, + 1034: 140, + 1036: 141, + 1035: 142, + 1039: 143, + 1106: 144, + 8216: 145, + 8217: 146, + 8220: 147, + 8221: 148, + 8226: 149, + 8211: 150, + 8212: 151, + 8482: 153, + 1113: 154, + 8250: 155, + 1114: 156, + 1116: 157, + 1115: 158, + 1119: 159, + 160: 160, + 1038: 161, + 1118: 162, + 1032: 163, + 164: 164, + 1168: 165, + 166: 166, + 167: 167, + 1025: 168, + 169: 169, + 1028: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 1031: 175, + 176: 176, + 177: 177, + 1030: 178, + 1110: 179, + 1169: 180, + 181: 181, + 182: 182, + 183: 183, + 1105: 184, + 8470: 185, + 1108: 186, + 187: 187, + 1112: 188, + 1029: 189, + 1109: 190, + 1111: 191, + 1040: 192, + 1041: 193, + 1042: 194, + 1043: 195, + 1044: 196, + 1045: 197, + 1046: 198, + 1047: 199, + 1048: 200, + 1049: 201, + 1050: 202, + 1051: 203, + 1052: 204, + 1053: 205, + 1054: 206, + 1055: 207, + 1056: 208, + 1057: 209, + 1058: 210, + 1059: 211, + 1060: 212, + 1061: 213, + 1062: 214, + 1063: 215, + 1064: 216, + 1065: 217, + 1066: 218, + 1067: 219, + 1068: 220, + 1069: 221, + 1070: 222, + 1071: 223, + 1072: 224, + 1073: 225, + 1074: 226, + 1075: 227, + 1076: 228, + 1077: 229, + 1078: 230, + 1079: 231, + 1080: 232, + 1081: 233, + 1082: 234, + 1083: 235, + 1084: 236, + 1085: 237, + 1086: 238, + 1087: 239, + 1088: 240, + 1089: 241, + 1090: 242, + 1091: 243, + 1092: 244, + 1093: 245, + 1094: 246, + 1095: 247, + 1096: 248, + 1097: 249, + 1098: 250, + 1099: 251, + 1100: 252, + 1101: 253, + 1102: 254, + 1103: 255, +}; + +/// Provides a windows 1251 / cp1251 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Windows1251Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Windows1251Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Windows1251Decoder get decoder => allowInvalid + ? const Windows1251Decoder(allowInvalid: true) + : const Windows1251Decoder(allowInvalid: false); + + @override + Windows1251Encoder get encoder => allowInvalid + ? const Windows1251Encoder(allowInvalid: true) + : const Windows1251Encoder(allowInvalid: false); + + @override + String get name => 'windows-1251'; +} + +/// Decodes windows 1251 / cp1251 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Windows1251Decoder extends WindowsDecoder { + const Windows1251Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_cp1251Symbols, allowInvalid: allowInvalid); +} + +/// Encodes texts into windows 1251 data +class Windows1251Encoder extends WindowsEncoder { + const Windows1251Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_cp1251Map, allowInvalid: allowInvalid); +} diff --git a/lib/windows/windows1252.dart b/lib/windows/windows1252.dart new file mode 100644 index 0000000..a07e1f8 --- /dev/null +++ b/lib/windows/windows1252.dart @@ -0,0 +1,184 @@ +import 'dart:convert' as cnvrt; + +import 'package:enough_convert/windows/windows.dart'; + +const String _cp1252Symbols = + '€?‚ƒ„…†‡ˆ‰Š‹Œ?Ž??‘’“”•–—˜™š›œ?žŸ\u{00A0}¡¢£¤¥¦§¨©ª«¬\u{00AD}®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; +const Map _cp1252Map = { + 8364: 128, + 8218: 130, + 402: 131, + 8222: 132, + 8230: 133, + 8224: 134, + 8225: 135, + 710: 136, + 8240: 137, + 352: 138, + 8249: 139, + 338: 140, + 381: 142, + 8216: 145, + 8217: 146, + 8220: 147, + 8221: 148, + 8226: 149, + 8211: 150, + 8212: 151, + 732: 152, + 8482: 153, + 353: 154, + 8250: 155, + 339: 156, + 382: 158, + 376: 159, + 160: 160, + 161: 161, + 162: 162, + 163: 163, + 164: 164, + 165: 165, + 166: 166, + 167: 167, + 168: 168, + 169: 169, + 170: 170, + 171: 171, + 172: 172, + 173: 173, + 174: 174, + 175: 175, + 176: 176, + 177: 177, + 178: 178, + 179: 179, + 180: 180, + 181: 181, + 182: 182, + 183: 183, + 184: 184, + 185: 185, + 186: 186, + 187: 187, + 188: 188, + 189: 189, + 190: 190, + 191: 191, + 192: 192, + 193: 193, + 194: 194, + 195: 195, + 196: 196, + 197: 197, + 198: 198, + 199: 199, + 200: 200, + 201: 201, + 202: 202, + 203: 203, + 204: 204, + 205: 205, + 206: 206, + 207: 207, + 208: 208, + 209: 209, + 210: 210, + 211: 211, + 212: 212, + 213: 213, + 214: 214, + 215: 215, + 216: 216, + 217: 217, + 218: 218, + 219: 219, + 220: 220, + 221: 221, + 222: 222, + 223: 223, + 224: 224, + 225: 225, + 226: 226, + 227: 227, + 228: 228, + 229: 229, + 230: 230, + 231: 231, + 232: 232, + 233: 233, + 234: 234, + 235: 235, + 236: 236, + 237: 237, + 238: 238, + 239: 239, + 240: 240, + 241: 241, + 242: 242, + 243: 243, + 244: 244, + 245: 245, + 246: 246, + 247: 247, + 248: 248, + 249: 249, + 250: 250, + 251: 251, + 252: 252, + 253: 253, + 254: 254, + 255: 255, +}; + +/// Provides a windows 1252 / cp1252 codec for easy encoding and decoding. +/// Note that the decoder directly modifies the data given in `decode(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// codec.decode([...data]); +/// ``` +class Windows1252Codec extends cnvrt.Encoding { + final bool allowInvalid; + + /// Creates a new codec + const Windows1252Codec({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? and decoded to � + this.allowInvalid = false, + }); + + @override + Windows1252Decoder get decoder => allowInvalid + ? const Windows1252Decoder(allowInvalid: true) + : const Windows1252Decoder(allowInvalid: false); + + @override + Windows1252Encoder get encoder => allowInvalid + ? const Windows1252Encoder(allowInvalid: true) + : const Windows1252Encoder(allowInvalid: false); + + @override + String get name => 'windows-1252'; +} + +/// Decodes windows 1252 / cp1252 data. +/// Note that the decoder directly modifies the data given in `convert(List data)`, +/// in doubt create a new array first, e.g. +/// ```dart +/// decoder.convert([...data]); +/// ``` +class Windows1252Decoder extends WindowsDecoder { + const Windows1252Decoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be decoded to � + bool allowInvalid = false, + }) : super(_cp1252Symbols, allowInvalid: allowInvalid); +} + +/// Encodes texts into windows 1252 data +class Windows1252Encoder extends WindowsEncoder { + const Windows1252Encoder({ + /// set [allowInvalid] to `true` for ignoring invalid data. + /// When invalid data is allowed it will be encoded to ? + bool allowInvalid = false, + }) : super(_cp1252Map, allowInvalid: allowInvalid); +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..6075f8a --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,14 @@ +name: enough_convert +description: Support for ISO 8859 / Latin and Windows character encodings missing from `dart:convert`. +version: 0.9.0 +homepage: https://github.com/Enough-Software/enough_convert + +environment: + sdk: '>=2.10.0 <3.0.0' + +#dependencies: +# characters: ^1.0.0 + +dev_dependencies: + pedantic: ^1.9.0 + test: ^1.14.4 diff --git a/test/latin/latin10_test.dart b/test/latin/latin10_test.dart new file mode 100644 index 0000000..f150da8 --- /dev/null +++ b/test/latin/latin10_test.dart @@ -0,0 +1,98 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin10.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin10Codec().name, 'iso-8859-10'); + // print('latin 10 map:'); + // final isoSymbols = + // 'ĄĒĢĪĨĶ§ĻĐŠŦŽ\u{00AD}ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin10Codec().encoder, isA()); + expect(Latin10Codec().decoder, isA()); + convert.Encoding encoding = const Latin10Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin10Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 10', () { + final bytes = const Latin10Encoder().convert('Hyggelig å møte deg!'); + expect(const Latin10Decoder().convert(bytes), 'Hyggelig å møte deg!'); + }); + + test('Decode latin 10 with invalid value when invalid input is allowed', + () { + expect(Latin10Decoder(allowInvalid: true).convert([0xC6, 0xE6, 0xFF1]), + 'Ææ�'); + }); + + test('Decode latin 10 with invalid value when invalid input is not allowed', + () { + expect(() => Latin10Decoder().convert([0xC6, 0xE6, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin10Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 10', () { + final bytes = const Latin10Encoder().convert('Hyggelig å møte deg!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin10Codec().encode('Hyggelig å møte deg!')); + expect( + bytes, + const Latin10Codec(allowInvalid: true) + .encode('Hyggelig å møte deg!')); + expect( + bytes, + const Latin10Codec(allowInvalid: false) + .encode('Hyggelig å møte deg!')); + }); + + test('encode more latin 10 ', () { + final input = + 'ĄĒĢĪĨĶ§ĻĐŠŦŽ\u{00AD}ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ'; + + var bytes = Latin10Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 10 with invalid value when invalid input is allowed', + () { + var bytes = + Latin10Encoder(allowInvalid: true).convert('Hyggelig å møte deg!�'); + expect(Latin10Decoder().convert(bytes), 'Hyggelig å møte deg!?'); + }); + + test('encode latin 10 with invalid value when invalid input is not allowed', + () { + expect(() => Latin10Encoder().convert('Hyggelig å møte deg!�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin11_test.dart b/test/latin/latin11_test.dart new file mode 100644 index 0000000..7c098e6 --- /dev/null +++ b/test/latin/latin11_test.dart @@ -0,0 +1,94 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin11.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin11Codec().name, 'iso-8859-11'); + // print('latin 11 map:'); + // final isoSymbols = + // 'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู????฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛????'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin11Codec().encoder, isA()); + expect(Latin11Codec().decoder, isA()); + convert.Encoding encoding = const Latin11Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin11Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 11', () { + final bytes = const Latin11Encoder().convert('ยินดีที่ได้พบคุณ!'); + expect(const Latin11Decoder().convert(bytes), 'ยินดีที่ได้พบคุณ!'); + }); + + test('Decode latin 11 with invalid value when invalid input is allowed', + () { + expect(Latin11Decoder(allowInvalid: true).convert([0xC6, 0xC7, 0xFF1]), + 'ฦว�'); + }); + + test('Decode latin 11 with invalid value when invalid input is not allowed', + () { + expect(() => Latin11Decoder().convert([0xC6, 0xC7, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin11Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 11', () { + final bytes = const Latin11Encoder().convert('ยินดีที่ได้พบคุณ!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin11Codec().encode('ยินดีที่ได้พบคุณ!')); + expect(bytes, + const Latin11Codec(allowInvalid: true).encode('ยินดีที่ได้พบคุณ!')); + expect(bytes, + const Latin11Codec(allowInvalid: false).encode('ยินดีที่ได้พบคุณ!')); + }); + + test('encode more latin 11 ', () { + final input = + 'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู????฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛????'; + + var bytes = Latin11Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 11 with invalid value when invalid input is allowed', + () { + var bytes = + Latin11Encoder(allowInvalid: true).convert('ยินดีที่ได้พบคุณ!�'); + expect(Latin11Decoder().convert(bytes), 'ยินดีที่ได้พบคุณ!?'); + }); + + test('encode latin 11 with invalid value when invalid input is not allowed', + () { + expect(() => Latin11Encoder().convert('ยินดีที่ได้พบคุณ!�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin13_test.dart b/test/latin/latin13_test.dart new file mode 100644 index 0000000..a6b96ce --- /dev/null +++ b/test/latin/latin13_test.dart @@ -0,0 +1,98 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin13.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin13Codec().name, 'iso-8859-13'); + // print('latin 13 map:'); + // final isoSymbols = + // '”¢£¤„¦§Ø©Ŗ«¬\u{00AD}®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin13Codec().encoder, isA()); + expect(Latin13Codec().decoder, isA()); + convert.Encoding encoding = const Latin13Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin13Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 13', () { + final bytes = const Latin13Encoder().convert('Hyggelig å møte deg!'); + expect(const Latin13Decoder().convert(bytes), 'Hyggelig å møte deg!'); + }); + + test('Decode latin 13 with invalid value when invalid input is allowed', + () { + expect(Latin13Decoder(allowInvalid: true).convert([0xC6, 0xE6, 0xFF1]), + 'Ęę�'); + }); + + test('Decode latin 13 with invalid value when invalid input is not allowed', + () { + expect(() => Latin13Decoder().convert([0xC6, 0xE6, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin13Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 13', () { + final bytes = const Latin13Encoder().convert('Hyggelig å møte deg!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin13Codec().encode('Hyggelig å møte deg!')); + expect( + bytes, + const Latin13Codec(allowInvalid: true) + .encode('Hyggelig å møte deg!')); + expect( + bytes, + const Latin13Codec(allowInvalid: false) + .encode('Hyggelig å møte deg!')); + }); + + test('encode more latin 13 ', () { + final input = + '”¢£¤„¦§Ø©Ŗ«¬\u{00AD}®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’'; + + var bytes = Latin13Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 13 with invalid value when invalid input is allowed', + () { + var bytes = + Latin13Encoder(allowInvalid: true).convert('Hyggelig å møte deg!�'); + expect(Latin13Decoder().convert(bytes), 'Hyggelig å møte deg!?'); + }); + + test('encode latin 13 with invalid value when invalid input is not allowed', + () { + expect(() => Latin13Encoder().convert('Hyggelig å møte deg!�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin14_test.dart b/test/latin/latin14_test.dart new file mode 100644 index 0000000..de9a677 --- /dev/null +++ b/test/latin/latin14_test.dart @@ -0,0 +1,107 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin14.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin14Codec().name, 'iso-8859-14'); + // print('latin 14 map:'); + // final isoSymbols = + // 'Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ\u{00AD}®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin14Codec().encoder, isA()); + expect(Latin14Codec().decoder, isA()); + convert.Encoding encoding = const Latin14Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin14Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 14', () { + final bytes = const Latin14Encoder() + .convert('Má tú ag lorg cara gan locht, béidh tú gan cara go deo.'); + expect(const Latin14Decoder().convert(bytes), + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.'); + }); + + test('Decode latin 14 with invalid value when invalid input is allowed', + () { + expect(Latin14Decoder(allowInvalid: true).convert([0xC6, 0xE6, 0xFF1]), + 'Ææ�'); + }); + + test('Decode latin 14 with invalid value when invalid input is not allowed', + () { + expect(() => Latin14Decoder().convert([0xC6, 0xE6, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin14Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 14', () { + final bytes = const Latin14Encoder() + .convert('Má tú ag lorg cara gan locht, béidh tú gan cara go deo.'); + expect(bytes.any((element) => element > 0xFF), false); + expect( + bytes, + const Latin14Codec().encode( + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.')); + expect( + bytes, + const Latin14Codec(allowInvalid: true).encode( + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.')); + expect( + bytes, + const Latin14Codec(allowInvalid: false).encode( + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.')); + }); + + test('encode more latin 14 ', () { + final input = + 'Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ\u{00AD}®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ'; + + var bytes = Latin14Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 14 with invalid value when invalid input is allowed', + () { + var bytes = Latin14Encoder(allowInvalid: true) + .convert('Má tú ag lorg cara gan locht, béidh tú gan cara go deo.�'); + expect(Latin14Decoder().convert(bytes), + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.?'); + }); + + test('encode latin 14 with invalid value when invalid input is not allowed', + () { + expect( + () => Latin14Encoder().convert( + 'Má tú ag lorg cara gan locht, béidh tú gan cara go deo.�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin15_test.dart b/test/latin/latin15_test.dart new file mode 100644 index 0000000..7cdd8b7 --- /dev/null +++ b/test/latin/latin15_test.dart @@ -0,0 +1,102 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin15.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin15Codec().name, 'iso-8859-15'); + // print('latin 15 map:'); + // final isoSymbols = + // '¡¢£€¥Š§š©ª«¬\u{00AD}®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin15Codec().encoder, isA()); + expect(Latin15Codec().decoder, isA()); + convert.Encoding encoding = const Latin15Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin15Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 15', () { + final bytes = + const Latin15Encoder().convert('Il faut être bête quand même.'); + expect(const Latin15Decoder().convert(bytes), + 'Il faut être bête quand même.'); + }); + + test('Decode latin 15 with invalid value when invalid input is allowed', + () { + expect(Latin15Decoder(allowInvalid: true).convert([0xC6, 0xE6, 0xFF1]), + 'Ææ�'); + }); + + test('Decode latin 15 with invalid value when invalid input is not allowed', + () { + expect(() => Latin15Decoder().convert([0xC6, 0xE6, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin15Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 15', () { + final bytes = + const Latin15Encoder().convert('Il faut être bête quand même.'); + expect(bytes.any((element) => element > 0xFF), false); + expect( + bytes, const Latin15Codec().encode('Il faut être bête quand même.')); + expect( + bytes, + const Latin15Codec(allowInvalid: true) + .encode('Il faut être bête quand même.')); + expect( + bytes, + const Latin15Codec(allowInvalid: false) + .encode('Il faut être bête quand même.')); + }); + + test('encode more latin 15 ', () { + final input = + '¡¢£€¥Š§š©ª«¬\u{00AD}®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; + + var bytes = Latin15Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 15 with invalid value when invalid input is allowed', + () { + var bytes = Latin15Encoder(allowInvalid: true) + .convert('Il faut être bête quand même.�'); + expect(Latin15Decoder().convert(bytes), 'Il faut être bête quand même.?'); + }); + + test('encode latin 15 with invalid value when invalid input is not allowed', + () { + expect(() => Latin15Encoder().convert('Il faut être bête quand même.�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin16_test.dart b/test/latin/latin16_test.dart new file mode 100644 index 0000000..52d32c6 --- /dev/null +++ b/test/latin/latin16_test.dart @@ -0,0 +1,101 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin16.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin16Codec().name, 'iso-8859-16'); + // print('latin 16 map:'); + // final isoSymbols = + // 'ĄąŁ€„Š§š©Ș«Ź\u{00AD}źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin16Codec().encoder, isA()); + expect(Latin16Codec().decoder, isA()); + convert.Encoding encoding = const Latin16Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin16Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 16', () { + final bytes = + const Latin16Encoder().convert('Örülök, hogy találkoztunk!'); + expect( + const Latin16Decoder().convert(bytes), 'Örülök, hogy találkoztunk!'); + }); + + test('Decode latin 16 with invalid value when invalid input is allowed', + () { + expect(Latin16Decoder(allowInvalid: true).convert([0xC6, 0xE6, 0xFF1]), + 'Ææ�'); + }); + + test('Decode latin 16 with invalid value when invalid input is not allowed', + () { + expect(() => Latin16Decoder().convert([0xC6, 0xE6, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin16Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 16', () { + final bytes = + const Latin16Encoder().convert('Örülök, hogy találkoztunk!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin16Codec().encode('Örülök, hogy találkoztunk!')); + expect( + bytes, + const Latin16Codec(allowInvalid: true) + .encode('Örülök, hogy találkoztunk!')); + expect( + bytes, + const Latin16Codec(allowInvalid: false) + .encode('Örülök, hogy találkoztunk!')); + }); + + test('encode more latin 16 ', () { + final input = + 'ĄąŁ€„Š§š©Ș«Ź\u{00AD}źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ'; + + var bytes = Latin16Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 16 with invalid value when invalid input is allowed', + () { + var bytes = Latin16Encoder(allowInvalid: true) + .convert('Örülök, hogy találkoztunk!�'); + expect(Latin16Decoder().convert(bytes), 'Örülök, hogy találkoztunk!?'); + }); + + test('encode latin 16 with invalid value when invalid input is not allowed', + () { + expect(() => Latin16Encoder().convert('Örülök, hogy találkoztunk!�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin1_test.dart b/test/latin/latin1_test.dart new file mode 100644 index 0000000..59bff5c --- /dev/null +++ b/test/latin/latin1_test.dart @@ -0,0 +1,58 @@ +import 'dart:convert' as convert; + +import 'package:enough_convert/latin/latin1.dart'; +import 'package:test/test.dart'; + +void main() { + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin1Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 1', () { + expect(Latin1Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = convert.latin1.encode('hello world motörhead ruleß ok ÿñô'); + expect( + Latin1Decoder().convert(bytes), 'hello world motörhead ruleß ok ÿñô'); + }); + + test('Decode latin 1 with invalid value when invalid input is allowed', () { + expect( + Latin1Decoder(allowInvalid: true).convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test('Decode latin 1 with invalid value when invalid input is not allowed', + () { + expect(() => Latin1Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin1Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 1', () { + var bytes = Latin1Encoder().convert('ÄÖü'); + expect(bytes, convert.latin1.encode('ÄÖü')); + bytes = Latin1Encoder().convert('hello world motörhead ruleß ok ÿñô'); + expect( + bytes, convert.latin1.encode('hello world motörhead ruleß ok ÿñô')); + }); + + test('encode latin 1 with invalid value when invalid input is allowed', () { + var bytes = Latin1Encoder(allowInvalid: true).convert('ÄÖü�'); + expect(Latin1Decoder().convert(bytes), 'ÄÖü?'); + }); + + test('encode latin 1 with invalid value when invalid input is not allowed', + () { + expect(() => Latin1Encoder().convert('ÄÖü�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin2_test.dart b/test/latin/latin2_test.dart new file mode 100644 index 0000000..d96e799 --- /dev/null +++ b/test/latin/latin2_test.dart @@ -0,0 +1,83 @@ +import 'dart:convert' as convert; + +import 'package:enough_convert/latin/latin2.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin2Codec().name, 'iso-8859-2'); + }); + test('Decoder/encoder classes', () { + expect(Latin2Codec().encoder, isA()); + expect(Latin2Codec().decoder, isA()); + }); + }); + + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin2Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 2', () { + expect(Latin2Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = Latin2Encoder().convert('hello world motörhead ruleß ok ô'); + expect( + Latin2Decoder().convert(bytes), 'hello world motörhead ruleß ok ô'); + }); + + test('Decode latin 2 with invalid value when invalid input is allowed', () { + expect( + Latin2Decoder(allowInvalid: true).convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test('Decode latin 2 with invalid value when invalid input is not allowed', + () { + expect(() => Latin2Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin2Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 2', () { + var bytes = Latin2Encoder().convert('ÄÖü'); + expect(bytes, [0xC4, 0xD6, 0xFC]); + bytes = Latin2Encoder().convert('hello world motörhead ruleß ok'); + + /// this works because umlauts are at the same position as in latin-1 + expect(bytes, convert.latin1.encode('hello world motörhead ruleß ok')); + + bytes = Latin2Encoder().convert('Těší mě, že vás poznávám!'); + expect(bytes.any((element) => element > 0xFF), false); + }); + + test('encode more latin 2 ', () { + var bytes = Latin2Encoder().convert( + 'ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙'); + var expected = List.generate(0xFF - 0xAD, (index) => index + 0xAE); + expect(bytes, expected); + + bytes = Latin2Encoder().convert('Ą˘Ł¤ĽŚ§¨ŠŞŤŹ\u{00AD}'); + expected = List.generate(0xAE - 0xA1, (index) => index + 0xA1); + expect(bytes, expected); + }); + + test('encode latin 2 with invalid value when invalid input is allowed', () { + var bytes = Latin2Encoder(allowInvalid: true).convert('ÄÖü�'); + expect(Latin2Decoder().convert(bytes), 'ÄÖü?'); + }); + + test('encode latin 2 with invalid value when invalid input is not allowed', + () { + expect(() => Latin2Encoder().convert('ÄÖü�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin3_test.dart b/test/latin/latin3_test.dart new file mode 100644 index 0000000..36fb8ff --- /dev/null +++ b/test/latin/latin3_test.dart @@ -0,0 +1,84 @@ +import 'dart:convert' as convert; + +import 'package:enough_convert/latin/latin3.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin3Codec().name, 'iso-8859-3'); + }); + test('Decoder/encoder classes', () { + expect(Latin3Codec().encoder, isA()); + expect(Latin3Codec().decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin3Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 3', () { + expect(Latin3Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = Latin3Encoder().convert('hello world motörhead ruleß ok ô'); + expect( + Latin3Decoder().convert(bytes), 'hello world motörhead ruleß ok ô'); + }); + + test('Decode latin 3 with invalid value when invalid input is allowed', () { + expect( + Latin3Decoder(allowInvalid: true).convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test('Decode latin 3 with invalid value when invalid input is not allowed', + () { + expect(() => Latin3Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin3Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 3', () { + var bytes = Latin3Encoder().convert('ÄÖü'); + expect(bytes, [0xC4, 0xD6, 0xFC]); + bytes = Latin3Encoder().convert('hello world motörhead ruleß ok'); + + /// this works because umlauts are at the same position as in latin-1 + expect(bytes, convert.latin1.encode('hello world motörhead ruleß ok')); + bytes = Latin3Encoder().convert('Tanıştığımıza memnun oldum!'); + expect(bytes.any((element) => element > 0xFF), false); + }); + + test('encode more latin 3 ', () { + final input = + 'Ħ˘£¤?Ĥ§¨İŞĞĴ\u{00AD}?Ż°ħ²³´µĥ·¸ışğĵ½?żÀÁÂ?ÄĊĈÇÈÉÊËÌÍÎÏ?ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ?äċĉçèéêëìíîï?ñòóôġö÷ĝùúûüŭŝ˙'; + var bytes = Latin3Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 3 with invalid value when invalid input is allowed', () { + var bytes = Latin3Encoder(allowInvalid: true).convert('ÄÖü�'); + expect(Latin3Decoder().convert(bytes), 'ÄÖü?'); + }); + + test('encode latin 3 with invalid value when invalid input is not allowed', + () { + expect(() => Latin3Encoder().convert('ÄÖü�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin4_test.dart b/test/latin/latin4_test.dart new file mode 100644 index 0000000..0b235ed --- /dev/null +++ b/test/latin/latin4_test.dart @@ -0,0 +1,88 @@ +import 'dart:convert' as convert; + +//import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin4.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin4Codec().name, 'iso-8859-4'); + //print('latin4 map:'); + // LatinEncoder.createEncodingMap( + // 'ĄĸŖ¤ĨĻ§¨ŠĒĢŦ\u{00AD}Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙'); + }); + test('Decoder/encoder classes', () { + expect(Latin4Codec().encoder, isA()); + expect(Latin4Codec().decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin4Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 4', () { + expect(Latin4Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = Latin4Encoder().convert('hello world motörhead ruleß ok ô'); + expect( + Latin4Decoder().convert(bytes), 'hello world motörhead ruleß ok ô'); + }); + + test('Decode latin 4 with invalid value when invalid input is allowed', () { + expect( + Latin4Decoder(allowInvalid: true).convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test('Decode latin 4 with invalid value when invalid input is not allowed', + () { + expect(() => Latin4Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin4Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 4', () { + var bytes = Latin4Encoder().convert('ÄÖü'); + expect(bytes, [0xC4, 0xD6, 0xFC]); + bytes = Latin4Encoder().convert('hello world motörhead ruleß ok'); + + /// this works because umlauts are at the same position as in latin-1 + expect(bytes, convert.latin1.encode('hello world motörhead ruleß ok')); + bytes = Latin4Encoder().convert('Priecājos iepazīties!'); + expect(bytes.any((element) => element > 0xFF), false); + }); + + test('encode more latin 4 ', () { + final input = + 'ĄĸŖ¤ĨĻ§¨ŠĒĢŦ\u{00AD}Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙'; + var bytes = Latin4Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 4 with invalid value when invalid input is allowed', () { + var bytes = Latin4Encoder(allowInvalid: true).convert('ÄÖü�'); + expect(Latin4Decoder().convert(bytes), 'ÄÖü?'); + }); + + test('encode latin 4 with invalid value when invalid input is not allowed', + () { + expect(() => Latin4Encoder().convert('ÄÖü�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin5_test.dart b/test/latin/latin5_test.dart new file mode 100644 index 0000000..b432fb9 --- /dev/null +++ b/test/latin/latin5_test.dart @@ -0,0 +1,90 @@ +import 'dart:convert' as convert; + +//import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin5.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin5Codec().name, 'iso-8859-5'); + // print('latin 5 map:'); + // LatinEncoder.createEncodingMap( + // 'ЁЂЃЄЅІЇЈЉЊЋЌ\u{00AD}ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ'); + }); + test('Decoder/encoder classes', () { + expect(Latin5Codec().encoder, isA()); + expect(Latin5Codec().decoder, isA()); + convert.Encoding encoding = const Latin5Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin5Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 5', () { + final bytes = const Latin5Encoder().convert('Приятно встретиться!'); + expect(const Latin5Decoder().convert(bytes), 'Приятно встретиться!'); + }); + + test('Decode latin 5 with invalid value when invalid input is allowed', () { + expect( + Latin5Decoder(allowInvalid: true).convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'Фжќ�'); + }); + + test('Decode latin 5 with invalid value when invalid input is not allowed', + () { + expect(() => Latin5Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin5Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 5', () { + final bytes = const Latin5Encoder().convert('Приятно встретиться!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin5Codec().encode('Приятно встретиться!')); + expect(bytes, + const Latin5Codec(allowInvalid: true).encode('Приятно встретиться!')); + expect( + bytes, + const Latin5Codec(allowInvalid: false) + .encode('Приятно встретиться!')); + }); + + test('encode more latin 5 ', () { + final input = + 'ЁЂЃЄЅІЇЈЉЊЋЌ\u{00AD}ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ'; + var bytes = Latin5Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 5 with invalid value when invalid input is allowed', () { + var bytes = Latin5Encoder(allowInvalid: true).convert('Фжќ�'); + expect(Latin5Decoder().convert(bytes), 'Фжќ?'); + }); + + test('encode latin 5 with invalid value when invalid input is not allowed', + () { + expect(() => Latin5Encoder().convert('Фжќ�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin6_test.dart b/test/latin/latin6_test.dart new file mode 100644 index 0000000..c38a89d --- /dev/null +++ b/test/latin/latin6_test.dart @@ -0,0 +1,87 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin6.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin6Codec().name, 'iso-8859-6'); + // print('latin 6 map:'); + // LatinEncoder.createEncodingMap( + // '???¤???????،\u{00AD}?????????????؛???؟?ءآأؤإئابةتثجحخدذرزسشصضطظعغ?????ـفقكلمنهوىيًٌٍَُِّْ?????????????'); + }); + test('Decoder/encoder classes', () { + expect(Latin6Codec().encoder, isA()); + expect(Latin6Codec().decoder, isA()); + convert.Encoding encoding = const Latin6Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin6Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 6', () { + final bytes = const Latin6Encoder().convert('سعدت بلقائك'); + expect(const Latin6Decoder().convert(bytes), 'سعدت بلقائك'); + }); + + test('Decode latin 6 with invalid value when invalid input is allowed', () { + expect(Latin6Decoder(allowInvalid: true).convert([0xC4, 0xD6, 0xFF1]), + 'ؤض�'); + }); + + test('Decode latin 6 with invalid value when invalid input is not allowed', + () { + expect(() => Latin6Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin6Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 6', () { + final bytes = const Latin6Encoder().convert('سعدت بلقائك'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin6Codec().encode('سعدت بلقائك')); + expect( + bytes, const Latin6Codec(allowInvalid: true).encode('سعدت بلقائك')); + expect( + bytes, const Latin6Codec(allowInvalid: false).encode('سعدت بلقائك')); + }); + + test('encode more latin 6 ', () { + final input = + '???¤???????،\u{00AD}?????????????؛???؟?ءآأؤإئابةتثجحخدذرزسشصضطظعغ?????ـفقكلمنهوىيًٌٍَُِّْ?????????????'; + var bytes = Latin6Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 6 with invalid value when invalid input is allowed', () { + var bytes = Latin6Encoder(allowInvalid: true).convert('سعدت بلقائك�'); + expect(Latin6Decoder().convert(bytes), 'سعدت بلقائك?'); + }); + + test('encode latin 6 with invalid value when invalid input is not allowed', + () { + expect(() => Latin6Encoder().convert('سعدت بلقائك�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin7_test.dart b/test/latin/latin7_test.dart new file mode 100644 index 0000000..d77e0b9 --- /dev/null +++ b/test/latin/latin7_test.dart @@ -0,0 +1,94 @@ +import 'dart:convert' as convert; + +//import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin7.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin7Codec().name, 'iso-8859-7'); + // print('latin 7 map:'); + // LatinEncoder.createEncodingMap( + // '‘’£€₯¦§¨©ͺ«¬\u{00AD}?―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ?ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ?'); + }); + test('Decoder/encoder classes', () { + expect(Latin7Codec().encoder, isA()); + expect(Latin7Codec().decoder, isA()); + convert.Encoding encoding = const Latin7Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin7Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 7', () { + final bytes = const Latin7Encoder().convert('Χαίρομαι που σας γνωρίζω!'); + expect(const Latin7Decoder().convert(bytes), 'Χαίρομαι που σας γνωρίζω!'); + }); + + test('Decode latin 7 with invalid value when invalid input is allowed', () { + expect(Latin7Decoder(allowInvalid: true).convert([0xC4, 0xD7, 0xFF1]), + 'ΔΧ�'); + }); + + test('Decode latin 7 with invalid value when invalid input is not allowed', + () { + expect(() => Latin7Decoder().convert([0xC4, 0xD7, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin7Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 7', () { + final bytes = const Latin7Encoder().convert('Χαίρομαι που σας γνωρίζω!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin7Codec().encode('Χαίρομαι που σας γνωρίζω!')); + expect( + bytes, + const Latin7Codec(allowInvalid: true) + .encode('Χαίρομαι που σας γνωρίζω!')); + expect( + bytes, + const Latin7Codec(allowInvalid: false) + .encode('Χαίρομαι που σας γνωρίζω!')); + }); + + test('encode more latin 7 ', () { + final input = + '‘’£€₯¦§¨©ͺ«¬\u{00AD}?―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ?ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ?'; + var bytes = Latin7Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 7 with invalid value when invalid input is allowed', () { + var bytes = Latin7Encoder(allowInvalid: true) + .convert('Χαίρομαι που σας γνωρίζω!�'); + expect(Latin7Decoder().convert(bytes), 'Χαίρομαι που σας γνωρίζω!?'); + }); + + test('encode latin 7 with invalid value when invalid input is not allowed', + () { + expect(() => Latin7Encoder().convert('Χαίρομαι που σας γνωρίζω!�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin8_test.dart b/test/latin/latin8_test.dart new file mode 100644 index 0000000..ab89312 --- /dev/null +++ b/test/latin/latin8_test.dart @@ -0,0 +1,102 @@ +import 'dart:convert' as convert; +// import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin8.dart'; +import 'package:test/test.dart'; + +//import 'package:characters/characters.dart'; +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin8Codec().name, 'iso-8859-8'); + // final symbols = + // '?¢£¤¥¦§¨©×«¬\u{00AD}®¯°±²³´µ¶·¸¹÷»¼½¾????????????????????????????????‗אבגדהוזחטיךכלםמןנסעףפץצקרשת??\u{8206}\u{8207}?'; + // print('latin 8 map:'); + // LatinEncoder.createEncodingMap(symbols); + }); + test('Decoder/encoder classes', () { + expect(Latin8Codec().encoder, isA()); + expect(Latin8Codec().decoder, isA()); + convert.Encoding encoding = const Latin8Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin8Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 8', () { + final bytes = + const Latin8Encoder().convert('נעים להכיר אותך.נעים להכיר אותך-.'); + expect(const Latin8Decoder().convert(bytes), + 'נעים להכיר אותך.נעים להכיר אותך-.'); + }); + + test('Decode latin 8 with invalid value when invalid input is allowed', () { + expect(Latin8Decoder(allowInvalid: true).convert([0xB2, 0xB3, 0xFF1]), + '²³�'); + }); + + test('Decode latin 8 with invalid value when invalid input is not allowed', + () { + expect(() => Latin8Decoder().convert([0xC4, 0xD8, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin8Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 8', () { + final bytes = + const Latin8Encoder().convert('נעים להכיר אותך.נעים להכיר אותך-.'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, + const Latin8Codec().encode('נעים להכיר אותך.נעים להכיר אותך-.')); + expect( + bytes, + const Latin8Codec(allowInvalid: true) + .encode('נעים להכיר אותך.נעים להכיר אותך-.')); + expect( + bytes, + const Latin8Codec(allowInvalid: false) + .encode('נעים להכיר אותך.נעים להכיר אותך-.')); + }); + + test('encode more latin 8 ', () { + final input = + '?¢£¤¥¦§¨©×«¬\u{00AD}®¯°±²³´µ¶·¸¹÷»¼½¾????????????????????????????????‗אבגדהוזחטיךכלםמןנסעףפץצקרשת??\u{8206}\u{8207}?'; + + var bytes = Latin8Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 8 with invalid value when invalid input is allowed', () { + var bytes = Latin8Encoder(allowInvalid: true) + .convert('נעים להכיר אותך.נעים להכיר אותך-.�'); + expect( + Latin8Decoder().convert(bytes), 'נעים להכיר אותך.נעים להכיר אותך-.?'); + }); + + test('encode latin 8 with invalid value when invalid input is not allowed', + () { + expect( + () => Latin8Encoder().convert('נעים להכיר אותך.נעים להכיר אותך-.�'), + throwsA(isA())); + }); + }); +} diff --git a/test/latin/latin9_test.dart b/test/latin/latin9_test.dart new file mode 100644 index 0000000..cfdc634 --- /dev/null +++ b/test/latin/latin9_test.dart @@ -0,0 +1,99 @@ +import 'dart:convert' as convert; + +//import 'package:enough_convert/latin/latin.dart'; +import 'package:enough_convert/latin/latin9.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Latin9Codec().name, 'iso-8859-9'); + // print('latin 9 map:'); + // final isoSymbols = + // '¡¢£¤¥¦§¨©ª«¬\u{00AD}®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ'; + // LatinEncoder.createEncodingMap(isoSymbols); + }); + test('Decoder/encoder classes', () { + expect(Latin9Codec().encoder, isA()); + expect(Latin9Codec().decoder, isA()); + convert.Encoding encoding = const Latin9Codec(allowInvalid: false); + expect(encoding.encoder, isA()); + expect(encoding.decoder, isA()); + }); + }); + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Latin9Decoder().convert(bytes), 'hello world'); + }); + + test('Decode latin 9', () { + final bytes = + const Latin9Encoder().convert('Tanıştığımıza memnun oldum!'); + expect( + const Latin9Decoder().convert(bytes), 'Tanıştığımıza memnun oldum!'); + }); + + test('Decode latin 9 with invalid value when invalid input is allowed', () { + expect(Latin9Decoder(allowInvalid: true).convert([0xC4, 0xD9, 0xFF1]), + 'ÄÙ�'); + }); + + test('Decode latin 9 with invalid value when invalid input is not allowed', + () { + expect(() => Latin9Decoder().convert([0xC4, 0xD9, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Latin9Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode latin 9', () { + final bytes = + const Latin9Encoder().convert('Tanıştığımıza memnun oldum!'); + expect(bytes.any((element) => element > 0xFF), false); + expect(bytes, const Latin9Codec().encode('Tanıştığımıza memnun oldum!')); + expect( + bytes, + const Latin9Codec(allowInvalid: true) + .encode('Tanıştığımıza memnun oldum!')); + expect( + bytes, + const Latin9Codec(allowInvalid: false) + .encode('Tanıştığımıza memnun oldum!')); + }); + + test('encode more latin 9 ', () { + final input = + '¡¢£¤¥¦§¨©ª«¬\u{00AD}®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ'; + + var bytes = Latin9Encoder().convert(input); + var expected = List.generate(95, (index) => index + 0xA1); + // print( + // 'input.length=${input.length} bytes.length=${bytes.length} expected.length=${expected.length}'); + for (var i = 0; i < input.length; i++) { + if (input.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode latin 9 with invalid value when invalid input is allowed', () { + var bytes = Latin9Encoder(allowInvalid: true) + .convert('Tanıştığımıza memnun oldum!�'); + expect(Latin9Decoder().convert(bytes), 'Tanıştığımıza memnun oldum!?'); + }); + + test('encode latin 9 with invalid value when invalid input is not allowed', + () { + expect(() => Latin9Encoder().convert('Tanıştığımıza memnun oldum!�'), + throwsA(isA())); + }); + }); +} diff --git a/test/windows/windows1250_test.dart b/test/windows/windows1250_test.dart new file mode 100644 index 0000000..56bc5c6 --- /dev/null +++ b/test/windows/windows1250_test.dart @@ -0,0 +1,94 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/base.dart'; +import 'package:enough_convert/windows/windows1250.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Windows1250Codec().name, 'windows-1250'); + // BaseEncoder.createEncodingMap(Windows1250Decoder().symbols, 0x7f); + }); + test('Decoder/encoder classes', () { + expect(Windows1250Codec().encoder, isA()); + expect(Windows1250Codec().decoder, isA()); + }); + }); + + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Windows1250Decoder().convert(bytes), 'hello world'); + }); + + test('Decode Windows1250', () { + expect(Windows1250Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = + Windows1250Encoder().convert('hello world motörhead ruleß ok ô'); + expect(Windows1250Decoder().convert(bytes), + 'hello world motörhead ruleß ok ô'); + }); + + test('Decode Windows1250 with invalid value when invalid input is allowed', + () { + expect( + Windows1250Decoder(allowInvalid: true) + .convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test( + 'Decode Windows1250 with invalid value when invalid input is not allowed', + () { + expect(() => Windows1250Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Windows1250Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode Windows1250', () { + var bytes = Windows1250Encoder().convert('ÄÖü'); + expect(bytes, [0xC4, 0xD6, 0xFC]); + bytes = Windows1250Encoder().convert('hello world motörhead ruleß ok'); + + /// this works because umlauts are at the same position as in latin-1 + expect(bytes, convert.latin1.encode('hello world motörhead ruleß ok')); + + bytes = Windows1250Encoder().convert('Těší mě, že vás poznávám!'); + expect(bytes.any((element) => element > 0xFF), false); + }); + + test('encode more Windows1250 ', () { + final encoder = Windows1250Encoder(); + final decoder = Windows1250Decoder(); + var bytes = encoder.convert(decoder.symbols); + var expected = List.generate(0xFF - 0x7F, (index) => index + 0x80); + for (var i = 0; i < decoder.symbols.length; i++) { + if (decoder.symbols.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode Windows1250 with invalid value when invalid input is allowed', + () { + var bytes = Windows1250Encoder(allowInvalid: true).convert('ÄÖü�'); + expect(Windows1250Decoder().convert(bytes), 'ÄÖü?'); + }); + + test( + 'encode Windows1250 with invalid value when invalid input is not allowed', + () { + expect(() => Windows1250Encoder().convert('ÄÖü�'), + throwsA(isA())); + }); + }); +} diff --git a/test/windows/windows1251_test.dart b/test/windows/windows1251_test.dart new file mode 100644 index 0000000..b378db6 --- /dev/null +++ b/test/windows/windows1251_test.dart @@ -0,0 +1,89 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/base.dart'; +import 'package:enough_convert/windows/windows1251.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Windows1251Codec().name, 'windows-1251'); + // BaseEncoder.createEncodingMap(Windows1251Decoder().symbols, 0x7f); + }); + test('Decoder/encoder classes', () { + expect(Windows1251Codec().encoder, isA()); + expect(Windows1251Codec().decoder, isA()); + }); + }); + + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Windows1251Decoder().convert(bytes), 'hello world'); + }); + + test('Decode Windows1251', () { + expect(Windows1251Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = + Windows1251Encoder().convert('hello world motörhead ruleß ok ô'); + expect(Windows1251Decoder().convert(bytes), + 'hello world motörhead ruleß ok ô'); + }); + + test('Decode Windows1251 with invalid value when invalid input is allowed', + () { + expect( + Windows1251Decoder(allowInvalid: true) + .convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test( + 'Decode Windows1251 with invalid value when invalid input is not allowed', + () { + expect(() => Windows1251Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Windows1251Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode Windows1251', () { + final bytes = Windows1251Encoder().convert('Радий познайомитися з Вами!'); + expect(bytes.any((element) => element > 0xFF), false); + expect( + Windows1251Decoder().convert(bytes), 'Радий познайомитися з Вами!'); + }); + + test('encode more Windows1251 ', () { + final encoder = Windows1251Encoder(); + final decoder = Windows1251Decoder(); + var bytes = encoder.convert(decoder.symbols); + var expected = List.generate(0xFF - 0x7F, (index) => index + 0x80); + for (var i = 0; i < decoder.symbols.length; i++) { + if (decoder.symbols.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode Windows1251 with invalid value when invalid input is allowed', + () { + var bytes = Windows1251Encoder(allowInvalid: true).convert('йз�'); + expect(Windows1251Decoder().convert(bytes), 'йз?'); + }); + + test( + 'encode Windows1251 with invalid value when invalid input is not allowed', + () { + expect(() => Windows1251Encoder().convert('йз�'), + throwsA(isA())); + }); + }); +} diff --git a/test/windows/windows1252_test.dart b/test/windows/windows1252_test.dart new file mode 100644 index 0000000..a7cef9d --- /dev/null +++ b/test/windows/windows1252_test.dart @@ -0,0 +1,94 @@ +import 'dart:convert' as convert; + +// import 'package:enough_convert/base.dart'; +import 'package:enough_convert/windows/windows1252.dart'; +import 'package:test/test.dart'; + +void main() { + group('Codec tests', () { + test('name', () { + expect(Windows1252Codec().name, 'windows-1252'); + //BaseEncoder.createEncodingMap(Windows1252Decoder().symbols, 0x7f); + }); + test('Decoder/encoder classes', () { + expect(Windows1252Codec().encoder, isA()); + expect(Windows1252Codec().decoder, isA()); + }); + }); + + group('Decoder tests', () { + test('Decode ascii', () { + final bytes = convert.ascii.encode('hello world'); + expect(Windows1252Decoder().convert(bytes), 'hello world'); + }); + + test('Decode Windows1252', () { + expect(Windows1252Decoder().convert([0xC4, 0xD6, 0xFC]), 'ÄÖü'); + final bytes = + Windows1252Encoder().convert('hello world motörhead ruleß ok ô'); + expect(Windows1252Decoder().convert(bytes), + 'hello world motörhead ruleß ok ô'); + }); + + test('Decode Windows1252 with invalid value when invalid input is allowed', + () { + expect( + Windows1252Decoder(allowInvalid: true) + .convert([0xC4, 0xD6, 0xFC, 0xFF1]), + 'ÄÖü�'); + }); + + test( + 'Decode Windows1252 with invalid value when invalid input is not allowed', + () { + expect(() => Windows1252Decoder().convert([0xC4, 0xD6, 0xFC, 0xFF1]), + throwsA(isA())); + }); + }); + + group('Encoder tests', () { + test('encode ascii', () { + final bytes = Windows1252Encoder().convert('hello world'); + expect(bytes, convert.latin1.encode('hello world')); + }); + + test('encode Windows1252', () { + var bytes = Windows1252Encoder().convert('ÄÖü'); + expect(bytes, [0xC4, 0xD6, 0xFC]); + bytes = Windows1252Encoder().convert('hello world motörhead ruleß ok'); + + /// this works because umlauts are at the same position as in latin-1 + expect(bytes, convert.latin1.encode('hello world motörhead ruleß ok')); + + bytes = Windows1252Encoder().convert('Il faut être bête quand même.'); + expect(bytes.any((element) => element > 0xFF), false); + }); + + test('encode more Windows1252 ', () { + final encoder = Windows1252Encoder(); + final decoder = Windows1252Decoder(); + var bytes = encoder.convert(decoder.symbols); + var expected = List.generate(0xFF - 0x7F, (index) => index + 0x80); + for (var i = 0; i < decoder.symbols.length; i++) { + if (decoder.symbols.codeUnitAt(i) == 0x3F) { + // ? + expected[i] = 0x3F; + } + } + expect(bytes, expected); + }); + + test('encode Windows1252 with invalid value when invalid input is allowed', + () { + var bytes = Windows1252Encoder(allowInvalid: true).convert('ÄÖü�'); + expect(Windows1252Decoder().convert(bytes), 'ÄÖü?'); + }); + + test( + 'encode Windows1252 with invalid value when invalid input is not allowed', + () { + expect(() => Windows1252Encoder().convert('ÄÖü�'), + throwsA(isA())); + }); + }); +}