Commit bbf4161e authored by Benjamin Krämer's avatar Benjamin Krämer

Added C# implementation

Using varints to work with the most recent version
parent 097d5d60

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "src", "src\gs-netstream.csproj", "{2B116210-044C-47C2-95A5-88CB65341C99}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2B116210-044C-47C2-95A5-88CB65341C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B116210-044C-47C2-95A5-88CB65341C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B116210-044C-47C2-95A5-88CB65341C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B116210-044C-47C2-95A5-88CB65341C99}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
\ No newline at end of file
namespace Netstream
{
//
// ----------------------------------
// GraphStream's graph events
// ----------------------------------
//
public enum NetStreamEvent
{
/**
* Followed by a node id (TYPE_STRING format)
*/
AddNode = 0x10,
/**
* Followed by a node id (TYPE_STRING format)
*/
DelNode = 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)
*/
AddEdge = 0x12,
/**
* Followed by an edge id (TYPE_STRING format)
*/
DelEdge = 0x13,
/**
* Followed by double (TYPE_DOUBLE format)
*/
Step = 0x14,
/**
*
*/
Cleared = 0x15,
/**
* Followed by - an attribute id (TYPE_STRING format) - the attribute TYPE -
* the attribute value
*/
AddGraphAttr = 0x16,
/**
* Followed by - an attribute id (TYPE_STRING format) - the attribute TYPE -
* the attribute old value - the attribute new value
*/
ChgGraphAttr = 0x17,
/**
* Followed by - the attribute id (TYPE_STRING format)
*/
DelGraphAttr = 0x18,
/**
* Followed by - an attribute id (TYPE_STRING format) - the attribute TYPE -
* the attribute value
*/
AddNodeAttr = 0x19,
/**
* Followed by - an attribute id (TYPE_STRING format) - the attribute TYPE -
* the attribute old value - the attribute new value
*/
ChgNodeAttr = 0x1a,
/**
* Followed by - the node id (TYPE_STRING format) - the attribute id
* (TYPE_STRING format)
*/
DelNodeAttr = 0x1b,
/**
* Followed by - an attribute id (TYPE_STRING format) - the attribute TYPE -
* the attribute value
*/
AddEdgeAttr = 0x1c,
/**
* Followed by - an attribute id (TYPE_STRING format) - the attribute TYPE -
* the attribute old value - the attribute new value
*/
ChgEdgeAttr = 0x1d,
/**
* Followed by - the edge id (TYPE_STRING format) - the attribute id
* (TYPE_STRING format)
*/
DelEdgeAttr = 0x1e
}
// Values types
public enum NetStreamType
{
/**
* Followed by a byte who's value is 0 or 1
*/
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
*/
BooleanArray = 0x51,
/**
* Followed by a signed byte [-127,127]
*/
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.
*/
ByteArray = 0x53,
/**
* Followed by an 16-bit signed integer (a short)
*/
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
*/
ShortArray = 0x55,
/**
* Followed by an 32-bit signed integer
*/
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
*/
IntArray = 0x57,
/**
* Followed by an 64-bit signed integer
*/
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
*/
LongArray = 0x59,
/**
* Followed by a single precision 32-bits floating point number
*/
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
*/
FloatArray = 0x5b,
/**
* Followed by a double precision 64-bits floating point number
*/
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
*/
DoubleArray = 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
*/
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.
*/
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.
*/
Array = 0x60,
/**
*
*/
Null = 0x61
}
}
namespace Netstream
{
public abstract class NetStreamPacker
{
/**
* Pack the given ByteBuffer from startIndex to endIdex
* @param buffer The buffer to pack/encode
* @param startIndex the index at which the encoding starts in the buffer
* @param endIndex the index at which the encoding stops
* @return a ByteBuffer that is the packed version of the input one. It may not have the same size.
*/
public abstract NetStreamStorage PackMessage(NetStreamStorage buffer, int startIndex, int endIndex);
/**
* Pack the given ByteBuffer form its position to its capacity.
* @param buffer The buffer to pack/encode
* @return a ByteBuffer that is the packed version of the input one. It may not have the same size.
*/
public NetStreamStorage PackMessage(NetStreamStorage buffer)
{
return this.PackMessage(buffer, 0, buffer.Capacity);
}
/**
* @param capacity
* @return
*/
public abstract NetStreamStorage PackMessageSize(int capacity);
}
}
This diff is collapsed.
using System;
using System.IO;
using System.Text;
namespace Netstream
{
public class NetStreamStorage : MemoryStream
{
public NetStreamStorage()
{
}
public NetStreamStorage(int capacity)
: base(capacity)
{
}
public void Flip()
{
int position = (int) Position;
Position = 0;
Capacity = position;
}
protected NetStreamType GetNetStreamType(object value)
{
if (value == null)
return NetStreamType.Null;
Type type = value.GetType();
bool isArray = type.IsArray;
if (isArray)
type = type.GetElementType();
if (type == typeof (bool))
return isArray ? NetStreamType.BooleanArray : NetStreamType.Boolean;
if (type == typeof (byte) || type == typeof (char))
return isArray ? NetStreamType.ByteArray : NetStreamType.Byte;
if (type == typeof (short))
return isArray ? NetStreamType.ShortArray : NetStreamType.Short;
if (type == typeof (int))
return isArray ? NetStreamType.IntArray : NetStreamType.Int;
if (type == typeof (long))
return isArray ? NetStreamType.LongArray : NetStreamType.Long;
if (type == typeof (float))
return isArray ? NetStreamType.FloatArray : NetStreamType.Float;
if (type == typeof (double))
return isArray ? NetStreamType.DoubleArray : NetStreamType.Double;
if (type == typeof (string))
return isArray ? NetStreamType.Array : NetStreamType.String;
return 0;
}
public NetStreamStorage EncodeValueWithType(object input)
{
// First encode value type:
NetStreamType valueType = GetNetStreamType(input);
EncodeType(valueType);
// Second encode data:
switch (valueType)
{
case NetStreamType.Boolean:
case NetStreamType.Byte:
case NetStreamType.Short:
case NetStreamType.Int:
case NetStreamType.Long:
case NetStreamType.Float:
case NetStreamType.Double:
return EncodeNative(input);
case NetStreamType.String:
return EncodeString((string) input);
case NetStreamType.BooleanArray:
case NetStreamType.ByteArray:
case NetStreamType.ShortArray:
case NetStreamType.IntArray:
case NetStreamType.LongArray:
case NetStreamType.FloatArray:
case NetStreamType.DoubleArray:
case NetStreamType.Array:
return EncodeArray((Array) input);
case NetStreamType.Null:
return this;
default:
return null;
}
}
/**
* @param input
* @return
*/
public NetStreamStorage EncodeArray(Array data)
{
Serialize((uint)data.Length);
foreach (object t in data)
Serialize(t);
return this;
}
/**
* @param input
* @return
*/
public NetStreamStorage EncodeString(string input)
{
byte[] data = Encoding.UTF8.GetBytes(input);
return EncodeArray(data);
}
/**
* @param input
* @return MemoryStream with encoded struct in it
*/
public NetStreamStorage EncodeEvent(NetStreamEvent input)
{
return EncodeNative((byte) input);
}
/**
* @param input
* @return MemoryStream with encoded struct in it
*/
public NetStreamStorage EncodeType(NetStreamType input)
{
return EncodeNative((byte) input);
}
/**
* @param input
* @return MemoryStream with encoded struct in it
*/
public NetStreamStorage EncodeNative(object input)
{
Serialize(input);
return this;
}
private byte[] GetVarint(long input)
{
return GetUnsignedVarint(input >= 0 ? (input << 1) : ((Math.Abs(input) << 1) ^ 1));
}
private byte[] GetUnsignedVarint(long number)
{
int byteSize = varintSize(number);
byte[] bytes = new byte[byteSize];
for (int i = 0; i < byteSize; i++)
{
int head = 128;
if (i == byteSize - 1) head = 0;
long b = ((number >> (7 * i)) & 127) ^ head;
bytes[i] = (byte)(b & 255);
}
return bytes;
}
private int varintSize(long data)
{
// 7 bits -> 127
if (data < (1L << 7))
{
return 1;
}
// 14 bits -> 16383
if (data < (1L << 14))
{
return 2;
}
// 21 bits -> 2097151
if (data < (1L << 21))
{
return 3;
}
// 28 bits -> 268435455
if (data < (1L << 28))
{
return 4;
}
// 35 bits -> 34359738367
if (data < (1L << 35))
{
return 5;
}
// 42 bits -> 4398046511103
if (data < (1L << 42))
{
return 6;
}
// 49 bits -> 562949953421311
if (data < (1L << 49))
{
return 7;
}
// 56 bits -> 72057594037927935
if (data < (1L << 56))
{
return 8;
}
return 9;
}
private void Serialize(object input)
{
byte[] bytes;
if (input is bool)
bytes = BitConverter.GetBytes((bool) input);
else if (input is byte || input is char)
bytes = new byte[] { Convert.ToByte(input) };
else if (input is short || input is int || input is long)
bytes = GetVarint(Convert.ToInt64(input));
else if (input is ushort || input is uint || input is ulong)
bytes = GetUnsignedVarint(Convert.ToInt64(input));
else if (input is float)
bytes = BitConverter.GetBytes((float) input);
else if (input is double)
bytes = BitConverter.GetBytes((double) input);
else
throw new ArgumentException();
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
}
}
using System.Text;
namespace Netstream
{
internal class Program
{
private static void Main(string[] args)
{
//Endless();
//EventsTest();
TypesTest();
//Example();
}
private static void Endless()
{
const string sourceId = "C++_netstream_test";
ulong timeId = 0L;
var stream = new NetStreamSender("default", "localhost", 2001);
const string n1 = "node";
while (true)
{
stream.AddNode(sourceId, timeId++, n1);
}
}
private static void Example()
{
const string sourceId = "C++_netstream_test";
ulong timeId = 0L;
var stream = new NetStreamSender("default", "localhost", 2001);
const string style = "node{fill-mode:plain;fill-color:#567;size:6px;}";
stream.AddGraphAttribute(sourceId, timeId++, "stylesheet", style);
stream.AddGraphAttribute(sourceId, timeId++, "test", "test");
stream.ChangeGraphAttribute(sourceId, timeId++, "test", "test", false);
stream.AddGraphAttribute(sourceId, timeId++, "ui.antialias", true);
stream.AddGraphAttribute(sourceId, timeId++, "layout.stabilization-limit", 0);
for (int i = 0; i < 500; i++)
{
var n1 = new StringBuilder();
n1.Append(i);
stream.AddNode(sourceId, timeId++, n1.ToString());
if (i > 0)
{
var n2 = new StringBuilder();
n2.Append(i - 1);
var n3 = new StringBuilder();
n3.Append(i/2);
var e1 = new StringBuilder();
e1.Append(n1).Append("-").Append(n2);
var e2 = new StringBuilder();
e2.Append(n1).Append("-").Append(n3);
stream.AddEdge(sourceId, timeId++, e1.ToString(), n1.ToString(), n2.ToString(), false);
stream.AddEdge(sourceId, timeId++, e2.ToString(), n1.ToString(), n3.ToString(), false);
}
}
}
private static void TypesTest()
{
const string sourceId = "C++_netstream_test";
ulong timeId = 0L;
var stream = new NetStreamSender("default", "localhost", 2001);
stream.AddGraphAttribute(sourceId, timeId++, "int", 1);
stream.AddGraphAttribute(sourceId, timeId++, "float", (float) 1);
stream.AddGraphAttribute(sourceId, timeId++, "double", 1.0);
stream.AddGraphAttribute(sourceId, timeId++, "long", 1L);
stream.AddGraphAttribute(sourceId, timeId++, "byte", (char) 0);
stream.AddGraphAttribute(sourceId, timeId++, "boolean", true);
int[] v = {1776, 7, 4};
stream.AddGraphAttribute(sourceId, timeId++, "intArray", v);
float[] v2 = {1776.3f, 7.3f};
stream.AddGraphAttribute(sourceId, timeId++, "floatArray", v2);
double[] v3 = {776.3, .3};
stream.AddGraphAttribute(sourceId, timeId++, "doubleArray", v3);
long[] v4 = {1776, 7, 4};
stream.AddGraphAttribute(sourceId, timeId++, "longArray", v4);
char[] v5 = {'0', (char) 0, 'z'};
stream.AddGraphAttribute(sourceId, timeId++, "byteArray", v5);
bool[] v6 = {true, false};
stream.AddGraphAttribute(sourceId, timeId++, "booleanArray", v6);
stream.AddGraphAttribute(sourceId, timeId++, "string", "true");
}
private static void EventsTest()
{
const string sourceId = "C++_netstream_test";
ulong timeId = 0L;
var stream = new NetStreamSender("localhost", 2001);
stream.AddNode(sourceId, timeId++, "node0");
stream.AddEdge(sourceId, timeId++, "edge", "node0", "node1", true);
stream.AddNodeAttribute(sourceId, timeId++, "node0", "nodeAttribute", 0);
stream.ChangeNodeAttribute(sourceId, timeId++, "node0", "nodeAttribute", 0, 1);
stream.RemoveNodeAttribute(sourceId, timeId++, "node0", "nodeAttribute");
stream.AddEdgeAttribute(sourceId, timeId++, "edge", "edgeAttribute", 0);
stream.ChangeEdgeAttribute(sourceId, timeId++, "edge", "edgeAttribute", 0, 1);
stream.RemoveEdgeAttribute(sourceId, timeId++, "edge", "edgeAttribute");
stream.AddGraphAttribute(sourceId, timeId++, "graphAttribute", 0);
stream.ChangeGraphAttribute(sourceId, timeId++, "graphAttribute", 0, 1);
stream.RemoveGraphAttribute(sourceId, timeId++, "graphAttribute");
stream.StepBegins(sourceId, timeId++, 1.1);
stream.RemoveEdge(sourceId, timeId++, "edge");
stream.RemoveNode(sourceId, timeId++, "node0");
stream.GraphClear(sourceId, timeId++);
}
}
}
using System.Reflection;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("src")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("src")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird