Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: utils/utf8/utf8.dart

Issue 9204006: Make SourceString Iterable<int>. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/scanner/token.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('utf8'); 5 #library('utf8');
6 6
7 class Utf8Decoder { 7 class Utf8Decoder implements Iterable<int>, Iterator<int> {
8 final List<int> bytes; 8 final List<int> bytes;
9 final int offset; 9 int offset;
10 final int length; 10 final int end;
11 11
12 Utf8Decoder(List<int> this.bytes, int this.offset, int this.length); 12 Utf8Decoder(List<int> this.bytes, int offset, int length)
13 : this.offset = offset, end = offset + length;
13 14
14 String toString() { 15 /** Decode the remaininder of the characters in this decoder
15 return new String.fromCharCodes(decodeUtf8(bytes.getRange(offset, length))); 16 * into a [List<int>].
17 */
18 List<int> decodeRest() {
19 List<int> result = <int>[];
20 for (int char in this) result.add(char);
21 return result;
22 }
23
24 Iterator<int> iterator() => this;
25
26 bool hasNext() => offset < end;
27
28 int next() {
29 assert(hasNext());
30 int byte = bytes[offset++];
31 if (byte < 0x80) {
32 return byte;
33 }
34 if (byte < 0xC2) {
35 throw new Exception('Cannot decode UTF-8 @ $offset');
36 }
37 if (byte < 0xE0) {
38 int char = (byte & 0x1F) << 6;
39 char += decodeTrailing(bytes[offset++]);
40 if (char < 0x80) {
41 throw new Exception('Cannot decode UTF-8 @ ${offset-1}');
42 }
43 return char;
44 }
45 if (byte < 0xF0) {
46 int char = (byte & 0x0F) << 6;
47 char += decodeTrailing(bytes[offset++]);
48 char <<= 6;
49 char += decodeTrailing(bytes[offset++]);
50 if (char < 0x800 || (0xD800 <= char && char <= 0xDFFF)) {
51 throw new Exception('Cannot decode UTF-8 @ ${offset-2}');
52 }
53 return char;
54 }
55 if (byte < 0xF8) {
56 int char = (byte & 0x07) << 6;
57 char += decodeTrailing(bytes[offset++]);
58 char <<= 6;
59 char += decodeTrailing(bytes[offset++]);
60 char <<= 6;
61 char += decodeTrailing(bytes[offset++]);
62 if (char < 0x10000) {
63 throw new Exception('Cannot decode UTF-8 @ ${offset-3}');
64 }
65 return char;
66 }
67 throw new Exception('Cannot decode UTF-8 @ ${offset}');
16 } 68 }
17 69
18 static int decodeTrailing(int byte) { 70 static int decodeTrailing(int byte) {
19 if (byte < 0x80 || 0xBF < byte) { 71 if (byte < 0x80 || 0xBF < byte) {
20 throw new Exception('Cannot decode UTF-8 $byte'); 72 throw new Exception('Cannot decode UTF-8 $byte');
21 } else { 73 } else {
22 return byte & 0x3F; 74 return byte & 0x3F;
23 } 75 }
24 } 76 }
25 77
26 static List<int> decodeUtf8(List<int> bytes) { 78 static List<int> decodeUtf8(List<int> bytes) {
27 List<int> result = new List<int>(); 79 return new Utf8Decoder(bytes, 0, bytes.length).decodeRest();
28 for (int i = 0; i < bytes.length; i++) {
29 if (bytes[i] < 0x80) {
30 result.add(bytes[i]);
31 } else if (bytes[i] < 0xC2) {
32 throw new Exception('Cannot decode UTF-8 @ $i');
33 } else if (bytes[i] < 0xE0) {
34 int char = (bytes[i++] & 0x1F) << 6;
35 char += decodeTrailing(bytes[i]);
36 if (char < 0x80) {
37 throw new Exception('Cannot decode UTF-8 @ ${i-1}');
38 } else {
39 result.add(char);
40 }
41 } else if (bytes[i] < 0xF0) {
42 int char = (bytes[i++] & 0x0F) << 6;
43 char += decodeTrailing(bytes[i++]);
44 char <<= 6;
45 char += decodeTrailing(bytes[i]);
46 if (char < 0x800 || (0xD800 <= char && char <= 0xDFFF)) {
47 throw new Exception('Cannot decode UTF-8 @ ${i-2}');
48 } else {
49 result.add(char);
50 }
51 } else if (bytes[i] < 0xF8) {
52 int char = (bytes[i++] & 0x07) << 6;
53 char += decodeTrailing(bytes[i++]);
54 char <<= 6;
55 char += decodeTrailing(bytes[i++]);
56 char <<= 6;
57 char += decodeTrailing(bytes[i]);
58 if (char < 0x10000) {
59 throw new Exception('Cannot decode UTF-8 @ ${i-3}');
60 } else {
61 result.add(char);
62 }
63 } else {
64 throw new Exception('Cannot decode UTF-8 @ $i');
65 }
66 }
67 return result;
68 } 80 }
69 } 81 }
OLDNEW
« no previous file with comments | « frog/leg/scanner/token.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698