validate and normalize received CDR data
The CDR deserializer failed to check it was staying within the bounds of the received data, and it turns out it also was inconsistent in its interpretation of the (undocumented) serializer instructions. This commit adds some information on the instruction format obtained by reverse engineering the code and studying the output of the IDL preprocessor, and furthermore changes a lot of the types used in the (de)serializer code to have some more compiler support. The IDL preprocessor is untouched and the generated instructinos do exactly the same thing (except where change was needed). The bulk of this commit replaces the implementation of the (de)serializer. It is still rather ugly, but at least the very long functions with several levels of nested conditions and switch statements have been split out into multiple functions. Most of these have single call-sites, so the compiler hopefully inlines them nicely. The other important thing is that it adds a "normalize" function that validates the structure of the CDR and performs byteswapping if necessary. This means the deserializer can now assume a well-formed input in native byte-order. Checks and conditional byteswaps have been removed accordingly. It changes some types to make a compile-time distinction between read-only, native-endianness input, a native-endianness output, and a big-endian output for dealing with key hashes. This should reduce the risk of accidentally mixing endianness or modifying an input stream. The preprocessor has been modified to indicate the presence of unions in a topic type in the descriptor flags. If a union is present, any memory allocated in a sample is freed first and the sample is zero'd out prior to deserializing the new value. This is to prevent reading garbage pointers for strings and sequences when switching union cases. The test tool has been included in the commit but it does not get run by itself. Firstly, it requires the presence of OpenSplice DDS as an alternative implementation to check the CDR processing against. Secondly, it takes quite a while to run and is of no interest unless one changes something in the (de)serialization. Finally, I have no idea why there was a "CDR stream" interface among the public functions. The existing interfaces are fundamentally broken by the removal of arbitrary-endianness streams, and the interfaces were already incapable of proper error notification. So, they have been removed. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
d91e7b34c9
commit
3067a69c92
25 changed files with 2315 additions and 1941 deletions
|
@ -24,7 +24,6 @@ PREPEND(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
|
|||
dds_qos.c
|
||||
dds_handles.c
|
||||
dds_entity.c
|
||||
dds_key.c
|
||||
dds_querycond.c
|
||||
dds_topic.c
|
||||
dds_listener.c
|
||||
|
@ -48,7 +47,6 @@ PREPEND(hdrs_public_ddsc "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/dd
|
|||
ddsc/dds_public_listener.h
|
||||
ddsc/dds_public_qos.h
|
||||
ddsc/dds_public_status.h
|
||||
ddsc/dds_public_stream.h
|
||||
)
|
||||
|
||||
PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
|
@ -58,7 +56,6 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
|
|||
dds__handles.h
|
||||
dds__entity.h
|
||||
dds__init.h
|
||||
dds__key.h
|
||||
dds__listener.h
|
||||
dds__participant.h
|
||||
dds__publisher.h
|
||||
|
|
|
@ -45,7 +45,6 @@ typedef int32_t dds_entity_t;
|
|||
#include "dds/ddsrt/time.h"
|
||||
#include "dds/ddsrt/retcode.h"
|
||||
#include "dds/ddsrt/log.h"
|
||||
#include "dds/ddsc/dds_public_stream.h"
|
||||
#include "dds/ddsc/dds_public_impl.h"
|
||||
#include "dds/ddsc/dds_public_alloc.h"
|
||||
#include "dds/ddsc/dds_public_qos.h"
|
||||
|
|
|
@ -21,9 +21,10 @@
|
|||
#ifndef DDS_IMPL_H
|
||||
#define DDS_IMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "dds/export.h"
|
||||
#include "dds/ddsc/dds_public_alloc.h"
|
||||
#include "dds/ddsc/dds_public_stream.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
|
@ -71,6 +72,7 @@ dds_topic_descriptor_t;
|
|||
|
||||
#define DDS_TOPIC_NO_OPTIMIZE 0x0001
|
||||
#define DDS_TOPIC_FIXED_KEY 0x0002
|
||||
#define DDS_TOPIC_CONTAINS_UNION 0x0004
|
||||
|
||||
/*
|
||||
Masks for read condition, read, take: there is only one mask here,
|
||||
|
@ -119,89 +121,119 @@ typedef int32_t dds_domainid_t;
|
|||
|
||||
/* Topic encoding instruction types */
|
||||
|
||||
#define DDS_OP_RTS 0x00000000
|
||||
#define DDS_OP_ADR 0x01000000
|
||||
#define DDS_OP_JSR 0x02000000
|
||||
#define DDS_OP_JEQ 0x03000000
|
||||
enum dds_stream_opcode {
|
||||
/* return from subroutine, exits top-level
|
||||
[RTS, 0, 0, 0] */
|
||||
DDS_OP_RTS = 0x00 << 24,
|
||||
/* data field
|
||||
[ADR, nBY, 0, k] [offset]
|
||||
[ADR, STR, 0, k] [offset]
|
||||
[ADR, BST, 0, k] [offset] [bound]
|
||||
[ADR, SEQ, nBY, 0] [offset]
|
||||
[ADR, SEQ, STR, 0] [offset]
|
||||
[ADR, SEQ, BST, 0] [offset] [bound]
|
||||
[ADR, SEQ, s, 0] [offset] [elem-size] [next-insn, elem-insn]
|
||||
where s = {SEQ,ARR,UNI,STU}
|
||||
[ADR, ARR, nBY, k] [offset] [alen]
|
||||
[ADR, ARR, STR, 0] [offset] [alen]
|
||||
[ADR, ARR, BST, 0] [offset] [alen] [0] [bound]
|
||||
[ADR, ARR, s, 0] [offset] [alen] [next-insn, elem-insn] [elem-size]
|
||||
where s = {SEQ,ARR,UNI,STU}
|
||||
[ADR, UNI, d, z] [offset] [alen] [next-insn, cases]
|
||||
where
|
||||
d = discriminant type of {1BY,2BY,4BY}
|
||||
z = default present/not present (DDS_OP_FLAG_DEF)
|
||||
offset = discriminant offset
|
||||
followed by alen case labels: in JEQ format
|
||||
note: [ADR, STU, ...] is illegal
|
||||
where
|
||||
s = subtype
|
||||
k = key/not key (DDS_OP_FLAG_KEY)
|
||||
[offset] = field offset from start of element in memory
|
||||
[elem-size] = element size in memory
|
||||
[bound] = string bound + 1
|
||||
[alen] = array length, number of cases
|
||||
[next-insn] = (unsigned 16 bits) offset to instruction for next field, from start of insn
|
||||
[elem-insn] = (unsigned 16 bits) offset to first instruction for element, from start of insn
|
||||
[cases] = (unsigned 16 bits) offset to first case label, from start of insn
|
||||
*/
|
||||
DDS_OP_ADR = 0x01 << 24,
|
||||
/* jump-to-subroutine (apparently not used at the moment)
|
||||
[JSR, 0, e]
|
||||
where
|
||||
e = (signed 16 bits) offset to first instruction in subroutine, from start of insn
|
||||
instruction sequence must end in RTS, execution resumes at instruction
|
||||
following JSR */
|
||||
DDS_OP_JSR = 0x02 << 24,
|
||||
/* union case
|
||||
[JEQ, nBY, 0] [disc] [offset]
|
||||
[JEQ, STR, 0] [disc] [offset]
|
||||
[JEQ, s, e] [disc] [offset]
|
||||
where
|
||||
s = subtype other than {nBY,STR}
|
||||
e = (unsigned 16 bits) offset to first instruction for case, from start of insn
|
||||
instruction sequence must end in RTS, at which point executes continues
|
||||
at the next field's instruction as specified by the union */
|
||||
DDS_OP_JEQ = 0x03 << 24
|
||||
};
|
||||
|
||||
/* Core type flags
|
||||
|
||||
1BY : One byte simple type
|
||||
2BY : Two byte simple type
|
||||
4BY : Four byte simple type
|
||||
8BY : Eight byte simple type
|
||||
STR : String
|
||||
BST : Bounded string
|
||||
SEQ : Sequence
|
||||
ARR : Array
|
||||
UNI : Union
|
||||
STU : Struct
|
||||
*/
|
||||
|
||||
#define DDS_OP_VAL_1BY 0x01
|
||||
#define DDS_OP_VAL_2BY 0x02
|
||||
#define DDS_OP_VAL_4BY 0x03
|
||||
#define DDS_OP_VAL_8BY 0x04
|
||||
#define DDS_OP_VAL_STR 0x05
|
||||
#define DDS_OP_VAL_BST 0x06
|
||||
#define DDS_OP_VAL_SEQ 0x07
|
||||
#define DDS_OP_VAL_ARR 0x08
|
||||
#define DDS_OP_VAL_UNI 0x09
|
||||
#define DDS_OP_VAL_STU 0x0a
|
||||
|
||||
#define DDS_OP_TYPE_1BY (DDS_OP_VAL_1BY << 16)
|
||||
#define DDS_OP_TYPE_2BY (DDS_OP_VAL_2BY << 16)
|
||||
#define DDS_OP_TYPE_4BY (DDS_OP_VAL_4BY << 16)
|
||||
#define DDS_OP_TYPE_8BY (DDS_OP_VAL_8BY << 16)
|
||||
#define DDS_OP_TYPE_STR (DDS_OP_VAL_STR << 16)
|
||||
#define DDS_OP_TYPE_SEQ (DDS_OP_VAL_SEQ << 16)
|
||||
#define DDS_OP_TYPE_ARR (DDS_OP_VAL_ARR << 16)
|
||||
#define DDS_OP_TYPE_UNI (DDS_OP_VAL_UNI << 16)
|
||||
#define DDS_OP_TYPE_STU (DDS_OP_VAL_STU << 16)
|
||||
#define DDS_OP_TYPE_BST (DDS_OP_VAL_BST << 16)
|
||||
enum dds_stream_typecode {
|
||||
DDS_OP_VAL_1BY = 0x01, /* one byte simple type (char, octet, boolean) */
|
||||
DDS_OP_VAL_2BY = 0x02, /* two byte simple type ((unsigned) short) */
|
||||
DDS_OP_VAL_4BY = 0x03, /* four byte simple type ((unsigned) long, enums, float) */
|
||||
DDS_OP_VAL_8BY = 0x04, /* eight byte simple type ((unsigned) long long, double) */
|
||||
DDS_OP_VAL_STR = 0x05, /* string */
|
||||
DDS_OP_VAL_BST = 0x06, /* bounded string */
|
||||
DDS_OP_VAL_SEQ = 0x07, /* sequence */
|
||||
DDS_OP_VAL_ARR = 0x08, /* array */
|
||||
DDS_OP_VAL_UNI = 0x09, /* union */
|
||||
DDS_OP_VAL_STU = 0x0a /* struct */
|
||||
};
|
||||
|
||||
/* primary type code for DDS_OP_ADR, DDS_OP_JEQ */
|
||||
enum dds_stream_typecode_primary {
|
||||
DDS_OP_TYPE_1BY = DDS_OP_VAL_1BY << 16,
|
||||
DDS_OP_TYPE_2BY = DDS_OP_VAL_2BY << 16,
|
||||
DDS_OP_TYPE_4BY = DDS_OP_VAL_4BY << 16,
|
||||
DDS_OP_TYPE_8BY = DDS_OP_VAL_8BY << 16,
|
||||
DDS_OP_TYPE_STR = DDS_OP_VAL_STR << 16,
|
||||
DDS_OP_TYPE_BST = DDS_OP_VAL_BST << 16,
|
||||
DDS_OP_TYPE_SEQ = DDS_OP_VAL_SEQ << 16,
|
||||
DDS_OP_TYPE_ARR = DDS_OP_VAL_ARR << 16,
|
||||
DDS_OP_TYPE_UNI = DDS_OP_VAL_UNI << 16,
|
||||
DDS_OP_TYPE_STU = DDS_OP_VAL_STU << 16
|
||||
};
|
||||
#define DDS_OP_TYPE_BOO DDS_OP_TYPE_1BY
|
||||
|
||||
/* sub-type code:
|
||||
- encodes element type for DDS_OP_TYPE_{SEQ,ARR},
|
||||
- discriminant type for DDS_OP_TYPE_UNI */
|
||||
enum dds_stream_typecode_subtype {
|
||||
DDS_OP_SUBTYPE_1BY = DDS_OP_VAL_1BY << 8,
|
||||
DDS_OP_SUBTYPE_2BY = DDS_OP_VAL_2BY << 8,
|
||||
DDS_OP_SUBTYPE_4BY = DDS_OP_VAL_4BY << 8,
|
||||
DDS_OP_SUBTYPE_8BY = DDS_OP_VAL_8BY << 8,
|
||||
DDS_OP_SUBTYPE_STR = DDS_OP_VAL_STR << 8,
|
||||
DDS_OP_SUBTYPE_BST = DDS_OP_VAL_BST << 8,
|
||||
DDS_OP_SUBTYPE_SEQ = DDS_OP_VAL_SEQ << 8,
|
||||
DDS_OP_SUBTYPE_ARR = DDS_OP_VAL_ARR << 8,
|
||||
DDS_OP_SUBTYPE_UNI = DDS_OP_VAL_UNI << 8,
|
||||
DDS_OP_SUBTYPE_STU = DDS_OP_VAL_STU << 8
|
||||
};
|
||||
#define DDS_OP_SUBTYPE_BOO DDS_OP_SUBTYPE_1BY
|
||||
|
||||
#define DDS_OP_SUBTYPE_1BY (DDS_OP_VAL_1BY << 8)
|
||||
#define DDS_OP_SUBTYPE_2BY (DDS_OP_VAL_2BY << 8)
|
||||
#define DDS_OP_SUBTYPE_4BY (DDS_OP_VAL_4BY << 8)
|
||||
#define DDS_OP_SUBTYPE_8BY (DDS_OP_VAL_8BY << 8)
|
||||
#define DDS_OP_SUBTYPE_STR (DDS_OP_VAL_STR << 8)
|
||||
#define DDS_OP_SUBTYPE_SEQ (DDS_OP_VAL_SEQ << 8)
|
||||
#define DDS_OP_SUBTYPE_ARR (DDS_OP_VAL_ARR << 8)
|
||||
#define DDS_OP_SUBTYPE_UNI (DDS_OP_VAL_UNI << 8)
|
||||
#define DDS_OP_SUBTYPE_STU (DDS_OP_VAL_STU << 8)
|
||||
#define DDS_OP_SUBTYPE_BST (DDS_OP_VAL_BST << 8)
|
||||
|
||||
#define DDS_OP_FLAG_KEY 0x01
|
||||
#define DDS_OP_FLAG_DEF 0x02
|
||||
#define DDS_OP_FLAG_KEY 0x01 /* key field: applicable to {1,2,4,8}BY, STR, BST, ARR-of-{1,2,4,8}BY */
|
||||
#define DDS_OP_FLAG_DEF 0x02 /* union has a default case (for DDS_OP_ADR | DDS_OP_TYPE_UNI) */
|
||||
|
||||
/**
|
||||
* Description : Enable or disable write batching. Overrides default configuration
|
||||
* setting for write batching (DDSI2E/Internal/WriteBatch).
|
||||
* setting for write batching (Internal/WriteBatch).
|
||||
*
|
||||
* Arguments :
|
||||
* -# enable Enables or disables write batching for all writers.
|
||||
*/
|
||||
DDS_EXPORT void dds_write_set_batch (bool enable);
|
||||
|
||||
/**
|
||||
* Description : Install tcp/ssl and encryption support. Depends on openssl.
|
||||
*
|
||||
* Arguments :
|
||||
* -# None
|
||||
*/
|
||||
DDS_EXPORT void dds_ssl_plugin (void);
|
||||
|
||||
/**
|
||||
* Description : Install client durability support. Depends on OSPL server.
|
||||
*
|
||||
* Arguments :
|
||||
* -# None
|
||||
*/
|
||||
DDS_EXPORT void dds_durability_plugin (void);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Stream API
|
||||
*
|
||||
* This header file defines the public API of the Streams in the
|
||||
* Eclipse Cyclone DDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_STREAM_H
|
||||
#define DDS_STREAM_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dds/export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dds_sequence;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t * p8;
|
||||
uint16_t * p16;
|
||||
uint32_t * p32;
|
||||
uint64_t * p64;
|
||||
float * pf;
|
||||
double * pd;
|
||||
void * pv;
|
||||
}
|
||||
dds_uptr_t;
|
||||
|
||||
typedef struct dds_stream
|
||||
{
|
||||
dds_uptr_t m_buffer; /* Union of pointers to start of buffer */
|
||||
uint32_t m_size; /* Buffer size */
|
||||
uint32_t m_index; /* Read/write offset from start of buffer */
|
||||
bool m_endian; /* Endian: big (false) or little (true) */
|
||||
bool m_failed; /* Attempt made to read beyond end of buffer */
|
||||
}
|
||||
dds_stream_t;
|
||||
|
||||
#define DDS_STREAM_BE false
|
||||
#define DDS_STREAM_LE true
|
||||
|
||||
DDS_EXPORT dds_stream_t * dds_stream_create (uint32_t size);
|
||||
DDS_EXPORT dds_stream_t * dds_stream_from_buffer (const void *buf, size_t sz, int bswap);
|
||||
DDS_EXPORT void dds_stream_delete (dds_stream_t * st);
|
||||
DDS_EXPORT void dds_stream_fini (dds_stream_t * st);
|
||||
DDS_EXPORT void dds_stream_reset (dds_stream_t * st);
|
||||
DDS_EXPORT void dds_stream_init (dds_stream_t * st, uint32_t size);
|
||||
DDS_EXPORT void dds_stream_grow (dds_stream_t * st, uint32_t size);
|
||||
DDS_EXPORT bool dds_stream_endian (void);
|
||||
|
||||
struct dds_topic_descriptor;
|
||||
DDS_EXPORT void dds_stream_read_sample_w_desc (dds_stream_t * is, void * data, const struct dds_topic_descriptor * desc);
|
||||
DDS_EXPORT bool dds_stream_read_bool (dds_stream_t * is);
|
||||
DDS_EXPORT uint8_t dds_stream_read_uint8 (dds_stream_t * is);
|
||||
DDS_EXPORT uint16_t dds_stream_read_uint16 (dds_stream_t * is);
|
||||
DDS_EXPORT uint32_t dds_stream_read_uint32 (dds_stream_t * is);
|
||||
DDS_EXPORT uint64_t dds_stream_read_uint64 (dds_stream_t * is);
|
||||
DDS_EXPORT float dds_stream_read_float (dds_stream_t * is);
|
||||
DDS_EXPORT double dds_stream_read_double (dds_stream_t * is);
|
||||
DDS_EXPORT char * dds_stream_read_string (dds_stream_t * is);
|
||||
DDS_EXPORT void dds_stream_read_buffer (dds_stream_t * is, uint8_t * buffer, uint32_t len);
|
||||
|
||||
inline char dds_stream_read_char (dds_stream_t *is) { return (char) dds_stream_read_uint8 (is); }
|
||||
inline int8_t dds_stream_read_int8 (dds_stream_t *is) { return (int8_t) dds_stream_read_uint8 (is); }
|
||||
inline int16_t dds_stream_read_int16 (dds_stream_t *is) { return (int16_t) dds_stream_read_uint16 (is); }
|
||||
inline int32_t dds_stream_read_int32 (dds_stream_t *is) { return (int32_t) dds_stream_read_uint32 (is); }
|
||||
inline int64_t dds_stream_read_int64 (dds_stream_t *is) { return (int64_t) dds_stream_read_uint64 (is); }
|
||||
|
||||
DDS_EXPORT void dds_stream_write_bool (dds_stream_t * os, bool val);
|
||||
DDS_EXPORT void dds_stream_write_uint8 (dds_stream_t * os, uint8_t val);
|
||||
DDS_EXPORT void dds_stream_write_uint16 (dds_stream_t * os, uint16_t val);
|
||||
DDS_EXPORT void dds_stream_write_uint32 (dds_stream_t * os, uint32_t val);
|
||||
DDS_EXPORT void dds_stream_write_uint64 (dds_stream_t * os, uint64_t val);
|
||||
DDS_EXPORT void dds_stream_write_float (dds_stream_t * os, float val);
|
||||
DDS_EXPORT void dds_stream_write_double (dds_stream_t * os, double val);
|
||||
DDS_EXPORT void dds_stream_write_string (dds_stream_t * os, const char * val);
|
||||
DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, const uint8_t * buffer);
|
||||
DDS_EXPORT void *dds_stream_address (dds_stream_t * s);
|
||||
DDS_EXPORT void *dds_stream_alignto (dds_stream_t * s, uint32_t a);
|
||||
|
||||
inline void dds_stream_write_char (dds_stream_t * os, char val) { dds_stream_write_uint8 (os, (uint8_t) val); }
|
||||
inline void dds_stream_write_int8 (dds_stream_t * os, int8_t val) { dds_stream_write_uint8 (os, (uint8_t) val); }
|
||||
inline void dds_stream_write_int16 (dds_stream_t * os, int16_t val) { dds_stream_write_uint16 (os, (uint16_t) val); }
|
||||
inline void dds_stream_write_int32 (dds_stream_t * os, int32_t val) { dds_stream_write_uint32 (os, (uint32_t) val); }
|
||||
inline void dds_stream_write_int64 (dds_stream_t * os, int64_t val) { dds_stream_write_uint64 (os, (uint64_t) val); }
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef _DDS_KEY_H_
|
||||
#define _DDS_KEY_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
struct dds_key_hash;
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dds_key_md5 (struct dds_key_hash * kh);
|
||||
|
||||
void dds_key_gen
|
||||
(
|
||||
const dds_topic_descriptor_t * const desc,
|
||||
struct dds_key_hash * kh,
|
||||
const char * sample
|
||||
);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -19,47 +19,46 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dds_stream_write_sample
|
||||
(
|
||||
dds_stream_t * os,
|
||||
const void * data,
|
||||
const struct ddsi_sertopic_default * topic
|
||||
);
|
||||
void dds_stream_read_sample
|
||||
(
|
||||
dds_stream_t * is,
|
||||
void * data,
|
||||
const struct ddsi_sertopic_default * topic
|
||||
);
|
||||
typedef struct dds_istream {
|
||||
const unsigned char *m_buffer;
|
||||
uint32_t m_size; /* Buffer size */
|
||||
uint32_t m_index; /* Read/write offset from start of buffer */
|
||||
} dds_istream_t;
|
||||
|
||||
size_t dds_stream_check_optimize (const dds_topic_descriptor_t * desc);
|
||||
void dds_stream_from_serdata_default (dds_stream_t * s, const struct ddsi_serdata_default *d);
|
||||
void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d);
|
||||
typedef struct dds_ostream {
|
||||
unsigned char *m_buffer;
|
||||
uint32_t m_size; /* Buffer size */
|
||||
uint32_t m_index; /* Read/write offset from start of buffer */
|
||||
} dds_ostream_t;
|
||||
|
||||
void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic);
|
||||
uint32_t dds_stream_extract_key (dds_stream_t *is, dds_stream_t *os, const uint32_t *ops, const bool just_key);
|
||||
void dds_stream_read_key
|
||||
(
|
||||
dds_stream_t * is,
|
||||
char * sample,
|
||||
const dds_topic_descriptor_t * desc
|
||||
);
|
||||
void dds_stream_read_keyhash
|
||||
(
|
||||
dds_stream_t * is,
|
||||
dds_key_hash_t * kh,
|
||||
const dds_topic_descriptor_t * desc,
|
||||
const bool just_key
|
||||
);
|
||||
char * dds_stream_reuse_string
|
||||
(
|
||||
dds_stream_t * is,
|
||||
char * str,
|
||||
const uint32_t bound
|
||||
);
|
||||
DDS_EXPORT void dds_stream_swap (void * buff, uint32_t size, uint32_t num);
|
||||
typedef struct dds_ostreamBE {
|
||||
dds_ostream_t x;
|
||||
} dds_ostreamBE_t;
|
||||
|
||||
extern const uint32_t dds_op_size[5];
|
||||
DDS_EXPORT void dds_ostream_init (dds_ostream_t * __restrict st, uint32_t size);
|
||||
DDS_EXPORT void dds_ostream_fini (dds_ostream_t * __restrict st);
|
||||
DDS_EXPORT void dds_ostreamBE_init (dds_ostreamBE_t * __restrict st, uint32_t size);
|
||||
DDS_EXPORT void dds_ostreamBE_fini (dds_ostreamBE_t * __restrict st);
|
||||
|
||||
bool dds_stream_normalize (void * __restrict data, uint32_t size, bool bswap, const struct ddsi_sertopic_default * __restrict topic, bool just_key);
|
||||
|
||||
void dds_stream_write_sample (dds_ostream_t * __restrict os, const void * __restrict data, const struct ddsi_sertopic_default * __restrict topic);
|
||||
void dds_stream_read_sample (dds_istream_t * __restrict is, void * __restrict data, const struct ddsi_sertopic_default * __restrict topic);
|
||||
|
||||
size_t dds_stream_check_optimize (const dds_topic_descriptor_t * __restrict desc);
|
||||
void dds_istream_from_serdata_default (dds_istream_t * __restrict s, const struct ddsi_serdata_default * __restrict d);
|
||||
void dds_ostream_from_serdata_default (dds_ostream_t * __restrict s, struct ddsi_serdata_default * __restrict d);
|
||||
void dds_ostream_add_to_serdata_default (dds_ostream_t * __restrict s, struct ddsi_serdata_default ** __restrict d);
|
||||
void dds_ostreamBE_from_serdata_default (dds_ostreamBE_t * __restrict s, struct ddsi_serdata_default * __restrict d);
|
||||
void dds_ostreamBE_add_to_serdata_default (dds_ostreamBE_t * __restrict s, struct ddsi_serdata_default ** __restrict d);
|
||||
|
||||
void dds_stream_write_key (dds_ostream_t * __restrict os, const char * __restrict sample, const struct ddsi_sertopic_default * __restrict topic);
|
||||
void dds_stream_write_keyBE (dds_ostreamBE_t * __restrict os, const char * __restrict sample, const struct ddsi_sertopic_default * __restrict topic);
|
||||
void dds_stream_extract_key_from_data (dds_istream_t * __restrict is, dds_ostream_t * __restrict os, const struct ddsi_sertopic_default * __restrict topic);
|
||||
void dds_stream_extract_keyBE_from_data (dds_istream_t * __restrict is, dds_ostreamBE_t * __restrict os, const struct ddsi_sertopic_default * __restrict topic);
|
||||
void dds_stream_extract_keyhash (dds_istream_t * __restrict is, dds_keyhash_t * __restrict kh, const struct ddsi_sertopic_default * __restrict topic, const bool just_key);
|
||||
|
||||
void dds_stream_read_key (dds_istream_t * __restrict is, char * __restrict sample, const struct ddsi_sertopic_default * __restrict topic);
|
||||
|
||||
/* For marshalling op code handling */
|
||||
|
||||
|
@ -70,14 +69,14 @@ extern const uint32_t dds_op_size[5];
|
|||
#define DDS_OP_FLAGS_MASK 0x000000ff
|
||||
#define DDS_JEQ_TYPE_MASK 0x00ff0000
|
||||
|
||||
#define DDS_OP(o) ((o) & DDS_OP_MASK)
|
||||
#define DDS_OP_TYPE(o) (((o) & DDS_OP_TYPE_MASK) >> 16)
|
||||
#define DDS_OP_SUBTYPE(o) (((o) & DDS_OP_SUBTYPE_MASK) >> 8)
|
||||
#define DDS_OP_FLAGS(o) ((o) & DDS_OP_FLAGS_MASK)
|
||||
#define DDS_OP(o) ((enum dds_stream_opcode) ((o) & DDS_OP_MASK))
|
||||
#define DDS_OP_TYPE(o) ((enum dds_stream_typecode) (((o) & DDS_OP_TYPE_MASK) >> 16))
|
||||
#define DDS_OP_SUBTYPE(o) ((enum dds_stream_typecode) (((o) & DDS_OP_SUBTYPE_MASK) >> 8))
|
||||
#define DDS_OP_FLAGS(o) ((o) & DDS_OP_FLAGS_MASK)
|
||||
#define DDS_OP_ADR_JSR(o) ((o) & DDS_OP_JMP_MASK)
|
||||
#define DDS_OP_JUMP(o) ((int16_t) ((o) & DDS_OP_JMP_MASK))
|
||||
#define DDS_OP_JUMP(o) ((int16_t) ((o) & DDS_OP_JMP_MASK))
|
||||
#define DDS_OP_ADR_JMP(o) ((o) >> 16)
|
||||
#define DDS_JEQ_TYPE(o) (((o) & DDS_JEQ_TYPE_MASK) >> 16)
|
||||
#define DDS_JEQ_TYPE(o) ((enum dds_stream_typecode) (((o) & DDS_JEQ_TYPE_MASK) >> 16))
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -179,6 +179,8 @@ void dds_sample_free_contents (char * data, const uint32_t * ops)
|
|||
if (seq->_release)
|
||||
{
|
||||
dds_free (seq->_buffer);
|
||||
seq->_maximum = 0;
|
||||
seq->_length = 0;
|
||||
seq->_buffer = NULL;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dds/ddsrt/md5.h"
|
||||
#include "dds__key.h"
|
||||
#include "dds__stream.h"
|
||||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/q_bswap.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
static bool keyhash_is_reset(const dds_key_hash_t *kh)
|
||||
{
|
||||
return !kh->m_set;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
dds_key_gen: Generates key and keyhash for a sample.
|
||||
See section 9.6.3.3 of DDSI spec.
|
||||
*/
|
||||
|
||||
static void dds_key_gen_stream (const dds_topic_descriptor_t * const desc, dds_stream_t *os, const char *sample)
|
||||
{
|
||||
const char * src;
|
||||
const uint32_t * op;
|
||||
uint32_t i;
|
||||
uint32_t len = 0;
|
||||
|
||||
for (i = 0; i < desc->m_nkeys; i++)
|
||||
{
|
||||
op = desc->m_ops + desc->m_keys[i].m_index;
|
||||
src = sample + op[1];
|
||||
assert ((*op & DDS_OP_FLAG_KEY) && ((DDS_OP_MASK & *op) == DDS_OP_ADR));
|
||||
|
||||
switch (DDS_OP_TYPE (*op))
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
{
|
||||
dds_stream_write_uint8 (os, *((const uint8_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_2BY:
|
||||
{
|
||||
dds_stream_write_uint16 (os, *((const uint16_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_4BY:
|
||||
{
|
||||
dds_stream_write_uint32 (os, *((const uint32_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
dds_stream_write_uint64 (os, *((const uint64_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
{
|
||||
src = *((char**) src);
|
||||
}
|
||||
/* FALLS THROUGH */
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
len = (uint32_t) (strlen (src) + 1);
|
||||
dds_stream_write_uint32 (os, len);
|
||||
dds_stream_write_buffer (os, len, (const uint8_t *) src);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_ARR:
|
||||
{
|
||||
uint32_t size = dds_op_size[DDS_OP_SUBTYPE (*op)];
|
||||
char *dst;
|
||||
len = size * op[2];
|
||||
dst = dds_stream_alignto (os, op[2]);
|
||||
dds_stream_write_buffer (os, len, (const uint8_t *) src);
|
||||
if (dds_stream_endian () && (size != 1u))
|
||||
dds_stream_swap (dst, size, op[2]);
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dds_key_gen (const dds_topic_descriptor_t * const desc, dds_key_hash_t * kh, const char * sample)
|
||||
{
|
||||
assert(keyhash_is_reset(kh));
|
||||
|
||||
kh->m_set = 1;
|
||||
if (desc->m_nkeys == 0)
|
||||
kh->m_iskey = 1;
|
||||
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
dds_stream_t os;
|
||||
kh->m_iskey = 1;
|
||||
dds_stream_init(&os, 0);
|
||||
os.m_endian = 0;
|
||||
os.m_buffer.pv = kh->m_hash;
|
||||
os.m_size = 16;
|
||||
dds_key_gen_stream (desc, &os, sample);
|
||||
}
|
||||
else
|
||||
{
|
||||
dds_stream_t os;
|
||||
ddsrt_md5_state_t md5st;
|
||||
kh->m_iskey = 0;
|
||||
dds_stream_init(&os, 64);
|
||||
os.m_endian = 0;
|
||||
dds_key_gen_stream (desc, &os, sample);
|
||||
ddsrt_md5_init (&md5st);
|
||||
ddsrt_md5_append (&md5st, os.m_buffer.p8, os.m_index);
|
||||
ddsrt_md5_finish (&md5st, (unsigned char *) kh->m_hash);
|
||||
dds_stream_fini (&os);
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
#include "dds/ddsi/q_bswap.h"
|
||||
#include "dds/ddsi/q_config.h"
|
||||
#include "dds/ddsi/q_freelist.h"
|
||||
#include "dds__key.h"
|
||||
#include "dds__stream.h"
|
||||
#include "dds__serdata_builtintopic.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue