337 lines
7.6 KiB
C++
337 lines
7.6 KiB
C++
#pragma once
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <functional>
|
|
#include <ostream>
|
|
#include <string>
|
|
|
|
#include <OnixS/FIXEngine/Compiler.h>
|
|
#include <OnixS/FIXEngine/FIX/Numeric.h>
|
|
|
|
#ifdef ONIXS_FIXENGINE_CXX17
|
|
|
|
#include <string_view>
|
|
|
|
#endif
|
|
|
|
namespace OnixS {
|
|
namespace FIX {
|
|
|
|
#ifdef ONIXS_FIXENGINE_CXX17
|
|
|
|
using StringRef = std::basic_string_view<Char>;
|
|
|
|
#else
|
|
|
|
/// Provides an efficient way of accessing text-based FIX field values.
|
|
///
|
|
/// By default, OnixS::FIX::Message and OnixS::FIX::GroupInstance classes
|
|
/// convert all values assigned to the fields into their text presentations
|
|
/// and store textual data. This approach optimizes message reuse when the same
|
|
/// message instance is used to update a few fields and is sent over the FIX
|
|
/// session multiple times. Also, when a message comes from the network and is
|
|
/// deserialized from its raw (tag=value) presentation, all field values
|
|
/// represent text segments. To access textual values, the StringRef class
|
|
/// was added together with new access members (FieldSet::getStringRef()).
|
|
/// If value is accessed using FieldSet::getStringRef() member, instance of
|
|
/// StringRef class is returned. That instance holds a reference to a read-only
|
|
/// segment of text. An important aspect is that no memory is allocated and
|
|
/// copied while accessing field values that way.
|
|
|
|
class
|
|
ONIXS_FIXENGINE_API
|
|
StringRef
|
|
{
|
|
public:
|
|
/// An immutable iterator over chars.
|
|
typedef const char * ConstIterator;
|
|
|
|
/// Initializes the blank instance.
|
|
StringRef()
|
|
: chars_(ONIXS_FIXENGINE_NULLPTR),
|
|
size_(0) {
|
|
}
|
|
|
|
/// The full initialization.
|
|
ONIXS_FIXENGINE_CONSTEXPR
|
|
StringRef(
|
|
const char * chars,
|
|
size_t size)
|
|
: chars_(chars),
|
|
size_(size) {
|
|
}
|
|
|
|
/// Initializes an instance from the string content.
|
|
explicit StringRef(
|
|
const std::string & stdStr)
|
|
: chars_(stdStr.c_str()),
|
|
size_(stdStr.size()) {
|
|
}
|
|
|
|
/// Initializes an instance from the zero-terminated string.
|
|
StringRef(const char * cStr)
|
|
: chars_(cStr),
|
|
size_(cStr ? strlen(cStr) : 0) {
|
|
}
|
|
|
|
/// Indicates whether the array has zero length.
|
|
bool empty() const {
|
|
return (0 == size_);
|
|
}
|
|
|
|
/// Returns the read-only content.
|
|
const char * data() const {
|
|
return chars_;
|
|
}
|
|
|
|
/// The STL-like begin().
|
|
ConstIterator begin() const {
|
|
return chars_;
|
|
}
|
|
|
|
/// The STL-like end().
|
|
ConstIterator end() const {
|
|
return chars_ + size_;
|
|
}
|
|
|
|
/// The number of chars.
|
|
size_t size() const {
|
|
return size_;
|
|
}
|
|
|
|
/// The number of chars.
|
|
size_t length() const {
|
|
return size_;
|
|
}
|
|
|
|
/// Resets the reference to nothing.
|
|
void reset() {
|
|
reset(ONIXS_FIXENGINE_NULLPTR, 0);
|
|
}
|
|
|
|
/// Updates data being referenced.
|
|
void
|
|
reset(
|
|
const char * chars,
|
|
size_t size) {
|
|
chars_ = chars;
|
|
size_ = size;
|
|
}
|
|
|
|
const char &
|
|
operator [](size_t index) const {
|
|
return chars_[index];
|
|
}
|
|
|
|
const char &
|
|
at(size_t index) const {
|
|
if(index < size_)
|
|
return chars_[index];
|
|
|
|
throw std::invalid_argument("index");
|
|
}
|
|
|
|
/// Returns the number if the text is a string
|
|
/// representation of an integer.
|
|
template
|
|
<
|
|
typename NumericType
|
|
>
|
|
bool
|
|
toNumber(NumericType & number) const {
|
|
return OnixS::FIX::Number::
|
|
tryParse(chars_, size_, number);
|
|
}
|
|
|
|
// Appends a copy of the text to the std::string.
|
|
void
|
|
toString(std::string & str) const {
|
|
str.append(chars_, size_);
|
|
}
|
|
|
|
// Returns a copy of the text as the std::string.
|
|
std::string
|
|
toString() const {
|
|
return std::string(chars_, size_);
|
|
}
|
|
|
|
/// Compares with another instance.
|
|
bool
|
|
operator == (
|
|
const StringRef & other) const {
|
|
return (
|
|
size_ == other.size_
|
|
&&
|
|
0 == std::memcmp(
|
|
chars_, other.chars_, size_));
|
|
}
|
|
|
|
/// Compares with another instance.
|
|
bool
|
|
operator != (
|
|
const StringRef & other) const {
|
|
return (
|
|
size_ != other.size_
|
|
||
|
|
0 != std::memcmp(
|
|
chars_, other.chars_, size_));
|
|
}
|
|
|
|
/// Swaps the content with another instance.
|
|
void
|
|
swap(StringRef & other) {
|
|
std::swap(chars_, other.chars_);
|
|
std::swap(size_, other.size_);
|
|
}
|
|
|
|
friend std::ostream & operator<< (std::ostream & out, const StringRef & ref);
|
|
|
|
private:
|
|
/// Items being referenced.
|
|
const char * chars_;
|
|
|
|
/// The number of chars being referenced.
|
|
size_t size_;
|
|
};
|
|
|
|
inline
|
|
bool
|
|
operator == (
|
|
const StringRef & ref,
|
|
const std::string & str)
|
|
{
|
|
return ref == StringRef(str);
|
|
}
|
|
|
|
inline
|
|
bool
|
|
operator != (
|
|
const StringRef & ref,
|
|
const std::string & str)
|
|
{
|
|
return ref != StringRef(str);
|
|
}
|
|
|
|
inline
|
|
bool
|
|
operator == (
|
|
const std::string & str,
|
|
const StringRef & ref)
|
|
{
|
|
return ref == StringRef(str);
|
|
}
|
|
|
|
inline
|
|
bool
|
|
operator != (
|
|
const std::string & str,
|
|
const StringRef & ref)
|
|
{
|
|
return ref != StringRef(str);
|
|
}
|
|
|
|
//
|
|
|
|
inline
|
|
bool
|
|
operator == (
|
|
const StringRef & ref,
|
|
const char * str)
|
|
{
|
|
return ref == StringRef(str);
|
|
}
|
|
|
|
inline
|
|
bool
|
|
operator != (
|
|
const StringRef & ref,
|
|
const char * str)
|
|
{
|
|
return ref != StringRef(str);
|
|
}
|
|
|
|
inline
|
|
bool
|
|
operator == (
|
|
const char * str,
|
|
const StringRef & ref)
|
|
{
|
|
return ref == StringRef(str);
|
|
}
|
|
|
|
inline
|
|
bool
|
|
operator != (
|
|
const char * str,
|
|
const StringRef & ref)
|
|
{
|
|
return ref != StringRef(str);
|
|
}
|
|
|
|
inline std::ostream & operator<< (std::ostream & out, const StringRef & ref)
|
|
{
|
|
if(! ref.empty())
|
|
out.write(ref.chars_, ref.size_);
|
|
|
|
return out;
|
|
}
|
|
|
|
#endif
|
|
|
|
template <size_t Size>
|
|
ONIXS_FIXENGINE_NODISCARD
|
|
inline
|
|
ONIXS_FIXENGINE_CONSTEXPR
|
|
StringRef constructStrRef(const char (&value)[Size]) ONIXS_FIXENGINE_NOTHROW
|
|
{
|
|
return StringRef(value, Size - 1);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
namespace std {
|
|
/// Allows the use of the StringRef in collections like std::map.
|
|
template<>
|
|
struct
|
|
ONIXS_FIXENGINE_API
|
|
less<OnixS::FIX::StringRef> {
|
|
bool
|
|
operator()(
|
|
const OnixS::FIX::StringRef & left,
|
|
const OnixS::FIX::StringRef & right) const {
|
|
ptrdiff_t
|
|
compareResult = std::memcmp(
|
|
left.data(), right.data(),
|
|
left.size() < right.size()
|
|
? left.size() : right.size());
|
|
|
|
if(0 == compareResult) {
|
|
compareResult =
|
|
static_cast<ptrdiff_t>(
|
|
left.size() - right.size());
|
|
}
|
|
|
|
return (0 > compareResult);
|
|
}
|
|
};
|
|
}
|