RTI Connext

Core Libraries and Utilities

User’s Manual

Part 2 — Core Concepts

Chapters 3-9

Version 5.0

© 2012 Real-Time Innovations, Inc.

All rights reserved.

Printed in U.S.A. First printing.

August 2012.

Trademarks

Real-Time Innovations, RTI, DataBus, and Connext are trademarks or registered trademarks of Real-Time Innovations, Inc. All other trademarks used in this document are the property of their respective owners.

Copy and Use Restrictions

No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form (including electronic, mechanical, photocopy, and facsimile) without the prior written permission of Real- Time Innovations, Inc. The software described in this document is furnished under and subject to the RTI software license agreement. The software may be used or copied only under the terms of the license agreement.

Third-Party Copyright Notices

Note: In this section, "the Software" refers to third-party software, portions of which are used in Connext; "the Software" does not refer to Connext.

This product implements the DCPS layer of the Data Distribution Service (DDS) specification version 1.2 and the DDS Interoperability Wire Protocol specification version 2.1, both of which are owned by the Object Management, Inc. Copyright 1997-2007 Object Management Group, Inc. The publication of these specifications can be found at the Catalog of OMG Data Distribution Service (DDS) Specifications. This documentation uses material from the OMG specification for the Data Distribution Service, section 7. Reprinted with permission. Object Management, Inc. © OMG. 2005.

Portions of this product were developed using ANTLR (www.ANTLR.org). This product includes software developed by the University of California, Berkeley and its contributors.

Portions of this product were developed using AspectJ, which is distributed per the CPL license. AspectJ source code may be obtained from Eclipse. This product includes software developed by the University of California, Berkeley and its contributors.

Portions of this product were developed using MD5 from Aladdin Enterprises.

Portions of this product include software derived from Fnmatch, (c) 1989, 1993, 1994 The Regents of the University of California. All rights reserved. The Regents and contributors provide this software "as is" without warranty.

Portions of this product were developed using EXPAT from Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 2001, 2002 Expat maintainers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

Technical Support

Real-Time Innovations, Inc.

232 E. Java Drive

Sunnyvale, CA 94089

Phone:

(408) 990-7444

Email:

support@rti.com

Website:

https://support.rti.com/

Contents, Part 2

3 Data Types and Data Samples

3-1

3.1 Introduction to the Type System

3-3

3.1.1

Sequences

3-4

3.1.2 Strings and Wide Strings

3-4

3.1.3

Introduction to TypeCode

3-4

 

3.1.3.1 Sending TypeCodes on the Network

3-5

3.2 Built-in Data Types

3-5

3.2.1

Registering Built-in Types

3-6

3.2.2 Creating Topics for Built-in Types

3-6

 

3.2.2.1

Topic Creation Examples

3-7

3.2.3 Creating ContentFilteredTopics for Built-in Types

3-8

 

3.2.3.1

ContentFilteredTopic Creation Examples

3-8

3.2.4

String Built-in Type

3-9

 

3.2.4.1 Creating and Deleting Strings

3-9

 

3.2.4.2

String DataWriter

3-10

 

3.2.4.3

String DataReader

3-11

3.2.5

KeyedString Built-in Type

3-13

 

3.2.5.1 Creating and Deleting Keyed Strings

3-14

 

3.2.5.2

Keyed String DataWriter

3-14

 

3.2.5.3

Keyed String DataReader

3-17

3.2.6

Octets Built-in Type

3-20

 

3.2.6.1 Creating and Deleting Octets

3-21

 

3.2.6.2

Octets DataWriter

3-21

 

3.2.6.3

Octets DataReader

3-23

3.2.7

KeyedOctets Built-in Type

3-26

 

3.2.7.1 Creating and Deleting KeyedOctets

3-26

 

3.2.7.2

Keyed Octets DataWriter

3-27

 

3.2.7.3

Keyed Octets DataReader

3-30

3.2.8 Managing Memory for Built-in Types

3-33

 

3.2.8.1 Examples—Setting the Maximum Size for a String Programmatically

3-34

3.2.9 Type Codes for Built-in Types

3-36

3.3 Creating User Data Types with IDL

3-37

3.3.1

Variable-Length Types

3-39

 

3.3.1.1

Sequences

3-39

 

3.3.1.2 Strings and Wide Strings

3-39

3.3.2

Value Types

3-40

iii

3.3.3

TypeCode and rtiddsgen

3-40

3.3.4 rtiddsgen Translations for IDL Types

3-41

3.3.5

Escaped Identifiers

3-54

3.3.6 Referring to Other IDL Files

3-55

3.3.7

Preprocessor Directives

3-55

3.3.8

Using Custom Directives

3-55

 

3.3.8.1

The @key Directive

3-56

 

3.3.8.2 The @copy and Related Directives

3-57

 

3.3.8.3

The @resolve-name Directive

3-58

 

3.3.8.4

The @top-level Directive

3-60

3.4 Creating User Data Types with Extensible Markup Language (XML)

3-61

3.5 Creating User Data Types with XML Schemas (XSD)

3-66

3.5.1

Primitive Types

3-78

3.6 Using rtiddsgen

3-78

3.6.1

rtiddsgen Command-Line Arguments

3-80

 

3.6.1.1

Optimizing Typedefs (-optimization)

3-83

3.7 Using Generated Types without Connext (Standalone)

3-85

3.7.1 Using Standalone Types in C

3-85

3.7.2 Using Standalone Types in C++

3-85

3.7.3 Standalone Types in Java

3-86

3.8 Interacting Dynamically with User Data Types

3-86

3.8.1

Introduction to TypeCode

3-86

3.8.2

Defining New Types

3-87

3.8.3 Sending Only a Few Fields

3-89

3.8.4 Type Extension and Versioning

3-90

3.8.5 Sending Type Codes on the Network

3-90

 

3.8.5.1 Type Codes for Built-in Types

3-91

3.9 Working with Data Samples

3-92

3.9.1 Objects of Concrete Types

3-92

3.9.2 Objects of Dynamically Defined Types

3-93

4 Entities

 

4-1

4.1 Common Operations for All Entities

4-2

4.1.1 Creating and Deleting Entities

4-2

4.1.2

Enabling Entities

4-3

 

4.1.2.1 Rules for Calling enable()

4-3

4.1.3 Getting an Entity’s Instance Handle

4-4

4.1.4 Getting Status and Status Changes

4-5

4.1.5 Getting and Setting Listeners

4-5

4.1.6

Getting the StatusCondition

4-5

4.1.7 Getting and Setting QosPolicies

4-6

 

4.1.7.1 Changing the QoS Defaults Used to Create Entities: set_default_*_qos()

4-6

 

4.1.7.2 Setting QoS During Entity Creation

4-7

 

4.1.7.3 Changing the QoS for an Existing Entity

4-8

 

4.1.7.4 Default Values

4-8

4.2 QosPolicies

4-9

4.2.1 QoS Requested vs. Offered Compatibility—the RxO Property

4-12

4.2.2 Special QosPolicy Handling Considerations for C

4-12

iv

4.3

Statuses

 

4-13

 

4.3.1 Types of Communication Status

4-14

 

 

4.3.1.1 Changes in Plain Communication Status

4-14

 

 

4.3.1.2 Changes in Read Communication Status

4-16

 

4.3.2 Special Status-Handling Considerations for C

4-18

4.4

Listeners

 

4-18

 

4.4.1

Types of Listeners

4-19

 

4.4.2 Creating and Deleting Listeners

4-20

 

4.4.3 Special Considerations for Listeners in C

4-20

 

4.4.4 Hierarchical Processing of Listeners

4-20

 

 

4.4.4.1 Processing Read Communication Statuses

4-21

 

4.4.5 Operations Allowed within Listener Callbacks

4-22

4.5

Exclusive Areas (EAs)

4-22

 

4.5.1 Restricted Operations in Listener Callbacks

4-25

4.6

Conditions and WaitSets

4-26

 

4.6.1 Creating and Deleting WaitSets

4-26

 

4.6.2

WaitSet Operations

4-28

 

4.6.3

Waiting for Conditions

4-28

 

 

4.6.3.1

How WaitSets Block

4-29

 

4.6.4 Processing Triggered Conditions—What to do when Wait() Returns

4-29

 

4.6.5 Conditions and WaitSet Example

4-30

 

4.6.6

GuardConditions

4-31

 

4.6.7

ReadConditions and QueryConditions

4-32

 

 

4.6.7.1 How ReadConditions are Triggered

4-32

 

 

4.6.7.2

QueryConditions

4-33

 

4.6.8

StatusConditions

4-33

 

 

4.6.8.1 How StatusConditions are Triggered

4-34

 

4.6.9 Using Both Listeners and WaitSets

4-35

5 Topics

 

 

5-1

5.1

Topics

 

 

5-1

 

5.1.1

Creating Topics

5-3

 

5.1.2

Deleting Topics

5-4

 

5.1.3

Setting Topic QosPolicies

5-4

 

 

5.1.3.1 Configuring QoS Settings when the Topic is Created

5-5

 

 

5.1.3.2 Changing QoS Settings After the Topic Has Been Created

5-6

 

5.1.4 Copying QoS From a Topic to a DataWriter or DataReader

5-7

 

5.1.5

Setting Up TopicListeners

5-7

 

5.1.6 Navigating Relationships Among Entities

5-7

 

 

5.1.6.1 Finding a Topic’s DomainParticipant

5-7

 

 

5.1.6.2 Retrieving a Topic’s Name or Type Name

5-8

5.2

Topic QosPolicies

5-8

 

5.2.1

TOPIC_DATA QosPolicy

5-8

 

 

5.2.1.1

Example

5-9

 

 

5.2.1.2

Properties

5-9

 

 

5.2.1.3

Related QosPolicies

5-9

 

 

5.2.1.4

Applicable Entities

5-9

 

 

5.2.1.5

System Resource Considerations

5-9

v

 

5.3 Status Indicator for Topics

5-9

 

 

5.3.1

INCONSISTENT_TOPIC Status

5-10

 

5.4

ContentFilteredTopics

5-10

 

 

5.4.1

Overview

5-10

 

 

5.4.2 Where Filtering is Applied—Publishing vs. Subscribing Side

5-11

 

 

5.4.3

Creating ContentFilteredTopics

5-12

 

 

5.4.4

Deleting ContentFilteredTopics

5-14

 

 

5.4.5

Using a ContentFilteredTopic

5-14

 

 

 

5.4.5.1

Getting the Current Expression Parameters

5-14

 

 

 

5.4.5.2

Setting Expression Parameters

5-14

 

 

 

5.4.5.3

Appending a String to an Expression Parameter

5-15

 

 

 

5.4.5.4

Removing a String from an Expression Parameter

5-15

 

 

 

5.4.5.5

Getting the Filter Expression

5-15

 

 

 

5.4.5.6

Getting the Related Topic

5-15

 

 

 

5.4.5.7

‘Narrowing’ a ContentFilteredTopic to a TopicDescription

5-16

 

 

5.4.6 SQL Filter Expression Notation

5-16

 

 

 

5.4.6.1

SQL Grammar

5-16

 

 

 

5.4.6.2

Token Expressions

5-17

 

 

 

5.4.6.3

Type Compatibility in the Predicate

5-19

 

 

 

5.4.6.4

SQL Extension: Regular Expression Matching

5-19

 

 

 

5.4.6.5

Composite Members

5-19

 

 

 

5.4.6.6

Strings

5-20

 

 

 

5.4.6.7

Enumerations

5-20

 

 

 

5.4.6.8

Pointers

5-20

 

 

 

5.4.6.9

Arrays

5-21

 

 

 

5.4.6.10

Sequences

5-21

 

 

 

5.4.6.11

Example SQL Filter Expressions

5-22

 

 

5.4.7 STRINGMATCH Filter Expression Notation

5-23

 

 

 

5.4.7.1

Example STRINGMATCH Filter Expressions

5-23

 

 

 

5.4.7.2

STRINGMATCH Filter Expression Parameters

5-23

 

 

5.4.8

Custom Content Filters

5-24

 

 

 

5.4.8.1

Filtering on the Writer Side with Custom Filters

5-24

 

 

 

5.4.8.2

Registering a Custom Filter

5-25

 

 

 

5.4.8.3

Unregistering a Custom Filter

5-26

 

 

 

5.4.8.4

Retrieving a ContentFilter

5-27

 

 

 

5.4.8.5

Compile Function

5-27

 

 

 

5.4.8.6

Evaluate Function

5-28

 

 

 

5.4.8.7

Finalize Function

5-28

 

 

 

5.4.8.8

Writer Attach Function

5-29

 

 

 

5.4.8.9

Writer Detach Function

5-29

 

 

 

5.4.8.10

Writer Compile Function

5-29

 

 

 

5.4.8.11

Writer Evaluate Function

5-29

 

 

 

5.4.8.12

Writer Return Loan Function

5-30

 

 

 

5.4.8.13

Writer Finalize Function

5-30

6

Sending Data

 

6-1

 

6.1 Preview: Steps to Sending Data

6-1

 

6.2

Publishers

 

6-2

 

 

6.2.1 Creating Publishers Explicitly vs. Implicitly

6-3

vi

6.2.2

Creating Publishers

6-5

6.2.3

Deleting Publishers

6-7

 

6.2.3.1

Deleting Contained DataWriters

6-7

6.2.4

Setting Publisher QosPolicies

6-7

 

6.2.4.1

Configuring QoS Settings when the Publisher is Created

6-8

 

6.2.4.2

Changing QoS Settings After the Publisher Has Been Created

6-10

 

6.2.4.3

Getting and Setting the Publisher’s Default QoS Profile and Library

6-11

 

6.2.4.4

Getting and Setting Default QoS for DataWriters

6-12

 

6.2.4.5

Other Publisher QoS-Related Operations

6-12

6.2.5

Setting Up PublisherListeners

6-13

6.2.6

Finding a Publisher’s Related Entities

6-14

6.2.7

Waiting for Acknowledgments in a Publisher

6-15

6.2.8

Statuses for Publishers

6-15

6.2.9

Suspending and Resuming Publications

6-15

6.3 DataWriters

 

6-15

6.3.1

Creating DataWriters

6-18

6.3.2

Getting All DataWriters

6-19

6.3.3

Deleting DataWriters

6-20

6.3.4

Setting Up DataWriterListeners

6-20

6.3.5

Checking DataWriter Status

6-21

6.3.6

Statuses for DataWriters

6-22

 

6.3.6.1

DATA_WRITER_CACHE_STATUS

6-22

 

6.3.6.2

DATA_WRITER_PROTOCOL_STATUS

6-22

 

6.3.6.3

LIVELINESS_LOST Status

6-25

 

6.3.6.4

OFFERED_DEADLINE_MISSED Status

6-25

 

6.3.6.5

OFFERED_INCOMPATIBLE_QOS Status

6-26

 

6.3.6.6

PUBLICATION_MATCHED Status

6-26

 

6.3.6.7

RELIABLE_WRITER_CACHE_CHANGED Status (DDS Extension)

6-27

 

6.3.6.8

RELIABLE_READER_ACTIVITY_CHANGED Status (DDS Extension)

6-28

6.3.7

Using a Type-Specific DataWriter (FooDataWriter)

6-28

6.3.8

Writing Data

6-29

 

6.3.8.1

Blocking During a write()

6-31

6.3.9

Flushing Batches of Data Samples

6-32

6.3.10 Writing Coherent Sets of Data Samples

6-32

6.3.11 Waiting for Acknowledgments in a DataWriter

6-33

6.3.12

Application Acknowledgment

6-33

 

6.3.12.1

Application Acknowledgment Kinds

6-34

 

6.3.12.2

Explicitly Acknowledging a Single Sample (C++)

6-34

 

6.3.12.3

Explicitly Acknowledging All Samples (C++)

6-34

 

6.3.12.4

Notification of Delivery with Application Acknowledgment

6-35

 

6.3.12.5

Application-Level Acknowledgment Protocol

6-35

 

6.3.12.6

Periodic and Non-Periodic AppAck Messages

6-36

 

6.3.12.7

Application Acknowledgment and Persistence Service

6-37

 

6.3.12.8

Application Acknowledgment and Routing Service

6-39

6.3.13

Required Subscriptions

6-39

 

6.3.13.1

Named, Required and Durable Subscriptions

6-40

 

6.3.13.2

Durability QoS and Required Subscriptions

6-40

 

6.3.13.3

Required Subscriptions Configuration

6-40

6.3.14 Managing Data Instances (Working with Keyed Data Types)

6-41

vii

 

6.3.14.1

Registering and Unregistering Instances

6-41

 

6.3.14.2

Disposing of Data

6-43

 

6.3.14.3

Looking Up an Instance Handle

6-43

 

6.3.14.4

