Path: blob/trunk/third_party/closure/goog/i18n/charlistdecompressor.js
2868 views
// Copyright 2009 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview The decompressor for Base88 compressed character lists.16*17* The compression is by base 88 encoding the delta between two adjacent18* characters in ths list. The deltas can be positive or negative. Also, there19* would be character ranges. These three types of values20* are given enum values 0, 1 and 2 respectively. Initial 3 bits are used for21* encoding the type and total length of the encoded value. Length enums 0, 122* and 2 represents lengths 1, 2 and 4. So (value * 8 + type * 3 + length enum)23* is encoded in base 88 by following characters for numbers from 0 to 87:24* 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ (continued in next line)25* abcdefghijklmnopqrstuvwxyz!#$%()*+,-.:;<=>?@[]^_`{|}~26*27* Value uses 0 based counting. That is value for the range [a, b] is 0 and28* that of [a, c] is 1. Simillarly, the delta of "ab" is 0.29*30* Following python script can be used to compress character lists taken31* standard input: http://go/charlistcompressor.py32*33*/3435goog.provide('goog.i18n.CharListDecompressor');3637goog.require('goog.array');38goog.require('goog.i18n.uChar');39404142/**43* Class to decompress base88 compressed character list.44* @constructor45* @final46*/47goog.i18n.CharListDecompressor = function() {48this.buildCharMap_(49'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr' +50'stuvwxyz!#$%()*+,-.:;<=>?@[]^_`{|}~');51};525354/**55* 1-1 mapping from ascii characters used in encoding to an integer in the56* range 0 to 87.57* @type {Object}58* @private59*/60goog.i18n.CharListDecompressor.prototype.charMap_ = null;616263/**64* Builds the map from ascii characters used for the base88 scheme to number65* each character represents.66* @param {string} str The string of characters used in base88 scheme.67* @private68*/69goog.i18n.CharListDecompressor.prototype.buildCharMap_ = function(str) {70if (!this.charMap_) {71this.charMap_ = {};72for (var i = 0; i < str.length; i++) {73this.charMap_[str.charAt(i)] = i;74}75}76};777879/**80* Gets the number encoded in base88 scheme by a substring of given length81* and placed at the a given position of the string.82* @param {string} str String containing sequence of characters encoding a83* number in base 88 scheme.84* @param {number} start Starting position of substring encoding the number.85* @param {number} leng Length of the substring encoding the number.86* @return {number} The encoded number.87* @private88*/89goog.i18n.CharListDecompressor.prototype.getCodeAt_ = function(90str, start, leng) {91var result = 0;92for (var i = 0; i < leng; i++) {93var c = this.charMap_[str.charAt(start + i)];94result += c * Math.pow(88, i);95}96return result;97};9899100/**101* Add character(s) specified by the value and type to given list and return102* the next character in the sequence.103* @param {Array<string>} list The list of characters to which the specified104* characters are appended.105* @param {number} lastcode The last codepoint that was added to the list.106* @param {number} value The value component that representing the delta or107* range.108* @param {number} type The type component that representing whether the value109* is a positive or negative delta or range.110* @return {number} Last codepoint that is added to the list.111* @private112*/113goog.i18n.CharListDecompressor.prototype.addChars_ = function(114list, lastcode, value, type) {115if (type == 0) {116lastcode += value + 1;117goog.array.extend(list, goog.i18n.uChar.fromCharCode(lastcode));118} else if (type == 1) {119lastcode -= value + 1;120goog.array.extend(list, goog.i18n.uChar.fromCharCode(lastcode));121} else if (type == 2) {122for (var i = 0; i <= value; i++) {123lastcode++;124goog.array.extend(list, goog.i18n.uChar.fromCharCode(lastcode));125}126}127return lastcode;128};129130131/**132* Gets the list of characters specified in the given string by base 88 scheme.133* @param {string} str The string encoding character list.134* @return {!Array<string>} The list of characters specified by the given135* string in base 88 scheme.136*/137goog.i18n.CharListDecompressor.prototype.toCharList = function(str) {138var metasize = 8;139var result = [];140var lastcode = 0;141var i = 0;142while (i < str.length) {143var c = this.charMap_[str.charAt(i)];144var meta = c % metasize;145var type = Math.floor(meta / 3);146var leng = (meta % 3) + 1;147if (leng == 3) {148leng++;149}150var code = this.getCodeAt_(str, i, leng);151var value = Math.floor(code / metasize);152lastcode = this.addChars_(result, lastcode, value, type);153154i += leng;155}156return result;157};158159160