--- /dev/null
+<!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>