more js: Slot.js plus dist version
[iotcloud.git] / src / js / iotjs / src / slot.js
1 "use strict";
2
3 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4
5 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7 var Slot = function () {
8         function Slot(table, seqnum, machineid, prevhmac, hmac) {
9                 _classCallCheck(this, Slot);
10
11                 this.SLOT_SIZE = 2048;
12                 this.RESERVED_SPACE = 64;
13                 this.HMAC_SIZE = 32;
14                 if (typeof seqnum === "number") {
15                         this.seqnum = seqnum;
16                 } else {
17                         throw new Error("seqnum should be a number");
18                 }
19                 if (typeof machineid === "number") {
20                         this.machineid = machineid;
21                 } else {
22                         throw new Error("machine should be a number");
23                 }
24                 this.livecount = 1;
25                 this.seqnumlive = true;
26                 if (prevhmac && prevhmac instanceof Uint8Array) {
27                         this.prevhmac = prevhmac;
28                 } else {
29                         throw new Error("prevhmac input not valid");
30                 }
31                 if (hmac && hmac instanceof Uint8Array) {
32                         this.hmac = hmac;
33                 } else {
34                         throw new Error("Hmac input not valid");
35                 }
36                 this.entries = [];
37                 this.freespace = this.SLOT_SIZE - getBaseSize(); //???????
38                 this.table = table;
39         }
40
41         _createClass(Slot, [{
42                 key: "getHMAC",
43                 value: function getHMAC() {
44                         return this.hmac;
45                 }
46         }, {
47                 key: "getPrevHmac",
48                 value: function getPrevHmac() {
49                         return this.prevhmac;
50                 }
51         }, {
52                 key: "addEntry",
53                 value: function addEntry(entry) {
54                         if (entry && entry instanceof Entry) {
55                                 var obj;
56                                 this.entries.push(_.extend(obj, entry));
57                                 this.livecount++;
58                                 this.freespace -= entry.getSize();
59                         }
60                 }
61         }, {
62                 key: "addShallowEntry",
63                 value: function addShallowEntry(entry) {
64                         if (entry && entry instanceof Entry) {
65                                 this.entries.push(entry);
66                                 this.livecount++;
67                                 this.freespace -= entry.getSize();
68                         }
69                 }
70         }, {
71                 key: "hasSpace",
72                 value: function hasSpace(entry) {
73                         var newfreespace = this.freespace - entry.getSize();
74                         return newfreespace > this.RESERVED_SPACE;
75                 }
76         }, {
77                 key: "getEntries",
78                 value: function getEntries() {
79                         return this.entries;
80                 }
81         }, {
82                 key: "encode",
83                 value: function encode(key) {
84                         var array = new Uint8Array(this.SLOT_SIZE);
85                         var bb = new ByteBuffer().wrap(array.join([separator = '']));
86                         //leave space for slot HMAC
87                         bb.skip(this.HMAC_SIZE);
88                         bb.writeIString(this.prevhmac.join([separator = '']));
89                         bb.writeInt64(this.seqnum);
90                         bb.writeInt64(this.machineid);
91                         bb.writeByte(this.entries.length);
92                         this.entries.forEach(function (entry) {
93                                 return entry.encode(bb);
94                         });
95
96                         var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator = '']), key);
97                         var realmac = new Uint8Array(mac.length);
98                         for (var i = 0; i < mac.length; i++) {
99                                 realmac[i] = mac.charCodeAt(i);
100                         }
101                         this.hmac = realmac;
102                         bb.reset();
103                         bb.wrap(realmac.join([separator = '']));
104                         return new Uint8Array(bb.toArrayBuffer());
105                 }
106                 /**
107    * Returns the empty size of a Slot. Includes 2 HMACs, the machine
108    * identifier, the sequence number, and the number of entries.
109    */
110
111         }, {
112                 key: "getBaseSize",
113                 value: function getBaseSize() {
114                         return 2 * this.HMAC_SIZE + 2 * 8 + 2 * 4; //Problematic area
115                 }
116         }, {
117                 key: "getLiveEntries",
118                 value: function getLiveEntries(resize) {
119                         var liveEntries = [];
120                         this.entries.forEach(function (entry) {
121                                 if (entry.isLive === true) {
122                                         if (!resize || entry.getType() !== entry.TypeTableStatus) {
123                                                 liveEntries.push(entry);
124                                         }
125                                 }
126                         });
127
128                         if (this.seqnumlive && !resize) {
129                                 liveEntries.push(new LastMessage(this, this.machineid, this.seqnumlive));
130                         }
131
132                         return liveEntries;
133                 }
134         }, {
135                 key: "getSequenceNumber",
136                 value: function getSequenceNumber() {
137                         return this.seqnum;
138                 }
139         }, {
140                 key: "getMachineID",
141                 value: function getMachineID() {
142                         return this.machineid;
143                 }
144         }, {
145                 key: "setDead",
146                 value: function setDead() {
147                         this.seqnumlive = false;
148                         this.decrementLiveCount();
149                 }
150         }, {
151                 key: "decrementLiveCount",
152                 value: function decrementLiveCount() {
153                         this.livecount--;
154                         if (this.livecount === 0) this.table.decrementLiveCount();
155                 }
156         }, {
157                 key: "isLive",
158                 value: function isLive() {
159                         return this.livecount > 0;
160                 }
161         }, {
162                 key: "toString",
163                 value: function toString() {
164                         return '<' + this.getSequenceNumber() + '>';
165                 }
166         }], [{
167                 key: "decode",
168                 value: function decode(table, array, key) {
169                         var cond1 = array && array instanceof Uint8Array;
170                         if (cond1) {
171                                 var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator = '']), key);
172
173                                 var realmac = new Uint8Array(mac.length);
174                                 for (var i = 0; i < mac.length; i++) {
175                                         realmac[i] = mac.charCodeAt(i);
176                                 }
177
178                                 var bb = new ByteBuffer().wrap(array.join([separator = ''])).flip();
179                                 var hmac = new Uint8Array(this.HMAC_SIZE);
180                                 var prevhmac = new Uint8Array(this.HMAC_SIZE);
181                                 for (var i = 0; i < this.HMAC_SIZE; i++) {
182                                         hmac[i] = bb.readByte();
183                                 }
184                                 for (var j = 0; j < this.HMAC_SIZE; j++) {
185                                         prevhmac[j] = bb.readByte();
186                                 }
187                                 //shallow compare
188                                 for (var k = 0; k < this.HMAC_SIZE; k++) {
189                                         if ((hmac[k] !== realmac[k])) {
190                                                 throw new Error("Server Error: Invalid HMAC!  Potential Attack!");
191                                         }
192                                 }
193                                 var _seqnum = bb.readLong();
194                                 var _machineid = bb.readLong();
195                                 var numentries = bb.readInt8();
196
197                                 var _slot = new Slot(table, _seqnum, _machineid, prevhmac, hmac);
198
199                                 for (var l = 0; l < numentries; l++) {
200                                         _slot.addShallowEntry(Entry.decode(_slot, bb));
201                                 }
202                                 return _slot;
203                         }
204                 }
205         }]);
206
207         return Slot;
208 }();