Advertisement
rplantiko

A class for bitfields

Oct 9th, 2016
521
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // A bitfield represents a binary number of arbitrary length
  2. // This implementation requires the JavaScript Uint32Array data type
  3. function BitField(length,data) {
  4.   if (length instanceof BitField) {
  5.     this.length    = length.length
  6.     this.maxIndex  = length.maxIndex
  7.     this.maxMask   = length.maxMask
  8.     this.maxPlaces = length.maxPlaces
  9.     this.data      = Uint32Array.from(length.data)
  10.   }
  11.   else {
  12.     this.length = length
  13.     this.maxIndex  = ( ~~(length/32) + (length % 32 && 1) ) - 1
  14.     this.maxMask   = length % 32 ? (1 << length % 32) - 1 : 0xffffffff
  15.     this.maxPlaces = length % 32 || 32
  16.     if (data) {
  17.       if (data instanceof Uint32Array)
  18.         this.data = data
  19.       else if (data instanceof Array) {
  20.         this.data = Uint32Array.from(data)
  21.       }
  22.       else if (typeof data == "number") {
  23.         this.data = new Uint32Array( this.maxIndex + 1 )
  24.         this.data[0] = data        
  25.       }
  26.     }
  27.     else
  28.       this.data = new Uint32Array( this.maxIndex + 1 )
  29.   }
  30. }
  31. BitField.prototype.get = function(pos) {
  32.   return ( this.data[~~(pos/32)] & (1 << (pos % 32) ) ) && 1
  33. }
  34. BitField.prototype.set = function(pos) {
  35.   this.data[~~(pos/32)] |= ( 1 << (pos % 32))
  36. }
  37. BitField.prototype.unset = function(pos) {
  38.   this.data[~~(pos/32)] &= ~( 1 << (pos % 32))
  39. }
  40. BitField.prototype.clear = function() {
  41.   this.data.fill(0)
  42. }
  43. BitField.prototype.increment = function() {
  44.   for (var i=0;i<this.maxIndex;i++) {
  45.     if (this.data[i] != 0xffffffff) {
  46.       this.data[i]++
  47.       return true
  48.     }
  49.     else {
  50.       this.data[i] = 0      
  51.     }    
  52.   }
  53.   if (this.data[this.maxIndex] != this.maxMask) {
  54.     this.data[this.maxIndex]++
  55.     return true
  56.   }
  57.   else {
  58.     return false // Maximum reached
  59.   }
  60. }
  61. BitField.prototype.equals = function(bf) {
  62.   if (this.length != bf.length) return false
  63.   for (var i=0;i<this.maxIndex;i++) {
  64.     if (this.data[i] != bf.data[i]) return false;
  65.   }
  66.   return (((this.data[this.maxIndex]^bf.data[this.maxIndex])&this.maxMask)==0)
  67. }
  68.  
  69. BitField.prototype.toString = function() {
  70.   return pad((this.data[this.maxIndex]&this.maxMask).toString(2),this.maxPlaces) +
  71.         this.data.slice(0,this.data.length-1).reverse().map(function(i){
  72.          return pad(i.toString(2),32)
  73.         }).join("")
  74.   function pad(s,k) {
  75.     return ("00000000000000000000000000000000"+s).slice(-k)
  76.   }
  77. }
  78.  
  79. /* Some additions for retarded browsers
  80.    The implementations do not pretend to be fully-featured
  81.    They are just enough to make the class BitField usable in older browsers */
  82.  
  83. if (!Uint32Array.from) {
  84.   Uint32Array.from = function(array) {
  85.     var result = new Uint32Array(array.length)
  86.     for (var i=0;i<array.length;i++) result[i] = array[i]
  87.     return result
  88.   }
  89. }
  90. if (!Array.prototype.fill) {
  91.   Array.prototype.fill = function(value) {
  92.     for (var i=0;i<this.length;i++) this[i] = value
  93.     return this
  94.   }
  95. }
  96. if (!Uint32Array.prototype.slice) {
  97.   Uint32Array.prototype.slice = function(i1,i2) {
  98.     var result = new Uint32Array(i2-i1)
  99.     for (var i=i1;i<i2;i++) result[i-i1] = this[i]
  100.     return result
  101.   }
  102. }
  103. if (!Uint32Array.prototype.reverse) {
  104.   Uint32Array.prototype.reverse = function() {
  105.     var len = this.length
  106.     var result = new Uint32Array(len)
  107.     for (var i=0;i<len;i++) result[i]=this[len-i-1]
  108.     return result
  109.   }
  110. }
  111. if (!Uint32Array.prototype.map) {
  112.   Uint32Array.prototype.map = function(f) {
  113.     var len = this.length
  114.     var result = new Uint32Array(len)
  115.     for (var i=0;i<len;i++) result[i] = f(this[i])
  116.     return result
  117.   }
  118. }
  119. if (!Uint32Array.prototype.join) {
  120.   Uint32Array.prototype.join = function(s) {
  121.     var len    = this.length
  122.     var result = ""
  123.     for (var i=0;i<len;i++) {
  124.       if (i>0 && i<len-1) result += s
  125.       result += this[i]
  126.     }
  127.     return result
  128.   }
  129. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement