Initial contribution
This commit is contained in:
		
							parent
							
								
									7b5cc4fa59
								
							
						
					
					
						commit
						11d9ce37aa
					
				
					 580 changed files with 155133 additions and 162 deletions
				
			
		
							
								
								
									
										26
									
								
								src/tools/pubsub/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/tools/pubsub/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#
 | 
			
		||||
# 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
 | 
			
		||||
#
 | 
			
		||||
find_package(Abstraction REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_executable(pubsub pubsub.c common.c testtype.c porting.c)
 | 
			
		||||
target_link_libraries(pubsub ddsc OSAPI)
 | 
			
		||||
 | 
			
		||||
# TODO: improve test inclusion.
 | 
			
		||||
if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800")))
 | 
			
		||||
  add_subdirectory(tests)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
install(
 | 
			
		||||
  TARGETS pubsub
 | 
			
		||||
  DESTINATION "${CMAKE_INSTALL_BINDIR}"
 | 
			
		||||
  COMPONENT dev
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										941
									
								
								src/tools/pubsub/common.c
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										941
									
								
								src/tools/pubsub/common.c
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,941 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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 <time.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include "testtype.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "os/os.h"
 | 
			
		||||
 | 
			
		||||
dds_entity_t dp = 0;
 | 
			
		||||
dds_entity_t qosprov = 0;
 | 
			
		||||
const dds_topic_descriptor_t *ts_KeyedSeq;
 | 
			
		||||
const dds_topic_descriptor_t *ts_Keyed32;
 | 
			
		||||
const dds_topic_descriptor_t *ts_Keyed64;
 | 
			
		||||
const dds_topic_descriptor_t *ts_Keyed128;
 | 
			
		||||
const dds_topic_descriptor_t *ts_Keyed256;
 | 
			
		||||
const dds_topic_descriptor_t *ts_OneULong;
 | 
			
		||||
 | 
			
		||||
const char *saved_argv0;
 | 
			
		||||
 | 
			
		||||
//void nowll_as_ddstime(DDS_Time_t *t) {
 | 
			
		||||
//    os_time ost = os_timeGet();
 | 
			
		||||
//    t->sec = ost.tv_sec;
 | 
			
		||||
//    t->nanosec = (DDS_unsigned_long) ost.tv_nsec;
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//void bindelta(unsigned long long *bins, unsigned long long d, unsigned repeat) {
 | 
			
		||||
//    int bin = 0;
 | 
			
		||||
//    while (d) {
 | 
			
		||||
//        bin++;
 | 
			
		||||
//        d >>= 1;
 | 
			
		||||
//    }
 | 
			
		||||
//    bins[bin] += repeat;
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//void binprint(unsigned long long *bins, unsigned long long telapsed) {
 | 
			
		||||
//    unsigned long long n;
 | 
			
		||||
//    unsigned i, minbin = BINS_LENGTH-1, maxbin = 0;
 | 
			
		||||
//    n = 0;
 | 
			
		||||
//    for (i = 0; i < BINS_LENGTH; i++) {
 | 
			
		||||
//        n += bins[i];
 | 
			
		||||
//        if (bins[i] && i < minbin)
 | 
			
		||||
//            minbin = i;
 | 
			
		||||
//        if (bins[i] && i > maxbin)
 | 
			
		||||
//            maxbin = i;
 | 
			
		||||
//    }
 | 
			
		||||
//    printf ("< 2**n | %llu in %.06fs avg %.1f/s\n", n, telapsed * 1e-9, n / (telapsed * 1e-9));
 | 
			
		||||
//    for (i = minbin; i <= maxbin; i++) {
 | 
			
		||||
//        static const char ats[] = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
 | 
			
		||||
//        double pct = 100.0 * (double) bins[i] / n;
 | 
			
		||||
//        int nats = (int) ((pct / 100.0) * (sizeof(ats) - 1));
 | 
			
		||||
//        printf ("%2d: %6.2f%% %*.*s\n", i, pct, nats, nats, ats);
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
struct hist {
 | 
			
		||||
    unsigned nbins;
 | 
			
		||||
    uint64_t binwidth;
 | 
			
		||||
    uint64_t bin0; /* bins are [bin0,bin0+binwidth),[bin0+binwidth,bin0+2*binwidth) */
 | 
			
		||||
    uint64_t binN; /* bin0 + nbins*binwidth */
 | 
			
		||||
    uint64_t min, max; /* min and max observed since last reset */
 | 
			
		||||
    uint64_t under, over; /* < bin0, >= binN */
 | 
			
		||||
    uint64_t bins[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct hist *hist_new(unsigned nbins, uint64_t binwidth, uint64_t bin0) {
 | 
			
		||||
    struct hist *h = dds_alloc(sizeof(*h) + nbins * sizeof(*h->bins));
 | 
			
		||||
    h->nbins = nbins;
 | 
			
		||||
    h->binwidth = binwidth;
 | 
			
		||||
    h->bin0 = bin0;
 | 
			
		||||
    h->binN = h->bin0 + h->nbins * h->binwidth;
 | 
			
		||||
    hist_reset(h);
 | 
			
		||||
    return h;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hist_free(struct hist *h) {
 | 
			
		||||
    dds_free(h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hist_reset_minmax(struct hist *h) {
 | 
			
		||||
    h->min = UINT64_MAX;
 | 
			
		||||
    h->max = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hist_reset(struct hist *h) {
 | 
			
		||||
    hist_reset_minmax(h);
 | 
			
		||||
    h->under = 0;
 | 
			
		||||
    h->over = 0;
 | 
			
		||||
    memset(h->bins, 0, h->nbins * sizeof(*h->bins));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hist_record(struct hist *h, uint64_t x, unsigned weight) {
 | 
			
		||||
    if (x < h->min)
 | 
			
		||||
        h->min = x;
 | 
			
		||||
    if (x > h->max)
 | 
			
		||||
        h->max = x;
 | 
			
		||||
    if (x < h->bin0)
 | 
			
		||||
        h->under += weight;
 | 
			
		||||
    else if (x >= h->binN)
 | 
			
		||||
        h->over += weight;
 | 
			
		||||
    else
 | 
			
		||||
        h->bins[(x - h->bin0) / h->binwidth] += weight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xsnprintf(char *buf, size_t bufsz, size_t *p, const char *fmt, ...) {
 | 
			
		||||
    if (*p < bufsz) {
 | 
			
		||||
        int n;
 | 
			
		||||
        va_list ap;
 | 
			
		||||
        va_start(ap, fmt);
 | 
			
		||||
        n = os_vsnprintf(buf + *p, bufsz - *p, fmt, ap);
 | 
			
		||||
        va_end(ap);
 | 
			
		||||
        *p += (size_t)n;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hist_print(struct hist *h, dds_time_t dt, int reset) {
 | 
			
		||||
    const size_t l_size = sizeof(char) * h->nbins + 200;
 | 
			
		||||
    const size_t hist_size = sizeof(char) * h->nbins + 1;
 | 
			
		||||
    char *l = (char *) dds_alloc(l_size);
 | 
			
		||||
    char *hist = (char *) dds_alloc(hist_size);
 | 
			
		||||
    double dt_s = dt / 1e9, avg;
 | 
			
		||||
    uint64_t peak = 0, cnt = h->under + h->over;
 | 
			
		||||
    size_t p = 0;
 | 
			
		||||
    hist[h->nbins] = 0;
 | 
			
		||||
    for (unsigned i = 0; i < h->nbins; i++) {
 | 
			
		||||
        cnt += h->bins[i];
 | 
			
		||||
        if (h->bins[i] > peak)
 | 
			
		||||
            peak = h->bins[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const uint64_t p1 = peak / 100;
 | 
			
		||||
    const uint64_t p10 = peak / 10;
 | 
			
		||||
    const uint64_t p20 = 1 * peak / 5;
 | 
			
		||||
    const uint64_t p40 = 2 * peak / 5;
 | 
			
		||||
    const uint64_t p60 = 3 * peak / 5;
 | 
			
		||||
    const uint64_t p80 = 4 * peak / 5;
 | 
			
		||||
    for (unsigned i = 0; i < h->nbins; i++) {
 | 
			
		||||
        if (h->bins[i] == 0) hist[i] = ' ';
 | 
			
		||||
        else if (h->bins[i] <= p1) hist[i] = '.';
 | 
			
		||||
        else if (h->bins[i] <= p10) hist[i] = '_';
 | 
			
		||||
        else if (h->bins[i] <= p20) hist[i] = '-';
 | 
			
		||||
        else if (h->bins[i] <= p40) hist[i] = '=';
 | 
			
		||||
        else if (h->bins[i] <= p60) hist[i] = 'x';
 | 
			
		||||
        else if (h->bins[i] <= p80) hist[i] = 'X';
 | 
			
		||||
        else hist[i] = '@';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    avg = cnt / dt_s;
 | 
			
		||||
    if (avg < 999.5)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%5.3g", avg);
 | 
			
		||||
    else if (avg < 1e6)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%4.3gk", avg / 1e3);
 | 
			
		||||
    else
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%4.3gM", avg / 1e6);
 | 
			
		||||
    xsnprintf(l, l_size, &p, "/s (");
 | 
			
		||||
 | 
			
		||||
    if (cnt < (uint64_t) 10e3)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%5"PRIu64" ", cnt);
 | 
			
		||||
    else if (cnt < (uint64_t) 1e6)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%5.1fk", cnt / 1e3);
 | 
			
		||||
    else
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%5.1fM", cnt / 1e6);
 | 
			
		||||
 | 
			
		||||
    xsnprintf(l, l_size, &p, " in %.1fs) ", dt_s);
 | 
			
		||||
 | 
			
		||||
    if (h->min == UINT64_MAX)
 | 
			
		||||
        xsnprintf(l, l_size, &p, " inf ");
 | 
			
		||||
    else if (h->min < 1000)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%3"PRIu64"n ", h->min);
 | 
			
		||||
    else if (h->min + 500 < 1000000)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%3"PRIu64"u ", (h->min + 500) / 1000);
 | 
			
		||||
    else if (h->min + 500000 < 1000000000)
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%3"PRIu64"m ", (h->min + 500000) / 1000000);
 | 
			
		||||
    else
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%3"PRIu64"s ", (h->min + 500000000) / 1000000000);
 | 
			
		||||
 | 
			
		||||
    if (h->bin0 > 0) {
 | 
			
		||||
        int pct = (cnt == 0) ? 0 : 100 * (int) ((h->under + cnt/2) / cnt);
 | 
			
		||||
        xsnprintf(l, l_size, &p, "%3d%% ", pct);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        int pct = (cnt == 0) ? 0 : 100 * (int) ((h->over + cnt/2) / cnt);
 | 
			
		||||
        xsnprintf(l, l_size, &p, "|%s| %3d%%", hist, pct);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (h->max < 1000)
 | 
			
		||||
        xsnprintf(l, l_size, &p, " %3"PRIu64"n", h->max);
 | 
			
		||||
    else if (h->max + 500 < 1000000)
 | 
			
		||||
        xsnprintf(l, l_size, &p, " %3"PRIu64"u", (h->max + 500) / 1000);
 | 
			
		||||
    else if (h->max + 500000 < 1000000000)
 | 
			
		||||
        xsnprintf(l, l_size, &p, " %3"PRIu64"m", (h->max + 500000) / 1000000);
 | 
			
		||||
    else
 | 
			
		||||
        xsnprintf(l, l_size, &p, " %3"PRIu64"s", (h->max + 500000000) / 1000000000);
 | 
			
		||||
 | 
			
		||||
    (void) p;
 | 
			
		||||
    puts(l);
 | 
			
		||||
    dds_free(l);
 | 
			
		||||
    dds_free(hist);
 | 
			
		||||
    if (reset)
 | 
			
		||||
        hist_reset(h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void error(const char *fmt, ...) {
 | 
			
		||||
    va_list ap;
 | 
			
		||||
    fprintf (stderr, "%s: error: ", saved_argv0);
 | 
			
		||||
    va_start(ap, fmt);
 | 
			
		||||
    vfprintf (stderr, fmt, ap);
 | 
			
		||||
    va_end(ap);
 | 
			
		||||
    fprintf (stderr, "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void save_argv0(const char *argv0) {
 | 
			
		||||
    saved_argv0 = argv0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int common_init(const char *argv0) {
 | 
			
		||||
    save_argv0(argv0);
 | 
			
		||||
    dp = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
 | 
			
		||||
    error_abort(dp, "dds_create_participant failed");
 | 
			
		||||
 | 
			
		||||
    ts_KeyedSeq = &KeyedSeq_desc;
 | 
			
		||||
    ts_Keyed32 = &Keyed32_desc;
 | 
			
		||||
    ts_Keyed64 = &Keyed64_desc;
 | 
			
		||||
    ts_Keyed128 = &Keyed128_desc;
 | 
			
		||||
    ts_Keyed256 = &Keyed256_desc;
 | 
			
		||||
    ts_OneULong = &OneULong_desc;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void common_fini(void) {
 | 
			
		||||
    dds_return_t rc;
 | 
			
		||||
    if (qosprov != 0) {
 | 
			
		||||
        rc = dds_delete(qosprov);
 | 
			
		||||
        error_report(rc, "dds_delete qosprov failed");
 | 
			
		||||
    }
 | 
			
		||||
    rc = dds_delete(dp);
 | 
			
		||||
    error_report(rc, "dds_delete participant failed");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int change_publisher_partitions(dds_entity_t pub, unsigned npartitions, const char *partitions[]) {
 | 
			
		||||
    dds_qos_t *qos;
 | 
			
		||||
    dds_return_t rc;
 | 
			
		||||
 | 
			
		||||
    qos = dds_qos_create();
 | 
			
		||||
    rc = dds_get_qos(pub, qos);
 | 
			
		||||
    if (rc == DDS_SUCCESS) {
 | 
			
		||||
        dds_qset_partition(qos, npartitions, partitions);
 | 
			
		||||
        rc = dds_set_qos(pub, qos);
 | 
			
		||||
    }
 | 
			
		||||
    dds_qos_delete(qos);
 | 
			
		||||
    return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int change_subscriber_partitions(dds_entity_t sub, unsigned npartitions, const char *partitions[]) {
 | 
			
		||||
    dds_qos_t *qos;
 | 
			
		||||
    dds_return_t rc;
 | 
			
		||||
 | 
			
		||||
    qos = dds_qos_create();
 | 
			
		||||
    rc = dds_get_qos(sub, qos);
 | 
			
		||||
    if (rc == DDS_SUCCESS) {
 | 
			
		||||
        dds_qset_partition(qos, npartitions, partitions);
 | 
			
		||||
        rc = dds_set_qos(sub, qos);
 | 
			
		||||
    }
 | 
			
		||||
    dds_qos_delete(qos);
 | 
			
		||||
    return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static dds_qos_t *get_topic_qos(dds_entity_t tp) {
 | 
			
		||||
    dds_qos_t *tQos = dds_qos_create();
 | 
			
		||||
    dds_return_t rc = dds_get_qos(tp, tQos);
 | 
			
		||||
    error_abort(rc, "dds_qos_get_topic_qos");
 | 
			
		||||
    return tQos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_qos_t *new_tqos(void) {
 | 
			
		||||
    dds_qos_t *q = dds_qos_create();
 | 
			
		||||
 | 
			
		||||
    /* Not all defaults are those of DCPS: */
 | 
			
		||||
    dds_qset_reliability(q, DDS_RELIABILITY_RELIABLE, DDS_SECS(1));
 | 
			
		||||
    dds_qset_destination_order(q, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
 | 
			
		||||
    return q;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_qos_t *new_rdqos(dds_entity_t tp) {
 | 
			
		||||
    dds_qos_t *tQos = get_topic_qos(tp);
 | 
			
		||||
    dds_qos_t *qos = dds_qos_create();
 | 
			
		||||
 | 
			
		||||
    dds_return_t rc = dds_qos_copy(qos, tQos);
 | 
			
		||||
    error_abort(rc ,"new_rdqos: dds_qos_copy");
 | 
			
		||||
    dds_qos_delete(tQos);
 | 
			
		||||
    return qos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_qos_t *new_wrqos(dds_entity_t tp) {
 | 
			
		||||
    dds_qos_t *tQos = get_topic_qos(tp);
 | 
			
		||||
    dds_qos_t *qos = dds_qos_create();
 | 
			
		||||
 | 
			
		||||
    dds_return_t rc = dds_qos_copy(qos, tQos);
 | 
			
		||||
    error_abort(rc ,"new_wrqos: dds_qos_copy");
 | 
			
		||||
    dds_qos_delete(tQos);
 | 
			
		||||
 | 
			
		||||
    /* Not all defaults are those of DCPS: */
 | 
			
		||||
    dds_qset_writer_data_lifecycle(qos, false);
 | 
			
		||||
    return qos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_topic(const char *name, const dds_topic_descriptor_t *topicDesc, const dds_qos_t *q) {
 | 
			
		||||
    dds_entity_t tp = dds_create_topic(dp, topicDesc, name, q, NULL);
 | 
			
		||||
    error_abort(tp, "dds_create_topic failed");
 | 
			
		||||
    return tp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_publisher(dds_qos_t *q, unsigned npartitions, const char **partitions) {
 | 
			
		||||
    dds_qos_t *pQos;
 | 
			
		||||
    if (q == NULL) {
 | 
			
		||||
        pQos = dds_qos_create();
 | 
			
		||||
    } else {
 | 
			
		||||
        pQos = q;
 | 
			
		||||
    }
 | 
			
		||||
    dds_qset_partition(pQos, npartitions, partitions);
 | 
			
		||||
    dds_entity_t pub = dds_create_publisher(dp, pQos, NULL);
 | 
			
		||||
    error_abort(pub, "new_publisher: dds_create_publisher");
 | 
			
		||||
    if (q == NULL)
 | 
			
		||||
        dds_qos_delete(pQos);
 | 
			
		||||
    return pub;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_subscriber(dds_qos_t *q, unsigned npartitions, const char **partitions) {
 | 
			
		||||
    dds_qos_t *sQos;
 | 
			
		||||
    if (q == NULL) {
 | 
			
		||||
        sQos = dds_qos_create();
 | 
			
		||||
    } else {
 | 
			
		||||
        sQos = q;
 | 
			
		||||
    }
 | 
			
		||||
    dds_qset_partition(sQos, npartitions, partitions);
 | 
			
		||||
    dds_entity_t sub = dds_create_subscriber(dp, sQos, NULL);
 | 
			
		||||
    error_abort(sub, "new_subscriber: dds_create_subscriber");
 | 
			
		||||
    if (q == NULL)
 | 
			
		||||
        dds_qos_delete(sQos);
 | 
			
		||||
    return sub;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_datawriter_listener(const dds_entity_t pub, const dds_entity_t tp, const dds_qos_t *q, const dds_listener_t *l) {
 | 
			
		||||
    dds_entity_t wr = dds_create_writer(pub, tp, q, l);
 | 
			
		||||
    error_abort(wr, "dds_create_writer failed");
 | 
			
		||||
    return wr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_datawriter(const dds_entity_t pub, const dds_entity_t tp, const dds_qos_t *q) {
 | 
			
		||||
    return new_datawriter_listener(pub, tp, q, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_datareader_listener(const dds_entity_t sub, const dds_entity_t tp, const dds_qos_t *q, const dds_listener_t *l) {
 | 
			
		||||
    dds_entity_t rd = dds_create_reader(sub, tp, q, l);
 | 
			
		||||
    error_abort(rd, "dds_create_reader failed");
 | 
			
		||||
    return rd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_entity_t new_datareader(const dds_entity_t sub, const dds_entity_t tp, const dds_qos_t *q) {
 | 
			
		||||
    return new_datareader_listener(sub, tp, q, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inapplicable_qos(dds_entity_kind_t qt, const char *n) {
 | 
			
		||||
    const char *en = "?";
 | 
			
		||||
    switch (qt) {
 | 
			
		||||
    case DDS_KIND_TOPIC: en = "topic"; break;
 | 
			
		||||
    case DDS_KIND_PUBLISHER: en = "publisher"; break;
 | 
			
		||||
    case DDS_KIND_SUBSCRIBER: en = "subscriber"; break;
 | 
			
		||||
    case DDS_KIND_WRITER: en = "writer"; break;
 | 
			
		||||
    case DDS_KIND_READER: en = "reader"; break;
 | 
			
		||||
    case DDS_KIND_DONTCARE: en = "dontcare"; break;
 | 
			
		||||
    case DDS_KIND_PARTICIPANT: en = "participant"; break;
 | 
			
		||||
    case DDS_KIND_COND_READ: en = "cond read"; break;
 | 
			
		||||
    case DDS_KIND_COND_QUERY: en = "cond query"; break;
 | 
			
		||||
    case DDS_KIND_WAITSET: en = "waitset"; break;
 | 
			
		||||
    case DDS_KIND_INTERNAL: en = "internal"; break;
 | 
			
		||||
    default: en = "?"; break;
 | 
			
		||||
    }
 | 
			
		||||
    fprintf(stderr, "warning: %s entity ignoring inapplicable QoS \"%s\"\n", en, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define   get_qos_T(qt, q, n) ((qt == DDS_KIND_TOPIC)                                                               ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
#define   get_qos_R(qt, q, n) ((qt == DDS_KIND_READER)                                                              ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
#define   get_qos_W(qt, q, n) ((qt == DDS_KIND_WRITER)                                                              ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
#define  get_qos_TW(qt, q, n) ((qt == DDS_KIND_TOPIC)     || (qt == DDS_KIND_WRITER)                                ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
#define  get_qos_RW(qt, q, n) ((qt == DDS_KIND_READER)    || (qt == DDS_KIND_WRITER)                                ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
#define  get_qos_PS(qt, q, n) ((qt == DDS_KIND_PUBLISHER) || (qt == DDS_KIND_SUBSCRIBER)                            ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
#define get_qos_TRW(qt, q, n) ((qt == DDS_KIND_TOPIC)     || (qt == DDS_KIND_READER)     || (qt == DDS_KIND_WRITER) ? q : (inapplicable_qos((qt), n), NULL))
 | 
			
		||||
 | 
			
		||||
void qos_durability(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "durability");
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (strcmp(arg, "v") == 0)
 | 
			
		||||
        dds_qset_durability(qp, DDS_DURABILITY_VOLATILE);
 | 
			
		||||
    else if (strcmp(arg, "tl") == 0)
 | 
			
		||||
        dds_qset_durability(qp, DDS_DURABILITY_TRANSIENT_LOCAL);
 | 
			
		||||
    else if (strcmp(arg, "t") == 0)
 | 
			
		||||
        dds_qset_durability(qp, DDS_DURABILITY_TRANSIENT);
 | 
			
		||||
    else if (strcmp(arg, "p") == 0)
 | 
			
		||||
        dds_qset_durability(qp, DDS_DURABILITY_PERSISTENT);
 | 
			
		||||
    else
 | 
			
		||||
        error_exit("durability qos: %s: invalid\n", arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_history(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "history");
 | 
			
		||||
    int hist_depth, pos;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (strcmp(arg, "all") == 0) {
 | 
			
		||||
        dds_qset_history(qp, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED);
 | 
			
		||||
    } else if (sscanf(arg, "%d%n", &hist_depth, &pos) == 1 && arg[pos] == 0 && hist_depth > 0) {
 | 
			
		||||
        dds_qset_history(qp, DDS_HISTORY_KEEP_LAST, hist_depth);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_exit("history qos: %s: invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_destination_order(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "destination_order");
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (strcmp(arg, "r") == 0) {
 | 
			
		||||
        dds_qset_destination_order(qp, DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP);
 | 
			
		||||
    } else if (strcmp(arg, "s") == 0) {
 | 
			
		||||
        dds_qset_destination_order(qp, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_exit("destination order qos: %s: invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_ownership(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "ownership");
 | 
			
		||||
    int strength, pos;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (strcmp(arg, "s") == 0) {
 | 
			
		||||
        dds_qset_ownership(qp, DDS_OWNERSHIP_SHARED);
 | 
			
		||||
    } else if (strcmp(arg, "x") == 0) {
 | 
			
		||||
        dds_qset_ownership(qp, DDS_OWNERSHIP_EXCLUSIVE);
 | 
			
		||||
    } else if (sscanf(arg, "x:%d%n", &strength, &pos) == 1 && arg[pos] == 0) {
 | 
			
		||||
        dds_qos_t *qps = get_qos_W(qt, q, "ownership_strength");
 | 
			
		||||
        dds_qset_ownership(qp, DDS_OWNERSHIP_EXCLUSIVE);
 | 
			
		||||
        if(qps) {
 | 
			
		||||
            dds_qset_ownership_strength(qps, strength);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        error_exit("ownership qos: %s invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_transport_priority(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_W(qt, q, "transport_priority");
 | 
			
		||||
    int pos;
 | 
			
		||||
    int value;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (sscanf(arg, "%d%n", &value, &pos) != 1 || arg[pos] != 0)
 | 
			
		||||
        error_exit("transport_priority qos: %s invalid\n", arg);
 | 
			
		||||
    dds_qset_transport_priority(qp, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned char gethexchar(const char **str) {
 | 
			
		||||
    unsigned char v = 0;
 | 
			
		||||
    int empty = 1;
 | 
			
		||||
    while (**str) {
 | 
			
		||||
        switch (**str) {
 | 
			
		||||
        case '0': case '1': case '2': case '3': case '4':
 | 
			
		||||
        case '5': case '6': case '7': case '8': case '9':
 | 
			
		||||
            v = 16 * v + (unsigned char) **str - '0';
 | 
			
		||||
            (*str)++;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
 | 
			
		||||
            v = 16 * v + (unsigned char) **str - 'a' + 10;
 | 
			
		||||
            (*str)++;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
 | 
			
		||||
            v = 16 * v + (unsigned char) **str - 'A' + 10;
 | 
			
		||||
            (*str)++;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            if (empty)
 | 
			
		||||
                error_exit("empty \\x escape");
 | 
			
		||||
            goto done;
 | 
			
		||||
        }
 | 
			
		||||
        empty = 0;
 | 
			
		||||
    }
 | 
			
		||||
    done:
 | 
			
		||||
        return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned char getoctchar(const char **str) {
 | 
			
		||||
    unsigned char v = 0;
 | 
			
		||||
    int nseen = 0;
 | 
			
		||||
    while (**str && nseen < 3) {
 | 
			
		||||
        if (**str >= '0' && **str <= '7') {
 | 
			
		||||
            v = 8 * v + (unsigned char) **str - '0';
 | 
			
		||||
            (*str)++;
 | 
			
		||||
            nseen++;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (nseen == 0)
 | 
			
		||||
                error_exit("empty \\ooo escape");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *unescape(const char *str, size_t *len) {
 | 
			
		||||
    /* results in a blob without explicit terminator, i.e., can't get
 | 
			
		||||
     * any longer than strlen(str) */
 | 
			
		||||
    unsigned char *x = dds_alloc(strlen(str)), *p = x;
 | 
			
		||||
    while (*str) {
 | 
			
		||||
        if (*str != '\\')
 | 
			
		||||
            *p++ = (unsigned char) *str++;
 | 
			
		||||
        else {
 | 
			
		||||
            str++;
 | 
			
		||||
            switch (*str) {
 | 
			
		||||
            case '\\': case ',': case '\'': case '"': case '?':
 | 
			
		||||
                *p++ = (unsigned char) *str;
 | 
			
		||||
                str++;
 | 
			
		||||
                break;
 | 
			
		||||
            case 'x':
 | 
			
		||||
                str++;
 | 
			
		||||
                *p++ = gethexchar(&str);
 | 
			
		||||
                break;
 | 
			
		||||
            case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
 | 
			
		||||
                *p++ = getoctchar(&str);
 | 
			
		||||
                break;
 | 
			
		||||
            case 'a': *p++ = '\a'; str++; break;
 | 
			
		||||
            case 'b': *p++ = '\b'; str++; break;
 | 
			
		||||
            case 'f': *p++ = '\f'; str++; break;
 | 
			
		||||
            case 'n': *p++ = '\n'; str++; break;
 | 
			
		||||
            case 'r': *p++ = '\r'; str++; break;
 | 
			
		||||
            case 't': *p++ = '\t'; str++; break;
 | 
			
		||||
            case 'v': *p++ = '\v'; str++; break;
 | 
			
		||||
            case 'e': *p++ = 0x1b; str++; break;
 | 
			
		||||
            default:
 | 
			
		||||
                error_exit("invalid escape string: %s\n", str);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    *len = (size_t) (p - x);
 | 
			
		||||
    return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_user_data(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_RW(qt, q, "user_data");
 | 
			
		||||
    size_t len;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    void *unesc = unescape(arg, &len);
 | 
			
		||||
    if(len==0) {
 | 
			
		||||
        dds_qset_userdata(qp, NULL, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        dds_qset_userdata(qp, unesc, len);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dds_free(unesc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int double_to_dds_duration(dds_duration_t *dd, double d) {
 | 
			
		||||
    if (d < 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
    double nanosec = d * 1e9;
 | 
			
		||||
    if(nanosec > INT64_MAX) {
 | 
			
		||||
        *dd = DDS_INFINITY;
 | 
			
		||||
    } else {
 | 
			
		||||
        *dd = (int64_t) nanosec;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_infinite_dds_duration(dds_duration_t *dd) {
 | 
			
		||||
    *dd = DDS_INFINITY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_reliability(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "reliability");
 | 
			
		||||
    const char *argp = arg;
 | 
			
		||||
    dds_duration_t max_block_t = DDS_MSECS(100);
 | 
			
		||||
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    switch (*argp++) {
 | 
			
		||||
    case 'b':
 | 
			
		||||
    case 'n':
 | 
			
		||||
        dds_qset_reliability(qp, DDS_RELIABILITY_BEST_EFFORT, max_block_t);
 | 
			
		||||
        break;
 | 
			
		||||
    case 'r':
 | 
			
		||||
    case 'y':
 | 
			
		||||
        if (*argp == ':') {
 | 
			
		||||
            double max_blocking_time;
 | 
			
		||||
            int pos;
 | 
			
		||||
            if (strcmp(argp, ":inf") == 0) {
 | 
			
		||||
                set_infinite_dds_duration(&max_block_t);
 | 
			
		||||
                argp += 4;
 | 
			
		||||
            } else if (sscanf(argp, ":%lf%n", &max_blocking_time, &pos) == 1 && argp[pos] == 0) {
 | 
			
		||||
                if (max_blocking_time <= 0 || double_to_dds_duration(&max_block_t, max_blocking_time) < 0)
 | 
			
		||||
                    error_exit("reliability qos: %s: max blocking time out of range\n", arg);
 | 
			
		||||
                argp += pos;
 | 
			
		||||
            } else {
 | 
			
		||||
                error_exit("reliability qos: %s: invalid max_blocking_time\n", arg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        dds_qset_reliability(qp, DDS_RELIABILITY_RELIABLE, max_block_t);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        error_exit("reliability qos: %s: invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (*argp != 0) {
 | 
			
		||||
        error_exit("reliability qos: %s: invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_liveliness(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_duration_t dd = 0;
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "liveliness");
 | 
			
		||||
    double lease_duration;
 | 
			
		||||
    int pos;
 | 
			
		||||
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (strcmp(arg, "a") == 0) {
 | 
			
		||||
        dds_qset_liveliness(qp, DDS_LIVELINESS_AUTOMATIC, DDS_INFINITY);
 | 
			
		||||
    } else if (sscanf(arg, "p:%lf%n", &lease_duration, &pos) == 1 && arg[pos] == 0) {
 | 
			
		||||
        if (lease_duration <= 0 || double_to_dds_duration(&dd, lease_duration) < 0)
 | 
			
		||||
            error_exit("liveliness qos: %s: lease duration out of range\n", arg);
 | 
			
		||||
        dds_qset_liveliness(qp, DDS_LIVELINESS_MANUAL_BY_PARTICIPANT, dd);
 | 
			
		||||
    } else if (sscanf(arg, "w:%lf%n", &lease_duration, &pos) == 1 && arg[pos] == 0) {
 | 
			
		||||
        if (lease_duration <= 0 || double_to_dds_duration(&dd, lease_duration) < 0)
 | 
			
		||||
            error_exit("liveliness qos: %s: lease duration out of range\n", arg);
 | 
			
		||||
        dds_qset_liveliness(qp, DDS_LIVELINESS_MANUAL_BY_TOPIC, dd);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_exit("liveliness qos: %s: invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qos_simple_duration(dds_duration_t *dd, const char *name, const char *arg) {
 | 
			
		||||
    double duration;
 | 
			
		||||
    int pos;
 | 
			
		||||
    if (strcmp(arg, "inf") == 0) {
 | 
			
		||||
        set_infinite_dds_duration(dd);
 | 
			
		||||
    } else if (sscanf(arg, "%lf%n", &duration, &pos) == 1 && arg[pos] == 0) {
 | 
			
		||||
        if (double_to_dds_duration(dd, duration) < 0)
 | 
			
		||||
            error_exit("%s qos: %s: duration invalid\n", name, arg);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_exit("%s qos: %s: invalid\n", name, arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_latency_budget(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "latency_budget");
 | 
			
		||||
    dds_duration_t duration = 0;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    qos_simple_duration(&duration, "latency_budget", arg);
 | 
			
		||||
    dds_qset_latency_budget(qp, duration);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_deadline(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "deadline");
 | 
			
		||||
    dds_duration_t deadline = 0;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    qos_simple_duration(&deadline, "deadline", arg);
 | 
			
		||||
    dds_qset_deadline(qp, deadline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_lifespan(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TW(qt, q, "lifespan");
 | 
			
		||||
    dds_duration_t duration = 0;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    qos_simple_duration(&duration, "lifespan", arg);
 | 
			
		||||
    dds_qset_lifespan(qp, duration);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int one_resource_limit(int32_t *val, const char **arg) {
 | 
			
		||||
    int pos;
 | 
			
		||||
    if (strncmp(*arg, "inf", 3) == 0) {
 | 
			
		||||
        *val = DDS_LENGTH_UNLIMITED;
 | 
			
		||||
        (*arg) += 3;
 | 
			
		||||
        return 1;
 | 
			
		||||
    } else if (sscanf(*arg, "%d%n", val, &pos) == 1) {
 | 
			
		||||
        (*arg) += pos;
 | 
			
		||||
        return 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_resource_limits(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_TRW(qt, q, "resource_limits");
 | 
			
		||||
    const char *argp = arg;
 | 
			
		||||
    int32_t max_samples = 0;
 | 
			
		||||
    int32_t max_instances = 0;
 | 
			
		||||
    int32_t max_samples_per_instance = 0;
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (!one_resource_limit(&max_samples, &argp))
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (*argp++ != '/')
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (!one_resource_limit(&max_instances, &argp))
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (*argp++ != '/')
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (!one_resource_limit(&max_samples_per_instance, &argp))
 | 
			
		||||
        goto err;
 | 
			
		||||
 | 
			
		||||
    dds_qset_resource_limits(qp, max_samples, max_instances, max_samples_per_instance);
 | 
			
		||||
 | 
			
		||||
    if (*argp != 0)
 | 
			
		||||
        goto err;
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
    err:
 | 
			
		||||
        error_exit("resource limits qos: %s: invalid\n", arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_durability_service(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_T(qt, q, "durability_service");
 | 
			
		||||
    const char *argp = arg;
 | 
			
		||||
    double service_cleanup_delay_t;
 | 
			
		||||
    int pos, hist_depth;
 | 
			
		||||
    dds_duration_t service_cleanup_delay = 0;
 | 
			
		||||
    dds_history_kind_t history_kind = DDS_HISTORY_KEEP_LAST;
 | 
			
		||||
    int32_t history_depth = 1;
 | 
			
		||||
    int32_t max_samples = DDS_LENGTH_UNLIMITED;
 | 
			
		||||
    int32_t max_instances = DDS_LENGTH_UNLIMITED;
 | 
			
		||||
    int32_t max_samples_per_instance = DDS_LENGTH_UNLIMITED;
 | 
			
		||||
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    argp = arg;
 | 
			
		||||
    if (strncmp(argp, "inf", 3) == 0) {
 | 
			
		||||
        set_infinite_dds_duration(&service_cleanup_delay);
 | 
			
		||||
        pos = 3;
 | 
			
		||||
    } else if (sscanf(argp, "%lf%n", &service_cleanup_delay_t, &pos) == 1) {
 | 
			
		||||
        if (service_cleanup_delay_t < 0 || double_to_dds_duration(&service_cleanup_delay, service_cleanup_delay_t) < 0)
 | 
			
		||||
            error_exit("durability service qos: %s: service cleanup delay out of range\n", arg);
 | 
			
		||||
    } else {
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (argp[pos] == 0) {
 | 
			
		||||
        dds_qset_durability_service(qp, service_cleanup_delay, history_kind, history_depth, max_samples, max_instances, max_samples_per_instance);
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (argp[pos] != '/') goto err;
 | 
			
		||||
    argp += pos + 1;
 | 
			
		||||
 | 
			
		||||
    if (strncmp(argp, "all", 3) == 0) {
 | 
			
		||||
        history_kind = DDS_HISTORY_KEEP_ALL;
 | 
			
		||||
        pos = 3;
 | 
			
		||||
    } else if (sscanf(argp, "%d%n", &hist_depth, &pos) == 1 && hist_depth > 0) {
 | 
			
		||||
        history_depth = hist_depth;
 | 
			
		||||
    } else {
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (argp[pos] == 0) {
 | 
			
		||||
        dds_qset_durability_service(qp, service_cleanup_delay, history_kind, history_depth, max_samples, max_instances, max_samples_per_instance);
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (argp[pos] != '/') goto err;
 | 
			
		||||
    argp += pos + 1;
 | 
			
		||||
 | 
			
		||||
    if (!one_resource_limit(&max_samples, &argp))
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (*argp++ != '/')
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (!one_resource_limit(&max_instances, &argp))
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (*argp++ != '/')
 | 
			
		||||
        goto err;
 | 
			
		||||
    if (!one_resource_limit(&max_samples_per_instance, &argp))
 | 
			
		||||
        goto err;
 | 
			
		||||
 | 
			
		||||
    dds_qset_durability_service(qp, service_cleanup_delay, history_kind, history_depth, max_samples, max_instances, max_samples_per_instance);
 | 
			
		||||
 | 
			
		||||
    if (*argp != 0)
 | 
			
		||||
        goto err;
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
    err:
 | 
			
		||||
        error_exit("durability service qos: %s: invalid\n", arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_presentation(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_PS(qt, q, "presentation");
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (strcmp(arg, "i") == 0) {
 | 
			
		||||
        dds_qset_presentation(qp, DDS_PRESENTATION_INSTANCE, 0, 0);
 | 
			
		||||
    } else if (strcmp(arg, "t") == 0) {
 | 
			
		||||
        dds_qset_presentation(qp, DDS_PRESENTATION_TOPIC, 1, 0);
 | 
			
		||||
    } else if (strcmp(arg, "g") == 0) {
 | 
			
		||||
        dds_qset_presentation(qp, DDS_PRESENTATION_GROUP, 1, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_exit("presentation qos: %s: invalid\n", arg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qos_autodispose_unregistered_instances(dds_entity_kind_t qt, dds_qos_t *q, const char *arg) {
 | 
			
		||||
    dds_qos_t *qp = get_qos_W(qt, q, "writer_data_lifecycle");
 | 
			
		||||
    if (qp == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    if (strcmp(arg, "n") == 0)
 | 
			
		||||
        dds_qset_writer_data_lifecycle(qp, false);
 | 
			
		||||
    else if (strcmp(arg, "y") == 0)
 | 
			
		||||
        dds_qset_writer_data_lifecycle(qp, true);
 | 
			
		||||
    else
 | 
			
		||||
        error_exit("autodispose_unregistered_instances qos: %s: invalid\n", arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *qos_arg_usagestr = "\
 | 
			
		||||
QOS (not all are universally applicable):\n\
 | 
			
		||||
    A={a|p:S|w:S}     liveliness (automatic, participant or writer, S in seconds)\n\
 | 
			
		||||
    d={v|tl|t|p}      durability (default: v)\n\
 | 
			
		||||
    D=P               deadline P in seconds (default: inf)\n\
 | 
			
		||||
    k={all|N}         KEEP_ALL or KEEP_LAST N\n\
 | 
			
		||||
    l=D               latency budget in seconds (default: 0)\n\
 | 
			
		||||
    L=D               lifespan in seconds (default: inf)\n\
 | 
			
		||||
    o=[r|s]           order by reception or source timestamp (default: s)\n\
 | 
			
		||||
    O=[s|x[:S]]       ownership: shared or exclusive, strength S (default: s)\n\
 | 
			
		||||
    p=PRIO            transport priority (default: 0)\n\
 | 
			
		||||
    P={i|t|g}         instance, or {topic|group} + coherent updates\n\
 | 
			
		||||
    r={r[:T]|b}       reliability, T is max blocking time in seconds,\n\
 | 
			
		||||
                      (default: r:1)\n\
 | 
			
		||||
    R=S/I/SpI         resource limits (samples, insts, S/I; default: inf/inf/inf)\n\
 | 
			
		||||
    S=C[/H[/S/I/SpI]] durability_service (cleanup delay, history, resource limits)\n\
 | 
			
		||||
    u={y|n}           autodispose unregistered instances (default: n)\n\
 | 
			
		||||
    U=TEXT            set user_data to TEXT\n\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
void set_qosprovider(const char *arg) {
 | 
			
		||||
    //Todo: There is no qosprovider_create in dds.h, yet
 | 
			
		||||
//    int result = DDS_RETCODE_OK;
 | 
			
		||||
//    const char *p = strchr(arg, ',');
 | 
			
		||||
//    const char *xs = strstr(arg, "://");
 | 
			
		||||
//    char *profile = NULL;
 | 
			
		||||
//    const char *uri;
 | 
			
		||||
//    if (p == NULL || xs == NULL || p >= xs)
 | 
			
		||||
//        uri = arg;
 | 
			
		||||
//    else {
 | 
			
		||||
//        uri = p+1;
 | 
			
		||||
//        profile = dds_string_dup(arg);
 | 
			
		||||
//        profile[p-arg] = 0;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    if((result = dds_qosprovider_create(&qosprov, uri, profile)) != DDS_RETCODE_OK)
 | 
			
		||||
//        error("dds_qosprovider_create(%s,%s) failed\n", uri, profile ? profile : "(null)");
 | 
			
		||||
//    dds_free(profile);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setqos_from_args(dds_entity_kind_t qt, dds_qos_t *q, int n, const char *args[]) {
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < n; i++) {
 | 
			
		||||
        char *args_copy = dds_string_dup(args[i]), *cursor = args_copy;
 | 
			
		||||
        const char *arg;
 | 
			
		||||
        while ((arg = os_strsep(&cursor, ",")) != NULL) {
 | 
			
		||||
            if (arg[0] && arg[1] == '=') {
 | 
			
		||||
                const char *a = arg + 2;
 | 
			
		||||
                switch (arg[0]) {
 | 
			
		||||
                case 'A': qos_liveliness(qt, q, a); break;
 | 
			
		||||
                case 'd': qos_durability(qt, q, a); break;
 | 
			
		||||
                case 'D': qos_deadline(qt, q, a); break;
 | 
			
		||||
                case 'k': qos_history(qt, q, a); break;
 | 
			
		||||
                case 'l': qos_latency_budget(qt, q, a); break;
 | 
			
		||||
                case 'L': qos_lifespan(qt, q, a); break;
 | 
			
		||||
                case 'o': qos_destination_order(qt, q, a); break;
 | 
			
		||||
                case 'O': qos_ownership(qt, q, a); break;
 | 
			
		||||
                case 'p': qos_transport_priority(qt, q, a); break;
 | 
			
		||||
                case 'P': qos_presentation(qt, q, a); break;
 | 
			
		||||
                case 'r': qos_reliability(qt, q, a); break;
 | 
			
		||||
                case 'R': qos_resource_limits(qt, q, a); break;
 | 
			
		||||
                case 'S': qos_durability_service(qt, q, a); break;
 | 
			
		||||
                case 'u': qos_autodispose_unregistered_instances(qt, q, a); break;
 | 
			
		||||
                case 'U': qos_user_data(qt, q, a); break;
 | 
			
		||||
                default:
 | 
			
		||||
                    error_exit("%s: unknown QoS\n", arg);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (!qosprov) {
 | 
			
		||||
                error_exit("QoS specification %s requires a QoS provider but none set\n", arg);
 | 
			
		||||
            } else {
 | 
			
		||||
                printf ("Qos provider not supported\n"); //Todo: Commentted qos provider. Could not find in dds.h. Fix required.
 | 
			
		||||
//                int result;
 | 
			
		||||
//                if (*arg == 0)
 | 
			
		||||
//                    arg = NULL;
 | 
			
		||||
//                switch (q->qt) {
 | 
			
		||||
//                case QT_TOPIC:
 | 
			
		||||
//                    if ((result = dds_qosprovider_get_topic_qos(qosprov, q->u.topic.q, arg)) != DDS_RETCODE_OK)
 | 
			
		||||
//                        error ("dds_qosprovider_get_topic_qos(%s): error %d (%s)\n", arg, (int) result, dds_strerror(result));
 | 
			
		||||
//                    break;
 | 
			
		||||
//                case QT_PUBLISHER:
 | 
			
		||||
//                    if ((result = dds_qosprovider_get_publisher_qos(qosprov, q->u.pub.q, arg)) != DDS_RETCODE_OK)
 | 
			
		||||
//                        error ("dds_qosprovider_get_publisher_qos(%s): error %d (%s)\n", arg, (int) result, dds_strerror(result));
 | 
			
		||||
//                    break;
 | 
			
		||||
//                case QT_SUBSCRIBER:
 | 
			
		||||
//                    if ((result = dds_qosprovider_get_subscriber_qos(qosprov, q->u.sub.q, arg)) != DDS_RETCODE_OK)
 | 
			
		||||
//                        error ("dds_qosprovider_subscriber_qos(%s): error %d (%s)\n", arg, (int) result, dds_strerror(result));
 | 
			
		||||
//                    break;
 | 
			
		||||
//                case QT_WRITER:
 | 
			
		||||
//                    if ((result = dds_qosprovider_get_writer_qos(qosprov, q->u.wr.q, arg)) != DDS_RETCODE_OK)
 | 
			
		||||
//                        error ("dds_qosprovider_get_writer_qos(%s): error %d (%s)\n", arg, (int) result, dds_strerror(result));
 | 
			
		||||
//                    break;
 | 
			
		||||
//                case QT_READER:
 | 
			
		||||
//                    if ((result = dds_qosprovider_get_reader_qos(qosprov, q->u.rd.q, arg)) != DDS_RETCODE_OK)
 | 
			
		||||
//                        error ("dds_qosprovider_get_reader_qos(%s): error %d (%s)\n", arg, (int) result, dds_strerror(result));
 | 
			
		||||
//                    break;
 | 
			
		||||
//                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        dds_free((char *)arg);
 | 
			
		||||
        dds_free(args_copy);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								src/tools/pubsub/common.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										116
									
								
								src/tools/pubsub/common.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,116 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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 COMMON_H
 | 
			
		||||
#define COMMON_H
 | 
			
		||||
 | 
			
		||||
#include "ddsc/dds.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define DDS_USERDATA_QOS_POLICY_NAME                            "UserData"
 | 
			
		||||
#define DDS_DURABILITY_QOS_POLICY_NAME                          "Durability"
 | 
			
		||||
#define DDS_PRESENTATION_QOS_POLICY_NAME                        "Presentation"
 | 
			
		||||
#define DDS_DEADLINE_QOS_POLICY_NAME                            "Deadline"
 | 
			
		||||
#define DDS_LATENCYBUDGET_QOS_POLICY_NAME                       "LatencyBudget"
 | 
			
		||||
#define DDS_OWNERSHIP_QOS_POLICY_NAME                           "Ownership"
 | 
			
		||||
#define DDS_OWNERSHIPSTRENGTH_QOS_POLICY_NAME                   "OwnershipStrength"
 | 
			
		||||
#define DDS_LIVELINESS_QOS_POLICY_NAME                          "Liveliness"
 | 
			
		||||
#define DDS_TIMEBASEDFILTER_QOS_POLICY_NAME                     "TimeBasedFilter"
 | 
			
		||||
#define DDS_PARTITION_QOS_POLICY_NAME                           "Partition"
 | 
			
		||||
#define DDS_RELIABILITY_QOS_POLICY_NAME                         "Reliability"
 | 
			
		||||
#define DDS_DESTINATIONORDER_QOS_POLICY_NAME                    "DestinationOrder"
 | 
			
		||||
#define DDS_HISTORY_QOS_POLICY_NAME                             "History"
 | 
			
		||||
#define DDS_RESOURCELIMITS_QOS_POLICY_NAME                      "ResourceLimits"
 | 
			
		||||
#define DDS_ENTITYFACTORY_QOS_POLICY_NAME                       "EntityFactory"
 | 
			
		||||
#define DDS_WRITERDATALIFECYCLE_QOS_POLICY_NAME                 "WriterDataLifecycle"
 | 
			
		||||
#define DDS_READERDATALIFECYCLE_QOS_POLICY_NAME                 "ReaderDataLifecycle"
 | 
			
		||||
#define DDS_TOPICDATA_QOS_POLICY_NAME                           "TopicData"
 | 
			
		||||
#define DDS_GROUPDATA_QOS_POLICY_NAME                           "GroupData"
 | 
			
		||||
#define DDS_TRANSPORTPRIORITY_QOS_POLICY_NAME                   "TransportPriority"
 | 
			
		||||
#define DDS_LIFESPAN_QOS_POLICY_NAME                            "Lifespan"
 | 
			
		||||
#define DDS_DURABILITYSERVICE_QOS_POLICY_NAME                   "DurabilityService"
 | 
			
		||||
#define DDS_SUBSCRIPTIONKEY_QOS_POLICY_NAME                     "SubscriptionKey"
 | 
			
		||||
#define DDS_VIEWKEY_QOS_POLICY_NAME                             "ViewKey"
 | 
			
		||||
#define DDS_READERLIFESPAN_QOS_POLICY_NAME                      "ReaderLifespan"
 | 
			
		||||
#define DDS_SHARE_QOS_POLICY_NAME                               "Share"
 | 
			
		||||
#define DDS_SCHEDULING_QOS_POLICY_NAME                          "Scheduling"
 | 
			
		||||
 | 
			
		||||
#define DDS_SUBSCRIPTIONKEY_QOS_POLICY_ID                       23
 | 
			
		||||
#define DDS_VIEWKEY_QOS_POLICY_ID                               24
 | 
			
		||||
#define DDS_READERLIFESPAN_QOS_POLICY_ID                        25
 | 
			
		||||
#define DDS_SHARE_QOS_POLICY_ID                                 26
 | 
			
		||||
#define DDS_SCHEDULING_QOS_POLICY_ID                            27
 | 
			
		||||
 | 
			
		||||
extern dds_entity_t dp;
 | 
			
		||||
extern const dds_topic_descriptor_t *ts_KeyedSeq;
 | 
			
		||||
extern const dds_topic_descriptor_t *ts_Keyed32;
 | 
			
		||||
extern const dds_topic_descriptor_t *ts_Keyed64;
 | 
			
		||||
extern const dds_topic_descriptor_t *ts_Keyed128;
 | 
			
		||||
extern const dds_topic_descriptor_t *ts_Keyed256;
 | 
			
		||||
extern const dds_topic_descriptor_t *ts_OneULong;
 | 
			
		||||
extern const char *saved_argv0;
 | 
			
		||||
extern const char *qos_arg_usagestr;
 | 
			
		||||
 | 
			
		||||
//#define BINS_LENGTH (8 * sizeof(unsigned long long) + 1)
 | 
			
		||||
 | 
			
		||||
//void nowll_as_ddstime(DDS_Time_t *t);
 | 
			
		||||
//void bindelta(unsigned long long *bins, unsigned long long d, unsigned repeat);
 | 
			
		||||
//void binprint(unsigned long long *bins, unsigned long long telapsed);
 | 
			
		||||
 | 
			
		||||
struct hist;
 | 
			
		||||
struct hist *hist_new(unsigned nbins, uint64_t binwidth, uint64_t bin0);
 | 
			
		||||
void hist_free(struct hist *h);
 | 
			
		||||
void hist_reset_minmax(struct hist *h);
 | 
			
		||||
void hist_reset(struct hist *h);
 | 
			
		||||
void hist_record(struct hist *h, uint64_t x, unsigned weight);
 | 
			
		||||
void hist_print(struct hist *h, dds_time_t dt, int reset);
 | 
			
		||||
 | 
			
		||||
void error(const char *fmt, ...);
 | 
			
		||||
#define error_abort(rc, fmt, ...) if (rc < DDS_SUCCESS) { error(fmt); DDS_ERR_CHECK(rc, DDS_CHECK_FAIL); }
 | 
			
		||||
#define error_report(rc, fmt, ...) if (rc < DDS_SUCCESS) { error(fmt); DDS_ERR_CHECK(rc, DDS_CHECK_REPORT); }
 | 
			
		||||
#define error_return(rc, fmt, ...) if (rc < DDS_SUCCESS) { error_report(rc, fmt); return; }
 | 
			
		||||
#define error_exit(fmt, ...) { error(fmt); exit(2); }
 | 
			
		||||
#define os_error_exit(osres, fmt, ...) if (osres != os_resultSuccess) { error(fmt); exit(2); }
 | 
			
		||||
 | 
			
		||||
void save_argv0(const char *argv0);
 | 
			
		||||
int common_init(const char *argv0);
 | 
			
		||||
void common_fini(void);
 | 
			
		||||
int change_publisher_partitions(dds_entity_t pub, unsigned npartitions, const char *partitions[]);
 | 
			
		||||
int change_subscriber_partitions(dds_entity_t sub, unsigned npartitions, const char *partitions[]);
 | 
			
		||||
dds_entity_t new_publisher(dds_qos_t *q, unsigned npartitions, const char **partitions);
 | 
			
		||||
dds_entity_t new_subscriber(dds_qos_t *q, unsigned npartitions, const char **partitions);
 | 
			
		||||
dds_qos_t *new_tqos(void);
 | 
			
		||||
dds_qos_t *new_rdqos(dds_entity_t tp);
 | 
			
		||||
dds_qos_t *new_wrqos(dds_entity_t tp);
 | 
			
		||||
void set_infinite_dds_duration(dds_duration_t *dd);
 | 
			
		||||
int double_to_dds_duration(dds_duration_t *dd, double d);
 | 
			
		||||
dds_entity_t new_topic(const char *name, const dds_topic_descriptor_t *topicDesc, const dds_qos_t *q);
 | 
			
		||||
dds_entity_t new_datawriter(const dds_entity_t pub, const dds_entity_t tp, const dds_qos_t *q);
 | 
			
		||||
dds_entity_t new_datareader(const dds_entity_t sub, const dds_entity_t tp, const dds_qos_t *q);
 | 
			
		||||
dds_entity_t new_datawriter_listener(const dds_entity_t pub, const dds_entity_t tp, const dds_qos_t *q, const dds_listener_t *l);
 | 
			
		||||
dds_entity_t new_datareader_listener(const dds_entity_t sub, const dds_entity_t tp, const dds_qos_t *q, const dds_listener_t *l);
 | 
			
		||||
void qos_liveliness(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_deadline(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_durability(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_history(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_destination_order(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_ownership(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_transport_priority(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_reliability(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_resource_limits(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_user_data(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_latency_budget(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_lifespan(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void qos_autodispose_unregistered_instances(dds_entity_kind_t qt, dds_qos_t *q, const char *arg);
 | 
			
		||||
void set_qosprovider(const char *arg);
 | 
			
		||||
void setqos_from_args(dds_entity_kind_t qt, dds_qos_t *q, int n, const char *args[]);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										32
									
								
								src/tools/pubsub/porting.c
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										32
									
								
								src/tools/pubsub/porting.c
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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 <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "porting.h"
 | 
			
		||||
 | 
			
		||||
#if NEED_STRSEP
 | 
			
		||||
char *strsep(char **str, const char *sep) {
 | 
			
		||||
    char *ret;
 | 
			
		||||
    if (*str == NULL)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    ret = *str;
 | 
			
		||||
    while (**str && strchr(sep, **str) == 0)
 | 
			
		||||
        (*str)++;
 | 
			
		||||
    if (**str == '\0') {
 | 
			
		||||
        *str = NULL;
 | 
			
		||||
    } else {
 | 
			
		||||
        **str = '\0';
 | 
			
		||||
        (*str)++;
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/tools/pubsub/porting.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								src/tools/pubsub/porting.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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 __ospli_osplo__porting__
 | 
			
		||||
#define __ospli_osplo__porting__
 | 
			
		||||
 | 
			
		||||
#ifndef __GNUC__
 | 
			
		||||
#define __attribute__(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if __SunOS_5_10 && ! defined NEED_STRSEP
 | 
			
		||||
#define NEED_STRSEP 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if NEED_STRSEP
 | 
			
		||||
char *strsep(char **str, const char *sep);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* defined(__ospli_osplo__porting__) */
 | 
			
		||||
							
								
								
									
										2768
									
								
								src/tools/pubsub/pubsub.c
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										2768
									
								
								src/tools/pubsub/pubsub.c
									
										
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										14
									
								
								src/tools/pubsub/tests/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/tools/pubsub/tests/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
#
 | 
			
		||||
# 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(Criterion)
 | 
			
		||||
add_criterion_executable(criterion_tools_pubsub . ../common.c ../testtype.c ../porting.c)
 | 
			
		||||
target_link_libraries(criterion_tools_pubsub util CycloneDDS::ddsc)
 | 
			
		||||
							
								
								
									
										28
									
								
								src/tools/pubsub/tests/basic.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/tools/pubsub/tests/basic.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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 <criterion/criterion.h>
 | 
			
		||||
#include <criterion/logging.h>
 | 
			
		||||
 | 
			
		||||
#define MAIN test_main
 | 
			
		||||
#include "../pubsub.c"
 | 
			
		||||
 | 
			
		||||
Test(tools_pubsub, main) {
 | 
			
		||||
    char *argv[] = {"pubsub", "-T", "pubsubTestTopic", "-K", "KS", "-w1:1", "-D", "1", "-q", "t:d=t,r=r", "pubsub_partition"};
 | 
			
		||||
    int argc = sizeof(argv) / sizeof(char*);
 | 
			
		||||
 | 
			
		||||
    cr_log_info("Starting pubsub basic test");
 | 
			
		||||
    int result = MAIN(argc, argv);
 | 
			
		||||
    if (result != 0)
 | 
			
		||||
        printf("exitcode was %d\n", result);
 | 
			
		||||
    cr_assert_eq(result, 0, "pubsub exited non-zero");
 | 
			
		||||
    cr_log_info("Stopping pubsub basic test");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										176
									
								
								src/tools/pubsub/testtype.c
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										176
									
								
								src/tools/pubsub/testtype.c
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,176 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
/****************************************************************
 | 
			
		||||
 | 
			
		||||
  Generated by Vortex Lite IDL to C Translator
 | 
			
		||||
  File name: testtype.c
 | 
			
		||||
  Source: testtype.idl
 | 
			
		||||
  Generated: Mon Jun 12 12:03:08 EDT 2017
 | 
			
		||||
  Vortex Lite: V2.1.0
 | 
			
		||||
 | 
			
		||||
*****************************************************************/
 | 
			
		||||
#include "testtype.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const uint32_t OneULong_ops [] =
 | 
			
		||||
{
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (OneULong, seq),
 | 
			
		||||
  DDS_OP_RTS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const dds_topic_descriptor_t OneULong_desc =
 | 
			
		||||
{
 | 
			
		||||
  sizeof (OneULong),
 | 
			
		||||
  4u,
 | 
			
		||||
  0u,
 | 
			
		||||
  0u,
 | 
			
		||||
  "OneULong",
 | 
			
		||||
  NULL,
 | 
			
		||||
  2,
 | 
			
		||||
  OneULong_ops,
 | 
			
		||||
  "<MetaData version=\"1.0.0\"><Struct name=\"OneULong\"><Member name=\"seq\"><ULong/></Member></Struct></MetaData>"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const dds_key_descriptor_t Keyed32_keys[1] =
 | 
			
		||||
{
 | 
			
		||||
  { "keyval", 2 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint32_t Keyed32_ops [] =
 | 
			
		||||
{
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (Keyed32, seq),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_KEY, offsetof (Keyed32, keyval),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (Keyed32, baggage), 24,
 | 
			
		||||
  DDS_OP_RTS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const dds_topic_descriptor_t Keyed32_desc =
 | 
			
		||||
{
 | 
			
		||||
  sizeof (Keyed32),
 | 
			
		||||
  4u,
 | 
			
		||||
  DDS_TOPIC_FIXED_KEY,
 | 
			
		||||
  1u,
 | 
			
		||||
  "Keyed32",
 | 
			
		||||
  Keyed32_keys,
 | 
			
		||||
  4,
 | 
			
		||||
  Keyed32_ops,
 | 
			
		||||
  "<MetaData version=\"1.0.0\"><Struct name=\"Keyed32\"><Member name=\"seq\"><ULong/></Member><Member name=\"keyval\"><Long/></Member><Member name=\"baggage\"><Array size=\"24\"><Octet/></Array></Member></Struct></MetaData>"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const dds_key_descriptor_t Keyed64_keys[1] =
 | 
			
		||||
{
 | 
			
		||||
  { "keyval", 2 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint32_t Keyed64_ops [] =
 | 
			
		||||
{
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (Keyed64, seq),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_KEY, offsetof (Keyed64, keyval),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (Keyed64, baggage), 56,
 | 
			
		||||
  DDS_OP_RTS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const dds_topic_descriptor_t Keyed64_desc =
 | 
			
		||||
{
 | 
			
		||||
  sizeof (Keyed64),
 | 
			
		||||
  4u,
 | 
			
		||||
  DDS_TOPIC_FIXED_KEY,
 | 
			
		||||
  1u,
 | 
			
		||||
  "Keyed64",
 | 
			
		||||
  Keyed64_keys,
 | 
			
		||||
  4,
 | 
			
		||||
  Keyed64_ops,
 | 
			
		||||
  "<MetaData version=\"1.0.0\"><Struct name=\"Keyed64\"><Member name=\"seq\"><ULong/></Member><Member name=\"keyval\"><Long/></Member><Member name=\"baggage\"><Array size=\"56\"><Octet/></Array></Member></Struct></MetaData>"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const dds_key_descriptor_t Keyed128_keys[1] =
 | 
			
		||||
{
 | 
			
		||||
  { "keyval", 2 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint32_t Keyed128_ops [] =
 | 
			
		||||
{
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (Keyed128, seq),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_KEY, offsetof (Keyed128, keyval),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (Keyed128, baggage), 120,
 | 
			
		||||
  DDS_OP_RTS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const dds_topic_descriptor_t Keyed128_desc =
 | 
			
		||||
{
 | 
			
		||||
  sizeof (Keyed128),
 | 
			
		||||
  4u,
 | 
			
		||||
  DDS_TOPIC_FIXED_KEY,
 | 
			
		||||
  1u,
 | 
			
		||||
  "Keyed128",
 | 
			
		||||
  Keyed128_keys,
 | 
			
		||||
  4,
 | 
			
		||||
  Keyed128_ops,
 | 
			
		||||
  "<MetaData version=\"1.0.0\"><Struct name=\"Keyed128\"><Member name=\"seq\"><ULong/></Member><Member name=\"keyval\"><Long/></Member><Member name=\"baggage\"><Array size=\"120\"><Octet/></Array></Member></Struct></MetaData>"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const dds_key_descriptor_t Keyed256_keys[1] =
 | 
			
		||||
{
 | 
			
		||||
  { "keyval", 2 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint32_t Keyed256_ops [] =
 | 
			
		||||
{
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (Keyed256, seq),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_KEY, offsetof (Keyed256, keyval),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (Keyed256, baggage), 248,
 | 
			
		||||
  DDS_OP_RTS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const dds_topic_descriptor_t Keyed256_desc =
 | 
			
		||||
{
 | 
			
		||||
  sizeof (Keyed256),
 | 
			
		||||
  4u,
 | 
			
		||||
  DDS_TOPIC_FIXED_KEY,
 | 
			
		||||
  1u,
 | 
			
		||||
  "Keyed256",
 | 
			
		||||
  Keyed256_keys,
 | 
			
		||||
  4,
 | 
			
		||||
  Keyed256_ops,
 | 
			
		||||
  "<MetaData version=\"1.0.0\"><Struct name=\"Keyed256\"><Member name=\"seq\"><ULong/></Member><Member name=\"keyval\"><Long/></Member><Member name=\"baggage\"><Array size=\"248\"><Octet/></Array></Member></Struct></MetaData>"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const dds_key_descriptor_t KeyedSeq_keys[1] =
 | 
			
		||||
{
 | 
			
		||||
  { "keyval", 2 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint32_t KeyedSeq_ops [] =
 | 
			
		||||
{
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (KeyedSeq, seq),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_KEY, offsetof (KeyedSeq, keyval),
 | 
			
		||||
  DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (KeyedSeq, baggage),
 | 
			
		||||
  DDS_OP_RTS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const dds_topic_descriptor_t KeyedSeq_desc =
 | 
			
		||||
{
 | 
			
		||||
  sizeof (KeyedSeq),
 | 
			
		||||
  sizeof (char *),
 | 
			
		||||
  DDS_TOPIC_FIXED_KEY | DDS_TOPIC_NO_OPTIMIZE,
 | 
			
		||||
  1u,
 | 
			
		||||
  "KeyedSeq",
 | 
			
		||||
  KeyedSeq_keys,
 | 
			
		||||
  4,
 | 
			
		||||
  KeyedSeq_ops,
 | 
			
		||||
  "<MetaData version=\"1.0.0\"><Struct name=\"KeyedSeq\"><Member name=\"seq\"><ULong/></Member><Member name=\"keyval\"><Long/></Member><Member name=\"baggage\"><Sequence><Octet/></Sequence></Member></Struct></MetaData>"
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										129
									
								
								src/tools/pubsub/testtype.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										129
									
								
								src/tools/pubsub/testtype.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,129 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
/****************************************************************
 | 
			
		||||
 | 
			
		||||
  Generated by Vortex Lite IDL to C Translator
 | 
			
		||||
  File name: testtype.h
 | 
			
		||||
  Source: testtype.idl
 | 
			
		||||
  Generated: Mon Jun 12 12:03:08 EDT 2017
 | 
			
		||||
  Vortex Lite: V2.1.0
 | 
			
		||||
 | 
			
		||||
*****************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "ddsc/dds.h"
 | 
			
		||||
 | 
			
		||||
#ifndef _DDSL_TESTTYPE_H_
 | 
			
		||||
#define _DDSL_TESTTYPE_H_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct OneULong
 | 
			
		||||
{
 | 
			
		||||
  uint32_t seq;
 | 
			
		||||
} OneULong;
 | 
			
		||||
 | 
			
		||||
extern const dds_topic_descriptor_t OneULong_desc;
 | 
			
		||||
 | 
			
		||||
#define OneULong__alloc() \
 | 
			
		||||
((OneULong*) dds_alloc (sizeof (OneULong)));
 | 
			
		||||
 | 
			
		||||
#define OneULong_free(d,o) \
 | 
			
		||||
dds_sample_free ((d), &OneULong_desc, (o))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct Keyed32
 | 
			
		||||
{
 | 
			
		||||
  uint32_t seq;
 | 
			
		||||
  int32_t keyval;
 | 
			
		||||
  uint8_t baggage[24];
 | 
			
		||||
} Keyed32;
 | 
			
		||||
 | 
			
		||||
extern const dds_topic_descriptor_t Keyed32_desc;
 | 
			
		||||
 | 
			
		||||
#define Keyed32__alloc() \
 | 
			
		||||
((Keyed32*) dds_alloc (sizeof (Keyed32)));
 | 
			
		||||
 | 
			
		||||
#define Keyed32_free(d,o) \
 | 
			
		||||
dds_sample_free ((d), &Keyed32_desc, (o))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct Keyed64
 | 
			
		||||
{
 | 
			
		||||
  uint32_t seq;
 | 
			
		||||
  int32_t keyval;
 | 
			
		||||
  uint8_t baggage[56];
 | 
			
		||||
} Keyed64;
 | 
			
		||||
 | 
			
		||||
extern const dds_topic_descriptor_t Keyed64_desc;
 | 
			
		||||
 | 
			
		||||
#define Keyed64__alloc() \
 | 
			
		||||
((Keyed64*) dds_alloc (sizeof (Keyed64)));
 | 
			
		||||
 | 
			
		||||
#define Keyed64_free(d,o) \
 | 
			
		||||
dds_sample_free ((d), &Keyed64_desc, (o))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct Keyed128
 | 
			
		||||
{
 | 
			
		||||
  uint32_t seq;
 | 
			
		||||
  int32_t keyval;
 | 
			
		||||
  uint8_t baggage[120];
 | 
			
		||||
} Keyed128;
 | 
			
		||||
 | 
			
		||||
extern const dds_topic_descriptor_t Keyed128_desc;
 | 
			
		||||
 | 
			
		||||
#define Keyed128__alloc() \
 | 
			
		||||
((Keyed128*) dds_alloc (sizeof (Keyed128)));
 | 
			
		||||
 | 
			
		||||
#define Keyed128_free(d,o) \
 | 
			
		||||
dds_sample_free ((d), &Keyed128_desc, (o))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct Keyed256
 | 
			
		||||
{
 | 
			
		||||
  uint32_t seq;
 | 
			
		||||
  int32_t keyval;
 | 
			
		||||
  uint8_t baggage[248];
 | 
			
		||||
} Keyed256;
 | 
			
		||||
 | 
			
		||||
extern const dds_topic_descriptor_t Keyed256_desc;
 | 
			
		||||
 | 
			
		||||
#define Keyed256__alloc() \
 | 
			
		||||
((Keyed256*) dds_alloc (sizeof (Keyed256)));
 | 
			
		||||
 | 
			
		||||
#define Keyed256_free(d,o) \
 | 
			
		||||
dds_sample_free ((d), &Keyed256_desc, (o))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct KeyedSeq
 | 
			
		||||
{
 | 
			
		||||
  uint32_t seq;
 | 
			
		||||
  int32_t keyval;
 | 
			
		||||
  dds_sequence_t baggage;
 | 
			
		||||
} KeyedSeq;
 | 
			
		||||
 | 
			
		||||
extern const dds_topic_descriptor_t KeyedSeq_desc;
 | 
			
		||||
 | 
			
		||||
#define KeyedSeq__alloc() \
 | 
			
		||||
((KeyedSeq*) dds_alloc (sizeof (KeyedSeq)));
 | 
			
		||||
 | 
			
		||||
#define KeyedSeq_free(d,o) \
 | 
			
		||||
dds_sample_free ((d), &KeyedSeq_desc, (o))
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* _DDSL_TESTTYPE_H_ */
 | 
			
		||||
							
								
								
									
										48
									
								
								src/tools/pubsub/tglib.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										48
									
								
								src/tools/pubsub/tglib.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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 __ospli_osplo__tglib__
 | 
			
		||||
#define __ospli_osplo__tglib__
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
struct tgtype;
 | 
			
		||||
 | 
			
		||||
struct tgtopic_key {
 | 
			
		||||
    char *name; /* field name */
 | 
			
		||||
    size_t off; /* from start of data */
 | 
			
		||||
    const struct tgtype *type; /* aliases tgtopic::type */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct tgtopic {
 | 
			
		||||
    char *name;
 | 
			
		||||
    size_t size;
 | 
			
		||||
    struct tgtype *type;
 | 
			
		||||
    unsigned nkeys;
 | 
			
		||||
    struct tgtopic_key *keys;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum tgprint_mode {
 | 
			
		||||
    TGPM_DENSE,
 | 
			
		||||
    TGPM_SPACE,
 | 
			
		||||
    TGPM_FIELDS,
 | 
			
		||||
    TGPM_MULTILINE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct tgtopic *tgnew(dds_entity_t tp, int printtype);
 | 
			
		||||
void tgfree(struct tgtopic *tp);
 | 
			
		||||
void tgprint(FILE *fp, const struct tgtopic *tp, const void *data, enum tgprint_mode mode);
 | 
			
		||||
void tgprintkey(FILE *fp, const struct tgtopic *tp, const void *keydata, enum tgprint_mode mode);
 | 
			
		||||
 | 
			
		||||
void *tgscan(const struct tgtopic *tp, const char *src, char **endp);
 | 
			
		||||
void tgfreedata(const struct tgtopic *tp, void *data);
 | 
			
		||||
 | 
			
		||||
#endif /* defined(__ospli_osplo__tglib__) */
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue