Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Typed DataWriter full CDR serialization #261

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 99 additions & 97 deletions Native/CSharpCDRImplTemplate.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions Native/CSharpJsonImplTemplate.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
{
return JsonSerializer.Deserialize(str, typeof(<%TYPE%>), _serializerContext) as <%TYPE%>;
}

public byte[] EncodeToBytes(<%TYPE%> sample)
{
throw new NotImplementedException();
}

public <%TYPE%> DecodeFromBytes(byte[] data)
{
throw new NotImplementedException();
}
#endregion
}

Expand Down
16 changes: 16 additions & 0 deletions Native/CWrapperHeaderTemplate.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,40 @@ EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_Write_Cdr(<%SCOPED%>DataWri

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_WriteWithTimestamp_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, int handle, ::DDS::Time_t time);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_WriteWithTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, int handle, const char* time_data, size_t time_size);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_RegisterInstance_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_RegisterInstance_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_RegisterInstanceTimestamp_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, ::DDS::Time_t time);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_RegisterInstanceTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, const char* time_data, size_t time_size);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_LookupInstance_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_LookupInstance_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_UnregisterInstance_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, ::DDS::InstanceHandle_t handle);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_UnregisterInstance_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, ::DDS::InstanceHandle_t handle);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_UnregisterInstanceTimestamp_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, ::DDS::InstanceHandle_t handle, ::DDS::Time_t time);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_UnregisterInstanceTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, ::DDS::InstanceHandle_t handle, const char* time_data, size_t time_size);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_Dispose_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, int handle);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_Dispose_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, int handle);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_DisposeTimestamp_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, int handle, ::DDS::Time_t time);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_DisposeTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, int handle, const char* time_data, size_t time_size);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_GetKeyValue_Json(<%SCOPED%>DataWriter_ptr dw, char* & json_data, int handle);

EXTERN_METHOD_EXPORT int <%SCOPED_METHOD%>DataWriter_GetKeyValue_Cdr(<%SCOPED%>DataWriter_ptr dw, char* & cdr_data, size_t & size, int handle);

/////////////////////////////////////////////////
// <%TYPE%> DataReader Methods
/////////////////////////////////////////////////
Expand Down
68 changes: 68 additions & 0 deletions Native/CWrapperImplTemplate.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ int <%SCOPED_METHOD%>DataWriter_WriteWithTimestamp_Json(<%SCOPED%>DataWriter_ptr
return dw->write_w_timestamp(sample, handle, time);
}

int <%SCOPED_METHOD%>DataWriter_WriteWithTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, int handle, const char* time_data, size_t time_size)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);
::DDS::Time_t time = marshal::dds_time_deserialize_from_bytes(time_data, time_size);

return dw->write_w_timestamp(sample, handle, time);
}

int <%SCOPED_METHOD%>DataWriter_RegisterInstance_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data)
{
<%SCOPED%>_var samplev = <%SCOPED_METHOD%>_DecodeJsonSample(json_data);
Expand Down Expand Up @@ -90,6 +98,14 @@ int <%SCOPED_METHOD%>DataWriter_RegisterInstanceTimestamp_Json(<%SCOPED%>DataWri
return dw->register_instance_w_timestamp(sample, time);
}

int <%SCOPED_METHOD%>DataWriter_RegisterInstanceTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, const char* time_data, size_t time_size)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);
::DDS::Time_t time = marshal::dds_time_deserialize_from_bytes(time_data, time_size);

return dw->register_instance_w_timestamp(sample, time);
}

int <%SCOPED_METHOD%>DataWriter_UnregisterInstance_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, ::DDS::InstanceHandle_t handle)
{
<%SCOPED%>_var samplev = <%SCOPED_METHOD%>_DecodeJsonSample(json_data);
Expand All @@ -102,6 +118,13 @@ int <%SCOPED_METHOD%>DataWriter_UnregisterInstance_Json(<%SCOPED%>DataWriter_ptr
return dw->unregister_instance(sample, handle);
}

int <%SCOPED_METHOD%>DataWriter_UnregisterInstance_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, ::DDS::InstanceHandle_t handle)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);

return dw->unregister_instance(sample, handle);
}

int <%SCOPED_METHOD%>DataWriter_UnregisterInstanceTimestamp_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, ::DDS::InstanceHandle_t handle, ::DDS::Time_t time)
{
<%SCOPED%>_var samplev = <%SCOPED_METHOD%>_DecodeJsonSample(json_data);
Expand All @@ -114,6 +137,14 @@ int <%SCOPED_METHOD%>DataWriter_UnregisterInstanceTimestamp_Json(<%SCOPED%>DataW
return dw->unregister_instance_w_timestamp(sample, handle, time);
}

int <%SCOPED_METHOD%>DataWriter_UnregisterInstanceTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, ::DDS::InstanceHandle_t handle, const char* time_data, size_t time_size)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);
::DDS::Time_t time = marshal::dds_time_deserialize_from_bytes(time_data, time_size);

