Files
2024-09-23 12:00:04 -04:00

355 lines
13 KiB
C++

/*
* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
*
* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
* and international copyright treaties.
*
* Access to and use of the software is governed by the terms of the applicable OnixS Software
* Services Agreement (the Agreement) and Customer end user license agreements granting
* a non-assignable, non-transferable and non-exclusive license to use the software
* for it's own data processing purposes under the terms defined in the Agreement.
*
* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
* of this source code or associated reference material to any other location for further reproduction
* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
*
* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
* the terms of the Agreement is a violation of copyright law.
*/
#pragma once
#include <iosfwd>
#include <string>
#include <OnixS/FIXEngine/FIX/SequenceNumber.h>
#include <OnixS/FIXEngine/FIX/FieldSet.h>
#include <OnixS/FIXEngine/FIX/Dictionary.h>
#include <OnixS/FIXEngine/FIX/MessageStringingFlags.h>
#include <OnixS/FIXEngine/FIX/MessageParsingFlags.h>
#include <OnixS/FIXEngine/FIX/MessageValidationFlags.h>
#include <OnixS/FIXEngine/FIX/RawMessage.h>
namespace OnixS {
namespace FIX {
/// Encapsulates operations over a FIX Message.
///
/// Message supports the 'unconstructed' state which can be
/// treated as a pointer in the null state. However, in contrast to
/// OnixS::FIX::Group and OnixS::FIX::GroupInstance classes it
/// does NOT represent a light-weight wrapper over internal structures.
/// In fact, it holds all the data which is fully copied on an assignment
/// or a copy construction and disposed at the instance destruction.
///
/// FIX field related operations now available via the OnixS::FIX::FieldSet
/// class from which the OnixS::FIX::Message class is now derived.
class
ONIXS_FIXENGINE_API
Message : public FieldSet
{
public:
/// Initializes a message in the unconstructed state.
///
/// @param expectedMessageSize An expected size of the FIX message.
/// The 'expectedMessageSize' parameter is used as a hint for the optimization of the manipulation (parsing, setting, etc.)
/// of large FIX messages with a lot of repeating groups.
///
/// @note The large value of the 'expectedMessageSize' parameter can increase the memory consumption by the `Message` object,
/// so try to increase the value only in case of a latency degradation of the large FIX messages manipulation.
explicit Message(size_t expectedMessageSize = DefaultExpectedMessageSize);
/// Constructs a FIX message of the given type which belongs to
/// the given dictionary of the FIX protocol (messaging specification).
///
/// @param type Defines the type of the message (MsgType field value).
/// @param dictionary The FIX protocol dictionary to which the message belongs to.
/// @param expectedMessageSize An expected size of the FIX message.
/// The 'expectedMessageSize' parameter is used as a hint for the optimization of the manipulation (parsing, setting, etc.)
/// of large FIX messages with a lot of repeating groups.
///
/// @note The large value of the 'expectedMessageSize' parameter can increase the memory consumption by the `Message` object,
/// so try to increase the value only in case of a latency degradation of the large FIX messages manipulation.
///
/// @warning The type of the message can't be changed by updating the MsgType
/// field value. Changing the MsgType field value have no effect for the known
/// message which are defined by the dictionary associated with message.
Message(const char * type, const Dictionary & dictionary, size_t expectedMessageSize = DefaultExpectedMessageSize);
/// Initializes an instance as a deep copy of other one.
///
/// @param other The message to be copied from.
Message(const Message & other);
/// Disposes all internal data structures.
///
/// @warning Once an instance is destructed, all instances of
/// OnixS::FIX::Group and OnixS::FIX::GroupInstance classes
/// obtained from this instance must not be used any more.
virtual ~Message();
/// An instance of the FIX dictionary or standard FIX messages
/// dictionary to which the message belongs to.
Dictionary dictionary() const;
/// Returns the message type (MsgType(35) field value).
FieldValueRef type() const;
/// Returns the message sequence number
/// (the MsgSeqNum (tag=34) field value).
SequenceNumber seqNum() const;
/// Sets the message sequence number
/// (the MsgSeqNum (tag=34) field value).
void seqNum(SequenceNumber value);
/// Returns the assigned value used to identify
/// the firm sending message (SenderCompID (49) field value).
FieldValueRef senderCompId() const;
/// Sets the assigned value used to identify the firm
/// sending message (SenderCompID (49) field value).
void senderCompId(const std::string &);
/// Returns the assigned value used to identify
/// the receiving firm (TargetCompID(56) field value).
FieldValueRef targetCompId() const;
/// Sets the assigned value used to identify
/// the receiving firm (TargetCompID(56) field value).
void targetCompId(const std::string &);
/// A user data associated with the message.
///
/// @return The pointer to data was previously
/// attached to the instance or NULL.
void * userData() const;
/// Attaches a user data to the message.
void userData(void * data);
/// Compares two messages. The comparison is performed
/// using 'tag=value' message presentations.
bool operator == (const Message &) const;
/// Compares two messages. The comparison is performed
/// using 'tag=value' message presentations.
bool operator != (const Message &) const;
/// Ensures the message satisfies basic FIX Specification requirements.
///
/// @throw The std::exception if the validation fails.
///
/// @note This method validates required fields for the application level only, without the message header/trailer
void validate() const;
/// Validates the message according to specified criteria.
///
/// @param validationFlags Specifies validation criteria.
///
/// @throw The std::exception if the validation fails.
///
/// @note This method validates required fields for the application level only, without the message header/trailer
void validate(MessageValidationFlags validationFlags) const;
/// Tries to validate the message according to specified criteria.
/// Returns 'true' if the validation is successful, otherwise - 'false'.
///
/// @param validationFlags Validation criteria.
/// @param errorDescription Contains the error description in case the validation fails.
///
/// @note This method validates required fields for the application level only, without the message header/trailer
bool tryValidate(MessageValidationFlags validationFlags, std::string & errorDescription) const;
/// Brings the message to the 'blank' state as it was just constructed.
///
/// @warning For messages constructed with the certain message type
/// member wipes out field values for all the fields except several
/// service fields (MsgType, BeginString, etc). For the message in
/// the unconstructed state does actually nothing.
void clear();
/// Builds the FIX-compliant 'tag=value' presentation of the message.
void toRaw(RawMessage &) const;
/// Returns the string representation of the message using
/// the given delimiter and additional control flags.
///
/// @param delimiter Defines the field delimiter to be used.
/// @param flags Affects how the message presentation looks like.
std::string
toString(
char delimiter = 0x1,
MessageStringingFlags flags =
MessageStringingFlag::IncludeFieldTagNumber) const;
/// Appends the string representation of the message using
/// the given delimiter and additional control flags.
///
/// @param str The string to which the presentation is appended.
/// @param delimiter Defines the field delimiter to be used.
/// @param flags Affects how the message presentation looks like.
void
toString(
std::string & str,
char delimiter = 0x1,
MessageStringingFlags flags =
MessageStringingFlag::IncludeFieldTagNumber) const;
/// Returns the XML representation of the message.
std::string
toXml() const;
/// Appends the XML representation of the message.
///
/// @param str The string to which the presentation is appended.
void
toXml(std::string & str) const;
/// Returns the JSON representation of the message.
std::string
toJson() const;
/// Appends the JSON representation of the message.
///
/// @param str The string to which the presentation is appended.
void
toJson(std::string & str) const;
/// Calculates the message body length and checkSum and updates corresponding fields.
void updateBodyLengthAndCheckSum();
// Reassigns the message as a copy of other one.
Message & operator = (const Message &);
// Copies all message fields (except the protocol version) from another message object.
void copyFields(const Message &);
/// De-serializes the FIX message from its raw (tag=value) presentation.
///
/// @param rawMessage The buffer in which the raw FIX message is stored.
/// @param rawMessageSize The size of the buffer in which the raw FIX message is stored.
/// @param message The parsed FIX message if the parsing succeeds.
///
/// @throw The std::exception if the parsing fails.
static
void
parse(
const char * rawMessage,
size_t rawMessageSize,
Message & message);
/// De-serializes the FIX message from its raw (tag=value) presentation.
///
/// @param rawMessage The buffer in which the raw FIX message is stored.
/// @param rawMessageSize The Size of the buffer in which the raw FIX message is stored.
/// @param parsingFlags Flags which affect the parsing behavior.
/// @param message The parsed FIX message if the parsing succeeds.
///
/// @throw The std::exception if the parsing fails.
static
void
parse(
const char * rawMessage,
size_t rawMessageSize,
MessageParsingFlags parsingFlags,
Message & message);
/// De-serializes the FIX message from its raw (tag=value) presentation.
///
/// @param rawMessage The buffer in which the raw FIX message is stored.
/// @param rawMessageSize The Size of the buffer in which the raw FIX message is stored.
/// @param dictionary The FIX dictionary to which the message supposed to belong.
/// @param parsingFlags Flags which affect the parsing behavior.
/// @param message The parsed FIX message if the parsing succeeds.
///
/// @throw The std::exception if the parsing fails.
static
void
parse(
const char * rawMessage,
size_t rawMessageSize,
const Dictionary & dictionary,
MessageParsingFlags parsingFlags,
Message & message);
/// De-serializes the FIX message from its raw (tag=value)
/// presentation which may be truncated.
///
/// @param rawMessage The buffer in which the raw FIX message is stored.
/// @param rawMessageSize The Size of the buffer in which the raw FIX message is stored.
/// @param message The parsed FIX message if the parsing succeeds.
///
/// @return true if the message can be recognized from the input.
static
bool
parsePartial(
const char * rawMessage,
size_t rawMessageSize,
Message & message);
/// De-serializes the FIX message from its raw (tag=value)
/// presentation which may be truncated.
///
/// @param rawMessage The buffer in which the raw FIX message is stored.
/// @param rawMessageSize The Size of the buffer in which the raw FIX message is stored.
/// @param dictionary The FIX dictionary to which the message supposed to belong.
/// @param message The parsed FIX message if the parsing succeeds.
///
/// @return true if the message can be recognized from the input.
static
bool
parsePartial(
const char * rawMessage,
size_t rawMessageSize,
const Dictionary & dictionary,
Message & message);
struct MakeShallowCopy {};
protected:
/// Initializes an instance as a shallow copy of other one.
///
/// @param other The message to be copied from.
Message(const Message & other, MakeShallowCopy);
private:
friend class MessageWrapper;
friend class MessageOperator;
Message(const void *);
private:
virtual void userDataImpl(void * data);
unsigned char impl_[6 * sizeof(size_t)];
unsigned char allocator_[4 * sizeof(size_t)];
static const size_t DefaultExpectedMessageSize = 10240;
void construct(size_t expectedMessageSize = DefaultExpectedMessageSize);
void destruct();
};
inline
std::string
Message::toString(
char delimiter,
MessageStringingFlags flags) const
{
std::string str;
toString(str, delimiter, flags);
return str;
}
/// The stream output.
ONIXS_FIXENGINE_API
std::ostream & operator << (std::ostream & os, const Message & message);
}
}