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

Side by Side Diff: mojo/dart/testing/validation_test_input_parser.dart

Issue 1132063007: Rationalize Dart mojo and sky package structure (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « mojo/dart/testing/pubspec.yaml ('k') | mojo/public/dart/BUILD.gn » ('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 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 library validation_input_parser;
6
7 import 'dart:typed_data';
8
9 class ValidationParseResult {
10 final Iterable<_Entry> _entries;
11 final int numHandles;
12 final ByteData data;
13
14 ValidationParseResult(this._entries, this.data, this.numHandles);
15
16 String toString() => _entries.map((e) => '$e').join('\n');
17 }
18
19 ValidationParseResult parse(String input) =>
20 new _ValidationTestParser(input).parse();
21
22 class ValidationParseError {
23 final String _message;
24 ValidationParseError(this._message);
25 String toString() => _message;
26 }
27
28 abstract class _Entry {
29 final int size;
30 void write(ByteData buffer, int offset, Map pointers);
31 }
32
33 class _UnsignedEntry implements _Entry {
34 final int size;
35 final int value;
36
37 _UnsignedEntry(this.size, this.value) {
38 if ((value >= (1 << (size * 8))) || (value < 0)) {
39 throw new ValidationParseError('$value does not fit in a u$size');
40 }
41 }
42
43 void write(ByteData buffer, int offset, Map pointers) {
44 switch (size) {
45 case 1: buffer.setUint8(offset, value); break;
46 case 2: buffer.setUint16(offset, value, Endianness.LITTLE_ENDIAN); break;
47 case 4: buffer.setUint32(offset, value, Endianness.LITTLE_ENDIAN); break;
48 case 8: buffer.setUint64(offset, value, Endianness.LITTLE_ENDIAN); break;
49 default: throw new ValidationParseError('Unexpected size: $size');
50 }
51 }
52
53 String toString() => "[u$size]$value";
54 bool operator==(_UnsignedEntry other) =>
55 (size == other.size) && (value == other.value);
56 }
57
58 class _SignedEntry implements _Entry {
59 final int size;
60 final int value;
61
62 _SignedEntry(this.size, this.value) {
63 if ((value >= (1 << ((size * 8) - 1))) ||
64 (value < -(1 << ((size * 8) - 1)))) {
65 throw new ValidationParseError('$value does not fit in a s$size');
66 }
67 }
68
69 void write(ByteData buffer, int offset, Map pointers) {
70 switch (size) {
71 case 1: buffer.setInt8(offset, value); break;
72 case 2: buffer.setInt16(offset, value, Endianness.LITTLE_ENDIAN); break;
73 case 4: buffer.setInt32(offset, value, Endianness.LITTLE_ENDIAN); break;
74 case 8: buffer.setInt64(offset, value, Endianness.LITTLE_ENDIAN); break;
75 default: throw new ValidationParseError('Unexpected size: $size');
76 }
77 }
78
79 String toString() => "[s$size]$value";
80 bool operator==(_SignedEntry other) =>
81 (size == other.size) && (value == other.value);
82 }
83
84 class _FloatEntry implements _Entry {
85 final int size;
86 final double value;
87
88 _FloatEntry(this.size, this.value);
89
90 void write(ByteData buffer, int offset, Map pointers) {
91 switch (size) {
92 case 4: buffer.setFloat32(offset, value, Endianness.LITTLE_ENDIAN); break;
93 case 8: buffer.setFloat64(offset, value, Endianness.LITTLE_ENDIAN); break;
94 default: throw new ValidationParseError('Unexpected size: $size');
95 }
96 }
97
98 String toString() => "[f$size]$value";
99 bool operator==(_FloatEntry other) =>
100 (size == other.size) && (value == other.value);
101 }
102
103 class _DistEntry implements _Entry {
104 final int size;
105 final String id;
106 int offset;
107 bool matched = false;
108
109 _DistEntry(this.size, this.id);
110
111 void write(ByteData buffer, int off, Map pointers) {
112 offset = off;
113 if (pointers[id] != null) {
114 throw new ValidationParseError(
115 'Pointer of same name already exists: $id');
116 }
117 pointers[id] = this;
118 }
119
120 String toString() => "[dist$size]$id matched = $matched";
121 bool operator==(_DistEntry other) =>
122 (size == other.size) && (id == other.id);
123 }
124
125 class _AnchrEntry implements _Entry {
126 final int size = 0;
127 final String id;
128
129 _AnchrEntry(this.id);
130
131 void write(ByteData buffer, int off, Map pointers) {
132 _DistEntry dist = pointers[id];
133 if (dist == null) {
134 throw new ValidationParseError('Did not find "$id" in pointers map.');
135 }
136 int value = off - dist.offset;
137 if (value < 0) {
138 throw new ValidationParseError('Found a backwards pointer: $id');
139 }
140 int offset = dist.offset;
141 switch (dist.size) {
142 case 4: buffer.setUint32(offset, value, Endianness.LITTLE_ENDIAN); break;
143 case 8: buffer.setUint64(offset, value, Endianness.LITTLE_ENDIAN); break;
144 default: throw new ValidationParseError('Unexpected size: $size');
145 }
146 dist.matched = true;
147 }
148
149 String toString() => "[anchr]$id";
150 bool operator==(_AnchrEntry other) => (id == other.id);
151 }
152
153 class _HandlesEntry implements _Entry {
154 final int size = 0;
155 final int value;
156
157 _HandlesEntry(this.value);
158
159 void write(ByteData buffer, int offset, Map pointers) {}
160
161 String toString() => "[handles]$value";
162 bool operator==(_HandlesEntry other) => (value == other.value);
163 }
164
165 class _CommentEntry implements _Entry {
166 final int size = 0;
167 final String value;
168
169 _CommentEntry(this.value);
170
171 void write(ByteData buffer, int offset, Map pointers) {}
172
173 String toString() => "// $value";
174 bool operator==(_CommentEntry other) => (value == other.value);
175 }
176
177 class _ValidationTestParser {
178 static final RegExp newline = new RegExp(r'[\r\n]+');
179 static final RegExp whitespace = new RegExp(r'[ \t\n\r]+');
180 static final RegExp nakedUintRegExp =
181 new RegExp(r'^0$|^[1-9][0-9]*$|^0[xX][0-9a-fA-F]+$');
182 static final RegExp unsignedRegExp =
183 new RegExp(r'^\[u([1248])\](0$|[1-9][0-9]*$|0[xX][0-9a-fA-F]+$)');
184 static final RegExp signedRegExp = new RegExp(
185 r'^\[s([1248])\]([-+]?0$|[-+]?[1-9][0-9]*$|[-+]?0[xX][0-9a-fA-F]+$)');
186 static final RegExp binaryRegExp =
187 new RegExp(r'^\[(b)\]([01]{8}$)');
188 static final RegExp floatRegExp =
189 new RegExp(r'^\[([fd])\]([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$)');
190 static final RegExp distRegExp =
191 new RegExp(r'^\[dist([48])\]([0-9a-zA-Z_]+$)');
192 static final RegExp anchrRegExp =
193 new RegExp(r'^\[(anchr)\]([0-9a-zA-Z_]+$)');
194 static final RegExp handlesRegExp =
195 new RegExp(r'^\[(handles)\](0$|([1-9][0-9]*$)|(0[xX][0-9a-fA-F]+$))');
196 static final RegExp commentRegExp =
197 new RegExp(r'//(.*)');
198
199 String _input;
200 Map<String, _DistEntry> _pointers;
201
202 _ValidationTestParser(this._input) : _pointers = {};
203
204 String _stripComment(String line) => line.replaceFirst(commentRegExp, "");
205
206 ValidationParseResult parse() {
207 var entries = _input.split(newline)
208 .map(_stripComment)
209 .expand((s) => s.split(whitespace))
210 .where((s) => s != "")
211 .map(_parseLine);
212 int size = _calculateSize(entries);
213 var data = (size > 0) ? new ByteData(size) : null;
214 int numHandles = 0;
215 int offset = 0;
216 bool first = true;
217
218 for (var entry in entries) {
219 entry.write(data, offset, _pointers);
220 offset += entry.size;
221
222 if (entry is _HandlesEntry) {
223 if (!first) {
224 throw new ValidationParseError('Handles entry was not first');
225 }
226 numHandles = entry.value;
227 }
228 first = false;
229 }
230
231 for (var entry in entries) {
232 if (entry is _DistEntry) {
233 if (!_pointers[entry.id].matched) {
234 throw new ValidationParseError('Unmatched dist: $entry');
235 }
236 }
237 }
238
239 return new ValidationParseResult(entries, data, numHandles);
240 }
241
242 _Entry _parseLine(String line) {
243 if (unsignedRegExp.hasMatch(line)) {
244 var match = unsignedRegExp.firstMatch(line);
245 return new _UnsignedEntry(
246 int.parse(match.group(1)), int.parse(match.group(2)));
247 } else if (signedRegExp.hasMatch(line)) {
248 var match = signedRegExp.firstMatch(line);
249 return new _SignedEntry(
250 int.parse(match.group(1)), int.parse(match.group(2)));
251 } else if (binaryRegExp.hasMatch(line)) {
252 var match = binaryRegExp.firstMatch(line);
253 return new _UnsignedEntry(1, int.parse(match.group(2), radix: 2));
254 } else if (floatRegExp.hasMatch(line)) {
255 var match = floatRegExp.firstMatch(line);
256 int size = match.group(1) == 'f' ? 4 : 8;
257 return new _FloatEntry(size, double.parse(match.group(2)));
258 } else if (distRegExp.hasMatch(line)) {
259 var match = distRegExp.firstMatch(line);
260 return new _DistEntry(int.parse(match.group(1)), match.group(2));
261 } else if (anchrRegExp.hasMatch(line)) {
262 var match = anchrRegExp.firstMatch(line);
263 return new _AnchrEntry(match.group(2));
264 } else if (handlesRegExp.hasMatch(line)) {
265 var match = handlesRegExp.firstMatch(line);
266 return new _HandlesEntry(int.parse(match.group(2)));
267 } else if (nakedUintRegExp.hasMatch(line)) {
268 var match = nakedUintRegExp.firstMatch(line);
269 return new _UnsignedEntry(1, int.parse(match.group(0)));
270 } else if (commentRegExp.hasMatch(line)) {
271 var match = commentRegExp.firstMatch(line);
272 return new _CommentEntry(match.group(1));
273 } else if (line == "") {
274 return new _CommentEntry("");
275 } else {
276 throw new ValidationParseError('Unkown entry: "$line" in \n$_input');
277 }
278 }
279
280 int _calculateSize(Iterable<_Entry> entries) =>
281 entries.fold(0, (value, entry) => value + entry.size);
282 }
283
284 bool _listEquals(Iterable i1, Iterable i2) {
285 var l1 = i1.toList();
286 var l2 = i2.toList();
287 if (l1.length != l2.length) return false;
288 for (int i = 0; i < l1.length; i++) {
289 if (l1[i] != l2[i]) return false;
290 }
291 return true;
292 }
293
294 parserTests() {
295 {
296 var input = " \t // hello world \n\r \t// the answer is 42 ";
297 var result = parse(input);
298 assert(result.data == null);
299 assert(result.numHandles == 0);
300 }
301 {
302 var input = "[u1]0x10// hello world !! \n\r \t [u2]65535 \n"
303 "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff";
304 var result = parse(input);
305
306 // Check the parse results.
307 var expected = [new _UnsignedEntry(1, 0x10),
308 new _UnsignedEntry(2, 65535),
309 new _UnsignedEntry(4, 65536),
310 new _UnsignedEntry(8, 0xFFFFFFFFFFFFFFFF),
311 new _UnsignedEntry(1, 0),
312 new _UnsignedEntry(1, 0xff)];
313 assert(_listEquals(result._entries, expected));
314
315 //Check the bits.
316 var buffer = new ByteData(17);
317 var offset = 0;
318 buffer.setUint8(offset, 0x10); offset++;
319 buffer.setUint16(offset, 65535, Endianness.LITTLE_ENDIAN); offset += 2;
320 buffer.setUint32(offset, 65536, Endianness.LITTLE_ENDIAN); offset += 4;
321 buffer.setUint64(offset, 0xFFFFFFFFFFFFFFFF, Endianness.LITTLE_ENDIAN); offs et += 8;
322 buffer.setUint8(offset, 0); offset++;
323 buffer.setUint8(offset, 0xff); offset++;
324 assert(_listEquals(buffer.buffer.asUint8List(),
325 result.data.buffer.asUint8List()));
326 }
327 {
328 var input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40";
329 var result = parse(input);
330
331 // Check the parse results.
332 var expected = [new _SignedEntry(8, -0x800),
333 new _SignedEntry(1, -128),
334 new _SignedEntry(2, 0),
335 new _SignedEntry(4, -40)];
336 assert(_listEquals(result._entries, expected));
337
338 // Check the bits.
339 var buffer = new ByteData(15);
340 var offset = 0;
341 buffer.setInt64(offset, -0x800, Endianness.LITTLE_ENDIAN); offset += 8;
342 buffer.setInt8(offset, -128); offset += 1;
343 buffer.setInt16(offset, 0, Endianness.LITTLE_ENDIAN); offset += 2;
344 buffer.setInt32(offset, -40, Endianness.LITTLE_ENDIAN); offset += 4;
345 assert(_listEquals(buffer.buffer.asUint8List(),
346 result.data.buffer.asUint8List()));
347 }
348 {
349 var input = "[b]00001011 [b]10000000 // hello world\r [b]00000000";
350 var result = parse(input);
351
352 // Check the parse results;
353 var expected = [new _UnsignedEntry(1, 11),
354 new _UnsignedEntry(1, 128),
355 new _UnsignedEntry(1, 0)];
356 assert(_listEquals(result._entries, expected));
357
358 // Check the bits.
359 var buffer = new ByteData(3);
360 var offset = 0;
361 buffer.setUint8(offset, 11); offset += 1;
362 buffer.setUint8(offset, 128); offset += 1;
363 buffer.setUint8(offset, 0); offset += 1;
364 assert(_listEquals(buffer.buffer.asUint8List(),
365 result.data.buffer.asUint8List()));
366 }
367 {
368 var input = "[f]+.3e9 [d]-10.03";
369 var result = parse(input);
370
371 // Check the parse results.
372 var expected = [new _FloatEntry(4, 0.3e9),
373 new _FloatEntry(8,-10.03)];
374 assert(_listEquals(result._entries, expected));
375
376 // Check the bits.
377 var buffer = new ByteData(12);
378 var offset = 0;
379 buffer.setFloat32(offset, 0.3e9, Endianness.LITTLE_ENDIAN); offset += 4;
380 buffer.setFloat64(offset, -10.03, Endianness.LITTLE_ENDIAN); offset += 8;
381 assert(_listEquals(buffer.buffer.asUint8List(),
382 result.data.buffer.asUint8List()));
383 }
384 {
385 var input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar";
386 var result = parse(input);
387
388 // Check the parse results.
389 var expected = [new _DistEntry(4, "foo"),
390 new _UnsignedEntry(1, 0),
391 new _DistEntry(8, "bar"),
392 new _UnsignedEntry(1, 0),
393 new _AnchrEntry("foo"),
394 new _AnchrEntry("bar")];
395 assert(_listEquals(result._entries, expected));
396
397 // Check the bits.
398 var buffer = new ByteData(14);
399 var offset = 0;
400 buffer.setUint32(offset, 14, Endianness.LITTLE_ENDIAN); offset += 4;
401 buffer.setUint8(offset, 0); offset += 1;
402 buffer.setUint64(offset, 9, Endianness.LITTLE_ENDIAN); offset += 8;
403 buffer.setUint8(offset, 0); offset += 1;
404 assert(_listEquals(buffer.buffer.asUint8List(),
405 result.data.buffer.asUint8List()));
406 }
407 {
408 var input = "// This message has handles! \n[handles]50 [u8]2";
409 var result = parse(input);
410 var expected = [new _HandlesEntry(50),
411 new _UnsignedEntry(8, 2)];
412 assert(_listEquals(result._entries, expected));
413 }
414 {
415 var errorInputs = ["/ hello world",
416 "[u1]x",
417 "[u2]-1000",
418 "[u1]0x100",
419 "[s2]-0x8001",
420 "[b]1",
421 "[b]1111111k",
422 "[dist4]unmatched",
423 "[anchr]hello [dist8]hello",
424 "[dist4]a [dist4]a [anchr]a",
425 "[dist4]a [anchr]a [dist4]a [anchr]a",
426 "0 [handles]50"];
427 for (var input in errorInputs) {
428 try {
429 var result = parse(input);
430 assert(false);
431 } on ValidationParseError catch(e) {
432 // Pass.
433 }
434 }
435 }
436 }
437
OLDNEW
« no previous file with comments | « mojo/dart/testing/pubspec.yaml ('k') | mojo/public/dart/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698