Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / UuidGenerator.html
diff --git a/docs/source/UuidGenerator.html b/docs/source/UuidGenerator.html
new file mode 100644 (file)
index 0000000..65ed089
--- /dev/null
@@ -0,0 +1,235 @@
+<!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 (&quot;Sequential&quot;) UUID's
+ *
+ * If a server can provide a proper timestamp and a &quot;cryptographic quality random number&quot;
+ * (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 &gt; length) {
+            ret = ret.substring(ret.length - length); // right-most digits
+        } else if (ret.length &lt; 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, &quot;sequential&quot; 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 &amp; 0xFFFF, 4);
+            parts[2] = toHex(((ts.hi &gt;&gt;&gt; 16) &amp; 0xFFF) | (me.version &lt;&lt; 12), 4);
+            parts[3] = toHex(0x80 | ((me.clockSeq &gt;&gt;&gt; 8) &amp; 0x3F), 2) +
+                       toHex(me.clockSeq &amp; 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 &gt;= 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: &quot;the least significant bit of the first octet of the
+                // node ID&quot; (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>