Skip to content

Commit

Permalink
Merge pull request #152 from iCsysAS/master
Browse files Browse the repository at this point in the history
Add methods to allow client read/write requests with externally managed arrays to reduce allocation.
  • Loading branch information
nauful authored Mar 4, 2024
2 parents d280572 + bee8267 commit da17f96
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 24 deletions.
57 changes: 42 additions & 15 deletions NET Core/LibUA/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2038,9 +2038,16 @@ public StatusCode CloseSession()
}
}

public StatusCode Read(ReadValueId[] Ids, out DataValue[] results)
public StatusCode Read(ReadValueId[] Ids, DataValue[] results, int Count)
{
results = null;
if (Ids.Length == 0)
return StatusCode.Good;

if (Ids.Length < Count)
throw new Exception("Count cannot be larger than Ids");

if (results.Length < Count)
throw new Exception("Results cannot be less than Count");

try
{
Expand All @@ -2055,7 +2062,7 @@ public StatusCode Read(ReadValueId[] Ids, out DataValue[] results)
var reqHeader = new RequestHeader()
{
RequestHandle = nextRequestHandle++,
Timestamp = DateTime.Now,
Timestamp = DateTime.UtcNow,
AuthToken = config.AuthToken,
};

Expand All @@ -2066,9 +2073,9 @@ public StatusCode Read(ReadValueId[] Ids, out DataValue[] results)
// maxAge
succeeded &= sendBuf.Encode((double)0);
// LocaleIds
succeeded &= sendBuf.Encode((UInt32)TimestampsToReturn.Both);
succeeded &= sendBuf.Encode((UInt32)Ids.Length);
for (int i = 0; i < Ids.Length; i++)
succeeded &= sendBuf.Encode((uint)TimestampsToReturn.Both);
succeeded &= sendBuf.Encode((uint)Count);
for (int i = 0; i < Count; i++)
{
succeeded &= sendBuf.Encode(Ids[i]);
}
Expand Down Expand Up @@ -2121,18 +2128,20 @@ public StatusCode Read(ReadValueId[] Ids, out DataValue[] results)

succeeded &= recvHandler.RecvBuf.DecodeArraySize(out uint numRecv);

results = new DataValue[numRecv];
for (int i = 0; i < numRecv && succeeded; i++)
{
succeeded &= recvHandler.RecvBuf.Decode(out results[i]);
if (results[i] == null)
succeeded &= recvHandler.RecvBuf.Decode(out results[i]);
else
succeeded &= recvHandler.RecvBuf.Decode(results[i]);
}

if (!succeeded)
{
return StatusCode.BadDecodingError;
}

if (numRecv != Ids.Length)
if (numRecv != Count)
{
return StatusCode.GoodResultsMayBeIncomplete;
}
Expand All @@ -2146,9 +2155,22 @@ public StatusCode Read(ReadValueId[] Ids, out DataValue[] results)
}
}

public StatusCode Write(WriteValue[] Ids, out uint[] results)
public StatusCode Read(ReadValueId[] Ids, out DataValue[] results)
{
results = null;
results = new DataValue[Ids.Length];
return Read(Ids, results,Ids.Length);
}