Getting the Key Value for an Instance

6-43

6.3.15

Setting DataWriter QosPolicies

6-43

 

6.3.15.1

Configuring QoS Settings when the DataWriter is Created

6-46

 

6.3.15.2

Changing QoS Settings After the DataWriter Has Been Created

6-49

 

6.3.15.3

Using a Topic’s QoS to Initialize a DataWriter’s QoS

6-50

6.3.16 Navigating Relationships Among Entities

6-52

 

6.3.16.1

Finding Matching Subscriptions

6-52

 

6.3.16.2

Finding Related Entities

6-53

6.3.17

Asserting Liveliness

6-53

6.4 Publisher/Subscriber QosPolicies

6-53

6.4.1 ASYNCHRONOUS_PUBLISHER QosPolicy (DDS Extension)

6-54

 

6.4.1.1

Properties

6-55

 

6.4.1.2

Related QosPolicies

6-55

 

6.4.1.3

Applicable Entities

6-55

 

6.4.1.4

System Resource Considerations

6-55

6.4.2

ENTITYFACTORY QosPolicy

6-55

 

6.4.2.1

Example

6-57

 

6.4.2.2

Properties

6-57

 

6.4.2.3

Related QosPolicies

6-57

 

6.4.2.4

Applicable Entities

6-57

 

6.4.2.5

System Resource Considerations

6-58

6.4.3 EXCLUSIVE_AREA QosPolicy (DDS Extension)

6-58

 

6.4.3.1

Example

6-59

 

6.4.3.2

Properties

6-59

 

6.4.3.3

Related QosPolicies

6-59

 

6.4.3.4

Applicable Entities

6-59

 

6.4.3.5

System Resource Considerations

6-59

6.4.4

GROUP_DATA QosPolicy

6-59

 

6.4.4.1

Example

6-60

 

6.4.4.2

Properties

6-60

 

6.4.4.3

Related QosPolicies

6-61

 

6.4.4.4

Applicable Entities

6-61

 

6.4.4.5

System Resource Considerations

6-61

6.4.5

PARTITION QosPolicy

6-62

 

6.4.5.1

Rules for PARTITION Matching

6-63

 

6.4.5.2

Pattern Matching for PARTITION Names

6-63

 

6.4.5.3

Example

6-64

 

6.4.5.4

Properties

6-66

 

6.4.5.5

Related QosPolicies

6-66

 

6.4.5.6

Applicable Entities

6-66

 

6.4.5.7

System Resource Considerations

6-66

6.4.6

PRESENTATION QosPolicy

6-67

 

6.4.6.1

Coherent Access

6-68

 

6.4.6.2

Ordered Access

6-68

 

6.4.6.3

Example

6-69

 

6.4.6.4

Properties

6-70

viii

 

6.4.6.5

Related QosPolicies

6-70

 

6.4.6.6

Applicable Entities

6-70

 

6.4.6.7

System Resource Considerations

6-71

6.5 DataWriter QosPolicies

6-71

6.5.1 AVAILABILITY QosPolicy (DDS Extension)

6-71

 

6.5.1.1

Availability QoS Policy and Collaborative DataWriters

6-72

 

6.5.1.2

Availability QoS Policy and Required Subscriptions

6-73

 

6.5.1.3

Properties

6-74

 

6.5.1.4

Related QosPolicies

6-74

 

6.5.1.5

Applicable Entities

6-74

 

6.5.1.6

System Resource Considerations

6-74

6.5.2 BATCH QosPolicy (DDS Extension)

6-75

 

6.5.2.1

Synchronous and Asynchronous Flushing

6-76

 

6.5.2.2

Batching vs. Coalescing

6-77

 

6.5.2.3

Batching and ContentFilteredTopics

6-78

 

6.5.2.4

Performance Considerations

6-78

 

6.5.2.5

Maximum Transport Datagram Size

6-78

 

6.5.2.6

Properties

6-78

 

6.5.2.7

Related QosPolicies

6-78

 

6.5.2.8

Applicable Entities

6-79

 

6.5.2.9

System Resource Considerations

6-79

6.5.3 DATA_WRITER_PROTOCOL QosPolicy (DDS Extension)

6-79

 

6.5.3.1

High and Low Watermarks

6-84

 

6.5.3.2

Normal, Fast, and Late-Joiner Heartbeat Periods

6-84

 

6.5.3.3

Disabling Positive Acknowledgements

6-85

 

6.5.3.4

Configuring the Send Window Size

6-86

 

6.5.3.5

Propagating Serialized Keys with Disposed-Instance Notifications

6-86

 

6.5.3.6

Virtual Heartbeats

6-87

 

6.5.3.7

Resending Over Multicast

6-87

 

6.5.3.8

Example

6-87

 

6.5.3.9

Properties

6-88

 

6.5.3.10

Related QosPolicies

6-88

 

6.5.3.11

Applicable Entities

6-88

 

6.5.3.12

System Resource Considerations

6-89

6.5.4 DATA_WRITER_RESOURCE_LIMITS QosPolicy (DDS Extension)

6-89

 

6.5.4.1

Example

6-90

 

6.5.4.2

Properties

6-90

 

6.5.4.3

Related QosPolicies

6-90

 

6.5.4.4

Applicable Entities

6-91

 

6.5.4.5

System Resource Considerations

6-91

6.5.5

DEADLINE QosPolicy

6-91

 

6.5.5.1

Example

6-92

 

6.5.5.2

Properties

6-92

 

6.5.5.3

Related QosPolicies

6-92

 

6.5.5.4

Applicable Entities

6-92

 

6.5.5.5

System Resource Considerations

6-93

6.5.6

DESTINATION_ORDER QosPolicy

6-93

 

6.5.6.1

Properties

6-94

 

6.5.6.2

Related QosPolicies

6-94

ix

 

6.5.6.3

Applicable Entities

6-94

 

6.5.6.4

System Resource Considerations

6-95

6.5.7

DURABILITY QosPolicy

6-95

 

6.5.7.1

Example

6-96

 

6.5.7.2

Properties

6-96

 

6.5.7.3

Related QosPolicies

6-96

 

6.5.7.4

Applicable Entities

6-97

 

6.5.7.5

System Resource Considerations

6-97

6.5.8

DURABILITY SERVICE QosPolicy

6-97

 

6.5.8.1

Properties

6-98

 

6.5.8.2

Related QosPolicies

6-98

 

6.5.8.3

Applicable Entities

6-99

 

6.5.8.4

System Resource Considerations

6-99

6.5.9 ENTITY_NAME QosPolicy (DDS Extension)

6-99

 

6.5.9.1

Properties

6-100

 

6.5.9.2

Related QosPolicies

6-100

 

6.5.9.3

Applicable Entities

6-100

 

6.5.9.4

System Resource Considerations

6-100

6.5.10

HISTORY QosPolicy

6-100

 

6.5.10.1

Example

6-102

 

6.5.10.2

Properties

6-102

 

6.5.10.3

Related QosPolicies

6-102

 

6.5.10.4

Applicable Entities

6-102

 

6.5.10.5

System Resource Considerations

6-103

6.5.11

LATENCYBUDGET QoS Policy

6-103

 

6.5.11.1

Applicable Entities

6-103

6.5.12

LIFESPAN QoS Policy

6-103

 

6.5.12.1

Properties

6-104

 

6.5.12.2

Related QoS Policies

6-104

 

6.5.12.3

Applicable Entities

6-104

 

6.5.12.4

System Resource Considerations

6-104

6.5.13

LIVELINESS QosPolicy

6-104

 

6.5.13.1

Example

6-106

 

6.5.13.2

Properties

6-106

 

6.5.13.3

Related QosPolicies

6-106

 

6.5.13.4

Applicable Entities

6-107

 

6.5.13.5

System Resource Considerations

6-107

6.5.14 MULTI_CHANNEL QosPolicy (DDS Extension)

6-107

 

6.5.14.1

Example

6-108

 

6.5.14.2

Properties

6-108

 

6.5.14.3

Related Qos Policies

6-109

 

6.5.14.4

Applicable Entities

6-109

 

6.5.14.5

System Resource Considerations

6-109

6.5.15

OWNERSHIP QosPolicy

6-109

 

6.5.15.1

How Connext Selects which DataWriter is the Exclusive Owner

6-110

 

6.5.15.2

Example

6-110

 

6.5.15.3

Properties

6-111

 

6.5.15.4

Related QosPolicies

6-111

 

6.5.15.5

Applicable Entities

6-111

 

6.5.15.6

System Resource Considerations

6-112

x

6.5.16

OWNERSHIP_STRENGTH QosPolicy

6-112

 

6.5.16.1

Example

6-112

 

6.5.16.2

Properties

6-112

 

6.5.16.3

Related QosPolicies

6-112

 

6.5.16.4

Applicable Entities

6-112

 

6.5.16.5

System Resource Considerations

6-112

6.5.17 PROPERTY QosPolicy (DDS Extension)

6-112

 

6.5.17.1

Properties

6-114

 

6.5.17.2

Related QosPolicies

6-114

 

6.5.17.3

Applicable Entities

6-114

 

6.5.17.4

System Resource Considerations

6-115

6.5.18 PUBLISH_MODE QosPolicy (DDS Extension)

6-115

 

6.5.18.1

Properties

6-117

 

6.5.18.2

Related QosPolicies

6-117

 

6.5.18.3

Applicable Entities

6-117

 

6.5.18.4

System Resource Considerations

6-117

6.5.19

RELIABILITY QosPolicy

6-117

 

6.5.19.1

Example

6-119

 

6.5.19.2

Properties

6-119

 

6.5.19.3

Related QosPolicies

6-120

 

6.5.19.4

Applicable Entities

6-120

 

6.5.19.5

System Resource Considerations

6-120

6.5.20

RESOURCE_LIMITS QosPolicy

6-120

 

6.5.20.1

Configuring Resource Limits for Asynchronous DataWriters

6-122

 

6.5.20.2

Configuring DataWriter Instance Replacement

6-122

 

6.5.20.3

Example

6-122

 

6.5.20.4

Properties

6-123

 

6.5.20.5

Related QosPolicies

6-123

 

6.5.20.6

Applicable Entities

6-123

 

6.5.20.7

System Resource Considerations

6-123

6.5.21

TRANSPORT_PRIORITY QosPolicy

6-123

 

6.5.21.1

Example

6-124

 

6.5.21.2

Properties

6-124

 

6.5.21.3

Related QosPolicies

6-124

 

6.5.21.4

Applicable Entities

6-124

 

6.5.21.5

System Resource Considerations

6-124

6.5.22 TRANSPORT_SELECTION QosPolicy (DDS Extension)

6-124

 

6.5.22.1

Example

6-125

 

6.5.22.2

Properties

6-125

 

6.5.22.3

Related QosPolicies

6-125

 

6.5.22.4

Applicable Entities

6-125

 

6.5.22.5

System Resource Considerations

6-125

6.5.23 TRANSPORT_UNICAST QosPolicy (DDS Extension)

6-125

 

6.5.23.1

Example

6-127

 

6.5.23.2

Properties

6-127

 

6.5.23.3

Related QosPolicies

6-127

 

6.5.23.4

Applicable Entities

6-127

 

6.5.23.5

System Resource Considerations

6-127

6.5.24 TYPESUPPORT QosPolicy (DDS Extension)

6-128

 

6.5.24.1

Properties

6-128

xi

 

 

 

6.5.24.2

Related QoS Policies

6-128

 

 

 

6.5.24.3

Applicable Entities

6-128

 

 

 

6.5.24.4

System Resource Considerations

6-128

 

 

6.5.25

USER_DATA QosPolicy

6-128

 

 

 

6.5.25.1

Example

6-129

 

 

 

6.5.25.2

Properties

6-129

 

 

 

6.5.25.3

Related QosPolicies

6-129

 

 

 

6.5.25.4

Applicable Entities

6-130

 

 

 

6.5.25.5

System Resource Considerations

6-130

 

 

6.5.26

WRITER_DATA_LIFECYCLE QoS Policy

6-130

 

 

 

6.5.26.1

Properties

6-131

 

 

 

6.5.26.2

Related QoS Policies

6-131

 

 

 

6.5.26.3

Applicable Entities

6-131

 

 

 

6.5.26.4

System Resource Considerations

6-132

 

6.6

FlowControllers (DDS Extension)

6-132

 

 

6.6.1 Flow Controller Scheduling Policies

6-133

 

 

6.6.2 Managing Fast DataWriters When Using a FlowController

6-134

 

 

6.6.3

Token Bucket Properties

6-134

 

 

 

6.6.3.1

max_tokens

6-135

 

 

 

6.6.3.2

tokens_added_per_period

6-135

 

 

 

6.6.3.3

tokens_leaked_per_period

6-135

 

 

 

6.6.3.4

period

6-135

 

 

 

6.6.3.5

bytes_per_token

6-136

 

 

6.6.4

Prioritized Samples

6-136

 

 

 

6.6.4.1

Designating Priorities

6-137

 

 

 

6.6.4.2

Priority-Based Filtering

6-137

 

 

6.6.5 Creating and Configuring Custom FlowControllers with Property QoS

6-138

 

 

 

6.6.5.1

Example

6-138

 

 

6.6.6 Creating and Deleting FlowControllers

6-140

 

 

6.6.7 Getting/Setting Default FlowController Properties

6-141

 

 

6.6.8 Getting/Setting Properties for a Specific FlowController

6-141

 

 

6.6.9 Adding an External Trigger

6-142

 

 

6.6.10

Other FlowController Operations

6-142

7

Receiving Data

7-1

 

7.1 Preview: Steps to Receiving Data

7-1

 

7.2

Subscribers

 

7-3

 

 

7.2.1 Creating Subscribers Explicitly vs. Implicitly

7-6

 

 

7.2.2

Creating Subscribers

7-6

 

 

7.2.3

Deleting Subscribers

7-7

 

 

 

7.2.3.1

Deleting Contained DataReaders

7-7

 

 

7.2.4

Setting Subscriber QosPolicies

7-8

 

 

 

7.2.4.1 Configuring QoS Settings when the Subscriber is Created

7-8

 

 

 

7.2.4.2

Changing QoS Settings After Subscriber Has Been Created

7-9

 

 

 

7.2.4.3

Getting and Settings the Subscriber’s Default QoS Profile and Library

7-11

 

 

 

7.2.4.4

Getting and Setting Default QoS for DataReaders

7-11

 

 

 

7.2.4.5

Subscriber QoS-Related Operations

7-12

 

 

7.2.5 Beginning and Ending Group-Ordered Access

7-12

 

 

7.2.6

Setting Up SubscriberListeners

7-13

xii

7.2.7 Getting DataReaders with Specific Samples

7-15

7.2.8 Finding a Subscriber’s Related Entities

7-15

7.2.9

Statuses for Subscribers

7-16

 

7.2.9.1

DATA_ON_READERS Status

7-16

7.3 DataReaders

 

7-16

7.3.1

Creating DataReaders

7-19

7.3.2

Getting All DataReaders

7-20

7.3.3

Deleting DataReaders

7-20

 

7.3.3.1

Deleting Contained ReadConditions

7-21

7.3.4

Setting Up DataReaderListeners

7-21

7.3.5 Checking DataReader Status and StatusConditions

7-22

7.3.6 Waiting for Historical Data

7-23

7.3.7

Statuses for DataReaders

7-23

 

7.3.7.1

DATA_AVAILABLE Status

7-24

 

7.3.7.2 DATA_READER_CACHE_STATUS

7-24

 

7.3.7.3 DATA_READER_PROTOCOL_STATUS

7-24

 

7.3.7.4

LIVELINESS_CHANGED Status

7-27

 

7.3.7.5

REQUESTED_DEADLINE_MISSED Status

7-28

 

7.3.7.6

REQUESTED_INCOMPATIBLE_QOS Status

7-28

 

7.3.7.7

SAMPLE_LOST Status

7-29

 

7.3.7.8

SAMPLE_REJECTED Status

7-30

 

7.3.7.9

SUBSCRIPTION_MATCHED Status

7-31

7.3.8

Setting DataReader QosPolicies

7-32

 

7.3.8.1 Configuring QoS Settings when the DataReader is Created

7-34

 

7.3.8.2 Changing QoS Settings After DataReader Has Been Created

7-34

 

7.3.8.3 Using a Topic’s QoS to Initialize a DataWriter’s QoS

7-35

7.3.9 Navigating Relationships Among Entities

7-36

 

7.3.9.1

Finding Matching Publications

7-36

 

7.3.9.2 Finding a DataReader’s Related Entities

7-37

 

7.3.9.3 Looking Up an Instance Handle

7-37

 

7.3.9.4 Getting the Key Value for an Instance

7-37

7.4 Using DataReaders to Access Data (Read & Take)

7-37

7.4.1 Using a Type-Specific DataReader (FooDataReader)

7-37

7.4.2 Loaning and Returning Data and SampleInfo Sequences

7-38

7.4.3 Accessing Data Samples with Read or Take

7-38

 

7.4.3.1

Read vs. Take

7-39

 

7.4.3.2 General Patterns for Accessing Data

7-41

 

7.4.3.3

read_next_sample and take_next_sample

7-41

 

7.4.3.4

read_instance and take_instance

7-42

 

7.4.3.5

read_next_instance and take_next_instance

7-42

 

7.4.3.6

read_w_condition and take_w_condition

7-43

 

7.4.3.7

read_instance_w_condition and take_instance_w_condition

7-44

 

7.4.3.8

read_next_instance_w_condition and take_next_instance_w_condition

7-44

7.4.4

Acknowledging Samples

7-44

7.4.5 The Sequence Data Structure

7-45

7.4.6

The SampleInfo Structure

7-46

 

7.4.6.1

Reception Timestamp

7-47

 

7.4.6.2

Sample States

7-47

 

7.4.6.3

View States

7-47

xiii

 

 

7.4.6.4

Instance States

7-47

 

 

7.4.6.5 Generation Counts and Ranks

7-48

 

 

7.4.6.6

Valid Data Flag

7-49

7.5

Subscriber QosPolicies

7-49

7.6

DataReader QosPolicies

7-49

 

7.6.1 DATA_READER_PROTOCOL QosPolicy (DDS Extension)

7-50

 

 

7.6.1.1

Receive Window Size

7-51

 

 

7.6.1.2 Round-Trip Time For Filtering Redundant NACKs

7-52

 

 

7.6.1.3

Example

7-53

 

 

7.6.1.4

Properties

7-53

 

 

7.6.1.5

Related QosPolicies

7-53

 

 

7.6.1.6

Applicable Entities

7-53

 

 

7.6.1.7

System Resource Considerations

7-54

 

7.6.2 DATA_READER_RESOURCE_LIMITS QosPolicy (DDS Extension)

7-54

 

 

7.6.2.1

max_total_instances and max_instances

7-58

 

 

7.6.2.2

Example

7-58

 

 

7.6.2.3

Properties

7-58

 

 

7.6.2.4

Related QosPolicies

7-59

 

 

7.6.2.5

Applicable Entities

7-59

 

 

7.6.2.6

System Resource Considerations

7-59

 

7.6.3

READER_DATA_LIFECYCLE QoS Policy

7-59

 

 

7.6.3.1

Properties

7-60

 

 

7.6.3.2

Related QoS Policies

7-60

 

 

7.6.3.3

Applicable Entities

7-60

 

 

7.6.3.4

System Resource Considerations

7-60

 

7.6.4

TIME_BASED_FILTER QosPolicy

7-60

 

 

7.6.4.1

Example

7-62

 

 

7.6.4.2

Properties

7-62

 

 

7.6.4.3

Related QosPolicies

7-62

 

 

7.6.4.4

Applicable Entities

7-62

 

 

7.6.4.5

System Resource Considerations

7-62

 

7.6.5 TRANSPORT_MULTICAST QosPolicy (DDS Extension)

7-62

 

 

7.6.5.1

Example

7-64

 

 

7.6.5.2

Properties

7-64

 

 

7.6.5.3

Related QosPolicies

7-65

 

 

7.6.5.4

Applicable Entities

7-65

 

 

7.6.5.5

System Resource Considerations

7-65

 

7.6.6

TYPE_CONSISTENCY_ENFORCEMENT QosPolicy

7-65

 

 

7.6.6.1

Properties

7-67

 

 

7.6.6.2

Related QoS Policies

7-67

 

 

7.6.6.3

Applicable Entities

7-67

 

 

7.6.6.4

System Resource Considerations

7-67

8 Working with Domains

8-1

8.1

Fundamentals of Domains and DomainParticipants

8-1

8.2

DomainParticipantFactory

8-3

 

8.2.1 Setting DomainParticipantFactory QosPolicies

8-4

8.2.1.1Getting and Setting the DomainParticipantFactory’s Default QoS Profile and Library8-5

xiv

 

8.2.2

Getting and Setting Default QoS for DomainParticipants

8-5

 

8.2.3

Freeing Resources Used by the DomainParticipantFactory

8-6

 

8.2.4

Looking Up a DomainParticipant

8-6

 

8.2.5

Getting QoS Values from a QoS Profile

8-6

8.3

DomainParticipants

8-7

 

8.3.1

Creating a DomainParticipant

8-11

 

8.3.2

Deleting DomainParticipants

8-12

 

8.3.3

Deleting Contained Entities

8-12

 

8.3.4

Choosing a Domain ID and Creating Multiple Domains

8-13

 

8.3.5

Setting Up DomainParticipantListeners

8-13

 

8.3.6

Setting DomainParticipant QosPolicies

8-15

 

 

8.3.6.1

Configuring QoS Settings when the DomainParticipant is Created

8-16

 

 

8.3.6.2

Changing QoS Settings After the DomainParticipant Has Been Created

8-18

 

 

8.3.6.3

Getting and Setting the DomainParticipant’s Default QoS Profile and Library 8-

 

 

 

19

 

 

 

8.3.6.4

Getting and Setting Default QoS for Child Entities

8-19

 

8.3.7

Looking up Topic Descriptions

8-20

 

8.3.8

Finding a Topic

8-20

 

8.3.9

Getting the Implicit Publisher or Subscriber

8-21

 

8.3.10

Asserting Liveliness

8-22

 

8.3.11

Learning about Discovered DomainParticipants

8-22

 

8.3.12 Learning about Discovered Topics

8-22

 

8.3.13

Other DomainParticipant Operations

8-22

 

 

8.3.13.1

Verifying Entity Containment

8-22

 

 

8.3.13.2

Getting the Current Time

8-23

 

 

8.3.13.3

Getting All Publishers and Subscribers

8-23

8.4

DomainParticipantFactory QosPolicies

8-23

 

8.4.1

LOGGING QosPolicy (DDS Extension)

8-23

 

 

8.4.1.1

Example

8-23

 

 

8.4.1.2

Properties

8-24

 

 

8.4.1.3

Related QosPolicies

8-24

 

 

8.4.1.4

Applicable Entities

8-24

 

 

8.4.1.5

System Resource Considerations

8-24

 

8.4.2

PROFILE QosPolicy (DDS Extension)

8-24

 

 

8.4.2.1

Example

8-25

 

 

8.4.2.2

Properties

8-25

 

 

8.4.2.3

Related QosPolicies

8-25

 

 

8.4.2.4

Applicable Entities

8-25

 

 

8.4.2.5

System Resource Considerations

8-25

 

8.4.3

SYSTEM_RESOURCE_LIMITS QoS Policy (DDS Extension)

8-25

 

 

8.4.3.1

Example

8-26

 

 

8.4.3.2

Properties

8-26

 

 

8.4.3.3

Related QoS Policies

8-26

 

 

8.4.3.4

Applicable Entities

8-26

 

 

8.4.3.5

System Resource Considerations

8-26

8.5

DomainParticipant QosPolicies

8-27

 

8.5.1

DATABASE QosPolicy (DDS Extension)

8-27

 

 

8.5.1.1

Example

8-29

 

 

8.5.1.2

Properties

8-29

xv

8.5.1.3

Related QosPolicies

8-29

8.5.1.4

Applicable Entities

8-29

8.5.1.5

System Resource Considerations

8-29

8.5.2 DISCOVERY QosPolicy (DDS Extension)

8-29

8.5.2.1

Transports Used for Discovery

8-30

8.5.2.2

Setting the ‘Initial Peers’ List

8-30

8.5.2.3

Adding and Removing Peers List Entries

8-30

8.5.2.4

Configuring Multicast Receive Addresses

8-31

8.5.2.5

Meta-Traffic Transport Priority

8-31

8.5.2.6

Controlling Acceptance of Unknown Peers

8-31

8.5.2.7

Example

8-32

8.5.2.8

Properties

8-32

8.5.2.9

Related QosPolicies

8-32

8.5.2.10

Applicable Entities

8-33

8.5.2.11

System Resource Considerations

8-33

8.5.3 DISCOVERY_CONFIG QosPolicy (DDS Extension)

8-33

8.5.3.1

Resource Limits for Builtin-Topic DataReaders

8-36

8.5.3.2

Controlling Purging of Remote Participants

8-38

8.5.3.3Controlling the Reliable Protocol Used by Builtin-Topic DataWriters/ DataReaders8-39

8.5.3.4

Example

8-39

8.5.3.5

Properties

8-39

8.5.3.6

Related QosPolicies

8-39

8.5.3.7

Applicable Entities

8-39

8.5.3.8

System Resource Considerations

8-39

8.5.4 DOMAIN_PARTICIPANT_RESOURCE_LIMITS QosPolicy (DDS Extension)

8-40

8.5.4.1 Configuring Resource Limits for Asynchronous DataWriters

8-43

8.5.4.2

Configuring Memory Allocation

8-43

8.5.4.3

Example

8-44

8.5.4.4

Properties

8-44

8.5.4.5

Related QosPolicies

8-45

8.5.4.6

Applicable Entities

8-45

8.5.4.7

System Resource Considerations

8-45

8.5.5 EVENT QosPolicy (DDS Extension)

8-45

8.5.5.1

Example

8-46

8.5.5.2

Properties

8-46

8.5.5.3

Related QosPolicies

8-46

8.5.5.4

Applicable Entities

8-46

8.5.5.5

System Resource Considerations

8-46

8.5.6 RECEIVER_POOL QosPolicy (DDS Extension)

8-46

8.5.6.1

Example

8-47

8.5.6.2

Properties

8-47

8.5.6.3

Related QosPolicies

8-47

8.5.6.4

Applicable Entities

8-48

8.5.6.5

System Resource Considerations

8-48

8.5.7 TRANSPORT_BUILTIN QosPolicy (DDS Extension)

8-48

8.5.7.1

Example

8-48

8.5.7.2

Properties

8-48

8.5.7.3

Related QosPolicies

8-48

8.5.7.4

Applicable Entities

8-49

xvi

 

 

8.5.7.5

System Resource Considerations

8-49

 

8.5.8 TRANSPORT_MULTICAST_MAPPING QosPolicy (DDS Extension)

8-49

 

 

8.5.8.1 Formatting Rules for Addresses

8-50

 

 

8.5.8.2

Example

8-50

 

 

8.5.8.3

Properties

8-50

 

 

8.5.8.4

Related QosPolicies

8-50

 

 

8.5.8.5

Applicable Entities

8-50

 

 

8.5.8.6

System Resource Considerations

8-51

 

8.5.9 WIRE_PROTOCOL QosPolicy (DDS Extension)

8-51

 

 

8.5.9.1

Choosing Participant IDs

8-51

 

 

8.5.9.2 Host, App, and Instance IDs

8-52

 

 

8.5.9.3 Ports Used for Discovery

8-53

 

 

8.5.9.4 Controlling How the GUID is Set (rtps_auto_id_kind)

8-53

 

 

8.5.9.5

Example

8-55

 

 

8.5.9.6

Properties

8-56

 

 

8.5.9.7

Related QosPolicies

8-56

 

 

8.5.9.8

Applicable Entities

8-56

 

 

8.5.9.9

System Resource Considerations

8-56

8.6

Clock Selection

 

8-56

 

8.6.1

Available Clocks

8-56

 

8.6.2

Clock Selection Strategy

8-56

8.7

System Properties

8-57

9 Building Applications

9-1

9.1

Running on a Computer Not Connected to a Network

9-1

9.2

Connext Header Files — All Architectures

9-2

9.3

UNIX-Based Platforms

9-2

 

9.3.1

Required Libraries

9-3

 

9.3.2

Compiler Flags

9-3

9.4

Windows Platforms

9-3

 

9.4.1 Using Microsoft Visual C++ 6.0

9-4

 

9.4.2 Using Visual Studio .NET, Visual Studio .NET 2003, or Visual Studio 2005

9-5

9.5

Java Platforms

9-6

 

9.5.1

Java Libraries

9-6

 

9.5.2

Native Libraries

9-6

xvii

Chapter 3 Data Types and Data Samples

How data is stored or laid out in memory can vary from language to language, compiler to compiler, operating system to operating system, and processor to processor. This combination of language/compiler/operating system/processor is called a platform. Any modern middleware must be able to take data from one specific platform (say C/gcc.3.2.2/Solaris/Sparc) and transparently deliver it to another (for example, Java/JDK 1.6/Windows XP/Pentium). This process is commonly called serialization/deserialization, or marshalling/demarshalling.

Messaging products have typically taken one of two approaches to this problem:

1.Do nothing. Messages consist only of opaque streams of bytes. The JMS BytesMessage is an example of this approach.

2.Send everything, every time. Self-describing messages are at the opposite extreme, embedding full reflective information, including data types and field names, with each message. The JMS MapMessage and the messages in TIBCO Rendezvous are examples of this approach.

The “do nothing” approach is lightweight on its surface but forces you, the user of the middleware API, to consider all data encoding, alignment, and padding issues. The “send everything” alternative results in large amounts of redundant information being sent with every packet, impacting performance.

Connext takes an intermediate approach. Just as objects in your application program belong to some data type, data samples sent on the same Connext topic share a data type. This type defines the fields that exist in the data samples and what their constituent types are. The middleware stores and propagates this meta-information separately from the individual data samples, allowing it to propagate samples efficiently while handling byte ordering and alignment issues for you.

To publish and/or subscribe to data with Connext, you will carry out the following steps:

1.Select a type to describe your data.

You have a number of choices. You can choose one of these options, or you can mix and match them.

Use a built-in type provided by the middleware.

This option may be sufficient if your data typing needs are very simple. If your data is highly structured, or you need to be able to examine fields within that data for filtering or other purposes, this option may not be appropriate. The built-in types are described in Built-in Data Types (Section 3.2).

Use the RTI code generator, rtiddsgen, to define a type at compile-time using a language-independent description language.

3-1

Code generation offers two strong benefits not available with dynamic type definition: (1) it allows you to share type definitions across programming languages, and (2) because the structure of the type is known at compile time, it provides rigorous static type safety.

The code generator accepts input in a number of formats to make it easy to integrate Connext with your development processes and IT infrastructure:

OMG IDL. This format is a standard component of both the DDS and CORBA specifications. It describes data types with a C++-like syntax. This format is described in Creating User Data Types with IDL (Section 3.3).

XML schema (XSD), either independent or embedded in a WSDL file. XSD should be the format of choice for those using Connext alongside or connected to a web- services infrastructure. This format is described in Creating User Data Types with XML Schemas (XSD) (Section 3.5).

XML in a DDS-specific format. This XML format is terser, and therefore easier to read and write by hand, than an XSD file. It offers the general benefits of XML- extensibility and ease of integration, while fully supporting DDS-specific data types and concepts. This format is described in Creating User Data Types with Extensible Markup Language (XML) (Section 3.4).

Define a type programmatically at run time.

This method may be appropriate for applications with dynamic data description needs: applications for which types change frequently or cannot be known ahead of time. It is described in Defining New Types (Section 3.8.2).

2.Register your type with a logical name.

If you've chosen to use a built-in type instead of defining your own, you can omit this step; the middleware pre-registers the built-in types for you.

This step is described in the Defining New Types (Section 3.8.2).

3.Create a Topic using the type name you previously registered.

If you've chosen to use a built-in type instead of defining your own, you will use the API constant corresponding to that type's name.

Creating and working with Topics is discussed in Chapter 5: Topics.

4.Create one or more DataWriters to publish your data and one or more DataReaders to subscribe to it.

The concrete types of these objects depend on the concrete data type you've selected, in order to provide you with a measure of type safety.

Creating and working with DataWriters and DataReaders are described in Chapter 6: Sending Data and Chapter 7: Receiving Data, respectively.

Whether publishing or subscribing to data, you will need to know how to create and delete data samples and how to get and set their fields. These tasks are described in Working with Data Samples (Section 3.9).

This chapter describes:

Introduction to the Type System (Section 3.1 on Page 3-3)

Built-in Data Types (Section 3.2 on Page 3-5)

Creating User Data Types with IDL (Section 3.3 on Page 3-37)

Creating User Data Types with Extensible Markup Language (XML) (Section 3.4 on Page 3-61)

3-2

Creating User Data Types with XML Schemas (XSD) (Section 3.5 on Page 3-66)

Using rtiddsgen (Section 3.6 on Page 3-78)

Using Generated Types without Connext (Standalone) (Section 3.7 on Page 3-85)

Interacting Dynamically with User Data Types (Section 3.8 on Page 3-86)

Working with Data Samples (Section 3.9 on Page 3-92)

3.1Introduction to the Type System

A user data type is any custom type that your application defines for use with Connext. It may be a structure, a union, a value type, an enumeration, or a typedef (or language equivalents).

Your application can have any number of user data types. They can be composed of any of the primitive data types listed below or of other user data types.

Only structures, unions, and value types may be read and written directly by Connext; enums, typedefs, and primitive types must be contained within a structure, union, or value type. In order for a DataReader and DataWriter to communicate with each other, the data types associated with their respective Topic definitions must be identical.

octet, char, wchar

short, unsigned short

long, unsigned long

long long, unsigned long long

float

double, long double

boolean

enum (with or without explicit values)

bounded and unbounded string and wstring

The following type-building constructs are also supported:

module (also called a package or namespace)

pointer

array of primitive or user type elements

bounded/unbounded sequence of elements1—a sequence is a variable-length ordered collection, such as a vector or list

typedef

bitfield2

union

struct

value type, a complex type that supports inheritance and other object-oriented features

1.Sequences of sequences are not supported directly. To work around this constraint, typedef the inner sequence and form a sequence of that new type.

2.Data types containing bitfield members are not supported by DynamicData.

3-3

To use a data type with Connext, you must define that type in a way the middleware understands and then register the type with the middleware. These steps allow Connext to serialize, deserialize, and otherwise operate on specific types. They will be described in detail in the following sections.

3.1.1Sequences

A sequence contains an ordered collection of elements that are all of the same type. The operations supported in the sequence are documented in the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Infrastructure Module, Sequence Support).

Java sequences implement the java.util.List interface from the standard Collections framework.

C++ users will find sequences conceptually similar to the deque class in the Standard Template Library (STL).

Elements in a sequence are accessed with their index, just like elements in an array. Indices start from zero. Unlike arrays, however, sequences can grow in size. A sequence has two sizes associated with it: a physical size (the "maximum") and a logical size (the "length"). The physical size indicates how many elements are currently allocated by the sequence to hold; the logical size indicates how many valid elements the sequence actually holds. The length can vary from zero up to the maximum. Elements cannot be accessed at indices beyond the current length.

A sequence may be declared as bounded or unbounded. A sequence's "bound" is the maximum number of elements tha tthe sequence can contain at any one time. The bound is very important because it allows Connext to preallocate buffers to hold serialized and deserialized samples of your types; these buffers are used when communicating with other nodes in your distributed system. If a sequence had no bound, Connext would not know how large to allocate its buffers and would therefore have to allocate them on the fly as individual samples were read and written—severely impacting the latency and determinism of your application. Therefore, Connext supports only bounded sequences; any unbounded sequences found in an IDL file will be given a default bound of 100 elements (see rtiddsgen Command-Line Arguments (Section 3.6.1)).

3.1.2Strings and Wide Strings

Connext supports both strings consisting of single-byte characters (the IDL string type) and strings consisting of wide characters (IDL wstring). The wide characters supported by Connext are four bytes long, large enough to store not only two-byte Unicode/UTF16 characters but also UTF32 characters.

Like sequences, strings may be bounded or unbounded. A string's "bound" is its maximum length (not counting the trailing NULL character in C and C++).

3.1.3Introduction to TypeCode

Type schemas—the names and definitions of a type and its fields—are represented by TypeCode objects. A type code value consists of a type code kind (see the TCKind enumeration below) and a list of members. For compound types like structs and arrays, this list will recursively include one or more type code values.

enum TCKind { TK_NULL, TK_SHORT, TK_LONG, TK_USHORT,

3-4

TK_ULONG,

TK_FLOAT,

TK_DOUBLE,

TK_BOOLEAN, TK_CHAR, TK_OCTET, TK_STRUCT, TK_UNION, TK_ENUM, TK_STRING, TK_SEQUENCE, TK_ARRAY, TK_ALIAS, TK_LONGLONG, TK_ULONGLONG, TK_LONGDOUBLE, TK_WCHAR, TK_WSTRING, TK_VALUE, TK_SPARSE

}

Type codes unambiguously match type representations and provide a more reliable test than comparing the string type names.

The TypeCode class, modeled after the corresponding CORBA API, provides access to type- code information. For details on the available operations for the TypeCode class, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Type Code Support).

3.1.3.1Sending TypeCodes on the Network

In addition to being used locally, serialized type codes are typically published automatically during discovery as part of the built-in topics for publications and subscriptions. See Built-in DataReaders (Section 16.2). This allows applications to publish or subscribe to topics of arbitrary types. This functionality is useful for generic system monitoring tools like the rtiddsspy debug tool (see the API Reference HTML documentation).

Note: Type codes are not cached by Connext upon receipt and are therefore not available from the built-in data returned by the DataWriter's get_matched_subscription_data() operation or the

DataReader's get_matched_publication_data() operation.

If your data type has an especially complex type code, you may need to increase the value of the type_code_max_serialized_length field in the DomainParticipant's

DOMAIN_PARTICIPANT_RESOURCE_LIMITS QosPolicy (DDS Extension) (Section 8.5.4). Or, to prevent the propagation of type codes altogether, you can set this value to zero (0). Be aware that some features of monitoring tools, as well as some features of the middleware itself (such as ContentFilteredTopics) will not work correctly if you disable TypeCode propagation.

3.2Built-in Data Types

Connext provides a set of standard types that are built into the middleware. These types can be used immediately; they do not require writing IDL, invoking the rtiddsgen utility (see Section 3.6), or using the dynamic type API (see Section 3.2.8).

3-5

The supported built-in types are String, KeyedString, Octets, and KeyedOctets. (The latter two types are called Bytes and KeyedBytes, respectively, on Java and .NET platforms.)

The built-in type API is located under the DDS namespace in C++ and .NET. For Java, the API is contained inside the package com.rti.dds.type.builtin.

Built-in data types are discussed in the following sections:

Registering Built-in Types (Section 3.2.1)

Creating Topics for Built-in Types (Section 3.2.2)

Creating ContentFilteredTopics for Built-in Types (Section 3.2.3)

String Built-in Type (Section 3.2.4)

KeyedString Built-in Type (Section 3.2.5)

Octets Built-in Type (Section 3.2.6)

KeyedOctets Built-in Type (Section 3.2.7)

Type Codes for Built-in Types (Section 3.2.9)

3.2.1Registering Built-in Types

By default, the built-in types are automatically registered when a DomainParticipant is created. You can change this behavior by setting the DomainParticipant’s dds.builtin_type.auto_register property to 0 (false) using the PROPERTY QosPolicy (DDS Extension) (Section 6.5.17).

3.2.2Creating Topics for Built-in Types

To create a topic for a built-in type, just use the standard DomainParticipant operations, create_topic() or create_topic_with_profile() (see Creating Topics (Section 5.1.1)); for the type_name parameter, use the value returned by the get_type_name() operation, listed below for each API.

Note: In the following examples, you will see the sentinel "<BuiltinType>."

For C and C++: <BuiltinType> = String, KeyedString, Octets or KeyedOctets For Java and .NET1: <BuiltinType> = String, KeyedString, Bytes or KeyedBytes

C API:

const char* DDS_<BuiltinType>TypeSupport_get_type_name();

C++ API with namespace:

const char* DDS::<BuiltinType>TypeSupport::get_type_name();

C++ API without namespace:

const char* DDS<BuiltinType>TypeSupport::get_type_name();

C++/CLI API:

System::String^ DDS:<BuiltinType>TypeSupport::get_type_name();

C# API:

System.String DDS.<BuiltinType>TypeSupport.get_type_name();

1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.

3-6

Java API:

String com.rti.dds.type.builtin.<BuiltinType>TypeSupport.get_type_name();

3.2.2.1Topic Creation Examples

For simplicity, error handling is not shown in the following examples.

C Example:

DDS_Topic * topic = NULL;

/* Create a builtin type Topic */

topic = DDS_DomainParticipant_create_topic( participant, "StringTopic",

DDS_StringTypeSupport_get_type_name(), &DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

C++ Example with Namespaces:

using namespace DDS;

...

/* Create a String builtin type Topic */ Topic * topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(),

DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

C++/CLI Example:

using namespace DDS;

...

/* Create a builtin type Topic */

Topic^ topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(), DomainParticipant::TOPIC_QOS_DEFAULT,

nullptr, StatusMask::STATUS_MASK_NONE);

C# Example:

using namespace DDS;

...

/* Create a builtin type Topic */

Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusMask.STATUS_MASK_NONE);

Java Example:

import com.rti.dds.type.builtin.*;

...

/* Create a builtin type Topic */

Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusKind.STATUS_MASK_NONE);

3-7

3.2.3Creating ContentFilteredTopics for Built-in Types

To create a ContentFilteredTopic for a built-in type, just use the standard DomainParticipant operations, create_contentfilteredtopic() or create_contentfilteredtopic_with_filter (see Section 5.4.3).

The field names used in the filter expressions for the built-in SQL (see Section 5.4.6) and StringMatch filters (see Section 5.4.7) must correspond to the names provided in the IDL description of the built-in types (see Section 3.2.4).

3.2.3.1ContentFilteredTopic Creation Examples

For simplicity, error handling is not shown in the following examples.

C Example:

DDS_Topic * topic = NULL;

DDS_ContentFilteredTopic * contentFilteredTopic = NULL; struct DDS_StringSeq parameters = DDS_SEQUENCE_INITIALIZER;

/* Create a string ContentFilteredTopic */ topic = DDS_DomainParticipant_create_topic(

participant, "StringTopic", DDS_StringTypeSupport_get_type_name(), &DDS_TOPIC_QOS_DEFAULT,NULL, DDS_STATUS_MASK_NONE);

contentFilteredTopic = DDS_DomainParticipant_create_contentfilteredtopic( participant, "StringContentFilteredTopic",

topic, "value = 'Hello World!'", & parameters);

C++ Example with Namespaces:

using namespace DDS;

...

/* Create a String ContentFilteredTopic */ Topic * topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(), TOPIC_QOS_DEFAULT, NULL, STATUS_MASK_NONE);

StringSeq parameters;

ContentFilteredTopic * contentFilteredTopic = participant->create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

C++/CLI Example:

using namespace DDS;

...

/* Create a String ContentFilteredTopic */ Topic^ topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(), DomainParticipant::TOPIC_QOS_DEFAULT,

nullptr, StatusMask::STATUS_MASK_NONE);

StringSeq^ parameters = gcnew StringSeq();

3-8

ContentFilteredTopic^ contentFilteredTopic = participant->create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

C# Example:

using namespace DDS;

...

/* Create a String ContentFilteredTopic */ Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusMask.STATUS_MASK_NONE);

StringSeq parameters = new StringSeq();

ContentFilteredTopic contentFilteredTopic = participant.create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

Java Example:

import com.rti.dds.type.builtin.*;

...

/* Create a String ContentFilteredTopic */ Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusKind.STATUS_MASK_NONE);

StringSeq parameters = new StringSeq();

ContentFilteredTopic contentFilteredTopic = participant.create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

3.2.4String Built-in Type

The String built-in type is represented by a NULL-terminated character array (char *) in C and C++ and an immutable String object in Java and .NET1. This type can be used to publish and subscribe to a single string.

3.2.4.1Creating and Deleting Strings

In C and C++, Connext provides a set of operations to create (DDS::String_alloc()), destroy (DDS::String_free()), and clone strings (DDS::String_dup()). Select Modules, DDS API Reference, Infrastructure Module, String support in the API Reference HTML documentation, which is available for all supported programming languages.

1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.

3-9

Memory Considerations in Copy Operations:

When the read/take operations that take a sequence of strings as a parameter are used in copy mode, Connext allocates the memory for the string elements in the sequence if they are initialized to NULL.

If the elements are not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory associated with the elements is reallocated with every sample, because strings are immutable objects.

In C and C++, the memory associated with the elements must be large enough to hold the received data. Insufficient memory may result in crashes.

When take_next_sample() and read_next_sample() are called in C and C++, you must make sure that the input string has enough memory to hold the received data. Insufficient memory may result in crashes.

3.2.4.2String DataWriter

The string DataWriter API matches the standard DataWriter API (see Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)). There are no extensions.

The following examples show how to write simple strings with a string built-in type DataWriter. For simplicity, error handling is not shown.

C Example:

DDS_StringDataWriter * stringWriter = ... ; DDS_ReturnCode_t retCode;

char * str = NULL;

/* Write some data */

retCode = DDS_StringDataWriter_write(

stringWriter, "Hello World!", &DDS_HANDLE_NIL);

str = DDS_String_dup("Hello World!");

retCode = DDS_StringDataWriter_write(stringWriter, str, &DDS_HANDLE_NIL); DDS_String_free(str);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

StringDataWriter * stringWriter = ... ;

/* Write some data */

ReturnCode_t retCode = stringWriter->write("Hello World!", HANDLE_NIL); char * str = DDS::String_dup("Hello World!");

retCode = stringWriter->write(str, HANDLE_NIL);

DDS::String_free(str);

C++/CLI Example:

using namespace System; using namespace DDS;

...

StringDataWriter^ stringWriter = ... ;

/* Write some data */

3-10

stringWriter->write("Hello World!", InstanceHandle_t::HANDLE_NIL); String^ str = "Hello World!";

stringWriter->write(str, InstanceHandle_t::HANDLE_NIL);

C# Example:

using System; using DDS;

...

StringDataWriter stringWriter = ... ;

/* Write some data */

stringWriter.write("Hello World!", InstanceHandle_t.HANDLE_NIL); String str = "Hello World!";

stringWriter.write(str, InstanceHandle_t.HANDLE_NIL);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

StringDataWriter stringWriter = ... ;

/* Write some data */

stringWriter.write("Hello World!", InstanceHandle_t.HANDLE_NIL); String str = "Hello World!";

stringWriter.write(str, InstanceHandle_t.HANDLE_NIL);

3.2.4.3String DataReader

The string DataReader API matches the standard DataReader API (see Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)). There are no extensions.

The following examples show how to read simple strings with a string built-in type DataReader. For simplicity, error handling is not shown.

C Example:

struct DDS_StringSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_StringDataReader * stringReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_StringDataReader_take(stringReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_StringSeq_get_length(&data_seq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&info_seq, i)->valid_data) { DDS_StringTypeSupport_print_data(

DDS_StringSeq_get(&data_seq, i));

}

}

/* Return loan */

retCode = DDS_StringDataReader_return_loan(stringReader, &data_seq, &info_seq);

3-11

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

StringSeq dataSeq;

SampleInfoSeq infoSeq;

StringDataReader * stringReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = stringReader->take(dataSeq, infoSeq, LENGTH_UNLIMITED, ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {

StringTypeSupport::print_data(dataSeq[i]);

}

}

/* Return loan */

retCode = stringReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

StringSeq^ dataSeq = gcnew StringSeq(); SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq(); StringDataReader^ stringReader = ... ;

/* Take and print the data */ stringReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

StringTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ stringReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

StringSeq dataSeq = new StringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

StringDataReader stringReader = ... ;

3-12

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

StringTypeSupport.print_data(dataSeq.get_at(i));

}

}

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

StringSeq dataSeq = new StringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

StringDataReader stringReader = ... ;

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println((String)dataSeq.get(i));

}

}

/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);

3.2.5KeyedString Built-in Type

The Keyed String built-in type is represented by a (key, value) pair, where key and value are strings. This type can be used to publish and subscribe to keyed strings. The language specific representations of the type are as follows:

C/C++ Representation (without namespaces):

struct DDS_KeyedString { char * key;

char * value;

};

C++/CLI Representation:

namespace DDS {

public ref struct KeyedString: { public:

System::String^ key; System::String^ value;

...

};

3-13

};

C# Representation:

namespace DDS {

public class KeyedString { public System.String key; public System.String value;

};

};

Java Representation:

namespace DDS {

public class KeyedString { public System.String key; public System.String value;

};

};

3.2.5.1Creating and Deleting Keyed Strings

Connext provides a set of constructors/destructors to create/destroy Keyed Strings. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Built-in Types).

If you want to manipulate the memory of the fields 'value' and 'key' in the KeyedString struct in C/C++, use the operations DDS::String_alloc(), DDS::String_dup(), and DDS::String_free(), as described in the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, String Support).

3.2.5.2Keyed String DataWriter

The keyed string DataWriter API is extended with the following methods (in addition to the standard methods described in Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)):

DDS::ReturnCode_t DDS::KeyedStringDataWriter::dispose( const char* key,

const DDS::InstanceHandle_t* instance_handle);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::dispose_w_timestamp( const char* key,

const DDS::InstanceHandle_t* instance_handle, const struct DDS::Time_t* source_timestamp);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::get_key_value( char * key,

const DDS::InstanceHandle_t* handle);

DDS::InstanceHandle_t DDS::KeyedStringDataWriter::lookup_instance(

const char * key);

DDS::InstanceHandle_t DDS::KeyedStringDataWriter::register_instance(

const char* key);

DDS::InstanceHandle_t

DDS_KeyedStringDataWriter::register_instance_w_timestamp(

const char * key,

const struct DDS_Time_t* source_timestamp);

3-14

DDS::ReturnCode_t DDS::KeyedStringDataWriter::unregister_instance( const char * key,

const DDS::InstanceHandle_t* handle);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::unregister_instance_w_timestamp(

const char* key,

const DDS::InstanceHandle_t* handle,

const struct DDS::Time_t* source_timestamp);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::write ( const char * key,

const char * str,

const DDS::InstanceHandle_t* handle);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::write_w_timestamp( const char * key,

const char * str,

const DDS::InstanceHandle_t* handle,

const struct DDS::Time_t* source_timestamp);

These operations are introduced to provide maximum flexibility in the format of the input parameters for the write and instance management operations. For additional information and a complete description of the operations, see the API Reference HTML documentation, which is available for all supported programming languages.

The following examples show how to write keyed strings using a keyed string built-in type DataWriter and some of the extended APIs. For simplicity, error handling is not shown.

C Example:

DDS_KeyedStringDataWriter * stringWriter = ... ; DDS_ReturnCode_t retCode;

struct DDS_KeyedString * keyedStr = NULL; char * str = NULL;

/* Write some data using the KeyedString structure */ keyedStr = DDS_KeyedString_new(255, 255); strcpy(keyedStr->key, "Key 1"); strcpy(keyedStr->value, "Value 1");

retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, keyedStr, &DDS_HANDLE_NIL);

DDS_KeyedString_delete(keyedStr);

/* Write some data using individual strings */

retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, "Key 1", "Value 1", &DDS_HANDLE_NIL);

str = DDS_String_dup("Value 2");

retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, "Key 1", str, &DDS_HANDLE_NIL);

DDS_String_free(str);

3-15

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedStringDataWriter * stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString * keyedStr = new KeyedString(255, 255); strcpy(keyedStr->key, "Key 1"); strcpy(keyedStr->value, "Value 1");

ReturnCode_t retCode = stringWriter->write(keyedStr, HANDLE_NIL);

delete keyedStr;

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedStringDataWriter * stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString * keyedStr = new KeyedString(255, 255); strcpy(keyedStr->key, "Key 1"); strcpy(keyedStr->value, "Value 1");

ReturnCode_t retCode = stringWriter->write(keyedStr, HANDLE_NIL);

delete keyedStr;

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedStringDataWriter^ stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString^ keyedStr = gcnew KeyedString(); keyedStr->key = "Key 1";

keyedStr->value = "Value 1";

stringWriter->write(keyedStr, InstanceHandle_t::HANDLE_NIL);

/* Write some data using individual strings */ stringWriter->write("Key 1","Value 1",InstanceHandle_t::HANDLE_NIL);

String^ str = "Value 2";

stringWriter->write("Key 1", str, InstanceHandle_t::HANDLE_NIL);

C# Example

using System; using DDS;

...

KeyedStringDataWriter stringWriter = ... ;

/* Write some data using the KeyedString */

3-16

KeyedString keyedStr = new KeyedString(); keyedStr.key = "Key 1";

keyedStr.value = "Value 1";

stringWriter.write(keyedStr, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ stringWriter.write("Key 1", "Value 1", InstanceHandle_t.HANDLE_NIL);

String str = "Value 2";

stringWriter.write("Key 1", str, InstanceHandle_t.HANDLE_NIL);

Java Example :

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

KeyedStringDataWriter stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString keyedStr = new KeyedString(); keyedStr.key = "Key 1";

keyedStr.value = "Value 1";

stringWriter.write(keyedStr, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ stringWriter.write("Key 1", "Value 1", InstanceHandle_t.HANDLE_NIL);

String str = "Value 2";

stringWriter.write("Key 1", str, InstanceHandle_t.HANDLE_NIL);

3.2.5.3Keyed String DataReader

The KeyedString DataReader API is extended with the following operations (in addition to the standard methods described in Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)):

DDS::ReturnCode_t DDS::KeyedStringDataReader::get_key_value(

char * key, const DDS::InstanceHandle_t* handle);

DDS::InstanceHandle_t DDS::KeyedStringDataReader::lookup_instance(

const char * key);

For additional information and a complete description of these operations in all supported languages, see the API Reference HTML documentation, which is available for all supported programming languages.

Memory considerations in copy operations:

For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the fields 'value' and 'key' if they are initialized to NULL.

If the fields are not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory associated to the fields 'value' and 'key' will be reallocated with every sample.

3-17

In C and C++, the memory associated with the fields 'value' and 'key' must be large enough to hold the received data. Insufficient memory may result in crashes.

The following examples show how to read keyed strings with a keyed string built-in type DataReader. For simplicity, error handling is not shown.

C Example:

struct DDS_KeyedStringSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_KeyedKeyedStringDataReader * stringReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_KeyedStringDataReader_take(stringReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_KeyedStringSeq_get_length(&data_seq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&info_seq, i)->valid_data) { DDS_KeyedStringTypeSupport_print_data(

DDS_KeyedStringSeq_get_reference(&data_seq, i));

}

}

/* Return loan */

retCode = DDS_KeyedStringDataReader_return_loan( stringReader, &data_seq, &info_seq);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedStringSeq dataSeq;

SampleInfoSeq infoSeq;

KeyedStringDataReader * stringReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = stringReader->take(dataSeq, infoSeq, LENGTH_UNLIMITED, ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {

KeyedStringTypeSupport::print_data(&dataSeq[i]);

}

}

/* Return loan */

retCode = stringReader->return_loan(dataSeq, infoSeq);

3-18

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedStringSeq^ dataSeq = gcnew KeyedStringSeq();

SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();

KeyedStringDataReader^ stringReader = ... ;

/* Take and print the data */ stringReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

KeyedStringTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ stringReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

KeyedStringSeq dataSeq = new KeyedStringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

KeyedStringDataReader stringReader = ... ;

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

KeyedStringTypeSupport.print_data(dataSeq.get_at(i));

}

}

/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

KeyedStringSeq dataSeq = new KeyedStringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

KeyedStringDataReader stringReader = ... ;

3-19

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println((

(KeyedString)dataSeq.get(i)).toString());

}

}

/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);

3.2.6Octets Built-in Type

The octets built-in type is used to send sequences of octets. The language-specific representations are as follows:

C/C++ Representation (without Namespaces):

struct DDS_Octets { int length;

unsigned char * value;

};

C++/CLI Representation:

namespace DDS {

public ref struct Bytes: { public:

System::Int32 length; System::Int32 offset; array<System::Byte>^ value;

...

};

};

C# Representation:

namespace DDS {

public class Bytes {

public System.Int32 length; public System.Int32 offset; public System.Byte[] value;

...

};

};

Java Representation:

package com.rti.dds.type.builtin;

public class Bytes implements Copyable { public int length;

public int offset; public byte[] value;

...

};

3-20

3.2.6.1Creating and Deleting Octets

Connext provides a set of constructors/destructors to create and destroy Octet objects. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Built-in Types).

If you want to manipulate the memory of the value field inside the Octets struct in C/C++, use the operations DDS::OctetBuffer_alloc(), DDS::OctetBuffer_dup(), and

DDS::OctetBuffer_free(), described in the API Reference HTML documentation (select

Modules, DDS API Reference, Infrastructure Module, Octet Buffer Support).

3.2.6.2Octets DataWriter

In addition to the standard methods (see Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)), the octets DataWriter API is extended with the following methods:

DDS::ReturnCode_t DDS::OctetsDataWriter::write(

const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle);

DDS::ReturnCode_t DDS::OctetsDataWriter::write(

const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle);

DDS::ReturnCode_t DDS::OctetsDataWriter::write_w_timestamp( const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::OctetsDataWriter::write_w_timestamp( const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle, const DDS::Time_t& source_timestamp);

These methods are introduced to provide maximum flexibility in the format of the input parameters for the write operations. For additional information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.

The following examples show how to write an array of octets using an octets built-in type DataWriter and some of the extended APIs. For simplicity, error handling is not shown.

C Example:

DDS_OctetsDataWriter * octetsWriter = ... ; DDS_ReturnCode_t retCode;

struct DDS_Octets * octets = NULL; char * octetArray = NULL;

/* Write some data using the Octets structure */ octets = DDS_Octets_new_w_size(1024); octets->length = 2;

octets->value[0] = 46; octets->value[1] = 47;

retCode = DDS_OctetsDataWriter_write(octetsWriter, octets, &DDS_HANDLE_NIL);

DDS_Octets_delete(octets);

/* Write some data using an octets array */

3-21

octetArray = (unsigned char *)malloc(1024); octetArray[0] = 46;

octetArray[1] = 47;

retCode = DDS_OctetsDataWriter_write_octets (octetsWriter, octetArray, 2, &DDS_HANDLE_NIL);

free(octetArray);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

OctetsDataWriter * octetsWriter = ... ;

/* Write some data using the Octets structure */ Octets * octets = new Octets(1024); octets->length = 2;

octets->value[0] = 46; octets->value[1] = 47;

ReturnCode_t retCode = octetsWriter->write(octets, HANDLE_NIL);

delete octets;

/* Write some data using an octet array */

unsigned char * octetArray = new unsigned char[1024]; octetArray[0] = 46;

octetArray[1] = 47;

retCode = octetsWriter->write(octetArray, 2, HANDLE_NIL);

delete []octetArray;

C++/CLI Example:

using namespace System; using namespace DDS;

...

BytesDataWriter^ octetsWriter = ...;

/* Write some data using Bytes */ Bytes^ octets = gcnew Bytes(1024); octets->value[0] =46; octets->value[1] =47; octets.length = 2;

octets.offset = 0;

octetWriter->write(octets, InstanceHandle_t::HANDLE_NIL);

/* Write some data using individual strings */ array<Byte>^ octetAray = gcnew array<Byte>(1024); octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter->write(octetArray, 0, 2, InstanceHandle_t::HANDLE_NIL);

C# Example:

using System; using DDS;

...

3-22

BytesDataWriter stringWriter = ...;

/* Write some data using the Bytes */ Bytes octets = new Bytes(1024); octets.value[0] = 46; octets.value[1] = 47;

octets.length = 2; octets.offset = 0;

octetWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter.write(octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

BytesDataWriter octetsWriter = ... ;

/* Write some data using the Bytes class*/ Bytes octets = new Bytes(1024); octets.length = 2;

octets.offset = 0; octets.value[0] = 46; octets.value[1] = 47;

octetsWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using a byte array */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter.write(octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

3.2.6.3Octets DataReader

The octets DataReader API matches the standard DataReader API (see Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)). There are no extensions.

Memory considerations in copy operations:

For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the field 'value' if it is initialized to NULL.

If the field 'value' is not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory for the field 'value' will be reallocated if the current size is not large enough to hold the received data.

In C and C++, the memory associated with the field 'value' must be big enough to hold the received data. Insufficient memory may result in crashes.

3-23

The following examples show how to read octets with an octets built-in type DataReader. For simplicity, error handling is not shown.

C Example:

struct DDS_OctetsSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_OctetsDataReader * octetsReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_OctetsDataReader_take(octetsReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_OctetsSeq_get_length(&dataSeq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&infoSeq, i)->valid_data) { DDS_OctetsTypeSupport_print_data(

DDS_OctetsSeq_get_reference(&dataSeq, i));

}

}

/* Return loan */ retCode =

DDS_OctetsDataReader_return_loan(octetsReader, &dataSeq, &infoSeq);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

OctetsSeq dataSeq; SampleInfoSeq infoSeq;

OctetsDataReader * octetsReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = octetsReader->take(dataSeq, infoSeq, LENGTH_UNLIMITED, ANY_SAMPLE_STATE, ANY_VIEW_STATE,ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {

OctetsTypeSupport::print_data(&dataSeq[i]);

}

}

/* Return loan */

retCode = octetsReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

BytesSeq^ dataSeq = gcnew BytesSeq();

SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();

BytesDataReader^ octetsReader = ... ;

/* Take and print the data */

3-24

octetsReader->take(dataSeq, infoSeq, ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

BytesTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ octetsReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

BytesSeq dataSeq = new BytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); BytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

BytesTypeSupport.print_data(dataSeq.get_at(i));

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

BytesSeq dataSeq = new BytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); BytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println(((Bytes)dataSeq.get(i)).toString());

}

}

3-25

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

3.2.7KeyedOctets Built-in Type

The keyed octets built-in type is used to send sequences of octets with a key. The language- specific representations of the type are as follows:

C/C++ Representation (without Namespaces):

struct DDS_KeyedOctets { char * key;

int length;

unsigned char * value;

};

C++/CLI Representation:

namespace DDS {

public ref struct KeyedBytes { public:

System::String^ key; System::Int32 length; System::Int32 offset; array<System::Byte>^ value;

...

};

};

C# Representation:

namespace DDS {

public class KeyedBytes { public System.String key; public System.Int32 length; public System.Int32 offset; public System.Byte[] value;

};

};

Java Representation:

package com.rti.dds.type.builtin; public class KeyedBytes {

public String key; public int length; public int offset; public byte[] value;

...

};

3.2.7.1Creating and Deleting KeyedOctets

Connext provides a set of constructors/destructors to create/destroy KeyedOctets objects. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Built-in Types).

To manipulate the memory of the value field in the KeyedOctets struct in C/C++: use

DDS::OctetBuffer_alloc(), DDS::OctetBuffer_dup(), and DDS::OctetBuffer_free(). See the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, Octet Buffer Support).

3-26

To manipulate the memory of the key field in the KeyedOctets struct in C/C++: use

DDS::String_alloc(), DDS::String_dup(), and DDS::String_free(). See the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, String Support).

3.2.7.2Keyed Octets DataWriter

