Skip to content

Commit

Permalink
[feature] Typed DataWriter full CDR serialization (#261)
Browse files Browse the repository at this point in the history
* [feature] Typed DataWriter full CDR serialization

* Serialized Time_t
  • Loading branch information
jmmorato authored Oct 23, 2024
1 parent a030bd9 commit eadea97
Show file tree
Hide file tree
Showing 12 changed files with 1,533 additions and 110 deletions.
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 @@ -174,7 +174,7 @@ public ReturnCode SetListener(DataWriterListener listener, StatusMask mask)
/// <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 @@ public ReturnCode GetPublicationMatchedStatus(ref PublicationMatchedStatus statu
/// <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 @@ private Publisher GetPublisher()
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

0 comments on commit eadea97

Please sign in to comment.