diff --git a/src/dotnet/design/Mil/Navy/Nrl/Norm/NormApi.puml b/src/dotnet/design/Mil/Navy/Nrl/Norm/NormApi.puml
index c23811a..027ac46 100644
--- a/src/dotnet/design/Mil/Navy/Nrl/Norm/NormApi.puml
+++ b/src/dotnet/design/Mil/Navy/Nrl/Norm/NormApi.puml
@@ -60,7 +60,6 @@ class NormApi
+ {static} NormSetTxRobustFactor(sessionHandle:long, robustFactor:int) : void
+ {static} NormFileEnqueue(sessionHandle:long, fileName:string, infoPtr:string, infoLen:int): long
+ {static} NormDataEnqueue(sessionHandle:long, dataPtr:nint, dataLen:int, infoPtr:nint, infoLen:int) : long
- + {static} NormDataEnqueue(sessionHandle:long, data:byte[], dataLen:int, info:byte[], infoLen:int) : long
+ {static} NormRequeueObject(sessionHandle:long, objectHandle:long) : bool
+ {static} NormStreamOpen(sessionHandle:long, bufferSize:long, infoPtr:string, infoLen:int) : long
+ {static} NormStreamClose(streamHandle:long, graceful:bool) : void
diff --git a/src/dotnet/src/Mil.Navy.Nrl.Norm/NormApi.cs b/src/dotnet/src/Mil.Navy.Nrl.Norm/NormApi.cs
index 5e969e9..e5f56b8 100644
--- a/src/dotnet/src/Mil.Navy.Nrl.Norm/NormApi.cs
+++ b/src/dotnet/src/Mil.Navy.Nrl.Norm/NormApi.cs
@@ -544,41 +544,6 @@ public struct NormEvent
[DllImport(NORM_LIBRARY)]
public static extern long NormDataEnqueue(long sessionHandle, nint dataPtr, int dataLen, nint infoPtr, int infoLen);
- ///
- /// This function enqueues a segment of application memory space for transmission within the specified NORM sessionHandle.
- ///
- /// Used to identify application in the NormSession.
- /// The data parameter must be a managed buffer to be transmitted.
- /// The dataLen parameter indicates the quantity of data to transmit.
- /// The optional info and infoLen parameters
- /// are used to associate NORM_INFO content with the sent transport object. The maximum allowed infoLen
- /// corresponds to the segmentSize used in the prior call to NormStartSender(). The use and interpretation of the
- /// NORM_INFO content is left to the application's discretion.
- /// The optional info and infoLen parameters
- /// are used to associate NORM_INFO content with the sent transport object. The maximum allowed infoLen
- /// corresponds to the segmentSize used in the prior call to NormStartSender(). The use and interpretation of the
- /// NORM_INFO content is left to the application's discretion
- /// A NormObjectHandle is returned which the application may use in other NORM API calls as needed.
- public static long NormDataEnqueue(long sessionHandle, byte[] data, int dataLen, byte[]? info, int infoLen)
- {
- long objectHandle;
- var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
- var infoHandle = GCHandle.Alloc(info, GCHandleType.Pinned);
-
- try
- {
- var dataPtr = dataHandle.AddrOfPinnedObject();
- var infoPtr = infoHandle.AddrOfPinnedObject();
- objectHandle = NormDataEnqueue(sessionHandle, dataPtr, dataLen, infoPtr, infoLen);
- }
- finally
- {
- dataHandle.Free();
- infoHandle.Free();
- }
- return objectHandle;
- }
-
///
/// This function allows the application to resend (or reset transmission of) a NORM_OBJECT_FILE or NORM_OBJECT_DATA
/// transmit object that was previously enqueued for the indicated sessionHandle.
diff --git a/src/dotnet/src/Mil.Navy.Nrl.Norm/NormSession.cs b/src/dotnet/src/Mil.Navy.Nrl.Norm/NormSession.cs
index f4b9177..b7a318b 100644
--- a/src/dotnet/src/Mil.Navy.Nrl.Norm/NormSession.cs
+++ b/src/dotnet/src/Mil.Navy.Nrl.Norm/NormSession.cs
@@ -1,4 +1,5 @@
-using System.Text;
+using System.Runtime.InteropServices;
+using System.Text;
namespace Mil.Navy.Nrl.Norm
{
@@ -497,6 +498,7 @@ public NormFile FileEnqueue(string filename, byte[] info, int infoOffset, int in
/// Size of the message.
/// A NormData is returned which the application may use in other NORM API calls as needed.
/// Thrown when NormDataEnqueue() returns NORM_OBJECT_INVALID, indicating the failure to enqueue data.
+ /// Thrown when the data offset or data length are outside of the data buffer.
public NormData DataEnqueue(byte[] dataBuffer, int dataOffset, int dataLength)
{
return DataEnqueue(dataBuffer, dataOffset, dataLength, null, 0, 0);
@@ -514,24 +516,46 @@ public NormData DataEnqueue(byte[] dataBuffer, int dataOffset, int dataLength)
/// The optional info and infoLength parameters are used to associate NORM_INFO content with the sent transport object.
/// A NormData is returned which the application may use in other NORM API calls as needed.
/// Thrown when NormDataEnqueue() returns NORM_OBJECT_INVALID, indicating the failure to enqueue data.
+ /// Thrown when the data offset, data length, info offset or info length are outside of the associated buffer.
public NormData DataEnqueue(byte[] dataBuffer, int dataOffset, int dataLength, byte[]? info, int infoOffset, int infoLength)
{
- var dataBytes = dataBuffer.Skip(dataOffset).Take(dataLength).ToArray();
- byte[]? infoBytes;
- if (info != null)
+ if (dataOffset < 0 || dataOffset >= dataBuffer.Length)
{
- infoBytes = info.Skip(infoOffset).Take(infoLength).ToArray();
- }
- else
+ throw new ArgumentOutOfRangeException(nameof(dataOffset), "The data offset is out of range");
+ }
+ if (dataOffset + dataLength > dataBuffer.Length)
{
- infoBytes = null;
- infoLength = 0;
+ throw new ArgumentOutOfRangeException(nameof(dataLength), "The data length is out of range");
}
- var objectHandle = NormDataEnqueue(_handle, dataBytes, dataLength, infoBytes, infoLength);
- if (objectHandle == NormObject.NORM_OBJECT_INVALID)
+ if (infoOffset < 0 || infoOffset >= info?.Length)
{
- throw new IOException("Failed to enqueue data");
+ throw new ArgumentOutOfRangeException(nameof(infoOffset), "The info offset is out of range");
}
+ if (infoOffset + infoLength > info?.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(infoLength), "The info length is out of range");
+ }
+
+ long objectHandle;
+ var dataHandle = GCHandle.Alloc(dataBuffer, GCHandleType.Pinned);
+ var infoHandle = GCHandle.Alloc(info, GCHandleType.Pinned);
+
+ try
+ {
+ var dataPtr = dataHandle.AddrOfPinnedObject() + dataOffset;
+ var infoPtr = infoHandle.AddrOfPinnedObject() + infoOffset;
+ objectHandle = NormDataEnqueue(_handle, dataPtr, dataLength, infoPtr, infoLength);
+ if (objectHandle == NormObject.NORM_OBJECT_INVALID)
+ {
+ throw new IOException("Failed to enqueue data");
+ }
+ }
+ finally
+ {
+ dataHandle.Free();
+ infoHandle.Free();
+ }
+
return new NormData(objectHandle);
}
diff --git a/src/dotnet/tests/Mil.Navy.Nrl.Norm.IntegrationTests/NormSessionTests.cs b/src/dotnet/tests/Mil.Navy.Nrl.Norm.IntegrationTests/NormSessionTests.cs
index 1470c07..a478299 100644
--- a/src/dotnet/tests/Mil.Navy.Nrl.Norm.IntegrationTests/NormSessionTests.cs
+++ b/src/dotnet/tests/Mil.Navy.Nrl.Norm.IntegrationTests/NormSessionTests.cs
@@ -186,12 +186,22 @@ public void StopsReceiver()
/// Generates text content
///
/// The generated text content
- private string GenerateTextContent()
+ private static string GenerateTextContent()
{
var faker = new Faker();
return faker.Lorem.Paragraph();
}
+ ///
+ /// Generates info content
+ ///
+ /// The generated info content
+ private static string GenerateInfoContent()
+ {
+ var faker = new Faker();
+ return faker.Lorem.Sentence();
+ }
+
private IEnumerable GetEvents(TimeSpan delayTime)
{
var normEvents = new List();
@@ -398,24 +408,85 @@ public void ReceivesFileWithRename()
}
}
- [SkippableFact(typeof(IOException))]
- public void EnqueuesData()
+ public static IEnumerable