Cleaned up git
[iotcloud.git] / version1 / src / js / iotjs / orig / slot.js
diff --git a/version1/src/js/iotjs/orig/slot.js b/version1/src/js/iotjs/orig/slot.js
new file mode 100644 (file)
index 0000000..6af5a18
--- /dev/null
@@ -0,0 +1,171 @@
+class Slot {
+    constructor(table, seqnum, machineid, prevhmac, hmac) {
+        this.SLOT_SIZE = 2048;
+        this.RESERVED_SPACE = 64;
+        this.HMAC_SIZE = 32;
+        if(typeof seqnum === "number"){
+               this.seqnum = seqnum;
+        }else{
+               throw new Error("seqnum should be a number");
+        }
+        if(typeof machineid === "number"){
+               this.machineid = machineid;
+        }else{
+               throw new Error("machine should be a number");
+        }
+        this.livecount = 1;
+        this.seqnumlive = true;
+        if(prevhmac && prevhmac instanceof Uint8Array){
+               this.prevhmac = prevhmac;
+        }else{
+               throw new Error("prevhmac input not valid");
+        }
+           if(hmac && hmac instanceof Uint8Array){
+               this.hmac = hmac
+           }else{
+               throw new Error("Hmac input not valid");
+           }
+       this.entries = [];
+       this.freespace = this.SLOT_SIZE - getBaseSize();   //???????
+       this.table = table;
+       }
+       getHMAC() {
+       return this.hmac;
+       }
+       getPrevHmac() {
+       return this.prevhmac;
+       }
+       addEntry(entry) {
+           if (entry && entry instanceof Entry) {
+               var obj;
+               this.entries.push(_.extend(obj, entry));
+               this.livecount++;
+               this.freespace -= entry.getSize();
+           }
+       }
+       addShallowEntry(entry){
+               if(entry && entry instanceof Entry){
+                       this.entries.push(entry);
+                       this.livecount++;
+               this.freespace -= entry.getSize();
+               }
+       }
+       hasSpace(entry){
+               var newfreespace = this.freespace - entry.getSize();
+               return newfreespace > this.RESERVED_SPACE;
+       }
+       getEntries(){
+               return this.entries;
+       }
+       static decode(table, array, key){
+               var cond1 = (array && array instanceof Uint8Array);
+               if(cond1){
+                       var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator='']),key);
+                       
+                       var realmac = new Uint8Array(mac.length);
+                       for(var i=0; i< mac.length ; i++){
+                               realmac[i] = mac.charCodeAt(i);
+                       }
+                       
+                       var bb = new ByteBuffer().wrap(array.join([separator=''])).flip();
+                       var hmac= new Uint8Array(this.HMAC_SIZE);
+                       var prevhmac = new Uint8Array(this.HMAC_SIZE);
+                       for(var i = 0; i<this.HMAC_SIZE; i++){
+                               hmac[i] = bb.readByte();
+                       }
+                       for(var j = 0; j<this.HMAC_SIZE; j++){
+                               prevhmac[j] = bb.readByte();
+                       }
+                       //shallow compare
+                       for(var k =0; k<this.HMAC_SIZE; k++){
+                               if(!(hmac[k] === realmac[k])){
+                                       throw new Error("Server Error: Invalid HMAC!  Potential Attack!");
+                               }
+                       }
+                       var _seqnum = bb.readLong();
+                       var _machineid = bb.readLong();
+                       var numentries = bb.readInt8();
+
+                       var _slot = new Slot(table,_seqnum,_machineid,prevhmac,hmac);
+
+                       for(var l= 0 ;l<numentries;l++){
+                               _slot.addShallowEntry(Entry.decode(_slot,bb));
+                       }
+                       return _slot;
+               }
+       }
+       encode(key){
+               var array = new Uint8Array(this.SLOT_SIZE);
+               var bb = new ByteBuffer().wrap(array.join([separator='']))
+               //leave space for slot HMAC
+               bb.skip(this.HMAC_SIZE);
+               bb.writeIString(this.prevhmac.join([separator='']));
+               bb.writeInt64(this.seqnum);
+               bb.writeInt64(this.machineid);
+               bb.writeByte(this.entries.length);
+               this.entries.forEach((entry) => entry.encode(bb));
+
+               var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator='']),key);
+               var realmac = new Uint8Array(mac.length);
+               for(var i=0; i< mac.length ; i++){
+                       realmac[i] = mac.charCodeAt(i);
+               }
+               this.hmac = realmac;
+               bb.reset();
+               bb.wrap(realmac.join([separator='']));
+               return new Uint8Array(bb.toArrayBuffer());
+       }
+       /**
+        * Returns the empty size of a Slot. Includes 2 HMACs, the machine
+        * identifier, the sequence number, and the number of entries.
+        */
+       getBaseSize(){
+               return 2*this.HMAC_SIZE+2*8+2*4; //Problematic area
+       }
+
+       getLiveEntries(resize){
+               var liveEntries = [];
+               this.entries.forEach(function(entry){
+                       if(entry.isLive === true){
+                               if(!resize || entry.getType() !== entry.TypeTableStatus){
+                                       liveEntries.push(entry);
+                               }
+                       };
+               });
+
+               if(this.seqnumlive && !resize){
+                       liveEntries.push(new LastMessage(this,this.machineid,this.seqnumlive))
+               }
+
+               return liveEntries;
+       }
+
+       getSequenceNumber() {
+               return this.seqnum;
+       }
+
+       getMachineID() {
+               return this.machineid;
+       }
+       
+       setDead() {
+               this.seqnumlive=false;
+               this.decrementLiveCount();
+       }
+
+       decrementLiveCount() {
+               this.livecount--;
+               if (this.livecount === 0)
+                       this.table.decrementLiveCount();
+       }
+
+       isLive() {
+               return this.livecount > 0;
+       }
+
+       toString() {
+               return '<'+this.getSequenceNumber()+'>';
+       }
+
+}
+       
\ No newline at end of file