blob: fa72dc6818e79f9cd1c869e74aacd815706ab8d3 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.9
import "package:expect/expect.dart";
import 'dart:convert';
var asciiStrings = [
"pure ascii",
"\x00 with control characters \n",
"\x01 edge cases \x7f"
];
var nonAsciiStrings = [
"\x80 edge case first",
"Edge case ASCII \u{80}",
"Edge case byte \u{ff}",
"Edge case super-BMP \u{10000}"
];
void main() {
// Build longer versions of the example strings.
for (int i = 0, n = asciiStrings.length; i < n; i++) {
var string = asciiStrings[i];
while (string.length < 1024) {
string += string;
}
asciiStrings.add(string);
}
for (int i = 0, n = nonAsciiStrings.length; i < n; i++) {
var string = nonAsciiStrings[i];
while (string.length < 1024) {
string += string;
}
nonAsciiStrings.add(string);
}
testDirectConversions();
testChunkedConversions();
}
void testDirectConversions() {
for (var codec in [ascii, new AsciiCodec()]) {
for (var asciiString in asciiStrings) {
List bytes = codec.encoder.convert(asciiString);
Expect.listEquals(asciiString.codeUnits.toList(), bytes, asciiString);
String roundTripString = codec.decoder.convert(bytes);
Expect.equals(asciiString, roundTripString);
roundTripString = codec.decode(bytes);
Expect.equals(asciiString, roundTripString);
}
for (var nonAsciiString in nonAsciiStrings) {
Expect.throws(() {
print(codec.encoder.convert(nonAsciiString));
}, null, nonAsciiString);
}
var encode = codec.encoder.convert;
Expect.listEquals([0x42, 0x43, 0x44], encode("ABCDE", 1, 4));
Expect.listEquals([0x42, 0x43, 0x44, 0x45], encode("ABCDE", 1));
Expect.listEquals([0x42, 0x43, 0x44], encode("\xffBCD\xff", 1, 4));
Expect.throws(() {
encode("\xffBCD\xff", 0, 4);
});
Expect.throws(() {
encode("\xffBCD\xff", 1);
});
Expect.throws(() {
encode("\xffBCD\xff", 1, 5);
});
Expect.throws(() {
encode("\xffBCD\xff", -1, 4);
});
Expect.throws(() {
encode("\xffBCD\xff", 1, -1);
});
Expect.throws(() {
encode("\xffBCD\xff", 3, 2);
});
var decode = codec.decoder.convert;
Expect.equals("BCD", decode([0x41, 0x42, 0x43, 0x44, 0x45], 1, 4));
Expect.equals("BCDE", decode([0x41, 0x42, 0x43, 0x44, 0x45], 1));
Expect.equals("BCD", decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1, 4));
Expect.throws(() {
decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 0, 4);
});
Expect.throws(() {
decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1);
});
Expect.throws(() {
decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1, 5);
});
Expect.throws(() {
decode([0xFF, 0x42, 0x43, 0x44, 0xFF], -1, 4);
});
Expect.throws(() {
decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1, -1);
});
Expect.throws(() {
decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 3, 2);
});
}
var allowInvalidCodec = new AsciiCodec(allowInvalid: true);
var invalidBytes = [0, 1, 0xff, 0xdead, 0];
String decoded = allowInvalidCodec.decode(invalidBytes);
Expect.equals("\x00\x01\uFFFD\uFFFD\x00", decoded);
decoded = allowInvalidCodec.decoder.convert(invalidBytes);
Expect.equals("\x00\x01\uFFFD\uFFFD\x00", decoded);
decoded = ascii.decode(invalidBytes, allowInvalid: true);
Expect.equals("\x00\x01\uFFFD\uFFFD\x00", decoded);
}
List<int> encode(
String str, int chunkSize, Converter<String, List<int>> converter) {
List<int> bytes = <int>[];
var byteSink = new ByteConversionSink.withCallback(bytes.addAll);
var stringConversionSink = converter.startChunkedConversion(byteSink);
for (int i = 0; i < str.length; i += chunkSize) {
if (i + chunkSize <= str.length) {
stringConversionSink.add(str.substring(i, i + chunkSize));
} else {
stringConversionSink.add(str.substring(i));
}
}
stringConversionSink.close();
return bytes;
}
String decode(
List<int> bytes, int chunkSize, Converter<List<int>, String> converter) {
StringBuffer buf = new StringBuffer();
var stringSink = new StringConversionSink.fromStringSink(buf);
var byteConversionSink = converter.startChunkedConversion(stringSink);
for (int i = 0; i < bytes.length; i += chunkSize) {
if (i + chunkSize <= bytes.length) {
byteConversionSink.add(bytes.sublist(i, i + chunkSize));
} else {
byteConversionSink.add(bytes.sublist(i));
}
}
byteConversionSink.close();
return buf.toString();
}
void testChunkedConversions() {
// Check encoding.
for (var converter in [
ascii.encoder,
new AsciiCodec().encoder,
new AsciiEncoder()
]) {
for (int chunkSize in [1, 2, 5, 50]) {
for (var asciiString in asciiStrings) {
var units = asciiString.codeUnits.toList();
List bytes = encode(asciiString, chunkSize, converter);
Expect.listEquals(units, bytes);
}
for (var nonAsciiString in nonAsciiStrings) {
Expect.throws(() {
encode(nonAsciiString, chunkSize, converter);
});
}
}
}
// Check decoding.
for (var converter in [
ascii.decoder,
new AsciiCodec().decoder,
new AsciiDecoder()
]) {
for (int chunkSize in [1, 2, 5, 50]) {
for (var asciiString in asciiStrings) {
var units = asciiString.codeUnits.toList();
Expect.equals(asciiString, decode(units, chunkSize, converter));
}
for (var nonAsciiString in nonAsciiStrings) {
var units = nonAsciiString.codeUnits.toList();
Expect.throws(() {
decode(units, chunkSize, converter);
});
}
}
}
}