In addition to the standard methods (see Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)), the keyed octets DataWriter API is extended with the following methods:

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::dispose( const char* key,

const DDS::InstanceHandle_t & instance_handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::dispose_w_timestamp( const char* key,

const DDS::InstanceHandle_t & instance_handle, const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::get_key_value( char * key,

const DDS::InstanceHandle_t& handle);

DDS::InstanceHandle_t DDS::KeyedOctetsDataWriter::lookup_instance(

const char * key);

DDS::InstanceHandle_t DDS::KeyedOctetsDataWriter::register_instance(

const char* key);

DDS::InstanceHandle_t

DDS::KeyedOctetsDataWriter::register_instance_w_timestamp(

const char * key,

const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::unregister_instance( const char * key,

const DDS::InstanceHandle_t & handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::unregister_instance_w_timestamp(

const char* key,

const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write( const char * key,

const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write( const char * key,

const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write_w_timestamp( const char * key,

const unsigned char * octets, int length,

3-27

const DDS::InstanceHandle_t& handle, const DDS::Time_t& source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write_w_timestamp( const char * key,

const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);

These methods are introduced to provide maximum flexibility in the format of the input parameters for the write and instance management operations. For more information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.

The following examples show how to write keyed octets using a keyed octets built-in type DataWriter and some of the extended APIs. For simplicity, error handling is not shown.

C Example:

DDS_KeyedOctetsDataWriter * octetsWriter = ... ; DDS_ReturnCode_t retCode;

struct DDS_KeyedOctets * octets = NULL; char * octetArray = NULL;

/* Write some data using the KeyedOctets structure */ octets = DDS_KeyedOctets_new_w_size(128,1024); strcpy(octets->key, "Key 1");

octets->length = 2; octets->value[0] = 46; octets->value[1] = 47;

retCode = DDS_KeyedOctetsDataWriter_write(

octetsWriter, octets, &DDS_HANDLE_NIL);

DDS_KeyedOctets_delete(octets);

/* Write some data using an octets array */ octetArray = (unsigned char *)malloc(1024); octetArray[0] = 46;

octetArray[1] = 47;

retCode = DDS_KeyedOctetsDataWriter_write_octets_w_key ( octetsWriter, "Key 1", octetArray, 2, &DDS_HANDLE_NIL);

free(octetArray);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedOctetsDataWriter * octetsWriter = ... ;

/* Write some data using the KeyedOctets structure */ KeyedOctets * octets = new KeyedOctets(128,1024); strcpy(octets->key, "Key 1");

octets->length = 2; octets->value[0] = 46; octets->value[1] = 47;

3-28

ReturnCode_t

retCode = octetsWriter->write(octets, HANDLE_NIL);

delete octets;

 

/* Write some

data using an octet array */

unsigned char

* octetArray = new unsigned char[1024];

octetArray[0]

= 46;

octetArray[1]

= 47;

retCode = octetsWriter->write("Key 1", octetArray, 2, HANDLE_NIL);

delete []octetArray;

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedOctetsDataWriter^ octetsWriter = ... ;

/* Write some data using KeyedBytes */ KeyedBytes^ octets = gcnew KeyedBytes(1024); octets->key = "Key 1";

octets->value[0] =46; octets->value[1] =47; octets.length = 2; octets.offset = 0;

octetWriter->write(octets, InstanceHandle_t::HANDLE_NIL);

/* Write some data using individual strings */ array<Byte>^ octetAray = gcnew array<Byte>(1024); octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter->write(

"Key 1", octetArray, 0, 2, InstanceHandle_t::HANDLE_NIL);

C# Example:

using System; using DDS;

...

KeyedBytesDataWriter stringWriter = ... ;

/* Write some data using the KeyedBytes */ KeyedBytes octets = new KeyedBytes(1024); octets.key = "Key 1";

octets.value[0] = 46; octets.value[1] = 47; octets.length = 2; octets.offset = 0;

octetWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47;

3-29

octetsWriter.write(

"Key 1", octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

KeyedBytesDataWriter octetsWriter = ... ;

/* Write some data using the KeyedBytes class*/ KeyedBytes octets = new KeyedBytes(1024); octets.key = "Key 1";

octets.length = 2; octets.offset = 0; octets.value[0] = 46; octets.value[1] = 47;

octetsWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using a byte array */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47; octetsWriter.write(

"Key 1", octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

3.2.7.3Keyed Octets DataReader

The KeyedOctets DataReader API is extended with the following methods (in addition to the standard methods described in Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)):

DDS::ReturnCode_t DDS::KeyedOctetsDataReader::get_key_value( char * key,

const DDS::InstanceHandle_t* handle);

DDS::InstanceHandle_t DDS::KeyedOctetsDataReader::lookup_instance(

const char * key);

For more information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.

Memory considerations in copy operations:

For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the fields 'value' and 'key' if they are initialized to NULL.

If the fields are not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory of the field 'value' will be reallocated if the current size is not large enough to hold the received data. The memory associated with the field 'key' will be reallocated with every sample (the key is an immutable object).

In C and C++, the memory associated with the fields 'value' and 'key' must be large enough to hold the received data. Insufficient memory may result in crashes.

The following examples show how to read keyed octets with a keyed octets built-in type DataReader. For simplicity, error handling is not shown.

3-30

C Example:

struct DDS_KeyedOctetsSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_KeyedOctetsDataReader * octetsReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_KeyedOctetsDataReader_take( octetsReader,

&dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_KeyedOctetsSeq_get_length(&data_seq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&info_seq, i)->valid_data) { DDS_KeyedOctetsTypeSupport_print_data(

DDS_KeyedOctetsSeq_get_reference(&data_seq, i));

}

}

/* Return loan */

retCode = DDS_KeyedOctetsDataReader_return_loan( octetsReader, &data_seq, &info_seq);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedOctetsSeq dataSeq; SampleInfoSeq infoSeq;

KeyedOctetsDataReader * octetsReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = octetsReader->take( dataSeq, infoSeq, LENGTH_UNLIMITED,

ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE); for (int i = 0; i < data_seq.length(); ++i) {

if (infoSeq[i].valid_data) { KeyedOctetsTypeSupport::print_data(&dataSeq[i]);

}

}

/* Return loan */

retCode = octetsReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedBytesSeq^ dataSeq = gcnew KeyedBytesSeq(); SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq(); KeyedBytesDataReader^ octetsReader = ... ;

/* Take and print the data */ octetsReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE,

3-31

ViewStateKind::ANY_VIEW_STATE,

InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

KeyedBytesTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ octetsReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

KeyedBytesSeq dataSeq = new KeyedButesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); KeyedBytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

KeyedBytesTypeSupport.print_data(dataSeq.get_at(i));

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

KeyedBytesSeq dataSeq = new KeyedBytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); KeyedBytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println(((KeyedBytes)dataSeq.get(i)).toString());

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

3-32

3.2.8Managing Memory for Built-in Types

When a sample is written, the DataWriter serializes it and stores the result in a buffer obtained from a pool of preallocated buffers. In the same way, when a sample is received, the DataReader deserializes it and stores the result in a sample coming from a pool of preallocated samples.

For data types generated by rtiddsgen, the size of the buffers and samples in both pools is known based on the IDL or XML description of the type.

For example:

struct MyString { string<128> value;

};

This IDL-defined type has a maximum serialized size of 133 bytes (4 bytes for length + 128 characters + 1 NULL terminating character). So the serialization buffers will have a size of 133 bytes. It can hold samples with 128 characters strings. Consequently, the preallocated samples will be sized to keep this length.

However, for built-in types, the maximum size of the buffers/samples is unknown and depends on the nature of the application using the built-in type.

For example, a video surveillance application that is using the keyed octets built-in type to publish a stream of images will require bigger buffers than a market-data application that uses the same built-in type to publish market-data values.

To accommodate both kinds of applications and optimize memory usage, you can configure the maximum size of the built-in types on a per-DataWriter or per-Datareader basis using the PROPERTY QosPolicy (DDS Extension) (Section 6.5.17). Table 3.1 on page 3-34 lists the supported built-in type properties. When the properties are defined in the DomainParticipant, they are applicable to all DataWriters and DataReaders belonging to the DomainParticipant, unless they are overwritten in the DataWriters and DataReaders.

Note: These properties must be set consistently with respect to the corresponding *.max_size properties in the DomainParticipant (see Table 3.14 on page 3-91). The value of the alloc_size property must be less than or equal to the max_size property with the same name prefix in the

DomainParticipant.

Section 3.2.8.1 includes examples of how to set the maximum size of a string built-in type for a DataWriter programmatically, for each API. You can also set the maximum size of the built-in types using XML QoS Profiles. For example, the following XML shows how to set the maximum size of a string built-in type for a DataWriter.

<dds>

<qos_library name="BuiltinExampleLibrary"> <qos_profile name="BuiltinExampleProfile">

<datawriter_qos> <property>

<value>

<element> <name>dds.builtin_type.string.alloc_size</name> <value>2048</value>

</element>

</value>

</property> </datawriter_qos> <datareader_qos>

<property>

<value>

<element>

3-33

<name>dds.builtin_type.string.alloc_size</name> <value>2048</value>

</element>

</value>

</property> </datareader_qos>

</qos_profile> </qos_library>

</dds>

Table 3.1 Properties for Allocating Size of Built-in Types, per DataWriter and DataReader

Built-in

Property

 

 

Description

 

 

 

Type

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the strings published by the DataWriter

 

 

or received by the DataReader (includes the NULL-

string

dds.builtin_type.string.alloc_size

terminated character).

 

 

 

 

 

 

Default: dds.builtin_type.string.max_size if defined (see

 

 

Table 3.14 on page 3-91). Otherwise, 1024.

 

 

 

 

 

 

 

 

Maximum size of the keys used by the DataWriter or

 

dds.builtin_type.keyed_string.

DataReader (includes the NULL-terminated character).

 

 

alloc_key_size

Default: dds.builtin_type.keyed_string.max_key_size if

 

 

defined (see Table 3.14 on page 3-91). Otherwise, 1024.

 

keyedstring

 

 

 

Maximum size of the strings published by the DataWriter

 

dds.builtin_type.keyed_string.

or received

by the DataReader

(includes

the

NULL-

 

terminated character).

 

 

 

 

 

alloc_size

 

 

 

 

 

Default:

dds.builtin_type.keyed_string.max_size

if

 

 

 

 

defined (see Table 3.14 on page 3-91). Otherwise, 1024.

 

 

 

 

 

 

Maximum size of the octet sequences published by the

octets

dds.builtin_type.octets.alloc_size

DataWriter or DataReader.

 

 

 

 

Default: dds.builtin_type.octets.max_size if defined (see

 

 

Table 3.14 on page 3-91). Otherwise, 2048.

 

 

 

 

 

 

 

 

Maximum size of the key published by the DataWriter or

 

dds.builtin_type.keyed_octets.

received

by

the DataReader

(includes

the

NULL-

 

terminated character).

 

 

 

 

 

alloc_key_size

 

 

 

 

 

Default:

dds.builtin_type.keyed_octets.max_key_size if

 

 

keyed-octets

 

defined (see Table 3.14 on page 3-91). Otherwise, 1024.

 

 

 

Maximum size of the octet sequences published by the

 

dds.builtin_type.keyed_octets.

DataWriter or DataReader.

 

 

 

 

 

alloc_size

Default:

dds.builtin_type.keyed_octets.max_size

if

 

 

defined (see Table 3.14 on page 3-91). Otherwise, 2048.

 

 

 

 

 

 

 

 

 

 

3.2.8.1Examples—Setting the Maximum Size for a String Programmatically

For simplicity, error handling is not shown in the following examples.

C Example:

DDS_DataWriter * writer = NULL; DDS_StringDataWriter * stringWriter = NULL; DDS_Publisher * publisher = ... ;

DDS_Topic * stringTopic = ... ;

struct DDS_DataWriterQos writerQos = DDS_DataWriterQos_INITIALIZER; DDS_ReturnCode_t retCode;

retCode = DDS_DomainParticipant_get_default_datawriter_qos ( participant, &writerQos);

3-34

retCode = DDS_PropertyQosPolicyHelper_add_property ( &writerQos.property, "dds.builtin_type.string.alloc_size", "1000", DDS_BOOLEAN_FALSE);

writer = DDS_Publisher_create_datawriter(

publisher, stringTopic, &writerQos, NULL, DDS_STATUS_MASK_NONE);

stringWriter = DDS_StringDataWriter_narrow(writer); DDS_DataWriterQos_finalize(&writerQos);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

Publisher * publisher = ... ;

Topic * stringTopic = ... ;

DataWriterQos writerQos;

ReturnCode_t retCode = participant->get_default_datawriter_qos(writerQos);

retCode = PropertyQosPolicyHelper::add_property ( &writerQos.property, dds.builtin_type.string.alloc_size",

"1000",

BOOLEAN_FALSE);

DataWriter * writer = publisher->create_datawriter( stringTopic, writerQos, NULL, STATUS_MASK_NONE);

StringDataWriter * stringWriter = StringDataWriter::narrow(writer);

C++/CLI Example:

using namespace DDS;

...

Topic^ stringTopic = ... ;

Publisher^ publisher = ... ;

DataWriterQos^ writerQos = gcnew DataWriterQos();

participant->get_default_datawriter_qos(writerQos);

PropertyQosPolicyHelper::add_property(writerQos->property_qos,

"dds.builtin_type.string.alloc_size","1000", false);

DataWriter^ writer = publisher->create_datawriter(stringTopic, writerQos, nullptr, StatusMask::STATUS_MASK_NONE);

StringDataWriter^ stringWriter = safe_cast<StringDataWriter^>(writer);

C# Example:

using DDS;

...

Topic stringTopic = ... ;

Publisher publisher = ... ;

3-35

DataWriterQos writerQos = new DataWriterQos();

participant.get_default_datawriter_qos(writerQos);

PropertyQosPolicyHelper.add_property (writerQos.property_qos,

"dds.builtin_type.string.alloc_size", "1000", false);

StringDataWriter stringWriter =

(StringDataWriter) publisher.create_datawriter(stringTopic, writerQos, null, StatusMask.STATUS_MASK_NONE);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

Topic stringTopic = ... ;

Publisher publisher = ... ;

DataWriterQos writerQos = new DataWriterQos();

participant.get_default_datawriter_qos(writerQos);

PropertyQosPolicyHelper.add_property (writerQos.property,

"dds.builtin_type.string.alloc_size", "1000", false);

StringDataWriter stringWriter =

(StringDataWriter) publisher.create_datawriter(stringTopic, writerQos, null, StatusKind.STATUS_MASK_NONE);

3.2.9Type Codes for Built-in Types

The type codes associated with the built-in types are generated from the following IDL type definitions:

module DDS {

/* String */ struct String {

string<max_size> value;

};

/* KeyedString */ struct KeyedString {

string<max_size> key; //@key string<max_size> value;

};

/* Octets */ struct Octets {

sequence<octet, max_size> value;

};

/* KeyedOctets */ struct KeyedOctets {

string<max_size> key; //@key sequence<octet, max_size> value;

};

};

The maximum size (max_size) of the strings and sequences that will be included in the type code definitions can be configured on a per-DomainParticipant-basis by using the properties in

3-36

Table 3.2.

Table 3.2 Properties for Allocating Size of Built-in Types, per DomainParticipant

Built-in

Property

 

 

Description

 

 

 

 

Type

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the strings published by the DataWriters

 

 

and received by the DataReaders belonging to a

String

dds.builtin_type.string.max_size

DomainParticipant (includes the NULL-terminated

 

 

character).

 

 

 

 

 

 

 

 

 

 

Default: 1024

 

 

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the keys used by the DataWriters and

 

dds.builtin_type.keyed_string.

DataReaders belonging to a DomainParticipant (includes the

 

max_key_size

NULL-terminated character).

 

 

 

 

 

 

 

Default: 1024

 

 

 

 

 

 

 

 

KeyedString

 

 

 

Maximum size of the strings published by the DataWriters

 

dds.builtin_type.keyed_string.

and received

by

the

DataReaders

belonging to

a

 

DomainParticipant using

the

built-in

type (includes

the

 

max_size

 

NULL-terminated character).

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Default: 1024

 

 

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the octet sequences published by the

Octets

dds.builtin_type.octets.max_size

DataWriters

and

DataReaders

belonging

to

a

DomainParticipant.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Default: 2048

 

 

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the key published by the DataWriter and

 

dds.builtin_type.keyed_octets.

received by

the

DataReaders

belonging

to

the

 

DomainParticipant (includes

the

 

NULL-terminated

 

max_key_size

 

 

character).

 

 

 

 

 

 

 

 

Keyed-

 

 

 

 

 

 

 

 

 

 

Default:1024.

 

 

 

 

 

 

 

 

Octets

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the octet sequences published by the

 

 

 

dds.builtin_type.keyed_octets.

DataWriters and DataReaders belonging to a

 

max_size

DomainParticipant.

 

 

 

 

 

 

 

 

 

Default: 2048

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.3Creating User Data Types with IDL

You can create user data types in a text file using IDL (Interface Description Language). IDL is programming-language independent, so the same file can be used to generate code in C, C++, C++/CLI, and Java (the languages supported by rtiddsgen). The rtiddsgen utility parses the IDL file and automatically generates all the necessary routines and wrapper functions to bind the types for use by Connext at run time. You will end up with a set of required routines and structures that your application and Connext will use to manipulate the data.

Connext only uses a subset of the IDL syntax. IDL was originally defined by the OMG for the use of CORBA client/server applications in an enterprise setting. Not all of the constructs that can be described by the language are as useful in the context of high-performance data-centric embedded applications. These include the constructs that define method and function prototypes like “interface.”

The rtiddsgen utility will parse any file that follows version 3.0.3 of the IDL specification. It will quietly ignore all syntax that is not recognized by Connext. In addition, even though “anonymous sequences” (sequences of sequences with no intervening typedef) are currently

3-37

legal in IDL, they have been deprecated by the specification, and thus rtiddsgen does not support them.

Certain keywords are considered reserved by the IDL specification; see Table 3.3.

Table 3.3 Reserved IDL Keywords

abstract

emits

local

pseudo

typeid

 

 

 

 

 

alias

enum

long

public

typename

 

 

 

 

 

any

eventtype

mirrorport

publishes

typeprefix

 

 

 

 

 

attribute

exception

module

raises

union

 

 

 

 

 

boolean

factory

multiple

readonly

unsigned

 

 

 

 

 

case

FALSE

native

sequence

uses

 

 

 

 

 

char

finder

object

setraises

valuebase

 

 

 

 

 

component

fixed

octet

short

valuetype

 

 

 

 

 

connector

float

oneway

string

void

 

 

 

 

 

const

getraises

out

struct

wchar

 

 

 

 

 

consumes

home

port

supports

wstring

 

 

 

 

 

context

import

porttype

switch

 

 

 

 

 

 

custom

in

primarykey

TRUE

 

 

 

 

 

 

default

inout

private

truncatable

 

 

 

 

 

 

double

interface

provides

typedef

 

 

 

 

 

 

The IDL constructs supported by rtiddsgen are described in Table 3.5, “Specifying Data Types in IDL for C and C++,” on page 3-41 and Table 3.7, “Specifying Data Types in IDL for Java,” on page 3-48. Use these tables to map primitive types to their equivalent IDL syntax, and vice versa.

For C and C++, rtiddsgen uses typedefs instead of the language keywords for primitive types. For example, DDS_Long instead of long or DDS_Double instead of double. This ensures that the types are of the same size regardless of the platform.1

The remainder of this section includes:

Variable-Length Types (Section 3.3.1)

Value Types (Section 3.3.2)

TypeCode and rtiddsgen (Section 3.3.3)

rtiddsgen Translations for IDL Types (Section 3.3.4)

Escaped Identifiers (Section 3.3.5)

Referring to Other IDL Files (Section 3.3.6)

Preprocessor Directives (Section 3.3.7)

Using Custom Directives (Section 3.3.8)

1. The number of bytes sent on the wire for each data type is determined by the Common Data Representation (CDR) standard. For details on CDR, please see the Common Object Request Broker Architecture (CORBA) Specification, Version 3.1, Part 2: CORBA Interoperability, Section 9.3, CDR Transfer Syntax (http://www.omg.org/ technology/documents/corba_spec_catalog.htm).

3-38

3.3.1Variable-Length Types

When rtiddsgen generates code for data structures with variable-length types—strings and sequences—it includes functions that create, initialize and finalize (destroy) those objects. These support functions will properly initialize pointers and allocate and deallocate the memory used for variable-length types. All Connext APIs assume that the data structures passed to them are properly initialized.

For variable-length types, the actual length (instead of the maximum length) of data is transmitted on the wire when the sample is written (regardless of whether the type has hard- coded bounds).

3.3.1.1Sequences

C, C++, C++/CLI, and C# users can allocate memory from a number of sources: from the heap, the stack, or from a custom allocator of some kind. In those languages, sequences provide the concept of memory "ownership." A sequence may own the memory allocated to it or be loaned memory from another source. If a sequence owns its memory, it will manage its underlying memory storage buffer itself. When a sequence's maximum size is changed, the sequence will free and reallocate its buffer as needed. However, if a sequence was created with loaned memory by user code, then its memory is not its own to free or reallocate. Therefore, you cannot set the maximum size of a sequence whose memory is loaned. See the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Infrastructure Module, Sequence Support) for more information about how to loan and unloan memory for sequence.

In IDL, as described above, a sequence may be declared as bounded or unbounded. A sequence's "bound" is the greatest value its maximum may take. If you use the initializer functions rtiddsgen provides for your types, all sequences will have their maximums set to their declared bounds. However, the amount of data transmitted on the wire when the sample is written will vary.

3.3.1.2Strings and Wide Strings

The initialization functions that rtiddsgen provides for your types will allocate all of the memory for strings in a type to their declared bounds. Take care—if you assign a string pointer (char *) in a data structure allocated or initialized by a Connext-generated function, you should release (free) the memory originally allocated for the string, otherwise the memory will be leaked.

To Java and .NET users, an IDL string is a String object: it is immutable and knows its own length. C and C++ users must take care, however, as there is no way to determine how much memory is allocated to a character pointer "string"; all that can be determined is the string's current logical length. In some cases, Connext may need to copy a string into a structure that user code has provided. Connext does not free the memory of the string provided to it, as it cannot know from where that memory was allocated.

In the C and C++ APIs, Connext therefore uses the following conventions:

A string's memory is "owned" by the structure that contains that string. Calling the finalization function provided for a type will free all recursively contained strings. If you have allocated a contained string in a special way, you must be careful to clean up your own memory and assign the pointer to NULL before calling the type’s finalize() method, so that Connext will skip over that string.

You must provide a non-NULL string pointer for Connext to copy into. Otherwise, Connext will log an error.

3-39

When you provide a non-NULL string pointer in your data structure, Connext will copy into the provided memory without performing any additional memory allocations. Be careful—if you provide Connext with an uninitialized pointer or allocate a string that is too short, you may corrupt the memory or cause a program crash. Connext will never try to copy a string that is longer than the bound of the destination string. However, your application must insure that any string that it allocates is long enough.

Connext provides a small set of C functions for dealing with strings. These functions simplify common tasks, avoid some platform-specific issues (such as the lack of a strdup() function on some platforms), and provide facilities for dealing with wide strings, for which no standard C library exists. Connext always uses these functions internally for managing string memory; you are recommended—but not required—to use them as well. See the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Infrastructure Module, String Support) for more information about strings.

3.3.2Value Types

A value type is like a structure, but with support for additional object-oriented features such as inheritance. It is similar to what is sometimes referred to in Java as a POJO—a Plain Old Java Object.

Readers familiar with value types in the context of CORBA should consult Table 3.4 to see which value type-related IDL keywords are supported and what their behavior is in the context of

Connext.

Table 3.4 Value Type Support

Aspect

Level of Support in rtiddsgen

 

 

Inheritance

Single inheritance from other value types

 

 

Public state members

Supported

 

 

Private state members

Become public when code is generated

 

 

Custom keyword

Ignored (the value type is parsed without the keyword and code is generated to

work with it)

 

 

 

Abstract value types

No code generated (the value type is parsed, but no code is generated)

 

 

Operations

No code generated (the value type is parsed, but no code is generated)

 

 

Truncatable keyword

Ignored (the value type is parsed without the keyword and code is generated to

work with it)

 

 

 

3.3.3TypeCode and rtiddsgen

Type codes are enabled by default when you run rtiddsgen. The -notypecode option disables generation of type code information. Type-code support does increase the amount of memory used, so if you need to save on memory, you may consider disabling type codes.

(The -notypecode option is described in rtiddsgen Command-Line Arguments (Section 3.6.1)

Locally, your application can access the type code for a generated type "Foo" by calling the Foo::get_typecode() operation in the code for the type generated by rtiddsgen (unless type-code support is disabled with the -notypecode option).

Note: Type-code support must be enabled if you are going to use ContentFilteredTopics (Section 5.4) with the default SQL filter. You may disable type codes and use a custom filter, as described in Creating ContentFilteredTopics (Section 5.4.3).

3-40

3.3.4rtiddsgen Translations for IDL Types

This section describes how to specify your data types in an IDL file. The rtiddsgen utility supports all the types listed in the following tables:

Table 3.5, “Specifying Data Types in IDL for C and C++,” on page 3-41

Table 3.6, “Specifying Data Types in IDL for C++/CLI,” on page 3-45

Table 3.7, “Specifying Data Types in IDL for Java,” on page 3-48

In each table, the middle column shows the syntax for an IDL data type in the IDL file. The rightmost column shows the corresponding language mapping created by rtiddsgen.

Table 3.5 Specifying Data Types in IDL for C and C++

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

char

struct PrimitiveStruct {

typedef struct PrimitiveStruct

{

(see Note 1

char char_member;

DDS_Char char_member;

below)

};

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

wchar

{

wchar wchar_member;

DDS_Wchar wchar_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

{

octet

octet octet_member;

DDS_Octet octect_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

short

{

short short_member;

DDS_Short short_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

unsigned

{

unsigned short

DDS_UnsignedShort

short

unsigned_short_member;

unsigned_short_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

long

{

long long_member;

DDS_Long long_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

unsigned

{

unsigned long

DDS_UnsignedLong

long

unsigned_long_member;

unsigned_long_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

{

long long

long long long_long_member;

DDS_LongLong long_long_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

unsigned

{

unsigned long long

DDS_UnsignedLongLong

long long

unsigned_long_long_member;

unsigned_long_long_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

float

{

float float_member;

DDS_Float float_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

3-41

Table 3.5 Specifying Data Types in IDL for C and C++

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

double

{

double double_member;

DDS_Double double_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

long

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

double

{

long double long_double_member;

(see Note 2

DDS_LongDouble long_double_member;

};

} PrimitiveStruct;

below)

 

 

 

 

pointer

struct MyStruct {

typedef struct MyStruct {

(see Note 9

long * member;

DDS_Long * member;

below)

};

} MyStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

boolean

{

boolean boolean_member;

DDS_Boolean boolean_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

enum PrimitiveEnum {

typedef enum PrimitiveEnum

 

 

{

 

 

ENUM1,

 

 

ENUM1,

 

 

ENUM2,

 

 

ENUM2,

 

 

ENUM3

 

 

ENUM3

 

 

};

 

 

} PrimitiveEnum;

 

 

 

enum

 

 

 

 

 

enum PrimitiveEnum {

typedef enum PrimitiveEnum

 

 

{

 

 

ENUM1 = 10,

 

 

ENUM1 = 10,

 

 

ENUM2 = 20,

 

 

ENUM2 = 20,

 

 

ENUM3 = 30

 

 

ENUM3 = 30

 

 

};

 

 

} PrimitiveEnum;

 

 

 

 

 

 

 

 

 

 

C: #define SIZE 5

constant

const short SIZE = 5;

C++: static const DDS_Short size = 5;

 

 

 

 

 

 

 

typedef struct BitfieldType

 

 

struct BitfieldType {

{

 

 

short myShort_1 : 1;

DDS_Short myShort_1 : 1;

 

 

unsigned short myUnsignedShort_1:

DDS_UnsignedShort myUnsignedShort_1

 

 

1;

: 1;

 

 

long myLong_1: 1;

DDS_Long myLong_1 : 1;

 

 

unsigned long myUnsignedLong_1 :1;

DDS_UnsignedLong myUnsignedLong_1 :

bitfield

char myChar_1 : 1;

1;

wchar myWChar_1 : 1;

DDS_Char myChar_1 : 1;

 

 

 

 

octet myOctet_1 : 1;

DDS_Wchar myWChar_1 : 1;

(see

Note

short : 0;

DDS_Octet myOctet_1 : 1;

12 below)

long myLong_5 : 5;

DDS_Short : 0;

long myLong_30 : 30;

DDS_Long myLong_5 : 5;

 

 

 

 

short myShort_6 : 6;

DDS_Long myLong_30 : 30;

 

 

short myShort_3and4 : 3+4;

DDS_Short myShort_6 : 6;

 

 

short myShort;

DDS_Short myShort_3and4 : 3+4;

 

 

short myShort_8 : 8;

DDS_Short myShort;

 

 

long myLong_32: 32;

DDS_Short myShort_8 : 8;

 

 

};

DDS_Long myLong_32 : 32;

 

 

 

} BitfieldType;

 

 

 

 

struct

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

 

 

 

{

 

 

char char_member;

(see

Note

char char_member;

};

} PrimitiveStruct;

10 below)

 

 

 

 

 

 

 

3-42

Table 3.5 Specifying Data Types in IDL for C and C++

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

 

 

typedef struct PrimitiveUnion

 

union

 

union PrimitiveUnion switch (long){

{

 

 

 

 

case 1:

DDS_Long _d;

 

 

(see Note 3

short short_member;

struct {

 

 

default:

DDS_Short short_member;

 

and

Note

 

long long_member;

DDS_Long long_member;

 

10 below)

};

} _u;

 

 

 

 

 

} PrimitiveUnion;

 

 

 

 

 

 

typedef

typedef short TypedefShort;

typedef DDS_Short TypedefShort;

 

 

 

 

 

 

 

 

struct OneDArrayStruct {

typedef struct OneDArrayStruct

 

 

 

{

 

 

 

 

short short_array[2];

 

 

 

 

DDS_Short short_array[2];

 

array

of

};

 

} OneDArrayStruct;

 

 

above

 

struct TwoDArrayStruct {

 

 

 

types

 

typedef struct TwoDArrayStruct

 

 

short short_array[1][2];

 

 

 

{

 

 

 

 

};

 

 

 

 

DDS_Short short_array[1][2];

 

 

 

 

 

 

 

 

} TwoDArrayStruct;

 

 

 

 

 

 

 

bounded

 

typedef struct SequenceStruct

 

sequence of

 

 

 

{

 

 

above

 

 

 

 

 

struct SequenceStruct {

DDSShortSeq short_sequence;

 

types

 

sequence<short,4> short_sequence;

} SequenceStruct;

 

 

 

 

};

Note: Sequences of primitive types have been

(see

Note

 

 

predefined by Connext.

 

 

11 below)

 

 

 

 

 

 

 

 

 

 

 

 

unbounded

 

typedef struct SequenceStruct

 

 

{

 

 

sequence of

 

 

 

 

DDSShortSeq short_sequence;

 

above

 

struct SequenceStruct {

} SequenceStruct;

 

 

types

 

sequence<short> short_sequence;

Note: rtiddsgen will supply a default bound.

 

 

};

(see

Note

 

You can specify that bound

with the

“-

 

sequenceSize” command-line

option;

see

11 below)

 

 

Section 3.6.1.

 

 

 

 

 

 

 

 

 

 

 

 

array

of

struct ArraysOfSequences{

typedef struct ArraysOfSequences

 

sequence<short,4>

{

 

 

sequences

sequences_array[2];

DDS_ShortSeq sequences_array[2];

 

 

 

};

} ArraysOfSequences;

 

 

 

 

 

 

 

 

 

 

typedef DDS_Short ShortArray[2];

 

 

 

 

DDS_SEQUENCE_NO_GET(ShortArraySeq,

 

 

 

 

ShortArray);

 

sequence of

typedef short ShortArray[2];

typedef struct SequenceOfArrays

 

arrays

 

 

 

 

struct SequenceofArrays {

{

 

 

 

 

 

 

(see

Note

sequence<ShortArray,2>

ShortArraySeq arrays_sequence;

 

arrays_sequence;

} SequenceOfArrays;

 

 

11 below)

};

DDS_SEQUENCE_NO_GET is a Connext

 

 

 

 

 

 

macro that defines a new sequence type for a

 

 

 

user data type. In this case, the user data type is

 

 

 

ShortArray.

 

 

 

 

 

 

 

 

3-43

Table 3.5 Specifying Data Types in IDL for C and C++

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

typedef sequence<short,4>

typedef DDS_ShortSeq ShortSequence;

 

sequence of

 

 

 

 

sequences

ShortSequence;

DDS_SEQUENCE(ShortSequenceSeq,

 

 

 

 

struct SequencesOfSequences{

 

ShortSequence);

 

 

 

 

 

 

(see Note 4

sequence<ShortSequence,2>

typedef struct SequencesOfSequences{

 

sequences_sequence;

 

and Note

ShortSequenceSeq

 

 

};

 

 

11 below)

sequences_sequence;

 

 

 

 

 

 

 

} SequencesOfSequences;

 

 

 

 

 

 

bounded

struct PrimitiveStruct {

typedef struct PrimitiveStruct {

 

char* string_member;

 

 

string<20> string_member;

 

 

string

 

/* maximum length = (20) */

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

 

 

 

typedef struct PrimitiveStruct {

 

 

 

char* string_member;

 

 

 

struct PrimitiveStruct {

 

/* maximum length = (255) */

unbounded

} PrimitiveStruct;

 

 

string string_member;

 

 

 

 

 

 

string

};

Note: rtiddsgen will supply a default bound.

 

 

 

 

You can specify that bound with the -

 

 

stringSize

command-line

option,

see

 

 

Section 3.6.1.

 

 

 

 

 

 

 

 

typedef struct PrimitiveStruct {

 

bounded

struct PrimitiveStruct {

DDS_Wchar * wstring_member;

 

wstring<20> wstring_member;

 

/* maximum length = (20)

wstring

 

};

*/

 

 

 

 

 

 

 

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

typedef struct PrimitiveStruct {

 

unbounded

struct PrimitiveStruct {

DDS_Wchar * wstring_member;

 

 

/* maximum length = (255) */

wstring

wstring wstring_member;

} PrimitiveStruct;

 

 

};

 

 

 

 

 

 

 

 

 

Note: rtiddsgen will supply a default bound.

 

 

 

 

 

 

 

With the -namespace option

(only available

 

 

for C++):

 

 

 

 

 

namespace PackageName{

 

 

module PackageName {

 

typedef struct Foo {

 

module

struct Foo {

 

DDS_Long field;

 

long field;

 

} Foo;

 

 

 

};

};

 

 

 

 

};

Without the -namespace option:

 

 

 

typedef struct PackageName_Foo {

 

 

 

DDS_Long field;

 

 

 

 

} PackageName_Foo;

 

 

 

 

 

 

 

 

3-44

Table 3.5 Specifying Data Types in IDL for C and C++

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

 

 

C++:

class MyValueType {

 

 

 

 

public:

 

 

 

 

 

MyValueType2 * member;

 

 

 

 

};

 

 

 

 

 

class MyValueType {

 

 

 

 

public:

 

 

 

valuetype MyValueType {

 

MyValueType2

member;

 

 

 

};

 

 

 

public MyValueType2 * member;

 

 

 

 

 

 

 

 

 

};

 

class MyValueType : public MyBa-

 

 

 

 

 

valuetype

 

 

seValueType

 

 

valuetype MyValueType {

 

{

 

 

 

 

public:

 

 

 

public MyValueType2 member;

 

 

 

(see Note 9

 

MyValueType2 * member;

 

};

 

 

 

};

 

 

and Note

 

 

 

 

 

 

 

 

 

 

C:

 

 

 

10 below)

 

typedef struct MyValueType {

 

 

valuetype MyValueType: MyBaseValueType

 

MyValueType2 * member;

 

 

{

 

} MyValueType;

 

 

 

public MyValueType2 * member;

 

 

 

 

 

};

 

typedef struct MyValueType {

 

 

 

 

MyValueType2

member;

 

 

 

 

} MyValueType;

 

 

 

 

 

typedef struct MyValueType

 

 

 

 

{

 

 

 

 

 

MyBaseValueType parent;

 

 

 

 

MyValueType2 * member;

 

 

 

 

} MyValueType;

 

 

 

 

 

 

 

Table 3.6 Specifying Data Types in IDL for C++/CLI

 

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

char

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

(see Note 1

char char_member;

System::Char char_member;

 

below)

};

};

 

 

 

 

 

 

 

wchar

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

wchar wchar_member;

System::Char wchar_member;

 

 

};

};

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

octet

octet octet_member;

System::Byte octet_member;

 

 

};

};

 

 

 

 

 

 

 

short

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

short short_member;

System::Int16 short_member;

 

 

};

};

 

 

 

 

 

 

 

 

 

unsigned

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

unsigned short

 

System::UInt16 unsigned_short_member;

 

short

unsigned_short_member;

 

};

 

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

 

long

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

long long_member;

System::Int32 long_member;

 

 

};

};

 

 

 

 

 

 

 

unsigned

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

unsigned long unsigned_long_member;

System::UInt32 unsigned_long_member;

 

long

 

};

};

 

 

 

 

 

 

 

 

 

 

 

 

3-45

Table 3.6 Specifying Data Types in IDL for C++/CLI

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

long long

struct PrimitiveStruct {

public ref class PrimitiveStruct {

long long long_long_member;

System::Int64 long_long_member;

 

 

};

};

 

 

 

 

unsigned

struct PrimitiveStruct {

public ref class PrimitiveStruct {

unsigned long long

System::UInt64

long long

unsigned_long_long_member;

unsigned_long_long_member;

 

 

};

};

 

 

 

 

float

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

float float_member;

System::Single float_member;

 

 

};

};

 

 

 

 

 

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

double

double double_member;

System::Double double_member;

 

 

};

} PrimitiveStruct;

 

 

 

 

long

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

double

long double long_double_member;

DDS::LongDouble long_double_member;

(see Note 2

};

} PrimitiveStruct;

below)

 

 

 

 

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

boolean

boolean boolean_member;

System::Boolean boolean_member;

 

 

};

};

 

 

 

 

 

 

 

