fprime/Fw/Buffer/Buffer.hpp
Vince Woo 48e4720419
Created new SerialBufferBase as a parent of SerializeBufferBase (now renamed LinearBufferBase). (#4288)
* Created new SerialBufferBase as a parent of SerializeBufferBase. Renaming interface functions to be less confusing.

* Deprecating copyRawOffset. No direct use-cases in F' core.

* Make SerialBufferBase a true pure virtual interface.

* Changing Serializable to work with SerialBufferBase parent interface.

* Changing copyRaw and copyRawOffset to work with SerialBufferBase

* Updating documentation for SerialBufferBase usage

* Adding some documentation. Adding missing ASSERT in copyRaw. Fixing some bugs that new ASSERT uncovered.

* Renaming SerializeBufferBase to LinearBufferBase. Add a using declaration to maintain backwards compatability. Properly mark LinearBufferBase functions as override.

* Filling in the rest of the docstrings for the classes in Serializable

* Removing redundant virtual keyword on override function

* Applying clang formatting

* Incorporating PR comments

* Fix compile issues

* Bump version to alpha

* Format

* v

---------

Co-authored-by: M Starch <LeStarch@googlemail.com>
2025-11-06 16:23:20 -08:00

207 lines
9.0 KiB
C++

// ======================================================================
// \title Buffer.hpp
// \author mstarch
// \brief hpp file for Fw::Buffer definition
//
// \copyright
// Copyright 2009-2020, by the California Institute of Technology.
// ALL RIGHTS RESERVED. United States Government Sponsorship
// acknowledged.
//
// ======================================================================
#ifndef BUFFER_HPP_
#define BUFFER_HPP_
#include <Fw/FPrimeBasicTypes.hpp>
#include <Fw/Types/Serializable.hpp>
#if FW_SERIALIZABLE_TO_STRING
#include <Fw/Types/StringType.hpp>
#ifdef BUILD_UT
#include <Fw/Types/String.hpp>
#include <iostream>
#endif
#endif
// Forward declaration for UTs
namespace Fw {
class BufferTester;
}
namespace Fw {
//! Buffer used for wrapping pointer to data for efficient transmission
//!
//! Fw::Buffer is a wrapper for a pointer to data. It allows for data to be passed around the system without a copy of
//! the data itself. However, it comes with the expectation that the user maintain and protect this memory as it moves
//! about the system until such a time as it is returned.
//!
//! Fw::Buffer is composed of several elements: a U8* pointer to the data, a U32 size of that data, and a U32 context
//! describing the origin of that data, such that it may be freed at some later point. The default context of 0xFFFFFFFF
//! should not be used for tracking purposes, as it represents a context-free buffer.
//!
//! Fw::Buffer also comes with functions to return a representation of the data as a SerializeBufferBase. These two
//! functions allow easy access to the data as if it were a serialize or deserialize buffer. This can aid in writing and
//! reading the wrapped data whereas the standard serialize and deserialize methods treat the data as a pointer to
//! prevent excessive copying.
//!
class Buffer : public Fw::Serializable {
friend class Fw::BufferTester;
public:
//! Buffer ownership state
//!
//! A convenience enumeration to help users implement ownership tracking of buffers.
enum class OwnershipState {
NOT_OWNED, //!< The buffer is currently not owned
OWNED, //!< The buffer is currently owned
};
public:
//! The size type for a buffer - for backwards compatibility
using SizeType = FwSizeType;
enum {
SERIALIZED_SIZE = sizeof(SizeType) + sizeof(U32) + sizeof(U8*), //!< Size of Fw::Buffer when serialized
NO_CONTEXT = 0xFFFFFFFF //!< Value representing no context
};
//! Construct a buffer with no context nor data
//!
//! Constructs a buffer setting the context to the default no-context value of 0xffffffff. In addition, the size
//! and data pointers are zeroed-out.
Buffer();
//! Construct a buffer by copying members from a reference to another buffer. Does not copy wrapped data.
//!
Buffer(const Buffer& src);
//! Construct a buffer to wrap the given data pointer of given size
//!
//! Wraps the given data pointer with given size in a buffer. The context by default is set to NO_CONTEXT but can
//! be set to specify a specific context.
//! \param data: data pointer to wrap
//! \param size: size of data located at data pointer
//! \param context: user-specified context to track creation. Default: no context
Buffer(U8* data, FwSizeType size, U32 context = NO_CONTEXT);
//! Assignment operator to set given buffer's members from another without copying wrapped data
//!
Buffer& operator=(const Buffer& src);
//! Equality operator returning true when buffers are equivalent
//!
//! Buffers are deemed equivalent if they contain a pointer to the same data, with the same size, and the same
//! context. The representation of that buffer for use with serialization and deserialization need not be
//! equivalent.
//! \param src: buffer to test against
//! \return: true if equivalent, false otherwise
bool operator==(const Buffer& src) const;
// ----------------------------------------------------------------------
// Serialization functions
// ----------------------------------------------------------------------
//! Returns a SerializeBufferBase representation of the wrapped data for serializing
//!
//! Returns a SerializeBufferBase representation of the wrapped data allowing for serializing other types of data
//! to the wrapped buffer. Once obtained the user should call one of two functions: `sbb.resetSer();` to setup for
//! serialization, or `sbb.setBuffLen(buffer.getSize());` to setup for deserializing.
//! \return representation of the wrapped data to aid in serializing to it
DEPRECATED(SerializeBufferBase& getSerializeRepr(), "Switch to .getSerializer() and .getDeserializer()");
//! Returns a ExternalSerializeBufferWithMemberCopy representation of the wrapped data for serializing
//!
//! \warning The serialization pointer of the returned ExternalSerializeBufferWithMemberCopy object is set to zero
//! \warning so that serialization will start at the beginning of the memory pointed to by the Fw::Buffer. If that
//! \warning behavior is not desired the caller may manipulate the serialization offsets with moveSerToOffset
//! \warning and serializeSkip methods prior to serialization.
//!
//! \return representation of the wrapped data to aid in serializing to it
ExternalSerializeBufferWithMemberCopy getSerializer();
//! Returns a ExternalSerializeBufferWithMemberCopy representation of the wrapped data for deserializing
//!
//! \warning The entire buffer (up to getSize) is available for deserialization.
//!
//! \return representation of the wrapped data to aid in deserializing to it
ExternalSerializeBufferWithMemberCopy getDeserializer();
//! Serializes this buffer to a SerializeBufferBase
//!
//! This serializes the buffer to a SerializeBufferBase, however, it DOES NOT serialize the wrapped data. It only
//! serializes the pointer to said data, the size, and context. This is done for efficiency in moving around data,
//! and is the primary usage of Fw::Buffer. To serialize the wrapped data, use either the data pointer accessor
//! or the serialize buffer base representation and serialize from that.
//! \param serialBuffer: serialize buffer to write data into
//! \return: status of serialization
Fw::SerializeStatus serializeTo(Fw::SerialBufferBase& serialBuffer,
Fw::Endianness mode = Fw::Endianness::BIG) const;
//! Deserializes this buffer from a SerializeBufferBase
//!
//! This deserializes the buffer from a SerializeBufferBase, however, it DOES NOT handle serialized data. It only
//! deserializes the pointer to said data, the size, and context. This is done for efficiency in moving around data,
//! and is the primary usage of Fw::Buffer. To deserialize the wrapped data, use either the data pointer accessor
//! or the serialize buffer base representation and deserialize from that.
//! \param buffer: serialize buffer to read data into
//! \return: status of serialization
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase& buffer, Fw::Endianness mode = Fw::Endianness::BIG);
// ----------------------------------------------------------------------
// Accessor functions
// ----------------------------------------------------------------------
//! Returns true if the buffer is valid (data pointer != nullptr and size > 0)
//!
bool isValid() const;
//! Returns wrapped data pointer
//!
U8* getData() const;
//! Returns size of wrapped data
//!
FwSizeType getSize() const;
//! Returns creation context
//!
U32 getContext() const;
//! Sets pointer to wrapped data and the size of the given data
//!
void setData(U8* data);
//! Sets pointer to wrapped data and the size of the given data
//!
void setSize(FwSizeType size);
//! Sets creation context
//!
void setContext(U32 context);
//! Sets all values
//! \param data: data pointer to wrap
//! \param size: size of data located at data pointer
//! \param context: user-specified context to track creation. Default: no context
void set(U8* data, FwSizeType size, U32 context = NO_CONTEXT);
#if FW_SERIALIZABLE_TO_STRING || BUILD_UT
//! Supports writing this buffer to a string representation
void toString(Fw::StringBase& text) const;
#endif
#ifdef BUILD_UT
//! Supports GTest framework for outputting this type to a stream
//!
friend std::ostream& operator<<(std::ostream& os, const Buffer& obj);
#endif
private:
Fw::ExternalSerializeBuffer m_serialize_repr; //<! Representation for serialization and deserialization functions
U8* m_bufferData; //<! data - A pointer to the data
FwSizeType m_size; //<! size - The data size in bytes
U32 m_context; //!< Creation context for disposal
};
} // end namespace Fw
#endif /* BUFFER_HPP_ */