File: XMLAttributeValueView.h

package info (click to toggle)
audacity 3.2.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 106,704 kB
  • sloc: cpp: 277,038; ansic: 73,623; lisp: 7,761; python: 3,305; sh: 2,715; perl: 821; xml: 275; makefile: 119
file content (166 lines) | stat: -rw-r--r-- 6,677 bytes parent folder | download | duplicates (3)
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 };
};