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>
|