protobuf.js 与 Long.js的使用详解

php中世界最好的语言
php中世界最好的语言 原创
2018-03-16 10:58:41 4210浏览

这次给大家带来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('radix');        var p;        if ((p = str.indexOf('-')) > 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('radix');        if (this.isZero())            return '0';        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 '-' + 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 = '';        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核实处理。