public function testBase64Vlq() { for ($i = -255; $i < 256; $i++) { $v = Kwf_SourceMaps_Base64VLQ::encode($i); $result = Kwf_SourceMaps_Base64VLQ::decode($v); $this->assertEquals($result, $i); $this->assertEquals($v, ""); } }
/** * Concat sourcemaps and keep mappings intact * * This is implemented very efficent by avoiding to parse the whole mappings string. */ public function concat(Kwf_SourceMaps_SourceMap $other) { if ($this->_mappingsChanged) { $this->_generateMappings(); } $missingLines = substr_count($this->_fileContents, "\n") - substr_count($this->_map->mappings, ";"); if ($missingLines > 0) { $this->_map->mappings .= str_repeat(';', $missingLines); } if (!isset($this->_map->{'_x_org_koala-framework_last'})) { $this->_addLastExtension(); } if (strlen($this->_fileContents) > 0) { if (substr($this->_fileContents, -1) != "\n") { $this->_fileContents .= "\n"; $this->_map->mappings .= ';'; } } $this->_fileContents .= $other->_fileContents; $data = $other->getMapContentsData(); if ($this->_map->mappings) { $previousFileLast = $this->_map->{'_x_org_koala-framework_last'}; } else { $previousFileLast = (object) array('source' => 0, 'originalLine' => 0, 'originalColumn' => 0, 'name' => 0); } if (!$data->mappings) { $data->mappings = str_repeat(';', substr_count($other->_fileContents, "\n")); $data->{'_x_org_koala-framework_last'} = (object) array('source' => -1, 'originalLine' => $previousFileLast->originalLine, 'originalColumn' => $previousFileLast->originalColumn, 'name' => -1); } $previousFileSourcesCount = count($this->_map->sources); $previousFileNamesCount = count($this->_map->names); if ($previousFileLast->source > $previousFileSourcesCount) { if ($previousFileSourcesCount != 0 && $previousFileLast->source != 0) { throw new Exception("Invalid last source, must not be higher than sources"); } } if ($previousFileLast->name > $previousFileNamesCount) { if ($previousFileNamesCount != 0 && $previousFileLast->name != 0) { throw new Exception("Invalid last name, must not be higher than names"); } } if ($data->sources) { foreach ($data->sources as $s) { $this->_map->sources[] = $s; } } if ($data->names) { foreach ($data->names as $n) { $this->_map->names[] = $n; } } $otherMappings = $data->mappings; $str = ''; $otherMappingsEnd = strlen($otherMappings); $otherMappingsPos = 0; while ($otherMappingsPos < $otherMappingsEnd && $otherMappings[$otherMappingsPos] === ';') { $str .= $otherMappings[$otherMappingsPos]; $otherMappingsPos++; } if ($otherMappingsPos < $otherMappingsEnd) { // Generated column. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos)); if ($otherMappingsPos < $otherMappingsEnd && !($otherMappings[$otherMappingsPos] == ',' || $otherMappings[$otherMappingsPos] == ';')) { // Original source. $value = Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos); if ($previousFileSourcesCount) { $absoluteValue = $value + $previousFileSourcesCount; $value = $absoluteValue - $previousFileLast->source; } $str .= Kwf_SourceMaps_Base64VLQ::encode($value); // Original line. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos) - $previousFileLast->originalLine); // Original column. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos) - $previousFileLast->originalColumn); // Original name. if ($otherMappingsPos < $otherMappingsEnd && !($otherMappings[$otherMappingsPos] == ',' || $otherMappings[$otherMappingsPos] == ';')) { $value = Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos); if ($previousFileNamesCount) { $absoluteValue = $value + $previousFileNamesCount; $value = $absoluteValue - $previousFileLast->name; } $str .= Kwf_SourceMaps_Base64VLQ::encode($value); } else { if (!count($data->names)) { //file doesn't have names at all, we don't have to adjust that offset } else { //loop thru mappings until we find a block with name while ($otherMappingsPos < $otherMappingsEnd) { if ($otherMappings[$otherMappingsPos] === ';') { $str .= $otherMappings[$otherMappingsPos]; $otherMappingsPos++; } else { if ($otherMappings[$otherMappingsPos] === ',') { $str .= $otherMappings[$otherMappingsPos]; $otherMappingsPos++; } else { // Generated column. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos)); if ($otherMappingsPos < $otherMappingsEnd && !($otherMappings[$otherMappingsPos] == ',' || $otherMappings[$otherMappingsPos] == ';')) { // Original source. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos)); // Original line. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos)); // Original column. $str .= Kwf_SourceMaps_Base64VLQ::encode(Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos)); if ($otherMappingsPos < $otherMappingsEnd && !($otherMappings[$otherMappingsPos] == ',' || $otherMappings[$otherMappingsPos] == ';')) { // Original name. $value = Kwf_SourceMaps_Base64VLQ::decodePos($otherMappings, $otherMappingsPos); if ($previousFileNamesCount) { $absoluteValue = $value + $previousFileNamesCount; $value = $absoluteValue - $previousFileLast->name; } $str .= Kwf_SourceMaps_Base64VLQ::encode($value); break; } } } } } } } } } $this->_map->mappings .= $str . substr($otherMappings, $otherMappingsPos); $this->_map->{'_x_org_koala-framework_last'} = (object) array('source' => $previousFileSourcesCount + $data->{'_x_org_koala-framework_last'}->source, 'name' => $previousFileNamesCount + $data->{'_x_org_koala-framework_last'}->name, 'originalLine' => $data->{'_x_org_koala-framework_last'}->originalLine, 'originalColumn' => $data->{'_x_org_koala-framework_last'}->originalColumn); }
* @param integer $number * @return string */ public static function base64Encode($number) { if ($number < 0 || $number > 63) { throw new Exception("Must be between 0 and 63: " . $number); } return self::$INT_TO_CHAR[$number]; } /** * Decode single 6-bit digit from base64 * * @param string $char * @return number */ public static function base64Decode($char) { if (!array_key_exists($char, self::$CHAR_TO_INT)) { throw new Exception("Not a valid base 64 digit: " . $char); } return self::$CHAR_TO_INT[$char]; } } // Initialize char conversion table. Kwf_SourceMaps_Base64VLQ::$CHAR_TO_INT = array(); Kwf_SourceMaps_Base64VLQ::$INT_TO_CHAR = array(); foreach (str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/') as $i => $char) { Kwf_SourceMaps_Base64VLQ::$CHAR_TO_INT[$char] = $i; Kwf_SourceMaps_Base64VLQ::$INT_TO_CHAR[$i] = $char; }