首頁  >  文章  >  web前端  >  protobuf.js 與 Long.js的使用詳解

protobuf.js 與 Long.js的使用詳解

php中世界最好的语言
php中世界最好的语言原創
2018-03-16 10:58:414852瀏覽

這次帶給大家protobuf.js 與Long.js的使用詳解,是急用protobuf.js 與Long.js的注意事項有哪些,下面就是實戰案例,一起來看一下。

protobuf.js的結構和webpack的載入之後的結構很相似。這樣的模組化組合是個不錯的結構方式。 1個是適應了不同的載入方式,2個模組直接很獨立。 webpack的功能更全一點。但如果自己封裝js函式庫這樣夠用了。而且模組對外統一介面 module.exports。這和node很像。

(function(global, undefined) {    "use strict";
    (function prelude(modules, cache, entries) {        function $require(name) {            var $module = cache[name];            //没有就去加载
            if (!$module)
                modules[name][0].call($module = cache[name] = { exports: {} }, $require, $module, $module.exports);            return $module.exports;
        }        //曝光成全局
        var proto = global.proto = $require(entries[0]);        // AMD
        if (typeof define === "function" && define.amd) {
            define(["long"], function(Long) {                if (Long && Long.isLong) {
                    proto.util.Long = Long;
                    proto.configure();
                }
            });            return proto;
        }        //CommonJS
        if (typeof module === "object" && module && module.exports)
            module.exports = proto;
    })    //传参    ({        1: [function (require, module, exports) {            function first() {
                console.log("first");
            }
            module.exports = first;
        }, {}],        2: [function(require, module, exports) {            function second() {
                console.log("second");
            }
            module.exports = second;
        }],        3: [function (require, module, exports) {            var proto = {};
            proto.first = require(1);
            proto.second = require(2);
            proto.build = "full";
            module.exports = proto;
        }]
      }, {}, [3]);
})(typeof window==="object"&&window||typeof self==="object"&&self||this)

在處理超過16位元的整形就得使用Long.js了。 主要是fromString和toString。

  function fromString(str, unsigned, radix) {        if (str.length === 0)            throw Error('empty string');        if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")            return ZERO;        if (typeof unsigned === 'number') {            // For goog.math.long compatibility
            radix = unsigned,
            unsigned = false;
        } else {
            unsigned = !!unsigned;
        }
        radix = radix || 10;        if (radix < 2 || 36 < radix)            throw RangeError(&#39;radix&#39;);        var p;        if ((p = str.indexOf(&#39;-&#39;)) > 0)            throw Error('interior hyphen');        else if (p === 0) {            return fromString(str.substring(1), unsigned, radix).neg();
        }        // Do several (8) digits each time through the loop, so as to
        // minimize the calls to the very expensive emulated p.
        var radixToPower = fromNumber(pow_dbl(radix, 8));        var result = ZERO;        for (var i = 0; i < str.length; i += 8) {            var size = Math.min(8, str.length - i),                value = parseInt(str.substring(i, i + size), radix);            if (size < 8) {                var power = fromNumber(pow_dbl(radix, size));
                result = result.mul(power).add(fromNumber(value));
            } else {                result = result.mul(radixToPower);
                result = result.add(fromNumber(value));
            }
        }
        result.unsigned = unsigned;        return result;
    }

fromstring的想法是把字串8位元一截取。再轉成Long型(高位,地位,符號位) 加起來。最後是一個Long型。 4294967296 是2的32次方。每次操作之前都會有一個基數的操作 mul(radixToPower)或mul(power)這兩者都是保證result的位數是正確的。

例如{low:123} 和{low:1} 相加之前,先讓{low:123}乘以10,得到{low:1230}再與{low:1}進行位元操作。因為第一個是高位,不能直接相加。

function fromBits(lowBits, highBits, unsigned) {        return new Long(lowBits, highBits, unsigned);
    }

fromBits 即轉為Long物件。 value%4294967296 得到低位。 /得到高位。結果通過位移合併起來。 mul是bit的乘法,add是bit的加法。 原理是說一個64位元的拆成四段。分別16位。 this.low左移16位 就得到 low的32-17位是啥。 然後和addend物件的同位相加

最後的合併是透過|運算。位移之後再還原確實很巧妙。一時看上去都不大理解。

 LongPrototype.add = function add(addend) {        if (!isLong(addend))
            addend = fromValue(addend);        // pide each number into 4 chunks of 16 bits, and then sum the chunks.
        var a48 = this.high >>> 16;        var a32 = this.high & 0xFFFF;        var a16 = this.low >>> 16;        var a00 = this.low & 0xFFFF;        var b48 = addend.high >>> 16;        var b32 = addend.high & 0xFFFF;        var b16 = addend.low >>> 16;        var b00 = addend.low & 0xFFFF;        var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
        c00 += a00 + b00;
        c16 += c00 >>> 16;
        c00 &= 0xFFFF;
        c16 += a16 + b16;
        c32 += c16 >>> 16;
        c16 &= 0xFFFF;
        c32 += a32 + b32;
        c48 += c32 >>> 16;
        c32 &= 0xFFFF;
        c48 += a48 + b48;
        c48 &= 0xFFFF;        return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
    };

>>>和>>有什麼差別? ? 。 

toString

LongPrototype.toString = function toString(radix) {
        radix = radix || 10;        if (radix < 2 || 36 < radix)            throw RangeError(&#39;radix&#39;);        if (this.isZero())            return &#39;0&#39;;        if (this.isNegative()) { // Unsigned Longs are never negative
            if (this.eq(MIN_VALUE)) {                // We need to change the Long value before it can be negated, so we remove
                // the bottom-most digit in this base and then recurse to do the rest.
                var radixLong = fromNumber(radix),
                    p = this.p(radixLong),
                    rem1 = p.mul(radixLong).sub(this);                return p.toString(radix) + rem1.toInt().toString(radix);
            } else
                return &#39;-&#39; + this.neg().toString(radix);
        }        // Do several (6) digits each time through the loop, so as to
        // minimize the calls to the very expensive emulated p.
        var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
            rem = this;        var result = &#39;&#39;;        while (true) {            var remp = rem.p(radixToPower),
                intval = rem.sub(remp.mul(radixToPower)).toInt() >>> 0,
                digits = intval.toString(radix);
            rem = remp;            if (rem.isZero())                return digits + result;            else {                while (digits.length < 6)
                    digits = '0' + digits;
                result = '' + digits + result;
            }
        }
    };

也是sub之後拼出來的。也就是fromstring的反向操作。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

有趣的UglifyJS

#讓JS自動比對proto Js的方法

#

以上是protobuf.js 與 Long.js的使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:有趣的UglifyJS下一篇:有趣的UglifyJS