1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/**********************************************************************
Audacity: A Digital Audio Editor
XMLAttributeValueView.h
Dmitry Vedenko
**********************************************************************/
#pragma once
#include <cstdint>
#include <stdexcept>
#include <string>
#include <string_view>
#include <limits>
#include <wx/string.h>
/*! \brief A view into an attribute value. The class does not take the ownership of the data.
*
* Audacity internally uses regular XML and an internal binary XML-like format.
* Binary format extends the possible XML types to support integers and floating point values,
* not just the string values.
*
* This class represents the attribute value for both text and binary XML formats.
*
* Class has a number of Get overloads, that allow to read the value with the required data type.
*
* Integer-based types can be read from the view if it was initialized by an integer value or with a
* string_view that is a textual representation of an integer value. To avoid runtime data loss it is not
* possible to read an integer from the floating point values. Boundary checks are always performed.
* If the type is not large enough to store the value, Get fails.
*
* Floating point values can be read from the view, if it is initialized using floating point, integer or
* a compatible string value. Conversion from Float to Double is forbidden.
*
* String values can be read only if the view was created using a string_view.
* However there are ToString() and ToWString() methods that allow conversion from any type to string.
* Null type is represented by an empty string.
*/
class XML_API XMLAttributeValueView final
{
public:
//! Type of the value represented by the XMLAttributeValueView.
enum class Type
{
Null, //!< The value is not initialized.
SignedInteger, //!< The value is a signed integer.
UnsignedInteger, //!< The value is an unsigned integer.
Float, //!< The value is a single precision floating point value.
Double, //!< The value is a double precision floating point value.
StringView //!< The value is a string_view.
};
//! Construct an uninitialized view of type Null
XMLAttributeValueView() = default;
XMLAttributeValueView(const XMLAttributeValueView&) = default;
XMLAttributeValueView(XMLAttributeValueView&&) = default;
XMLAttributeValueView& operator = (const XMLAttributeValueView&) = default;
XMLAttributeValueView& operator = (XMLAttributeValueView&&) = default;
//! Construct a view of type UnsignedInteger from the value.
explicit XMLAttributeValueView(bool value) noexcept;
//! Construct a view of type SignedInteger from the value.
explicit XMLAttributeValueView(short value) noexcept;
//! Construct a view of type UnsignedInteger from the value.
explicit XMLAttributeValueView(unsigned short value) noexcept;
//! Construct a view of type SignedInteger from the value.
explicit XMLAttributeValueView(int value) noexcept;
//! Construct a view of type UnsignedInteger from the value.
explicit XMLAttributeValueView(unsigned int value) noexcept;
//! Construct a view of type SignedInteger from the value.
explicit XMLAttributeValueView(long value) noexcept;
//! Construct a view of type UnsignedInteger from the value.
explicit XMLAttributeValueView(unsigned long value) noexcept;
//! Construct a view of type SignedInteger from the value.
explicit XMLAttributeValueView(long long value) noexcept;
//! Construct a view of type UnsignedInteger from the value.
explicit XMLAttributeValueView(unsigned long long value) noexcept;
//! Construct a view of type Float from the value.
explicit XMLAttributeValueView(float value) noexcept;
//! Construct a view of type Double from the value.
explicit XMLAttributeValueView(double value) noexcept;
//! Construct a view of type StringView from the value.
explicit XMLAttributeValueView(const std::string_view& value) noexcept;
//! Get the view type.
Type GetType() const noexcept;
//! Check if view is Null.
bool IsNull() const noexcept;
//! Check if view has the SignedInteger type.
bool IsSignedInteger() const noexcept;
//! Check if view has the UnsignedInteger type.
bool IsUnsignedInteger() const noexcept;
//! Check if view has the Float type.
bool IsFloat() const noexcept;
//! Check if view has the Double type.
bool IsDouble() const noexcept;
//! Check if view has the StringView type.
bool IsStringView() const noexcept;
//! Try to get a boolean value from the view.
bool TryGet(bool& value) const noexcept;
//! Try to get a short value from the view.
bool TryGet(short& value) const noexcept;
//! Try to get an unsigned short value from the view.
bool TryGet(unsigned short& value) const noexcept;
//! Try to get an int value from the view.
bool TryGet(int& value) const noexcept;
//! Try to get an unsigned int value from the view.
bool TryGet(unsigned int& value) const noexcept;
//! Try to get a long value from the view.
bool TryGet(long& value) const noexcept;
//! Try to get an unsigned long value from the view.
bool TryGet(unsigned long& value) const noexcept;
//! Try to get a long long value from the view.
bool TryGet(long long& value) const noexcept;
//! Try to get an unsigned long long value from the view.
bool TryGet(unsigned long long& value) const noexcept;
//! Try to get a float value from the view.
bool TryGet(float& value) const noexcept;
//! Try to get a double value from the view.
bool TryGet(double& value) const noexcept;
//! Try to get a string_view value from the view.
bool TryGet(std::string_view& value) const noexcept;
//! Returns the value if there is a viable conversion, default value otherwise
template<typename T>
T Get(T defaultValue = {}) const noexcept
{
// TryGet only modifies the value if conversion is possible,
// so just reuse the defaultValue
(void) TryGet(defaultValue);
return defaultValue;
}
//! Convert the view value to an UTF8 string.
std::string ToString() const;
//! Convert the view value to wxString.
wxString ToWString() const;
private:
template <typename ResultType>
bool TryGetInteger(ResultType& value) const noexcept;
// std::variant requires macOS 10.14, which is significantly higher than
// the current target
union
{
int64_t mInteger;
double mDouble;
float mFloat;
struct
{
const char* Data;
size_t Length;
} mStringView;
};
Type mType { Type::Null };
};
|