Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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