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);
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Netstream
{
internal class NetStreamSender
{
private readonly byte[] _streamIdArray;
private readonly String _host;
private readonly int _port;
private Socket _socket;
private BufferedStream _outStream;
private NetStreamPacker _packer = new DefaultPacker();
private class DefaultPacker : NetStreamPacker
{
private readonly NetStreamStorage _sizeBuffer = new NetStreamStorage(sizeof (int));
public override NetStreamStorage PackMessage(NetStreamStorage buffer, int startIndex, int endIndex)
{
return buffer;
}
public override NetStreamStorage PackMessageSize(int capacity)
{
_sizeBuffer.Position = 0;
byte[] bytes = BitConverter.GetBytes(capacity);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
_sizeBuffer.Write(bytes, 0, bytes.Length);
return _sizeBuffer;
}
};
public NetStreamSender(int port)
: this("default", "localhost", port)
{
}
public NetStreamSender(String host, int port)
: this("default", host, port)
{
}
public NetStreamSender(String stream, String host, int port)
{
_host = host;
_port = port;
_streamIdArray = Encoding.UTF8.GetBytes(stream);
Connect();
}
/**
* Sets an optional NetStreamPaker whose "pack" method will be called on
* each message.
*
* a Packer can do extra encoding on the all byte array message, it may also
* crypt things.
*
* @param paker
* The packer object
*/
public void SetPacker(NetStreamPacker paker)
{
_packer = paker;
}
public void RemovePacker()
{
_packer = new DefaultPacker();
}
protected void Connect()
{
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(new DnsEndPoint(_host, _port));
_outStream = new BufferedStream(new NetworkStream(_socket));
}
/**
* @param buff
*/
private void DoSend(NetStreamStorage buff)
{
if (!_socket.Connected)
{
Console.Error.WriteLine("NetStreamSender : can't send. The socket is closed.");
}
else
{
buff.Flip();
NetStreamStorage buffer = _packer.PackMessage(buff);
NetStreamStorage sizeBuffer = _packer.PackMessageSize(buffer.Capacity);
buff.Position = 0;
// real sending
try
{
_outStream.Write(sizeBuffer.ToArray(), 0, sizeBuffer.Capacity);
_outStream.Write(buffer.ToArray(), 0, buffer.Capacity);
_outStream.Flush();
}
catch (IOException e)
{
Console.Error.WriteLine(e.StackTrace);
}
}
}
protected void AddAttribute(String sourceId, ulong timeId, String attribute, Object value, NetStreamEvent e)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(e).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(attribute).
EncodeValueWithType(value);
DoSend(buff);
}
protected void ChangeAttribute(String sourceId, ulong timeId, String attribute, Object oldValue, Object newValue,
NetStreamEvent e)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(e).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(attribute).
EncodeValueWithType(oldValue).
EncodeValueWithType(newValue);
DoSend(buff);
}
protected void RemoveAttribute(String sourceId, ulong timeId, String attribute, NetStreamEvent e)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(e).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(attribute);
DoSend(buff);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#graphAttributeAdded(java.lang.String
* , long, java.lang.String, java.lang.Object)
*/
public void AddGraphAttribute(String sourceId, ulong timeId, String attribute, Object value)
{
AddAttribute(sourceId, timeId, attribute, value, NetStreamEvent.AddGraphAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#graphAttributeChanged(java.lang.
* String, long, java.lang.String, java.lang.Object, java.lang.Object)
*/
public void ChangeGraphAttribute(String sourceId, ulong timeId, String attribute, Object oldValue,
Object newValue)
{
ChangeAttribute(sourceId, timeId, attribute, oldValue, newValue, NetStreamEvent.ChgGraphAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#graphAttributeRemoved(java.lang.
* String, long, java.lang.String)
*/
public void RemoveGraphAttribute(String sourceId, ulong timeId, String attribute)
{
RemoveAttribute(sourceId, timeId, attribute, NetStreamEvent.DelGraphAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#nodeAttributeAdded(java.lang.String,
* long, java.lang.String, java.lang.String, java.lang.Object)
*/
public void AddNodeAttribute(String sourceId, ulong timeId, String nodeId,
String attribute, Object value)
{
AddAttribute(sourceId, timeId, attribute, value, NetStreamEvent.AddNodeAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#nodeAttributeChanged(java.lang.String
* , long, java.lang.String, java.lang.String, java.lang.Object,
* java.lang.Object)
*/
public void ChangeNodeAttribute(String sourceId, ulong timeId,
String nodeId, String attribute, Object oldValue, Object newValue)
{
ChangeAttribute(sourceId, timeId, attribute, oldValue, newValue, NetStreamEvent.ChgNodeAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#nodeAttributeRemoved(java.lang.String
* , long, java.lang.String, java.lang.String)
*/
public void RemoveNodeAttribute(String sourceId, ulong timeId,
String nodeId, String attribute)
{
RemoveAttribute(sourceId, timeId, attribute, NetStreamEvent.DelNodeAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#edgeAttributeAdded(java.lang.String,
* long, java.lang.String, java.lang.String, java.lang.Object)
*/
public void AddEdgeAttribute(String sourceId, ulong timeId, String edgeId,
String attribute, Object value)
{
AddAttribute(sourceId, timeId, attribute, value, NetStreamEvent.AddEdgeAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#edgeAttributeChanged(java.lang.String
* , long, java.lang.String, java.lang.String, java.lang.Object,
* java.lang.Object)
*/
public void ChangeEdgeAttribute(String sourceId, ulong timeId,
String edgeId, String attribute, Object oldValue, Object newValue)
{
ChangeAttribute(sourceId, timeId, attribute, oldValue, newValue, NetStreamEvent.ChgEdgeAttr);
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.stream.AttributeSink#edgeAttributeRemoved(java.lang.String
* , long, java.lang.String, java.lang.String)
*/
public void RemoveEdgeAttribute(String sourceId, ulong timeId,
String edgeId, String attribute)
{
RemoveAttribute(sourceId, timeId, attribute, NetStreamEvent.DelEdgeAttr);
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.ElementSink#nodeAdded(java.lang.String, long,
* java.lang.String)
*/
public void AddNode(String sourceId, ulong timeId, String nodeId)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(NetStreamEvent.AddNode).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(nodeId);
DoSend(buff);
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.ElementSink#nodeRemoved(java.lang.String,
* long, java.lang.String)
*/
public void RemoveNode(String sourceId, ulong timeId, String nodeId)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(NetStreamEvent.DelNode).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(nodeId);
DoSend(buff);
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.ElementSink#edgeAdded(java.lang.String, long,
* java.lang.String, java.lang.String, java.lang.String, boolean)
*/
public void AddEdge(String sourceId, ulong timeId, String edgeId,
String fromNodeId, String toNodeId, bool directed)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(NetStreamEvent.AddEdge).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(edgeId).
EncodeString(fromNodeId).
EncodeString(toNodeId).
EncodeNative(directed);
DoSend(buff);
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.ElementSink#edgeRemoved(java.lang.String,
* long, java.lang.String)
*/
public void RemoveEdge(String sourceId, ulong timeId, String edgeId)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(NetStreamEvent.DelEdge).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeString(edgeId);
DoSend(buff);
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.ElementSink#graphCleared(java.lang.String,
* long)
*/
public void GraphClear(String sourceId, ulong timeId)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(NetStreamEvent.Cleared).
EncodeString(sourceId).
EncodeNative(timeId);
DoSend(buff);
}
/*
* (non-Javadoc)
*
* @see org.graphstream.stream.ElementSink#stepBegins(java.lang.String,
* long, double)
*/
public void StepBegins(String sourceId, ulong timeId, double step)
{
NetStreamStorage buff = new NetStreamStorage().
EncodeArray(_streamIdArray).
EncodeEvent(NetStreamEvent.Step).
EncodeString(sourceId).
EncodeNative(timeId).
EncodeNative(step);
DoSend(buff);
}
/**
* Force the connection to close (properly) with the server
*
* @throws IOException
*/
public void Close()
{
_socket.Close();
}
}
}