- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten - svcTabCommon: Export-Header-Fix via Fallback-Target - TrainingAreaBase: Stub-Header für BUILD_RTI=OFF - ddsfts: Include-Pfad und Dependency-Fixes - BUILD_RTI=OFF Compilation vollständig unterstützt Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
409 lines
13 KiB
C
409 lines
13 KiB
C
/*
|
|
* (c) Copyright, Real-Time Innovations, 2002-2026.
|
|
* All rights reserved.
|
|
* No duplications, whole or partial, manual or electronic, may be made
|
|
* without express written permission. Any such copies, or
|
|
* revisions thereof, must display this notice unaltered.
|
|
* This code contains trade secrets of Real-Time Innovations, Inc.
|
|
*/
|
|
|
|
#ifndef reda_buffer_h
|
|
#define reda_buffer_h
|
|
|
|
#include "reda/reda_dll.h"
|
|
#include "osapi/osapi_type.h"
|
|
#include "osapi/osapi_alignment.h"
|
|
#include "osapi/osapi_compression.h"
|
|
|
|
/*e \file
|
|
\brief Defines the REDABuffer interface
|
|
*/
|
|
|
|
/*e \defgroup REDABufferClass REDABuffer
|
|
\ingroup REDAModule
|
|
\brief REDA buffers are equivalent to iovec buffers supported by the
|
|
sendmsg() socket API, or the WSABUF array used to do gather send on
|
|
Windows.
|
|
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Generic buffer to hold data, described by a pointer to the data, as
|
|
well as the length of the data.
|
|
|
|
This structure deliberately mirrors
|
|
windows WSABUF so we can cast the passed in structure directly without
|
|
copying the fields into a structure on the stack.
|
|
|
|
@see REDABufferArray_getSize
|
|
*/
|
|
#define REDABuffer RTIOsapiBuffer
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Manages where in the buffer is the next available memory to use
|
|
|
|
@see REDABufferArray_getSize
|
|
*/
|
|
struct REDABufferManager {
|
|
/*e The buffer: its length and starting position */
|
|
struct REDABuffer buffer;
|
|
|
|
/*e Where in the buffer is the next available memory to use */
|
|
char *currentPosition;
|
|
|
|
/*e Increased every time getBuffer fails. */
|
|
unsigned int errorCount;
|
|
};
|
|
|
|
#define REDABufferManager_INITIALIZER \
|
|
{ \
|
|
{ 0, NULL }, /* buffer */ \
|
|
NULL, /* currentPosition */ \
|
|
0 /* errorCount */ \
|
|
}
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Configures a REDADynamicBufferManager
|
|
|
|
@see REDADynamicBufferManager_ensureCapacity
|
|
*/
|
|
struct REDADynamicBufferManagerProperty {
|
|
/*e The size of the initial buffer. That is, the minimum size that
|
|
* a DynamicBufferManager will allocate.
|
|
*/
|
|
unsigned int initialSize;
|
|
|
|
/*e Whether to trim to the intial size or not. When enabled, after calling
|
|
* reset or ensureCapacity with a size <= initialSize, the auxiliary buffer
|
|
* is deleted. When set to false, the auxiliary buffer never shrinks and
|
|
* will always be as big as the largest size ever requested with
|
|
* ensureCapacity.
|
|
*/
|
|
RTIBool trim;
|
|
};
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Default values for REDADynamicBufferManagerProperty
|
|
|
|
@see REDADynamicBufferManagerProperty
|
|
*/
|
|
#define REDADynamicBufferManagerProperty_INITIALIZER { 4092, RTI_FALSE }
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief A memory-allocation utility to improve memory usage.
|
|
|
|
A REDADynamicBufferManager provides memory chunks of arbitrary sizes from a
|
|
contiguous buffer (see REDADynamicBufferManager_getBuffer).
|
|
|
|
Before you start asking for memory, you need to call ensureCapacity(x).
|
|
This guarantees you can request up to x bytes by calling getBuffer()
|
|
a number of times. (Note: since each chunk of memory can be aligned, the
|
|
total memory may you get may be less, so you need to account for that when
|
|
calling ensureCapacity())
|
|
|
|
You can "free" all the memory you requested at once by calling
|
|
reset(). Any memory previously requested with getBuffer() should be considered
|
|
invalid after that. The buffer manager won't actually release the underlying
|
|
buffer. After that, start over asking for memory, calling ensureCapacity()
|
|
again if needed.
|
|
|
|
When you call ensureCapacity(x) and x > property.initialSize the buffer
|
|
manager allocates (or reallocates) an auxiliary buffer of size x. When
|
|
property.trim is set and you call trim() or ensureCapacity(y) with y <=
|
|
property.initialSize the buffer manager deletes the auxiliary buffer and uses
|
|
the initial one. If trim is not set, the auxiliary buffer will never shrink.
|
|
|
|
@see REDADynamicBufferManagerProperty
|
|
*/
|
|
struct REDADynamicBufferManager {
|
|
/*e Internal buffer manager */
|
|
struct REDABufferManager _bufferManager;
|
|
|
|
/*e Configuration properties */
|
|
struct REDADynamicBufferManagerProperty _property;
|
|
|
|
/*e Initial buffer allocation */
|
|
struct REDABuffer _initialBuffer;
|
|
|
|
/*e Auxiliary buffer for larger allocations */
|
|
struct REDABuffer _largeBuffer;
|
|
};
|
|
|
|
#define REDADynamicBufferManager_INITIALIZER \
|
|
{ \
|
|
REDABufferManager_INITIALIZER, /* _bufferManager */ \
|
|
REDADynamicBufferManagerProperty_INITIALIZER, /* _property */ \
|
|
{ 0, NULL }, /* _initialBuffer */ \
|
|
{ 0, NULL }, /* _largeBuffer */ \
|
|
}
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief static method to calculate the total data length in a gather buffer
|
|
|
|
@todo Needs to be renamed
|
|
Calculates the total size of an array of REDABuffer elements.
|
|
|
|
@pre valid answer, array, and arrayCount.
|
|
|
|
@param answer \b Out. Pointer to the integer sum of the lengths of all the
|
|
buffers.
|
|
@param array \b In. Iovec array, that is array of REDABuffer elements
|
|
@param arrayCount \b In. Number of elements in the array.
|
|
*/
|
|
extern REDADllExport void REDABufferArray_getSize(
|
|
size_t *answer,
|
|
const struct REDABuffer *array,
|
|
int arrayCount);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Set the elements of a REDABuffer.
|
|
It is safer and more portable than setting the individual fields.
|
|
|
|
@pre buf answer and array.
|
|
|
|
@param pointer \b In. Underlying memory for the buffer
|
|
@param length \n In. The length of the underlying memory for the buffer
|
|
*/
|
|
extern REDADllExport void REDABuffer_set(
|
|
struct REDABuffer *me,
|
|
char *pointer,
|
|
int length);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
* \brief Set the elements of a REDABuffer from an unsigned int.
|
|
* The buffer will point to the int, and the length will be 4 bytes.
|
|
*
|
|
* @param uint32Ptr \b In. The pointer to the value that the buffer's pointer
|
|
* shall be set to
|
|
*/
|
|
extern REDADllExport void REDABuffer_initializeFromUInt32(
|
|
struct REDABuffer *me,
|
|
RTI_UINT32 *uint32Ptr);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Reset the elements of a REDABuffer.
|
|
It is safer and more portable than setting the individual fields.
|
|
|
|
@pre Valid buffer.
|
|
@post buffer set to REDA_BUFFER_INVALID
|
|
*/
|
|
extern REDADllExport void REDABuffer_reset(struct REDABuffer *me);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Free the given REDABuffer and allocate a new one.
|
|
This has the potential to be faster than calling realloc when one does not
|
|
need to preserve the contents of the current buffer. If the given buffer is
|
|
already large enough, it is simply returned.
|
|
|
|
@note The given buffer must be in a valid state, i.e., the length must match
|
|
the size of the buffer pointer. A buffer in the reset state (length 0 and NULL
|
|
pointer) is valid.
|
|
|
|
@pre Buffer pointer not NULL and size greater than 0.
|
|
@post Buffer allocated to given size or reset if allocation failed.
|
|
|
|
@param self \b InOut. Pointer to the REDABuffer structure that is being
|
|
checked and potentially reallocated.
|
|
@param length \b In. The desired new length of the buffer. The function will
|
|
ensure that the buffer is at least this long.
|
|
@param alignment \b In. The alignment requirement for the buffer. This
|
|
ensures that the buffer's starting address satisfies the specified alignment.
|
|
*/
|
|
extern REDADllExport RTIBool REDABuffer_ensureLengthWithAlignment(
|
|
struct REDABuffer *self,
|
|
RTI_INT32 length,
|
|
RTIOsapiAlignment alignment);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief An invalid buffer, useful for initialization as indicated by
|
|
the usage:
|
|
\code
|
|
struct REDABuffer buf = REDA_BUFFER_INVALID;
|
|
\endcode
|
|
*/
|
|
#define REDA_BUFFER_INVALID { 0, NULL }
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Convert to string for printing during log messages and diagnostics.
|
|
|
|
@pre pre-allocated buffer big enough to hold the answer and valid
|
|
ptr. The function should verify this and either fail if there is not
|
|
enough space, or else truncate the output.
|
|
|
|
@post On success, the buffer holds the string and the length field
|
|
of the buffer is the numbers of characters (including the
|
|
terminating '\0'). The length field will never exceed the one passed
|
|
in. If fewer bytes are written than the available then it will be
|
|
shortened to reflect the true length of the string. On failure, the
|
|
REDABuffer is left unchanged.
|
|
|
|
@param ptr \b. In. "this" The object to be stringified.
|
|
|
|
@param buffer \b InOut. Pointer to a single REDABuffer that
|
|
satisfies the pre-condition. The function will use this to determine
|
|
where to write and the maximum number of bytes to write. REDABuffer.
|
|
|
|
@exception RTI_LOG_PRECONDITION_FAILURE
|
|
|
|
@return On success it returns the pointer to the character array
|
|
underlying the REDABuffer \e buffer. This character array should
|
|
contain the string representation of \e ptr. On failure the function
|
|
should return NULL.
|
|
|
|
@mtsafety should be implemented as a re-entrant function which will
|
|
be automatically thread-safe provided that it is not invoked
|
|
concurrently on the same buffer.
|
|
*/
|
|
typedef char *(*REDAToStringBufferFunction)(
|
|
const void *ptr,
|
|
struct REDABuffer *buffer);
|
|
|
|
/*e
|
|
* \ingroup REDABufferClass
|
|
* \brief Set the elements of a REDABufferManager.
|
|
*
|
|
* The buffer is loaned.
|
|
*
|
|
* @param pointer \b In. Underlying memory for the buffer
|
|
* @param length \n In. The length of the underlying memory for the buffer
|
|
*/
|
|
extern REDADllExport RTIBool REDABufferManager_init(
|
|
struct REDABufferManager *me,
|
|
char *pointer,
|
|
RTI_INT32 length);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Initializes a REDABufferManager allocating a buffer of a given size.
|
|
|
|
The buffer is owned. Delete it with REDABufferManager_deleteBuffer
|
|
|
|
@param length \n In. The length of buffer to allocate
|
|
*/
|
|
extern REDADllExport RTIBool
|
|
REDABufferManager_createBuffer(struct REDABufferManager *me, int length);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Deletes the buffer in this REDABufferManager.
|
|
|
|
Use this function when you initialized <code>me</code> with
|
|
<code>REDABufferManager_createBuffer</code>
|
|
*/
|
|
extern REDADllExport void REDABufferManager_deleteBuffer(
|
|
struct REDABufferManager *me);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Resets the buffer by pointing to the beginning
|
|
|
|
After this function is called, the buffer has its original capacity and
|
|
all previous chunks of memory obtained by getBuffer should be considered
|
|
invalid. the error count is set to zero.
|
|
*/
|
|
extern REDADllExport void REDABufferManager_reset(
|
|
struct REDABufferManager *me,
|
|
RTIBool zeroBuffer);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
\brief Return the starting location within the buffer of the next available
|
|
memory of a certain size.
|
|
|
|
If there's not enough space it returns NULL and increases errorCount.
|
|
|
|
@param sizeInBytes \b In. Size of memory requested
|
|
@param alignment \b In. Alignment of memory requested
|
|
*/
|
|
extern REDADllExport char *REDABufferManager_getBuffer(
|
|
struct REDABufferManager *me,
|
|
size_t sizeInBytes,
|
|
RTIOsapiAlignment alignment);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
|
|
\brief Returns the number of times getBuffer has failed since the last
|
|
init or reset.
|
|
|
|
*/
|
|
extern REDADllExport unsigned int REDABufferManager_getErrorCount(
|
|
struct REDABufferManager *me);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
*
|
|
*/
|
|
extern REDADllExport RTIBool REDADynamicBufferManager_initialize(
|
|
struct REDADynamicBufferManager *self,
|
|
const struct REDADynamicBufferManagerProperty *property);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
*
|
|
* Ensures a buffer size of a given capacity for future calls to getBuffer().
|
|
*
|
|
* @see REDADynamicBufferManager
|
|
*/
|
|
extern REDADllExport RTIBool REDADynamicBufferManager_ensureCapacity(
|
|
struct REDADynamicBufferManager *self,
|
|
unsigned int capacity);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
*
|
|
*/
|
|
extern REDADllExport unsigned int REDADynamicBufferManager_getCapacity(
|
|
struct REDADynamicBufferManager *self);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
*
|
|
* @see REDADynamicBufferManager
|
|
*/
|
|
extern REDADllExport void REDADynamicBufferManager_trim(
|
|
struct REDADynamicBufferManager *self);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
*
|
|
* Returns a buffer of a given size.
|
|
*
|
|
* Returns NULL if this buffer manager doesn't have enough capacity to return
|
|
* a buffer of that size with the requested alignment.
|
|
*
|
|
* @see REDADynamicBufferManager
|
|
*/
|
|
extern REDADllExport char *REDADynamicBufferManager_getBuffer(
|
|
struct REDADynamicBufferManager *self,
|
|
unsigned int sizeInBytes,
|
|
RTIOsapiAlignment alignment);
|
|
|
|
/*e
|
|
* \ingroup REDABufferClass
|
|
*
|
|
* Allows re-using the underlying buffer from the beginning. After calling
|
|
* reset() all memory previously obtained with getBuffer() is invalid.
|
|
*
|
|
* The caller can choose whether the contents of the buffers are zeroed out
|
|
* by providing the value of zeroBuffer.
|
|
*
|
|
* @param self The manager to reset
|
|
* @param zeroBuffer if set to TRUE, the buffer contents will be reset to 0. If
|
|
* set to FALSE, the contents of the memory are left as-is
|
|
*
|
|
* @see REDADynamicBufferManager
|
|
*/
|
|
extern REDADllExport void REDADynamicBufferManager_reset(
|
|
struct REDADynamicBufferManager *self,
|
|
RTIBool zeroBuffer);
|
|
|
|
/*e \ingroup REDABufferClass
|
|
*
|
|
*/
|
|
extern REDADllExport void REDADynamicBufferManager_finalize(
|
|
struct REDADynamicBufferManager *self);
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
/* pick up hidden performance boosting macros and optimizations */
|
|
#include "reda/reda_buffer_impl.h"
|
|
|
|
#endif /* reda_buffer_h */
|