| OLD | NEW |
| 1 part of dart.convert; | 1 part of dart.convert; |
| 2 const int UNICODE_REPLACEMENT_CHARACTER_RUNE = 0xFFFD; | 2 const int UNICODE_REPLACEMENT_CHARACTER_RUNE = 0xFFFD; |
| 3 const int UNICODE_BOM_CHARACTER_RUNE = 0xFEFF; | 3 const int UNICODE_BOM_CHARACTER_RUNE = 0xFEFF; |
| 4 const Utf8Codec UTF8 = const Utf8Codec(); | 4 const Utf8Codec UTF8 = const Utf8Codec(); |
| 5 class Utf8Codec extends Encoding {final bool _allowMalformed; | 5 class Utf8Codec extends Encoding {final bool _allowMalformed; |
| 6 const Utf8Codec({ | 6 const Utf8Codec({ |
| 7 bool allowMalformed : false} | 7 bool allowMalformed : false} |
| 8 ) : _allowMalformed = allowMalformed; | 8 ) : _allowMalformed = allowMalformed; |
| 9 String get name => "utf-8"; | 9 String get name => "utf-8"; |
| 10 String decode(List<int> codeUnits, { | 10 String decode(List<int> codeUnits, { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f); | 66 _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f); |
| 67 _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f); | 67 _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f); |
| 68 return false; | 68 return false; |
| 69 } | 69 } |
| 70 } | 70 } |
| 71 int _fillBuffer(String str, int start, int end) { | 71 int _fillBuffer(String str, int start, int end) { |
| 72 if (start != end && _isLeadSurrogate(str.codeUnitAt(end - 1))) { | 72 if (start != end && _isLeadSurrogate(str.codeUnitAt(end - 1))) { |
| 73 end--; | 73 end--; |
| 74 } | 74 } |
| 75 int stringIndex; | 75 int stringIndex; |
| 76 for (stringIndex = start; | 76 for (stringIndex = start; stringIndex < end; stringIndex++) { |
| 77 stringIndex < end; | |
| 78 stringIndex++) { | |
| 79 int codeUnit = str.codeUnitAt(stringIndex); | 77 int codeUnit = str.codeUnitAt(stringIndex); |
| 80 if (codeUnit <= _ONE_BYTE_LIMIT) { | 78 if (codeUnit <= _ONE_BYTE_LIMIT) { |
| 81 if (_bufferIndex >= _buffer.length) break; | 79 if (_bufferIndex >= _buffer.length) break; |
| 82 _buffer[_bufferIndex++] = codeUnit; | 80 _buffer[_bufferIndex++] = codeUnit; |
| 83 } | 81 } |
| 84 else if (_isLeadSurrogate(codeUnit)) { | 82 else if (_isLeadSurrogate(codeUnit)) { |
| 85 if (_bufferIndex + 3 >= _buffer.length) break; | 83 if (_bufferIndex + 3 >= _buffer.length) break; |
| 86 int nextCodeUnit = str.codeUnitAt(stringIndex + 1); | 84 int nextCodeUnit = str.codeUnitAt(stringIndex + 1); |
| 87 bool wasCombined = _writeSurrogate(codeUnit, nextCodeUnit); | 85 bool wasCombined = _writeSurrogate(codeUnit, nextCodeUnit); |
| 88 if (wasCombined) stringIndex++; | 86 if (wasCombined) stringIndex++; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 void convert(List<int> codeUnits, int startIndex, int endIndex) { | 214 void convert(List<int> codeUnits, int startIndex, int endIndex) { |
| 217 int value = _value; | 215 int value = _value; |
| 218 int expectedUnits = _expectedUnits; | 216 int expectedUnits = _expectedUnits; |
| 219 int extraUnits = _extraUnits; | 217 int extraUnits = _extraUnits; |
| 220 _value = 0; | 218 _value = 0; |
| 221 _expectedUnits = 0; | 219 _expectedUnits = 0; |
| 222 _extraUnits = 0; | 220 _extraUnits = 0; |
| 223 int scanOneByteCharacters(units, int from) { | 221 int scanOneByteCharacters(units, int from) { |
| 224 final to = endIndex; | 222 final to = endIndex; |
| 225 final mask = _ONE_BYTE_LIMIT; | 223 final mask = _ONE_BYTE_LIMIT; |
| 226 for (var i = from; | 224 for (var i = from; i < to; i++) { |
| 227 i < to; | |
| 228 i++) { | |
| 229 final unit = units[i]; | 225 final unit = units[i]; |
| 230 if ((unit & mask) != unit) return i - from; | 226 if ((unit & mask) != unit) return i - from; |
| 231 } | 227 } |
| 232 return to - from; | 228 return to - from; |
| 233 } | 229 } |
| 234 void addSingleBytes(int from, int to) { | 230 void addSingleBytes(int from, int to) { |
| 235 assert (from >= startIndex && from <= endIndex); assert (to >= startIndex && to
<= endIndex); _stringSink.write(new String.fromCharCodes(codeUnits, from, to)); | 231 assert (from >= startIndex && from <= endIndex); assert (to >= startIndex && to
<= endIndex); _stringSink.write(new String.fromCharCodes(codeUnits, from, to)); |
| 236 } | 232 } |
| 237 int i = startIndex; | 233 int i = startIndex; |
| 238 loop: while (true) { | 234 loop: while (true) { |
| 239 multibyte: if (expectedUnits > 0) { | 235 multibyte: if (expectedUnits > 0) { |
| 240 do { | 236 do { |
| 241 if (i == endIndex) { | 237 if (i == endIndex) { |
| 242 break loop; | 238 break loop; |
| 243 } | 239 } |
| 244 int unit = codeUnits[i]; | 240 int unit = codeUnits[i]; |
| 245 if ((unit & 0xC0) != 0x80) { | 241 if ((unit & 0xC0) != 0x80) { |
| 246 expectedUnits = 0; | 242 expectedUnits = 0; |
| 247 if (!_allowMalformed) { | 243 if (!_allowMalformed) { |
| 248 throw new FormatException("Bad UTF-8 encoding 0x${unit.toRadixString(16)} | 244 throw new FormatException("Bad UTF-8 encoding 0x${unit.toRadixString(16)}"); |
| 249 "); | 245 } |
| 250 } | |
| 251 _isFirstCharacter = false; | 246 _isFirstCharacter = false; |
| 252 _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE); | 247 _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE); |
| 253 break multibyte; | 248 break multibyte; |
| 254 } | 249 } |
| 255 else { | 250 else { |
| 256 value = (value << 6) | (unit & 0x3f); | 251 value = (value << 6) | (unit & 0x3f); |
| 257 expectedUnits--; | 252 expectedUnits--; |
| 258 i++; | 253 i++; |
| 259 } | 254 } |
| 260 } | 255 } |
| 261 while (expectedUnits > 0); if (value <= _LIMITS[extraUnits - 1]) { | 256 while (expectedUnits > 0); if (value <= _LIMITS[extraUnits - 1]) { |
| 262 if (!_allowMalformed) { | 257 if (!_allowMalformed) { |
| 263 throw new FormatException("Overlong encoding of 0x${value.toRadixString(16)} | 258 throw new FormatException("Overlong encoding of 0x${value.toRadixString(16)}"); |
| 264 "); | |
| 265 } | 259 } |
| 266 expectedUnits = extraUnits = 0; | 260 expectedUnits = extraUnits = 0; |
| 267 value = UNICODE_REPLACEMENT_CHARACTER_RUNE; | 261 value = UNICODE_REPLACEMENT_CHARACTER_RUNE; |
| 268 } | 262 } |
| 269 if (value > _FOUR_BYTE_LIMIT) { | 263 if (value > _FOUR_BYTE_LIMIT) { |
| 270 if (!_allowMalformed) { | 264 if (!_allowMalformed) { |
| 271 throw new FormatException("Character outside valid Unicode range: " "0x${value.t
oRadixString(16)} | 265 throw new FormatException("Character outside valid Unicode range: " "0x${value.t
oRadixString(16)}"); |
| 272 "); | |
| 273 } | 266 } |
| 274 value = UNICODE_REPLACEMENT_CHARACTER_RUNE; | 267 value = UNICODE_REPLACEMENT_CHARACTER_RUNE; |
| 275 } | 268 } |
| 276 if (!_isFirstCharacter || value != UNICODE_BOM_CHARACTER_RUNE) { | 269 if (!_isFirstCharacter || value != UNICODE_BOM_CHARACTER_RUNE) { |
| 277 _stringSink.writeCharCode(value); | 270 _stringSink.writeCharCode(value); |
| 278 } | 271 } |
| 279 _isFirstCharacter = false; | 272 _isFirstCharacter = false; |
| 280 } | 273 } |
| 281 while (i < endIndex) { | 274 while (i < endIndex) { |
| 282 int oneBytes = scanOneByteCharacters(codeUnits, i); | 275 int oneBytes = scanOneByteCharacters(codeUnits, i); |
| 283 if (oneBytes > 0) { | 276 if (oneBytes > 0) { |
| 284 _isFirstCharacter = false; | 277 _isFirstCharacter = false; |
| 285 addSingleBytes(i, i + oneBytes); | 278 addSingleBytes(i, i + oneBytes); |
| 286 i += oneBytes; | 279 i += oneBytes; |
| 287 if (i == endIndex) break; | 280 if (i == endIndex) break; |
| 288 } | 281 } |
| 289 int unit = codeUnits[i++]; | 282 int unit = codeUnits[i++]; |
| 290 if (unit < 0) { | 283 if (unit < 0) { |
| 291 if (!_allowMalformed) { | 284 if (!_allowMalformed) { |
| 292 throw new FormatException("Negative UTF-8 code unit: -0x${(-unit).toRadixString(
16)} | 285 throw new FormatException("Negative UTF-8 code unit: -0x${(-unit).toRadixString(
16)}"); |
| 293 "); | |
| 294 } | 286 } |
| 295 _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE); | 287 _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE); |
| 296 } | 288 } |
| 297 else { | 289 else { |
| 298 assert (unit > _ONE_BYTE_LIMIT); if ((unit & 0xE0) == 0xC0) { | 290 assert (unit > _ONE_BYTE_LIMIT); if ((unit & 0xE0) == 0xC0) { |
| 299 value = unit & 0x1F; | 291 value = unit & 0x1F; |
| 300 expectedUnits = extraUnits = 1; | 292 expectedUnits = extraUnits = 1; |
| 301 continue loop; | 293 continue loop; |
| 302 } | 294 } |
| 303 if ((unit & 0xF0) == 0xE0) { | 295 if ((unit & 0xF0) == 0xE0) { |
| 304 value = unit & 0x0F; | 296 value = unit & 0x0F; |
| 305 expectedUnits = extraUnits = 2; | 297 expectedUnits = extraUnits = 2; |
| 306 continue loop; | 298 continue loop; |
| 307 } | 299 } |
| 308 if ((unit & 0xF8) == 0xF0 && unit < 0xF5) { | 300 if ((unit & 0xF8) == 0xF0 && unit < 0xF5) { |
| 309 value = unit & 0x07; | 301 value = unit & 0x07; |
| 310 expectedUnits = extraUnits = 3; | 302 expectedUnits = extraUnits = 3; |
| 311 continue loop; | 303 continue loop; |
| 312 } | 304 } |
| 313 if (!_allowMalformed) { | 305 if (!_allowMalformed) { |
| 314 throw new FormatException("Bad UTF-8 encoding 0x${unit.toRadixString(16)} | 306 throw new FormatException("Bad UTF-8 encoding 0x${unit.toRadixString(16)}"); |
| 315 "); | |
| 316 } | 307 } |
| 317 value = UNICODE_REPLACEMENT_CHARACTER_RUNE; | 308 value = UNICODE_REPLACEMENT_CHARACTER_RUNE; |
| 318 expectedUnits = extraUnits = 0; | 309 expectedUnits = extraUnits = 0; |
| 319 _isFirstCharacter = false; | 310 _isFirstCharacter = false; |
| 320 _stringSink.writeCharCode(value); | 311 _stringSink.writeCharCode(value); |
| 321 } | 312 } |
| 322 } | 313 } |
| 323 break loop; | 314 break loop; |
| 324 } | 315 } |
| 325 if (expectedUnits > 0) { | 316 if (expectedUnits > 0) { |
| 326 _value = value; | 317 _value = value; |
| 327 _expectedUnits = expectedUnits; | 318 _expectedUnits = expectedUnits; |
| 328 _extraUnits = extraUnits; | 319 _extraUnits = extraUnits; |
| 329 } | 320 } |
| 330 } | 321 } |
| 331 } | 322 } |
| OLD | NEW |