// 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. 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)); }, (_) => true, 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 encode( String str, int chunkSize, Converter> converter) { List bytes = []; 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 bytes, int chunkSize, Converter, 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); }); } } } }