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

Side by Side Diff: frog/server/utf8.dart

Issue 9462001: Unify most of our utf8 implementations. This takes the implementation (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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/server/frog_server.dart ('k') | frog/tests/leg/src/ScannerTest.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
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.
4
5
6 // TODO(jmesserly): this should be in the corelib somewhere. They were taken
7 // from samples/chat/http_impl.dart. There are actually various UTF8 decoders
8 // in the codebase but this one has the API we need (StringStream not quite
9 // flexible enough). I couldn't find another encoder.
10
11 String decodeUtf8(List<int> bytes) {
12 var d = new UTF8Decoder();
13 d.writeList(bytes);
14 return d.toString();
15 }
16
17 List<int> encodeUtf8(String str) => UTF8Encoder.encodeString(str);
18
19 // Utility class for decoding UTF-8 from data delivered as a stream of
20 // bytes.
21 class UTF8Decoder {
22 UTF8Decoder()
23 : _bufferList = new BufferList(),
24 _result = new StringBuffer();
25
26 // Add UTF-8 encoded data.
27 void writeList(List<int> buffer) {
28 _bufferList.add(buffer);
29 // Only process as much data as we know is safe.
30 while (_bufferList.length >= 4) {
31 _processNext();
32 }
33 }
34
35 // Return the decoded string.
36 String toString() {
37 // Process any leftover data.
38 while (_bufferList.length > 0) {
39 _processNext();
40 }
41 return _result.toString();
42 }
43
44 // Process the next UTF-8 encoded character.
45 void _processNext() {
46 int value = _bufferList.next() & 0xFF;
47 if ((value & 0x80) == 0x80) {
48 int additionalBytes;
49 if ((value & 0xe0) == 0xc0) { // 110xxxxx
50 value = value & 0x1F;
51 additionalBytes = 1;
52 } else if ((value & 0xf0) == 0xe0) { // 1110xxxx
53 value = value & 0x0F;
54 additionalBytes = 2;
55 } else { // 11110xxx
56 value = value & 0x07;
57 additionalBytes = 3;
58 }
59 for (int i = 0; i < additionalBytes; i++) {
60 int byte = _bufferList.next();
61 value = value << 6 | (byte & 0x3F);
62 }
63 }
64 _result.addCharCode(value);
65 }
66
67 BufferList _bufferList;
68 StringBuffer _result;
69 }
70
71 // Utility class which can deliver bytes one by one from a number of
72 // buffers added.
73 class BufferList {
74 BufferList() : _index = 0, _length = 0, _buffers = new Queue<List<int>>();
75
76 void add(List<int> buffer) {
77 _buffers.addLast(buffer);
78 _length += buffer.length;
79 }
80
81 int next() {
82 int value = _buffers.first()[_index++];
83 _length--;
84 if (_index == _buffers.first().length) {
85 _buffers.removeFirst();
86 _index = 0;
87 }
88 return value;
89 }
90
91 int get length() => _length;
92
93 int _length;
94 Queue<List<int>> _buffers;
95 int _index;
96 }
97
98
99 // Utility class for encoding a string into UTF-8 byte stream.
100 class UTF8Encoder {
101 static List<int> encodeString(String string) {
102 int size = _encodingSize(string);
103 List result = new List<int>(size);
104 _encodeString(string, result);
105 return result;
106 }
107
108 static int _encodingSize(String string) => _encodeString(string, null);
109
110 static int _encodeString(String string, List<int> buffer) {
111 int pos = 0;
112 int length = string.length;
113 for (int i = 0; i < length; i++) {
114 int additionalBytes;
115 int charCode = string.charCodeAt(i);
116 if (charCode <= 0x007F) {
117 additionalBytes = 0;
118 if (buffer != null) buffer[pos] = charCode;
119 } else if (charCode <= 0x07FF) {
120 // 110xxxxx (xxxxx is top 5 bits).
121 if (buffer != null) buffer[pos] = ((charCode >> 6) & 0x1F) | 0xC0;
122 additionalBytes = 1;
123 } else if (charCode <= 0xFFFF) {
124 // 1110xxxx (xxxx is top 4 bits)
125 if (buffer != null) buffer[pos] = ((charCode >> 12) & 0x0F)| 0xE0;
126 additionalBytes = 2;
127 } else {
128 // 11110xxx (xxx is top 3 bits)
129 if (buffer != null) buffer[pos] = ((charCode >> 18) & 0x07) | 0xF0;
130 additionalBytes = 3;
131 }
132 pos++;
133 if (buffer != null) {
134 for (int i = additionalBytes; i > 0; i--) {
135 // 10xxxxxx (xxxxxx is next 6 bits from the top).
136 buffer[pos++] = ((charCode >> (6 * (i - 1))) & 0x3F) | 0x80;
137 }
138 } else {
139 pos += additionalBytes;
140 }
141 }
142 return pos;
143 }
144 }
OLDNEW
« no previous file with comments | « frog/server/frog_server.dart ('k') | frog/tests/leg/src/ScannerTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698