return dw->unregister_instance_w_timestamp(sample, handle, time);
}

int <%SCOPED_METHOD%>DataWriter_LookupInstance_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data)
{
<%SCOPED%>_var samplev = <%SCOPED_METHOD%>_DecodeJsonSample(json_data);
Expand All @@ -126,6 +157,13 @@ int <%SCOPED_METHOD%>DataWriter_LookupInstance_Json(<%SCOPED%>DataWriter_ptr dw,
return dw->lookup_instance(sample);
}

int <%SCOPED_METHOD%>DataWriter_LookupInstance_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);

return dw->lookup_instance(sample);
}

int <%SCOPED_METHOD%>DataWriter_Dispose_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, int handle)
{
<%SCOPED%>_var samplev = <%SCOPED_METHOD%>_DecodeJsonSample(json_data);
Expand All @@ -138,6 +176,13 @@ int <%SCOPED_METHOD%>DataWriter_Dispose_Json(<%SCOPED%>DataWriter_ptr dw, const
return dw->dispose(sample, handle);
}

int <%SCOPED_METHOD%>DataWriter_Dispose_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, int handle)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);

return dw->dispose(sample, handle);
}

int <%SCOPED_METHOD%>DataWriter_DisposeTimestamp_Json(<%SCOPED%>DataWriter_ptr dw, const char* json_data, int handle, ::DDS::Time_t time)
{
<%SCOPED%>_var samplev = <%SCOPED_METHOD%>_DecodeJsonSample(json_data);
Expand All @@ -150,6 +195,14 @@ int <%SCOPED_METHOD%>DataWriter_DisposeTimestamp_Json(<%SCOPED%>DataWriter_ptr d
return dw->dispose_w_timestamp(sample, handle, time);
}

int <%SCOPED_METHOD%>DataWriter_DisposeTimestamp_Cdr(<%SCOPED%>DataWriter_ptr dw, const char* cdr_data, size_t size, int handle, const char* time_data, size_t time_size)
{
<%SCOPED%> sample = <%SCOPED_METHOD%>_deserialize_from_bytes(cdr_data, size);
::DDS::Time_t time = marshal::dds_time_deserialize_from_bytes(time_data, time_size);

return dw->dispose_w_timestamp(sample, handle, time);
}

int <%SCOPED_METHOD%>DataWriter_GetKeyValue_Json(<%SCOPED%>DataWriter_ptr dw, char* & json_data, int handle)
{
<%SCOPED%> sample_key;
Expand All @@ -165,6 +218,21 @@ int <%SCOPED_METHOD%>DataWriter_GetKeyValue_Json(<%SCOPED%>DataWriter_ptr dw, ch
return ret;
}

int <%SCOPED_METHOD%>DataWriter_GetKeyValue_Cdr(<%SCOPED%>DataWriter_ptr dw, char* & cdr_data, size_t & size, int handle)
{
<%SCOPED%> sample_key;
::DDS::ReturnCode_t ret = dw->get_key_value(sample_key, handle);

if (ret == ::DDS::RETCODE_OK)
{
<%SCOPED%> sample;
<%SCOPED_METHOD%>_CopyKeys(&sample_key, &sample);
<%SCOPED_METHOD%>_serialize_to_bytes(sample, cdr_data, size);
}

return ret;
}

<%SCOPED%>DataReader_ptr <%SCOPED_METHOD%>DataReader_Narrow(DDS::DataReader_ptr dr)
{
return <%SCOPED%>DataReader::_narrow(dr);
Expand Down
20 changes: 19 additions & 1 deletion Native/marshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "ace/Basic_Types.h"
#include "tao/Unbounded_Value_Sequence_T.h"
#include "dds/DCPS/Serializer.h"
#include "dds/DdsDcpsCoreC.h"

class marshal {

Expand Down Expand Up @@ -498,14 +500,30 @@ class marshal {
static void *wchar_to_ptr(wchar_t wchar) {
const size_t size = sizeof(wchar_t);

// Alloc memory for the poninter
// Alloc memory for the pointer
void *ptr = ACE_OS::malloc(size);

// Copy the bytes in the pointer
ACE_OS::memcpy(ptr, &wchar, size);

return ptr;
}

static DDS::Time_t dds_time_deserialize_from_bytes(const char *bytes, size_t size) {
const OpenDDS::DCPS::Encoding encoding(OpenDDS::DCPS::Encoding::KIND_XCDR1, OpenDDS::DCPS::ENDIAN_LITTLE);
ACE_Message_Block mb(size);
mb.copy(bytes, size);
OpenDDS::DCPS::Serializer serializer(&mb, encoding);
DDS::Time_t time_value;
if (!(serializer >> time_value.sec)) {
throw std::runtime_error("Failed to deserialize DDS::Time_t seconds from bytes");
}

if (!(serializer >> time_value.nanosec)) {
throw std::runtime_error("Failed to deserialize DDS::Time_t nanoseconds from bytes");
}
return time_value;
}
};

#endif
6 changes: 3 additions & 3 deletions Sources/OpenDDSharp/DDS/DataWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
/// Allows access to the attached <see cref="DataWriterListener" />.
/// </summary>
/// <returns>The attached <see cref="DataWriterListener" />.</returns>
[Obsolete(nameof(GetListener) + " is deprecated, please use Listener property instead.")]

Check warning on line 133 in Sources/OpenDDSharp/DDS/DataWriter.cs

View workflow job for this annotation

GitHub Actions / build_macos_arm64

Do not forget to remove this deprecated code someday. (https://rules.sonarsource.com/csharp/RSPEC-1133)
[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Keep coherency with the setter method and DDS API.")]
public DataWriterListener GetListener()
{
Expand Down Expand Up @@ -174,7 +174,7 @@
/// <remarks>
/// <para>This operation is intended to be used only if the <see cref="DataWriter" /> has
/// configured <see cref="ReliabilityQosPolicyKind.ReliableReliabilityQos" />.
/// Otherwise the operation will return immediately with <see cref="ReturnCode.Ok" />.</para>
/// Otherwise, the operation will return immediately with <see cref="ReturnCode.Ok" />.</para>
/// <para>A return value of <see cref="ReturnCode.Ok" /> indicates that all the samples
/// written have been acknowledged by all reliable matched data readers; a return value of
/// <see cref="ReturnCode.Timeout" /> indicates that maxWait
Expand Down Expand Up @@ -256,7 +256,7 @@
/// <see cref="LivelinessQosPolicyKind.ManualByParticipantLivelinessQos" />
/// or <see cref="LivelinessQosPolicyKind.ManualByTopicLivelinessQos" />. Otherwise, it has no effect.</para>
/// <para>NOTE: Writing data via the write operation on a <see cref="DataWriter" /> asserts liveliness on
/// the <see cref="DataWriter" /> itself and its <see cref="DomainParticipant" />. Consequently the use of
/// the <see cref="DataWriter" /> itself and its <see cref="DomainParticipant" />. Consequently, the use of
/// AssertLiveliness is only needed if the application is not writing data regularly.</para>
/// </remarks>
/// <returns>The <see cref="ReturnCode" /> that indicates the operation result.</returns>
Expand Down Expand Up @@ -372,7 +372,7 @@
else
{
publisher = new Publisher(ptrPublisher);
EntityManager.Instance.Add((publisher as Entity).ToNative(), publisher);
EntityManager.Instance.Add(((Entity)publisher).ToNative(), publisher);
}
}

Expand Down
14 changes: 14 additions & 0 deletions Sources/OpenDDSharp/DDS/ITypeSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,18 @@ public interface ITypeSupport<T> : ITypeSupport
/// <param name="encoded">The sample JSON representation.</param>
/// <returns>The decoded sample.</returns>
T DecodeFromString(string encoded);

/// <summary>
/// Encodes a sample into a byte array using CDR format.
/// </summary>
/// <param name="sample">The sample to be encoded.</param>
/// <returns>The CDR sample representation.</returns>
byte[] EncodeToBytes(T sample);

/// <summary>
/// Decodes a CDR byte array into a sample.
/// </summary>
/// <param name="encoded">The sample CDR representation.</param>
/// <returns>The decoded sample.</returns>
T DecodeFromBytes(byte[] encoded);
}
4 changes: 2 additions & 2 deletions Sources/OpenDDSharp/Timestamp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public uint NanoSeconds
/// Converts the time value to a CDR representation.
/// </summary>
/// <returns>The byte span serialized.</returns>
internal ReadOnlySpan<byte> ToCDR()
public ReadOnlySpan<byte> ToCDR()
{
var writer = new Marshaller.Cdr.CdrWriter();
writer.WriteInt32(Seconds);
Expand All @@ -70,7 +70,7 @@ internal ReadOnlySpan<byte> ToCDR()
/// Updates the time value from a CDR representation.
/// </summary>
/// <param name="data">The byte span serialized.</param>
internal void FromCDR(ReadOnlySpan<byte> data)
public void FromCDR(ReadOnlySpan<byte> data)
{
var reader = new Marshaller.Cdr.CdrReader(data.ToArray());
Seconds = reader.ReadInt32();
Expand Down
Loading
Loading