public StatusCode Write(WriteValue[] Ids, uint[] results, int Count)
{
if (Ids.Length == 0)
return StatusCode.Good;

if (Count > Ids.Length)
throw new Exception("Count cannot be larger than Ids");

if (results.Length < Count)
throw new Exception("Results cannot be less than count");

try
{
Expand All @@ -2171,8 +2193,8 @@ public StatusCode Write(WriteValue[] Ids, out uint[] results)
succeeded &= sendBuf.Encode(new NodeId(RequestCode.WriteRequest));
succeeded &= sendBuf.Encode(reqHeader);

succeeded &= sendBuf.Encode((UInt32)Ids.Length);
for (int i = 0; i < Ids.Length; i++)
succeeded &= sendBuf.Encode((UInt32)Count);
for (int i = 0; i < Count; i++)
{
succeeded &= sendBuf.Encode(Ids[i]);
}
Expand Down Expand Up @@ -2225,7 +2247,6 @@ public StatusCode Write(WriteValue[] Ids, out uint[] results)

succeeded &= recvHandler.RecvBuf.DecodeArraySize(out uint numRecv);

results = new uint[numRecv];
for (int i = 0; i < numRecv && succeeded; i++)
{
succeeded &= recvHandler.RecvBuf.Decode(out results[i]);
Expand All @@ -2236,7 +2257,7 @@ public StatusCode Write(WriteValue[] Ids, out uint[] results)
return StatusCode.BadDecodingError;
}

if (numRecv != Ids.Length)
if (numRecv != Count)
{
return StatusCode.GoodResultsMayBeIncomplete;
}
Expand All @@ -2250,6 +2271,12 @@ public StatusCode Write(WriteValue[] Ids, out uint[] results)
}
}

public StatusCode Write(WriteValue[] Ids, out uint[] results)
{
results = new uint[Ids.Length];
return Write(Ids, results, Ids.Length);
}

public StatusCode AddNodes(AddNodesItem[] addNodesItems, out AddNodesResult[] results)
{
results = null;
Expand Down
26 changes: 20 additions & 6 deletions NET Core/LibUA/MemoryBufferExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,9 +1174,11 @@ public static bool Encode(this MemoryBuffer mem, BrowseDescription bd)
return true;
}

public static bool Decode(this MemoryBuffer mem, out DataValue dv)
public static bool Decode(this MemoryBuffer mem, DataValue dv)
{
dv = null;
if (dv == null)
throw new Exception("Cannot decode empty dv");

object Value = null;
uint statusCode = 0;
Int64 sourceTimestamp = 0;
Expand Down Expand Up @@ -1210,10 +1212,10 @@ public static bool Decode(this MemoryBuffer mem, out DataValue dv)

try
{
dv = new DataValue(Value,
hasStatusCode ? (StatusCode?)statusCode : null,
hasSourceTimestamp ? (DateTime?)DateTime.FromFileTimeUtc(sourceTimestamp) : null,
hasServerTimestamp ? (DateTime?)DateTime.FromFileTimeUtc(serverTimestamp) : null);
dv.Value = Value;
dv.StatusCode = hasStatusCode ? statusCode : null;
dv.SourceTimestamp = hasSourceTimestamp ? DateTime.FromFileTimeUtc(sourceTimestamp) : null;
dv.ServerTimestamp = hasServerTimestamp ? DateTime.FromFileTimeUtc(serverTimestamp) : null;
}
catch
{
Expand All @@ -1223,6 +1225,18 @@ public static bool Decode(this MemoryBuffer mem, out DataValue dv)
return true;
}

public static bool Decode(this MemoryBuffer mem, out DataValue dv)
{
dv = new DataValue();
if (!mem.Decode(dv))
{
dv = null;
return false;
}
return true;

}

public static int CodingSize(this MemoryBuffer mem, DataValue dv)
{
int sum = 0;
Expand Down
7 changes: 4 additions & 3 deletions NET Core/LibUA/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5739,6 +5739,7 @@ public enum DataValueSpecifierMask

public struct QualifiedName
{

public ushort NamespaceIndex;

public string Name;
Expand Down Expand Up @@ -5961,9 +5962,9 @@ public TPayload Value

public class DataValue
{
public object Value { get; protected set; }
public uint? StatusCode { get; protected set; }
public DateTime? SourceTimestamp { get; protected set; }
public object Value { get; set; }
public uint? StatusCode { get; set; }
public DateTime? SourceTimestamp { get; set; }
public DateTime? ServerTimestamp { get; set; }

public DataValue(object Value = null, uint? StatusCode = null, DateTime? SourceTimestamp = null, DateTime? ServerTimestamp = null)
Expand Down

0 comments on commit da17f96

Please sign in to comment.