Commit f9f690ff authored by Yoann Pigné's avatar Yoann Pigné

on the way to a websocket implementation of netstream...

parent 80b6473d
//
// netstream_commons.js
// netstream project
//
// Created by Yoann Pigné on 2012-05-14.
// Copyright 2012 University of Le Havre. All rights reserved.
//
(function (global) {
"use strict";
if (!global.netstream) {
global.netstream = {};
}
// Copyright (c) 2008 notmasteryet
global.netstream.TypedArrayReader = function (t_array) {
"use strict";
this.position = 0;
this.array = new Uint8Array(t_array.buffer, t_array.byteOffset, t_array.byteLength);
this.readByte = function () {
if (this.position >= this.array.length) {
return null;
}
return this.array[this.position++];
};
}
// RFC 2279
global.netstream.Utf8Translator = function (reader) {
this.reader = reader;
this.waitBom = true;
this.pendingChar = null;
this.readChar = function () {
var ch = null;
do {
if (this.pendingChar !== null) {
ch = this.pendingChar;
this.pendingChar = null;
} else {
var b1 = this.reader.readByte();
if (b1 < 0) {
return null;
}
if ((b1 & 0x80) === 0) {
ch = String.fromCharCode(b1);
} else {
var currentPrefix = 0xC0;
var validBits = 5;
do {
var mask = currentPrefix >> 1 | 0x80;
if ((b1 & mask) === currentPrefix){
break;
}
currentPrefix = currentPrefix >> 1 | 0x80;
--validBits;
}
while (validBits >= 0);
if (validBits > 0) {
var code = (b1 & ((1 << validBits) - 1));
for (var i = 5; i >= validBits; --i) {
var bi = this.reader.readByte();
if ((bi & 0xC0) != 0x80) throw "Invalid sequence character";
code = (code << 6) | (bi & 0x3F);
}
if (code <= 0xFFFF) {
if (code == 0xFEFF && this.waitBom)
ch = null;
else
ch = String.fromCharCode(code);
} else {
var v = code - 0x10000;
var w1 = 0xD800 | ((v >> 10) & 0x3FF);
var w2 = 0xDC00 | (v & 0x3FF);
this.pendingChar = String.fromCharCode(w2);
ch = String.fromCharCode(w1);
}
} else {
throw "Invalid character";
}
}
}
this.waitBom = false;
}
while (ch === null);
return ch;
};
}
//
// Takes a typed Array received from the websocket and supposly encoding an utf8 string.
// Converts it to a unicode string.
//
// BEING USED
//
global.netstream.typedArrayToString = function (input) {
"use strict";
var reader = new netstream.TypedArrayReader(input),
utf8 = new netstream.Utf8Translator(reader),
result = [],
i = 0,
ch = 0,
s = "";
do {
ch = utf8.readChar();
result[i++] = ch;
}
while (ch.charCodeAt(0) !== 0);
s = result.join("");
return s;
}
global.netstream.base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
_keyCode: {
65: 0,
66: 1,
67: 2,
68: 3,
69: 4,
70: 5,
71: 6,
72: 7,
73: 8,
74: 9,
75: 10,
76: 11,
77: 12,
78: 13,
79: 14,
80: 15,
81: 16,
82: 17,
83: 18,
84: 19,
85: 20,
86: 21,
87: 22,
88: 23,
89: 24,
90: 25,
97: 26,
98: 27,
99: 28,
100: 29,
101: 30,
102: 31,
103: 32,
104: 33,
105: 34,
106: 35,
107: 36,
108: 37,
109: 38,
110: 39,
111: 40,
112: 41,
113: 42,
114: 43,
115: 44,
116: 45,
117: 46,
118: 47,
119: 48,
120: 49,
121: 50,
122: 51,
48: 52,
49: 53,
50: 54,
51: 55,
52: 56,
53: 57,
54: 58,
55: 59,
56: 60,
57: 61,
43: 62,
47: 63,
61: 64
},
decode: function(input) {
var lkey1 = this._keyStr.indexOf(input[input.length - 1]);
var lkey2 = this._keyStr.indexOf(input[input.length - 2]);
var bytes = Math.ceil((3 * input.length) / 4.0);
if (lkey1 == 64) bytes--;
//padding chars, so skip
if (lkey2 == 64) bytes--;
//padding chars, so skip
var arrayBuffer = new ArrayBuffer(bytes);
var uarray;
var chr1,
chr2,
chr3;
var enc1,
enc2,
enc3,
enc4;
var i = 0;
var j = 0;
if (arrayBuffer) uarray = new Uint8Array(arrayBuffer);
else uarray = new Uint8Array(bytes);
//input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
for (i = 0; i < input.length; i++) {
var d = input[i];
if ((d < 65 || d > 90) && (d < 97 || d > 122) & (d < 47 || d > 57) & d != 61 & d != 43) {
throw "illegal character in base64 string "+d;
}
}
for (i = 0; i < bytes; i += 3) {
enc1 = this._keyCode[input[j++]];
//.indexOf(input.charAt(j++));
enc2 = this._keyCode[input[j++]];
//this._keyStr.indexOf(input.charAt(j++));
enc3 = this._keyCode[input[j++]];
//this._keyStr.indexOf(input.charAt(j++));
enc4 = this._keyCode[input[j++]];
//this._keyStr.indexOf(input.charAt(j++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
uarray[i] = chr1;
if (enc3 != 64) uarray[i + 1] = chr2;
if (enc4 != 64) uarray[i + 2] = chr3;
}
return uarray;
},
encode: function(arrayBuffer) {
var base64 = '';
var bytes = new Uint8Array(arrayBuffer);
var byteLength = bytes.byteLength;
var byteRemainder = byteLength % 3;
var mainLength = byteLength - byteRemainder;
var a,
b,
c,
d;
var chunk;
for (var i = 0; i < mainLength; i = i + 3) {
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
a = (chunk & 16515072) >> 18;
b = (chunk & 258048) >> 12;
c = (chunk & 4032) >> 6;
d = chunk & 63;
base64 += this._keyStr[a] + this._keyStr[b] + this._keyStr[c] + this._keyStr[d];
}
if (byteRemainder == 1) {
chunk = bytes[mainLength];
a = (chunk & 252) >> 2;
b = (chunk & 3) << 4;
base64 += this._keyStr[a] + this._keyStr[b] + '==';
} else if (byteRemainder == 2) {
chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];
a = (chunk & 64512) >> 10;
b = (chunk & 1008) >> 4;
c = (chunk & 15) << 2;
base64 += this._keyStr[a] + this._keyStr[b] + this._keyStr[c] + '=';
}
return base64;
}
};
global.netstream.LOGGER = function (msg) {
//console.log("-");return;
if (typeof(console.log) == "function") {
console.log(msg);
}
else if (typeof(window.status) == "string") {
window.status = msg;
}
}
}(this));
\ No newline at end of file
//
// netstream_constants.js
// netstream project
//
// Created by Yoann Pigné on 2012-05-04.
// Copyright 2012 University of Le Havre. All rights reserved.
//
// Contains the constant bytes used in the protocol to identifie data types and "EVENTs.
//
(function (global) {
"use strict";
if (!global.netstream) {
global.netstream = {};
}
global.netstream.constants = {
// Followed by an 32-bit signed integer for this protocol version. Certainly useless.
"EVENT_GETVERSION": 0x00,
// Not used.
"EVENT_START": 0x01,
// Not used.
"EVENT_END": 0x02,
//" ::::::::::::::::::::::::::::::
//" : GraphStream graph "EVENTs" :
//" ::::::::::::::::::::::::::::::
// Followed by a node id (TYPE_STRING format)
"EVENT_ADD_NODE": 0x10,
// Followed by a node id (TYPE_STRING format)
"EVENT_DEL_NODE": 0x11,
// Followed by
// - an edge id (TYPE_STRING format),
// - an source node id (TYPE_STRING format),
// - a target node id (TYPE_STRING format
// - a boolean indicating if directed (TYPE_BOOLEAN format)
"EVENT_ADD_EDGE": 0x12,
// Followed by an edge id (TYPE_STRING format)
"EVENT_DEL_EDGE": 0x13,
// Followed by double (TYPE_DOUBLE format)
"EVENT_STEP": 0x14,
"EVENT_CLEARED": 0x15,
//
// Followed by
// - an attribute id (TYPE_STRING format)
// - the attribute "TYPE
// - the attribute value
//
"EVENT_ADD_GRAPH_ATTR": 0x16,
//
// Followed by
// - an attribute id (TYPE_STRING format)
// - the attribute "TYPE
// - the attribute old value
// - the attribute new value
//
"EVENT_CHG_GRAPH_ATTR": 0x17,
//
// Followed by
// - the attribute id (TYPE_STRING format)
//
"EVENT_DEL_GRAPH_ATTR": 0x18,
//
// Followed by
// - an attribute id (TYPE_STRING format)
// - the attribute "TYPE
// - the attribute value
//
"EVENT_ADD_NODE_ATTR": 0x19,
//
// Followed by
// - an attribute id (TYPE_STRING format)
// - the attribute "TYPE
// - the attribute old value
// - the attribute new value
//
"EVENT_CHG_NODE_ATTR": 0x1a,
//
// Followed by
// - the node id (TYPE_STRING format)
// - the attribute id (TYPE_STRING format)
//
"EVENT_DEL_NODE_ATTR": 0x1b,
//
// Followed by
// - an attribute id (TYPE_STRING format)
// - the attribute "TYPE
// - the attribute value
//
"EVENT_ADD_EDGE_ATTR": 0x1c,
//
// Followed by
// - an attribute id (TYPE_STRING format)
// - the attribute "TYPE
// - the attribute old value
// - the attribute new value
//
"EVENT_CHG_EDGE_ATTR": 0x1d,
//
// Followed by
// - the edge id (TYPE_STRING format)
// - the attribute id (TYPE_STRING format)
//
"EVENT_DEL_EDGE_ATTR": 0x1e,
//" :::::::::::::::
//" : Value Types" :
//" :::::::::::::::
//
// Followed by a byte who's value is 0 or 1
//
"TYPE_BOOLEAN": 0x50,
//
// An array of booleans. Followed by first, a 16-bits integer for the number
// of booleans and then, a list of bytes who's value is 0 or 1
//
"TYPE_BOOLEAN_ARRAY": 0x51,
// Followed by a signed byte [-127,127]
"TYPE_BYTE": 0x52,
//
// An array of bytes. Followed by first, a 16-bits integer for the number
// of integers and then, a list of signed bytes.
//
"TYPE_BYTE_ARRAY": 0x53,
// Followed by an 16-bit signed integer (a short)
"TYPE_SHORT": 0x54,
//
// An array of shorts. Followed by first, a 16-bits integer for the number
// of integers and then, a list of 16-bit signed shorts
//
"TYPE_SHORT_ARRAY": 0x55,
// Followed by an 32-bit signed integer
"TYPE_INT": 0x56,
//
// An array of integers. Followed by first, a 16-bits integer for the number
// of integers and then, a list of 32-bit signed integers
//
"TYPE_INT_ARRAY": 0x57,
//
// Followed by an 64-bit signed integer
//
"TYPE_LONG": 0x58,
//
// An array of longs. Followed by first, a 16-bits integer for the number of
// longs and then, a list of 62-bit signed integers
//
"TYPE_LONG_ARRAY": 0x59,
//
// Followed by a single precision 32-bits floating point number
//
"TYPE_FLOAT": 0x5a,
//
// Array of double. Followed by first, a 16-bits integer for the number of
// floats and then, a list of 32-bit floats
//
"TYPE_FLOAT_ARRAY": 0x5b,
// Followed by a double precision 64-bits floating point number
"TYPE_DOUBLE": 0x5c,
//
// Array of double. Followed by first, a 16-bits integer for the number of
// doubles and then, a list of 64-bit doubles
//
"TYPE_DOUBLE_ARRAY": 0x5d,
//
// Array of characters. Followed by first, a 16-bits integer for the size in
// bytes (not in number of characters) of the string, then by the unicode
// string
//
"TYPE_STRING": 0x5e,
//
// Raw data, good for serialization. Followed by first, a 16-bits integer
// indicating the length in bytes of the dataset, and then the data itself.
//
"TYPE_RAW": 0x5f,
//
// An type-unspecified array. Followed by first, a
// 16-bits integer indicating the number of elements, and then, the elements
// themselves. The elements themselves have to give their type.
//
"TYPE_ARRAY": 0x60
};
}(this));
\ No newline at end of file
(function (global) {
"use strict";
if (!global.netstream) {
global.netstream = {};
}
global.netstream.DefaultGSSink = function () {
};
global.netstream.DefaultGSSink.prototype = {
nodeAdded: function () {},
nodeRemoved: function () {},
nodeAttributeAdded: function () {},
nodeAttributeChanged: function () {},
nodeAttributeRemoved: function () {},
edgeAdded: function () {},
edgeRemoved: function () {},
edgeAttributeAdded: function () {},
edgeAttributeChanged: function () {},
edgeAttributeRemoved: function () {},
graphAttributeAdded: function () {},
graphAttributeChanged: function () {},
graphAttributeRemoved: function () {},
graphCleared: function () {},
stepBegins: function () {}
};
global.netstream.DOMGSSink = function (element) {
this.element = element;
};
global.netstream.DOMGSSink.prototype = {
element: "",
appendMsg: function (msg) {
var textNode = global.document.createTextNode(msg);
var parNode = global.document.createElement('p');
parNode.appendChild(textNode);
this.element.appendChild(parNode);
},
nodeAdded: function (sourceId, timeId, nodeId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : an \"" + nodeId + "\"");
},
nodeRemoved: function (sourceId, timeId, nodeId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : dn \"" + nodeId + "\"");
},
nodeAttributeAdded: function (sourceId, timeId, nodeId, attrId, value) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + nodeId + "\" \"" + attrId + "\":" + value);
},
nodeAttributeChanged: function (sourceId, timeId, nodeId, attrId, oldValue, newValue) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + nodeId + "\" \"" + attrId + "\":" + newValue);
},
nodeAttributeRemoved: function (sourceId, timeId, nodeId, attrId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + nodeId + "\" \"" + attrId + "\":null");
},
edgeAdded: function (sourceId, timeId, edgeId, from, to, directed) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : ae \"" + edgeId + "\" \"" + from + (directed === true ? "\">\"": "\" \"") + to + "\"");
},
edgeRemoved: function (sourceId, timeId, edgeId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : de \"" + nodeId + "\"");
},
edgeAttributeAdded: function (sourceId, timeId, edgeId, attrId, value) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : ce \"" + edgeId + "\" \"" + attrId + "\":" + value);
},
edgeAttributeChanged: function (sourceId, timeId, edgeId, attrId, oldValue, newValue) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : ce \"" + edgeId + "\" \"" + attrId + "\":" + newValue);
},
edgeAttributeRemoved: function (sourceId, timeId, edgeId, attrId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + edgeId + "\" \"" + attrId + "\":null");
},
graphAttributeAdded: function (sourceId, timeId, attrId, value) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cg \"" + attrId + "\":" + value);
},
graphAttributeChanged: function (sourceId, timeId, attrId, oldValue, newValue) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cg \"" + attrId + "\":" + newValue);
},
graphAttributeRemoved: function (sourceId, timeId, edgeId, attrId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cg \"" + attrId + "\":null");
},
graphCleared: function (sourceId, timeId) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : cl");
},
stepBegins: function (sourceId, timeId, time) {
this.appendMsg("(GSSink, " + sourceId + ":" + timeId + ") : st " + time);
}
};
global.netstream.LoggerGSSink = function () {
};
global.netstream.LoggerGSSink.prototype = {
nodeAdded: function (sourceId, timeId, nodeId) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : an \"" + nodeId + "\"");
},
nodeRemoved: function (sourceId, timeId, nodeId) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : dn \"" + nodeId + "\"");
},
nodeAttributeAdded: function (sourceId, timeId, nodeId, attrId, value) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + nodeId + "\" \"" + attrId + "\":" + value);
},
nodeAttributeChanged: function (sourceId, timeId, nodeId, attrId, oldValue, newValue) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + nodeId + "\" \"" + attrId + "\":" + newValue);
},
nodeAttributeRemoved: function (sourceId, timeId, nodeId, attrId) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + nodeId + "\" \"" + attrId + "\":null");
},
edgeAdded: function (sourceId, timeId, edgeId, from, to, directed) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : ae \"" + edgeId + "\" \"" + from + (directed === true ? "\">\"": "\" \"") + to + "\"");
},
edgeRemoved: function (sourceId, timeId, edgeId) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : de \"" + nodeId + "\"");
},
edgeAttributeAdded: function (sourceId, timeId, edgeId, attrId, value) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : ce \"" + edgeId + "\" \"" + attrId + "\":" + value);
},
edgeAttributeChanged: function (sourceId, timeId, edgeId, attrId, oldValue, newValue) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : ce \"" + edgeId + "\" \"" + attrId + "\":" + newValue);
},
edgeAttributeRemoved: function (sourceId, timeId, edgeId, attrId) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : cn \"" + edgeId + "\" \"" + attrId + "\":null");
},
graphAttributeAdded: function (sourceId, timeId, attrId, value) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : cg \"" + attrId + "\":" + value);
},
graphAttributeChanged: function (sourceId, timeId, attrId, oldValue, newValue) {
netstream.LOGGER("(GSSink, " + sourceId + ":" + timeId + ") : cg \"" + attrId + "\":" + newValue);