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

Side by Side Diff: pkg/source_maps/lib/src/vlq.dart

Issue 12207008: Move source maps package to the dart repo, so it can be used by other internal (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: updates Created 7 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 | « pkg/source_maps/lib/src/utils.dart ('k') | pkg/source_maps/pubspec.yaml » ('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) 2013, 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 /// Utilities to encode and decode VLQ values used in source maps.
7 ///
8 /// Sourcemaps are encoded with variable length numbers as base64 encoded
9 /// strings with the least significant digit coming first. Each base64 digit
10 /// encodes a 5-bit value (0-31) and a continuation bit. Signed values can be
11 /// represented by using the least significant bit of the value as the sign bit.
12 ///
13 /// For more details see the source map [version 3 documentation][spec].
14 /// [spec]: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1K RlpiOFze0b-_2gc6fAH0KY0k/edit
15 library source_maps.src.vlq;
16
17 import 'dart:math';
18
19 const int VLQ_BASE_SHIFT = 5;
20
21 const int VLQ_BASE_MASK = (1 << 5) - 1;
22
23 const int VLQ_CONTINUATION_BIT = 1 << 5;
24
25 const int VLQ_CONTINUATION_MASK = 1 << 5;
26
27 const String BASE64_DIGITS =
28 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
29
30 final Map<String, int> _digits = () {
31 var map = <String, int>{};
32 for (int i = 0; i < 64; i++) {
33 map[BASE64_DIGITS[i]] = i;
34 }
35 return map;
36 }();
37
38 final int MAX_INT32 = pow(2, 31) - 1;
39 final int MIN_INT32 = -pow(2, 31);
40
41 /// Creates the VLQ encoding of [value] as a sequence of characters
42 Iterable<String> encodeVlq(int value) {
43 if (value < MIN_INT32 || value > MAX_INT32) {
44 throw new ArgumentError('expected 32 bit int, got: $value');
45 }
46 var res = <String>[];
47 int signBit = 0;
48 if (value < 0) {
49 signBit = 1;
50 value = -value;
51 }
52 value = (value << 1) | signBit;
53 do {
54 int digit = value & VLQ_BASE_MASK;
55 value >>= VLQ_BASE_SHIFT;
56 if (value > 0) {
57 digit |= VLQ_CONTINUATION_BIT;
58 }
59 res.add(BASE64_DIGITS[digit]);
60 } while (value > 0);
61 return res;
62 }
63
64 /// Decodes a value written as a sequence of VLQ characters. The first input
65 /// character will be `chars.current` after calling `chars.moveNext` once. The
66 /// iterator is advanced until a stop character is found (a character without
67 /// the [VLQ_CONTINUATION_BIT]).
68 int decodeVlq(Iterator<String> chars) {
69 int result = 0;
70 bool stop = false;
71 int shift = 0;
72 while (!stop) {
73 if (!chars.moveNext()) throw new StateError('incomplete VLQ value');
74 var char = chars.current;
75 if (!_digits.containsKey(char)) {
76 throw new FormatException('invalid character in VLQ encoding: $char');
77 }
78 var digit = _digits[char];
79 stop = (digit & VLQ_CONTINUATION_BIT) == 0;
80 digit &= VLQ_BASE_MASK;
81 result += (digit << shift);
82 shift += VLQ_BASE_SHIFT;
83 }
84
85 // Result uses the least significant bit as a sign bit. We convert it into a
86 // two-complement value. For example,
87 // 2 (10 binary) becomes 1
88 // 3 (11 binary) becomes -1
89 // 4 (100 binary) becomes 2
90 // 5 (101 binary) becomes -2
91 // 6 (110 binary) becomes 3
92 // 7 (111 binary) becomes -3
93 bool negate = (result & 1) == 1;
94 result = result >> 1;
95 result = negate ? -result : result;
96
97 // TODO(sigmund): can we detect this earlier?
98 if (result < MIN_INT32 || result > MAX_INT32) {
99 throw new FormatException(
100 'expected an encoded 32 bit int, but we got: $result');
101 }
102 return result;
103 }
OLDNEW
« no previous file with comments | « pkg/source_maps/lib/src/utils.dart ('k') | pkg/source_maps/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698