public enum class

 

 

enum PrimitiveEnum {

PrimitiveEnum : System::Int32 {

 

 

ENUM1,

ENUM1,

 

 

ENUM2,

ENUM2,

 

 

ENUM3

ENUM3

enum

 

};

};

 

 

 

 

 

enum PrimitiveEnum {

public enum class

 

 

ENUM1 = 10,

PrimitiveEnum : System::Int32 {

 

 

ENUM2 = 20,

ENUM1 = 10,

 

 

ENUM3 = 30

ENUM2 = 20,

 

 

};

ENUM3 = 30

 

 

 

};

 

 

 

 

 

 

 

public ref class SIZE {

constant

const short SIZE = 5;

public:

static System::Int16 VALUE = 5;

 

 

 

 

 

 

};

 

 

 

 

struct

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

 

 

 

 

(see

Note

char char_member;

System::Char char_member;

};

};

10 below)

 

 

 

 

 

 

 

 

 

 

public ref class PrimitiveUnion

union

 

union PrimitiveUnion switch (long){

{

 

 

case 1:

System::Int32 _d;

(see Note 3

short short_member;

struct PrimitiveUnion_u {

default:

System::Int16 short_member;

and

Note

long long_member;

System::Int32 long_member;

10 below)

};

} _u;

 

 

 

};

 

 

 

 

