| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-data-UuidGenerator'>/**</span> * @extend Ext.data.IdGenerator * @author Don Griffin * * This class generates UUID's according to RFC 4122. This class has a default id property. * This means that a single instance is shared unless the id property is overridden. Thus, * two {@link Ext.data.Model} instances configured like the following share one generator: * *     Ext.define('MyApp.data.MyModelX', { *         extend: 'Ext.data.Model', *         idgen: 'uuid' *     }); * *     Ext.define('MyApp.data.MyModelY', { *         extend: 'Ext.data.Model', *         idgen: 'uuid' *     }); * * This allows all models using this class to share a commonly configured instance. * * # Using Version 1 ("Sequential") UUID's * * If a server can provide a proper timestamp and a "cryptographic quality random number" * (as described in RFC 4122), the shared instance can be configured as follows: * *     Ext.data.IdGenerator.get('uuid').reconfigure({ *         version: 1, *         clockSeq: clock, // 14 random bits *         salt: salt,      // 48 secure random bits (the Node field) *         timestamp: ts    // timestamp per Section 4.1.4 *     }); * *     // or these values can be split into 32-bit chunks: * *     Ext.data.IdGenerator.get('uuid').reconfigure({ *         version: 1, *         clockSeq: clock, *         salt: { lo: saltLow32, hi: saltHigh32 }, *         timestamp: { lo: timestampLow32, hi: timestamptHigh32 } *     }); * * This approach improves the generator's uniqueness by providing a valid timestamp and * higher quality random data. Version 1 UUID's should not be used unless this information * can be provided by a server and care should be taken to avoid caching of this data. * * See http://www.ietf.org/rfc/rfc4122.txt for details. */Ext.define('Ext.data.UuidGenerator', (function () {    var twoPow14 = Math.pow(2, 14),        twoPow16 = Math.pow(2, 16),        twoPow28 = Math.pow(2, 28),        twoPow32 = Math.pow(2, 32);    function toHex (value, length) {        var ret = value.toString(16);        if (ret.length > length) {            ret = ret.substring(ret.length - length); // right-most digits        } else if (ret.length < length) {            ret = Ext.String.leftPad(ret, length, '0');        }        return ret;    }    function rand (lo, hi) {        var v = Math.random() * (hi - lo + 1);        return Math.floor(v) + lo;    }    function split (bignum) {        if (typeof(bignum) == 'number') {            var hi = Math.floor(bignum / twoPow32);            return {                lo: Math.floor(bignum - hi * twoPow32),                hi: hi            };        }        return bignum;    }    return {        extend: 'Ext.data.IdGenerator',        alias: 'idgen.uuid',        id: 'uuid', // shared by default<span id='Ext-data-UuidGenerator-property-salt'>        /**</span>         * @property {Number/Object} salt         * When created, this value is a 48-bit number. For computation, this value is split         * into 32-bit parts and stored in an object with `hi` and `lo` properties.         */<span id='Ext-data-UuidGenerator-property-timestamp'>        /**</span>         * @property {Number/Object} timestamp         * When created, this value is a 60-bit number. For computation, this value is split         * into 32-bit parts and stored in an object with `hi` and `lo` properties.         */<span id='Ext-data-UuidGenerator-cfg-version'>        /**</span>         * @cfg {Number} version         * The Version of UUID. Supported values are:         *         *  * 1 : Time-based, "sequential" UUID.         *  * 4 : Pseudo-random UUID.         *         * The default is 4.         */        version: 4,        constructor: function() {            var me = this;            me.callParent(arguments);            me.parts = [];            me.init();        },        generate: function () {            var me = this,                parts = me.parts,                ts = me.timestamp;            /*               The magic decoder ring (derived from RFC 4122 Section 4.2.2):               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |                          time_low                             |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |           time_mid            |  ver  |        time_hi        |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |res|  clock_hi |   clock_low   |    salt 0   |M|     salt 1    |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |                         salt (2-5)                            |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                         time_mid      clock_hi (low 6 bits)                time_low     | time_hi |clock_lo                    |        |     |   || salt[0]                    |        |     |   ||   | salt[1..5]                    v        v     v   vv   v v                    0badf00d-aced-1def-b123-dfad0badbeef                                  ^    ^     ^                            version    |     multicast (low bit)                                       |                                    reserved (upper 2 bits)            */            parts[0] = toHex(ts.lo, 8);            parts[1] = toHex(ts.hi & 0xFFFF, 4);            parts[2] = toHex(((ts.hi >>> 16) & 0xFFF) | (me.version << 12), 4);            parts[3] = toHex(0x80 | ((me.clockSeq >>> 8) & 0x3F), 2) +                       toHex(me.clockSeq & 0xFF, 2);            parts[4] = toHex(me.salt.hi, 4) + toHex(me.salt.lo, 8);            if (me.version == 4) {                me.init(); // just regenerate all the random values...            } else {                // sequentially increment the timestamp...                ++ts.lo;                if (ts.lo >= twoPow32) { // if (overflow)                    ts.lo = 0;                    ++ts.hi;                }            }            return parts.join('-').toLowerCase();        },        getRecId: function (rec) {            return rec.getId();        },<span id='Ext-data-UuidGenerator-method-init'>        /**</span>         * @private         */        init: function () {            var me = this,                salt, time;            if (me.version == 4) {                // See RFC 4122 (Secion 4.4)                //   o  If the state was unavailable (e.g., non-existent or corrupted),                //      or the saved node ID is different than the current node ID,                //      generate a random clock sequence value.                me.clockSeq = rand(0, twoPow14-1);                // we run this on every id generation...                salt = me.salt || (me.salt = {});                time = me.timestamp || (me.timestamp = {});                // See RFC 4122 (Secion 4.4)                salt.lo = rand(0, twoPow32-1);                salt.hi = rand(0, twoPow16-1);                time.lo = rand(0, twoPow32-1);                time.hi = rand(0, twoPow28-1);            } else {                // this is run only once per-instance                me.salt = split(me.salt);                me.timestamp = split(me.timestamp);                // Set multicast bit: "the least significant bit of the first octet of the                // node ID" (nodeId = salt for this implementation):                me.salt.hi |= 0x100;            }        },<span id='Ext-data-UuidGenerator-method-reconfigure'>        /**</span>         * Reconfigures this generator given new config properties.         */        reconfigure: function (config) {            Ext.apply(this, config);            this.init();        }    };}()));</pre></body></html>
 |