Merge branch '3.1' into 5.2
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / api / leafo / scssphp / src / SourceMap / Base64VLQ.php
1 <?php
2 /**
3 * SCSSPHP
4 *
5 * @copyright 2012-2015 Leaf Corcoran
6 *
7 * @license http://opensource.org/licenses/MIT MIT
8 *
9 * @link http://leafo.github.io/scssphp
10 */
11
12 namespace Leafo\ScssPhp\SourceMap;
13
14 use Leafo\ScssPhp\SourceMap\Base64;
15
16 /**
17 * Base 64 VLQ
18 *
19 * Based on the Base 64 VLQ implementation in Closure Compiler:
20 * https://github.com/google/closure-compiler/blob/master/src/com/google/debugging/sourcemap/Base64VLQ.java
21 *
22 * Copyright 2011 The Closure Compiler Authors.
23 *
24 * Licensed under the Apache License, Version 2.0 (the "License");
25 * you may not use this file except in compliance with the License.
26 * You may obtain a copy of the License at
27 *
28 * http://www.apache.org/licenses/LICENSE-2.0
29 *
30 * Unless required by applicable law or agreed to in writing, software
31 * distributed under the License is distributed on an "AS IS" BASIS,
32 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 * See the License for the specific language governing permissions and
34 * limitations under the License.
35 *
36 * @author John Lenz <johnlenz@google.com>
37 * @author Anthon Pang <anthon.pang@gmail.com>
38 */
39 class Base64VLQ
40 {
41 // A Base64 VLQ digit can represent 5 bits, so it is base-32.
42 const VLQ_BASE_SHIFT = 5;
43
44 // A mask of bits for a VLQ digit (11111), 31 decimal.
45 const VLQ_BASE_MASK = 31;
46
47 // The continuation bit is the 6th bit.
48 const VLQ_CONTINUATION_BIT = 32;
49
50 /**
51 * Returns the VLQ encoded value.
52 *
53 * @param integer $value
54 *
55 * @return string
56 */
57 public static function encode($value)
58 {
59 $encoded = '';
60 $vlq = self::toVLQSigned($value);
61
62 do {
63 $digit = $vlq & self::VLQ_BASE_MASK;
64 $vlq >>= self::VLQ_BASE_SHIFT;
65
66 if ($vlq > 0) {
67 $digit |= self::VLQ_CONTINUATION_BIT;
68 }
69
70 $encoded .= Base64::encode($digit);
71 } while ($vlq > 0);
72
73 return $encoded;
74 }
75
76 /**
77 * Decodes VLQValue.
78 *
79 * @param string $str
80 * @param integer $index
81 *
82 * @return integer
83 */
84 public static function decode($str, &$index)
85 {
86 $result = 0;
87 $shift = 0;
88
89 do {
90 $c = $str[$index++];
91 $digit = Base64::decode($c);
92 $continuation = ($digit & self::VLQ_CONTINUATION_BIT) != 0;
93 $digit &= self::VLQ_BASE_MASK;
94 $result = $result + ($digit << $shift);
95 $shift = $shift + self::VLQ_BASE_SHIFT;
96 } while ($continuation);
97
98 return self::fromVLQSigned($result);
99 }
100
101 /**
102 * Converts from a two-complement value to a value where the sign bit is
103 * is placed in the least significant bit. For example, as decimals:
104 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
105 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
106 *
107 * @param integer $value
108 *
109 * @return integer
110 */
111 private static function toVLQSigned($value)
112 {
113 if ($value < 0) {
114 return ((-$value) << 1) + 1;
115 }
116
117 return ($value << 1) + 0;
118 }
119
120 /**
121 * Converts to a two-complement value from a value where the sign bit is
122 * is placed in the least significant bit. For example, as decimals:
123 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
124 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
125 *
126 * @param integer $value
127 *
128 * @return integer
129 */
130 private static function fromVLQSigned($value)
131 {
132 $negate = ($value & 1) === 1;
133 $value = $value >> 1;
134
135 return $negate ? -$value : $value;
136 }
137 }