array

of

struct OneDArrayStruct {

public ref class OneDArrayStruct {

array<System::Int16>^ short_array;

above

 

short short_array[2];

 

/*length == 2*/

types

 

};

 

};

 

 

 

 

 

 

 

3-46

Table 3.6 Specifying Data Types in IDL for C++/CLI

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

 

bounded

 

public ref class SequenceStruct {

 

sequence of

 

 

 

ShortSeq^ short_sequence;

 

above

 

 

 

 

struct SequenceStruct {

/*max = 4*/

 

 

types

 

sequence<short,4> short_sequence;

};

 

 

 

 

 

};

Note: Sequences of primitive types have been

(see

Note

 

 

predefined by Connext.

 

 

11 below)

 

 

 

 

 

 

 

 

 

 

 

 

unbounded

 

public ref class SequenceStruct {

 

sequence of

 

ShortSeq^ short_sequence;

 

above

 

struct SequenceStruct {

/*max = <default bound>*/

 

 

};

 

 

 

types

 

 

 

 

 

sequence<short> short_sequence;

 

 

 

 

Note: rtiddsgen will supply a default bound.

 

 

};

 

 

You can specify that bound with the

 

(see

Note

 

 

 

-sequenceSize command-line option; see

11 below)

 

Section 3.6.1.

 

 

 

 

 

 

 

 

 

 

 

public ref class ArraysOfSequences

 

array

of

struct ArraysOfSequences{

{

 

 

 

sequence<short,4>

array<DDS::ShortSeq^>^

 

 

sequences

sequences_array[2];

sequences_array;

 

 

 

 

};

// maximum length = (2)

 

 

 

 

 

};

 

 

 

 

 

 

 

 

bounded

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

System::String^ string_member;

 

string<20> string_member;

 

string

 

// maximum length = (20)

 

 

};

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public ref class PrimitiveStruct {

 

 

 

 

System::String^ string_member;

 

unbounded

struct PrimitiveStruct {

// maximum length = (255)

 

string string_member;

};

 

 

 

string

 

};

Note: rtiddsgen will supply a default bound.

 

 

 

You can specify that bound with the -

 

 

 

stringSize

command-line

option,

see

 

 

 

Section 3.6.1.

 

 

 

 

 

 

 

 

bounded

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

System::String^ string_member;

 

wstring<20> wstring_member;

 

wstring

// maximum length = (20)

 

};

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public ref class PrimitiveStruct {

 

 

 

 

System::String^ string_member; //

 

 

struct PrimitiveStruct {

maximum length = (255)

 

 

unbounded

};

 

 

 

wstring

wstring wstring_member;

Note: rtiddsgen will supply a default bound.

};

 

 

You can specify that bound with the -

 

 

 

 

 

 

stringSize

command-line

option,

see

 

 

 

Section 3.6.1.

 

 

 

 

 

 

 

 

 

 

 

module PackageName {

namespace PackageName {

 

 

module

struct Foo {

public ref class Foo {

 

 

long field;

System::Int32 field;

 

 

 

};

};

 

 

 

 

 

};

};

 

 

 

 

 

 

 

 

 

 

3-47

Table 3.7 Specifying Data Types in IDL for Java

IDL Type

Sample Entry in IDL file

Sample Java Output Generated by

rtiddsgen

 

 

 

 

 

 

 

char

 

 

public class PrimitiveStruct

 

 

struct PrimitiveStruct {

{

(see Note

5

char char_member;

public char char_member;

};

...

below)

 

 

}

 

 

 

 

wchar

 

 

public class PrimitiveStruct

 

 

struct PrimitiveStruct {

{

(see Note

5

wchar wchar_member;

public char wchar_member;

};

...

below)

 

 

}

 

 

 

 

 

 

 

public class PrimitiveStruct

octet

 

struct PrimitiveStruct {

{

 

octet octet_member;

public byte byte_member;

 

 

};

...

 

 

 

}

 

 

 

 

 

 

 

public class PrimitiveStruct

short

 

struct PrimitiveStruct {

{

 

short short_member;

public short short_member;

 

 

};

...

 

 

 

}

 

 

 

 

unsigned

 

struct PrimitiveStruct {

public class PrimitiveStruct

short

 

 

{

 

 

unsigned short

 

 

public short unsigned_short_member;

 

 

unsigned_short_member;

(see Note

6

...

};

}

below)

 

 

 

 

 

 

 

 

 

 

 

 

public class PrimitiveStruct

long

 

struct PrimitiveStruct {

{

 

long long_member;

public int long_member;

 

 

};

...

 

 

 

}

 

 

 

 

unsigned

 

struct PrimitiveStruct {

public class PrimitiveStruct

long

 

 

{

 

 

unsigned long

 

 

public int unsigned_long_member;

 

 

unsigned_long_member;

(see Note

6

...

};

}

below)

 

 

 

 

 

 

 

 

 

 

 

 

public class PrimitiveStruct

long long

 

struct PrimitiveStruct {

{

 

long long long_long_member;

public long long_long_member;

 

 

};

...

 

 

 

}

 

 

 

 

unsigned

 

 

public class PrimitiveStruct

long long

 

struct PrimitiveStruct {

{

 

 

unsigned long long

public long

(see Note

7

unsigned_long_long_member;

unsigned_long_long_member;

};

...

below)

 

 

}

 

 

 

 

 

 

 

public class PrimitiveStruct

float

 

struct PrimitiveStruct {

{

 

float float_member;

public float float_member;

 

 

};

...

 

 

 

}

 

 

 

 

3-48

Table 3.7 Specifying Data Types in IDL for Java

IDL Type

Sample Entry in IDL file

Sample Java Output Generated by

rtiddsgen

 

 

 

 

 

 

 

 

 

 

public class PrimitiveStruct

double

 

struct PrimitiveStruct {

{

 

double double_member;

public double double_member;

 

 

};

...

 

 

 

}

 

 

 

long double

 

public class PrimitiveStruct

 

 

struct PrimitiveStruct {

{

(see Note

7

long double long_double_member;

public double long_double_member;

};

...

below)

 

 

}

 

 

 

 

pointer

 

struct MyStruct {

public class MyStruct {

 

public int member;

(see Note

9

long * member;

...

below)

 

};

 

};

 

 

 

 

 

 

 

 

 

 

public class PrimitiveStruct

 

 

struct PrimitiveStruct {

{

boolean

 

boolean boolean_member;

public boolean boolean_member;

 

 

};

...

 

 

 

}

 

 

 

 

 

 

 

public class PrimitiveEnum extends Enum

 

 

 

{

 

 

 

public static PrimitiveEnum ENUM1 =

 

 

 

new PrimitiveEnum ("ENUM1", 0);

 

 

enum PrimitiveEnum {

public static PrimitiveEnum ENUM2 =

 

 

ENUM1,

new PrimitiveEnum ("ENUM2", 1);

 

 

ENUM2,

 

 

 

ENUM3

public static PrimitiveEnum ENUM3 =

 

 

};

new PrimitiveEnum ("ENUM3", 2);

 

 

 

public static PrimitiveEnum

 

 

 

valueOf(int ordinal);

 

 

 

...

enum

 

 

}

 

 

 

 

 

public class PrimitiveEnum extends Enum

 

 

 

 

 

 

{

 

 

 

public static PrimitiveEnum ENUM1 =

 

 

 

new PrimitiveEnum ("ENUM1", 10);

 

 

enum PrimitiveEnum {

public static PrimitiveEnum ENUM2 =

 

 

ENUM1 = 10,

new PrimitiveEnum ("ENUM2", 10);

 

 

ENUM2 = 20,

 

 

 

ENUM3 = 30

public static PrimitiveEnum ENUM3 =

 

 

};

new PrimitiveEnum ("ENUM3", 20);

 

 

 

public static PrimitiveEnum

 

 

 

valueOf(int ordinal);

 

 

 

...

 

 

 

}

 

 

 

 

constant

 

 

public class SIZE {

 

const short SIZE = 5;

public static final short VALUE = 5;

 

 

 

}

 

 

 

 

3-49

Table 3.7 Specifying Data Types in IDL for Java

IDL Type

Sample Entry in IDL file

Sample Java Output Generated by

rtiddsgen

 

 

 

 

 

 

 

 

 

struct BitfieldType {

public class BitfieldType

 

 

{

 

 

short myShort_1 : 1;

 

 

public short myShort_1;

 

 

long myLong_1: 1;

 

 

public int myLong_1;

 

 

char myChar_1 : 1;

 

 

public byte myChar_1;

 

 

wchar myWChar_1 : 1;

 

 

public char myWChar_1;

bitfield

 

octet myOctet_1 : 1;

 

public byte myOctet_1;

 

 

short : 0;

 

 

public int myLong_5;

 

 

long myLong_5 : 5;

(see Note 12

public int myLong_30;

long myLong_30 : 30;

public short myShort_6;

below)

 

short myShort_6 : 6;

 

public short myShort_3and4;

 

 

short myShort_3and4 : 3+4;

 

 

public short myShort;

 

 

short myShort;

 

 

public short myShort_8;

 

 

short myShort_8 : 8;

 

 

public int myLong_32;

 

 

long myLong_32: 32;

 

 

...

 

 

};

 

 

}

 

 

 

 

 

 

 

struct

 

 

public class PrimitiveStruct

 

struct PrimitiveStruct {

{

 

 

(see Note 10

char char_member;

public char char_member;

};

below)

 

 

}

 

 

 

 

 

 

 

union

 

union PrimitiveUnion switch (long){

public class PrimitiveUnion {

 

case 1:

public int _d;

 

 

 

 

short short_member;

public short short_member;

(see Note 10

default:

public int long_member;

below)

 

long long_member;

...

 

};

}

 

 

 

 

 

 

typedef

of

 

/* typedefs are unwounded to the original

primitives,

 

typedef short ShortType;

type when used */

enums,

 

 

 

public class PrimitiveStruct

strings

 

 

 

struct PrimitiveStruct {

{

 

 

ShortType short_member;

public short short_member;

(see Note

8

};

...

below)

 

 

}

 

 

 

 

 

 

 

typedef

of

 

/* Wrapper class */

sequences

 

 

public class ShortArray

or arrays

 

typedef short ShortArray[2];

{

 

public short[] userData = new

 

 

 

(see Note

8

 

short[2];

 

...

below)

 

 

}

 

 

 

 

 

 

 

public class OneDArrayStruct

 

 

struct OneDArrayStruct {

{

 

 

public short[] short_array = new

 

 

short short_array[2];

 

 

short[2];

 

 

};

 

 

...

 

 

 

array

 

 

}

 

 

 

 

 

public class TwoDArrayStruct

 

 

 

 

 

struct TwoDArrayStruct {

{

 

 

public short[][] short_array = new

 

 

short short_array[1][2];

 

 

short[1][2];

 

 

};

 

 

...

 

 

 

 

 

 

}

 

 

 

 

3-50

Table 3.7 Specifying Data Types in IDL for Java

IDL Type

Sample Entry in IDL file

Sample Java Output Generated by

rtiddsgen

 

 

 

 

 

 

 

 

 

 

public class SequenceStruct

bounded

 

 

{

sequence

 

struct SequenceStruct {

public ShortSeq short_sequence = new

 

 

sequence<short,4>

ShortSeq((4));

(see Note 11

short_sequence;

...

};

}

below)

 

 

Note: Sequences of primitive types have been

 

 

 

predefined by Connext.

 

 

 

 

 

 

 

public class SequenceStruct

unbounded

 

{

 

public ShortSeq short_sequence = new

sequence

 

struct SequenceStruct {

ShortSeq((100));

 

 

sequence<short> short_sequence;

...

(see Note 11

};

}

Note: rtiddsgen will supply a default bound. You

below)

 

 

 

 

can specify that bound with the “-sequenceSize”

 

 

 

 

 

 

command-line option; see Section 3.6.1.

 

 

 

 

 

 

 

public class ArraysOfSequences

array

of

struct ArraysOfSequences{

{

sequence<short,4>

public ShortSeq[] sequences_array =

sequences

 

sequences_array[2];

new ShortSeq[2];

 

 

};

...

 

 

 

}

 

 

 

 

 

 

 

/* Wrapper class */

 

 

 

public class ShortArray

 

 

 

{

 

 

 

public short[] userData = new

 

 

 

short[2];

 

 

 

...

 

 

 

}

sequence

of

typedef short ShortArray[2];

/* Sequence of wrapper class objects */

arrays

 

 

 

struct SequenceOfArrays{

public final class ShortArraySeq

 

 

 

 

extends ArraySequence

 

 

sequence<ShortArray,2>

(see Note 11

{

arrays_sequence;

...

below)

 

};

 

}

 

 

 

 

 

 

public class SequenceOfArrays

 

 

 

{

 

 

 

public ShortArraySeq arrays_sequence