This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
9.3 KiB
288 lines
9.3 KiB
'use strict'; |
|
var $ = require('./$') |
|
, global = require('./$.global') |
|
, $typed = require('./$.typed') |
|
, redefineAll = require('./$.redefine-all') |
|
, strictNew = require('./$.strict-new') |
|
, toInteger = require('./$.to-integer') |
|
, toLength = require('./$.to-length') |
|
, arrayFill = require('./$.array-fill') |
|
, $ArrayBuffer = global.ArrayBuffer |
|
, $DataView = global.DataView |
|
, Math = global.Math |
|
, parseInt = global.parseInt |
|
, abs = Math.abs |
|
, pow = Math.pow |
|
, min = Math.min |
|
, floor = Math.floor |
|
, log = Math.log |
|
, LN2 = Math.LN2 |
|
, BYTE_LENGTH = 'byteLength'; |
|
|
|
// pack / unpack based on |
|
// https://github.com/inexorabletash/polyfill/blob/v0.1.11/typedarray.js#L123-L264 |
|
// TODO: simplify |
|
var signed = function(value, bits){ |
|
var s = 32 - bits; |
|
return value << s >> s; |
|
}; |
|
var unsigned = function(value, bits){ |
|
var s = 32 - bits; |
|
return value << s >>> s; |
|
}; |
|
var roundToEven = function(n){ |
|
var w = floor(n) |
|
, f = n - w; |
|
return f < .5 ? w : f > .5 ? w + 1 : w % 2 ? w + 1 : w; |
|
}; |
|
var packI8 = function(n){ |
|
return [n & 0xff]; |
|
}; |
|
var unpackI8 = function(bytes){ |
|
return signed(bytes[0], 8); |
|
}; |
|
var packU8 = function(n){ |
|
return [n & 0xff]; |
|
}; |
|
var unpackU8 = function(bytes){ |
|
return unsigned(bytes[0], 8); |
|
}; |
|
var packI16 = function(n){ |
|
return [n & 0xff, n >> 8 & 0xff]; |
|
}; |
|
var unpackI16 = function(bytes){ |
|
return signed(bytes[1] << 8 | bytes[0], 16); |
|
}; |
|
var packU16 = function(n){ |
|
return [n & 0xff, n >> 8 & 0xff]; |
|
}; |
|
var unpackU16 = function(bytes){ |
|
return unsigned(bytes[1] << 8 | bytes[0], 16); |
|
}; |
|
var packI32 = function(n){ |
|
return [n & 0xff, n >> 8 & 0xff, n >> 16 & 0xff, n >> 24 & 0xff]; |
|
}; |
|
var unpackI32 = function(bytes){ |
|
return signed(bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0], 32); |
|
}; |
|
var packU32 = function(n){ |
|
return [n & 0xff, n >> 8 & 0xff, n >> 16 & 0xff, n >> 24 & 0xff]; |
|
}; |
|
var unpackU32 = function(bytes){ |
|
return unsigned(bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0], 32); |
|
}; |
|
var packIEEE754 = function(v, ebits, fbits) { |
|
var bias = (1 << ebits - 1) - 1 |
|
, s, e, f, i, bits, str, bytes; |
|
// Compute sign, exponent, fraction |
|
if (v !== v) { |
|
// NaN |
|
// http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping |
|
e = (1 << ebits) - 1; |
|
f = pow(2, fbits - 1); |
|
s = 0; |
|
} else if(v === Infinity || v === -Infinity){ |
|
e = (1 << ebits) - 1; |
|
f = 0; |
|
s = v < 0 ? 1 : 0; |
|
} else if(v === 0){ |
|
e = 0; |
|
f = 0; |
|
s = 1 / v === -Infinity ? 1 : 0; |
|
} else { |
|
s = v < 0; |
|
v = abs(v); |
|
if(v >= pow(2, 1 - bias)){ |
|
e = min(floor(log(v) / LN2), 1023); |
|
var significand = v / pow(2, e); |
|
if(significand < 1){ |
|
e -= 1; |
|
significand *= 2; |
|
} |
|
if(significand >= 2){ |
|
e += 1; |
|
significand /= 2; |
|
} |
|
f = roundToEven(significand * pow(2, fbits)); |
|
if(f / pow(2, fbits) >= 2){ |
|
e = e + 1; |
|
f = 1; |
|
} |
|
if(e > bias){ |
|
// Overflow |
|
e = (1 << ebits) - 1; |
|
f = 0; |
|
} else { |
|
// Normalized |
|
e = e + bias; |
|
f = f - pow(2, fbits); |
|
} |
|
} else { |
|
// Denormalized |
|
e = 0; |
|
f = roundToEven(v / pow(2, 1 - bias - fbits)); |
|
} |
|
} |
|
// Pack sign, exponent, fraction |
|
bits = []; |
|
for(i = fbits; i; i -= 1){ |
|
bits.push(f % 2 ? 1 : 0); |
|
f = floor(f / 2); |
|
} |
|
for(i = ebits; i; i -= 1){ |
|
bits.push(e % 2 ? 1 : 0); |
|
e = floor(e / 2); |
|
} |
|
bits.push(s ? 1 : 0); |
|
bits.reverse(); |
|
str = bits.join(''); |
|
// Bits to bytes |
|
bytes = []; |
|
while(str.length){ |
|
bytes.unshift(parseInt(str.slice(0, 8), 2)); |
|
str = str.slice(8); |
|
} |
|
return bytes; |
|
}; |
|
var unpackIEEE754 = function(bytes, ebits, fbits){ |
|
var bits = [] |
|
, i, j, b, str, bias, s, e, f; |
|
for(i = 0; i < bytes.length; ++i)for(b = bytes[i], j = 8; j; --j){ |
|
bits.push(b % 2 ? 1 : 0); |
|
b = b >> 1; |
|
} |
|
bits.reverse(); |
|
str = bits.join(''); |
|
// Unpack sign, exponent, fraction |
|
bias = (1 << ebits - 1) - 1; |
|
s = parseInt(str.slice(0, 1), 2) ? -1 : 1; |
|
e = parseInt(str.slice(1, 1 + ebits), 2); |
|
f = parseInt(str.slice(1 + ebits), 2); |
|
// Produce number |
|
if(e === (1 << ebits) - 1)return f !== 0 ? NaN : s * Infinity; |
|
// Normalized |
|
else if(e > 0)return s * pow(2, e - bias) * (1 + f / pow(2, fbits)); |
|
// Denormalized |
|
else if(f !== 0)return s * pow(2, -(bias - 1)) * (f / pow(2, fbits)); |
|
return s < 0 ? -0 : 0; |
|
}; |
|
var unpackF64 = function(b){ |
|
return unpackIEEE754(b, 11, 52); |
|
}; |
|
var packF64 = function(v){ |
|
return packIEEE754(v, 11, 52); |
|
}; |
|
var unpackF32 = function(b){ |
|
return unpackIEEE754(b, 8, 23); |
|
}; |
|
var packF32 = function(v){ |
|
return packIEEE754(v, 8, 23); |
|
}; |
|
|
|
var addGetter = function(C, key, internal){ |
|
$.setDesc(C.prototype, key, {get: function(){ return this[internal]; }}); |
|
}; |
|
|
|
var get = function(view, bytes, index, conversion, isLittleEndian){ |
|
var numIndex = +index |
|
, intIndex = toInteger(numIndex); |
|
if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view._l)throw RangeError(); |
|
var store = view._b._b |
|
, start = intIndex + view._o |
|
, pack = store.slice(start, start + bytes); |
|
isLittleEndian || pack.reverse(); |
|
return conversion(pack); |
|
}; |
|
var set = function(view, bytes, index, conversion, value, isLittleEndian){ |
|
var numIndex = +index |
|
, intIndex = toInteger(numIndex); |
|
if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view._l)throw RangeError(); |
|
var store = view._b._b |
|
, start = intIndex + view._o |
|
, pack = conversion(+value); |
|
isLittleEndian || pack.reverse(); |
|
for(var i = 0; i < bytes; i++)store[start + i] = pack[i]; |
|
}; |
|
|
|
if(!$typed.ABV){ |
|
$ArrayBuffer = function ArrayBuffer(length){ |
|
strictNew(this, $ArrayBuffer, 'ArrayBuffer'); |
|
var numberLength = +length |
|
, byteLength = toLength(numberLength); |
|
if(numberLength != byteLength)throw RangeError(); |
|
this._b = arrayFill.call(Array(byteLength), 0); |
|
this._l = byteLength; |
|
}; |
|
addGetter($ArrayBuffer, BYTE_LENGTH, '_l'); |
|
|
|
$DataView = function DataView(buffer, byteOffset, byteLength){ |
|
strictNew(this, $DataView, 'DataView'); |
|
if(!(buffer instanceof $ArrayBuffer))throw TypeError(); |
|
var bufferLength = buffer._l |
|
, offset = toInteger(byteOffset); |
|
if(offset < 0 || offset > bufferLength)throw RangeError(); |
|
byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength); |
|
if(offset + byteLength > bufferLength)throw RangeError(); |
|
this._b = buffer; |
|
this._o = offset; |
|
this._l = byteLength; |
|
}; |
|
addGetter($DataView, 'buffer', '_b'); |
|
addGetter($DataView, BYTE_LENGTH, '_l'); |
|
addGetter($DataView, 'byteOffset', '_o'); |
|
redefineAll($DataView.prototype, { |
|
getInt8: function getInt8(byteOffset){ |
|
return get(this, 1, byteOffset, unpackI8); |
|
}, |
|
getUint8: function getUint8(byteOffset){ |
|
return get(this, 1, byteOffset, unpackU8); |
|
}, |
|
getInt16: function getInt16(byteOffset /*, littleEndian */){ |
|
return get(this, 2, byteOffset, unpackI16, arguments.length > 1 ? arguments[1] : undefined); |
|
}, |
|
getUint16: function getUint16(byteOffset /*, littleEndian */){ |
|
return get(this, 2, byteOffset, unpackU16, arguments.length > 1 ? arguments[1] : undefined); |
|
}, |
|
getInt32: function getInt32(byteOffset /*, littleEndian */){ |
|
return get(this, 4, byteOffset, unpackI32, arguments.length > 1 ? arguments[1] : undefined); |
|
}, |
|
getUint32: function getUint32(byteOffset /*, littleEndian */){ |
|
return get(this, 4, byteOffset, unpackU32, arguments.length > 1 ? arguments[1] : undefined); |
|
}, |
|
getFloat32: function getFloat32(byteOffset /*, littleEndian */){ |
|
return get(this, 4, byteOffset, unpackF32, arguments.length > 1 ? arguments[1] : undefined); |
|
}, |
|
getFloat64: function getFloat64(byteOffset /*, littleEndian */){ |
|
return get(this, 8, byteOffset, unpackF64, arguments.length > 1 ? arguments[1] : undefined); |
|
}, |
|
setInt8: function setInt8(byteOffset, value){ |
|
return set(this, 1, byteOffset, packI8, value); |
|
}, |
|
setUint8: function setUint8(byteOffset, value){ |
|
return set(this, 1, byteOffset, packU8, value); |
|
}, |
|
setInt16: function setInt16(byteOffset, value /*, littleEndian */){ |
|
return set(this, 2, byteOffset, packI16, value, arguments.length > 2 ? arguments[2] : undefined); |
|
}, |
|
setUint16: function setUint16(byteOffset, value /*, littleEndian */){ |
|
return set(this, 2, byteOffset, packU16, value, arguments.length > 2 ? arguments[2] : undefined); |
|
}, |
|
setInt32: function setInt32(byteOffset, value /*, littleEndian */){ |
|
return set(this, 4, byteOffset, packI32, value, arguments.length > 2 ? arguments[2] : undefined); |
|
}, |
|
setUint32: function setUint32(byteOffset, value /*, littleEndian */){ |
|
return set(this, 4, byteOffset, packU32, value, arguments.length > 2 ? arguments[2] : undefined); |
|
}, |
|
setFloat32: function setFloat32(byteOffset, value /*, littleEndian */){ |
|
return set(this, 4, byteOffset, packF32, value, arguments.length > 2 ? arguments[2] : undefined); |
|
}, |
|
setFloat64: function setFloat64(byteOffset, value /*, littleEndian */){ |
|
return set(this, 8, byteOffset, packF64, value, arguments.length > 2 ? arguments[2] : undefined); |
|
} |
|
}); |
|
} |
|
require('./$.hide')($DataView.prototype, $typed.VIEW, true); |
|
module.exports = { |
|
ArrayBuffer: $ArrayBuffer, |
|
DataView: $DataView |
|
}; |