32struct QQmlProfilerEvent {
34 m_timestamp(-1), m_typeIndex(-1), m_dataType(Inline8Bit), m_dataLength(0)
37 template<
typename Number>
38 QQmlProfilerEvent(qint64 timestamp,
int typeIndex, std::initializer_list<Number> list)
39 : m_timestamp(timestamp), m_typeIndex(typeIndex)
41 assignNumbers<std::initializer_list<Number>, Number>(list);
44 QQmlProfilerEvent(qint64 timestamp,
int typeIndex,
const QString &data)
45 : m_timestamp(timestamp), m_typeIndex(typeIndex)
47 assignNumbers<QByteArray, qint8>(data.toUtf8());
50 template<
typename Number>
51 QQmlProfilerEvent(qint64 timestamp,
int typeIndex,
const QVector<Number> &data)
52 : m_timestamp(timestamp), m_typeIndex(typeIndex)
54 assignNumbers<QVector<Number>, Number>(data);
57 QQmlProfilerEvent(
const QQmlProfilerEvent &other)
58 : m_timestamp(other.m_timestamp), m_typeIndex(other.m_typeIndex),
59 m_dataType(other.m_dataType), m_dataLength(other.m_dataLength)
64 QQmlProfilerEvent(QQmlProfilerEvent &&other)
66 memcpy(
static_cast<
void *>(
this),
static_cast<
const void *>(&other),
sizeof(QQmlProfilerEvent));
67 other.m_dataType = Inline8Bit;
70 QQmlProfilerEvent &operator=(
const QQmlProfilerEvent &other)
74 m_timestamp = other.m_timestamp;
75 m_typeIndex = other.m_typeIndex;
76 m_dataType = other.m_dataType;
77 m_dataLength = other.m_dataLength;
83 QQmlProfilerEvent &operator=(QQmlProfilerEvent &&other)
86 memcpy(
static_cast<
void *>(
this),
static_cast<
const void *>(&other),
sizeof(QQmlProfilerEvent));
87 other.m_dataType = Inline8Bit;
97 qint64 timestamp()
const {
return m_timestamp; }
98 void setTimestamp(qint64 timestamp) { m_timestamp = timestamp; }
100 int typeIndex()
const {
return m_typeIndex; }
101 void setTypeIndex(
int typeIndex) { m_typeIndex = typeIndex; }
103 template<
typename Number>
104 Number number(
int i)
const
107 if (i >= m_dataLength)
109 switch (m_dataType) {
111 return m_data.internal8bit[i];
113QT_WARNING_DISABLE_GCC(
"-Warray-bounds")
115 return m_data.internal16bit[i];
117 return m_data.internal32bit[i];
119 return m_data.internal64bit[i];
122 return static_cast<
const qint8 *>(m_data.external)[i];
124 return static_cast<
const qint16 *>(m_data.external)[i];
126 return static_cast<
const qint32 *>(m_data.external)[i];
128 return static_cast<
const qint64 *>(m_data.external)[i];
134 template<
typename Number>
135 void setNumber(
int i, Number number)
137 QVarLengthArray<Number> nums = numbers<QVarLengthArray<Number>, Number>();
138 int prevSize = nums.size();
143 nums[prevSize++] = 0;
146 setNumbers<QVarLengthArray<Number>, Number>(nums);
149 template<
typename Container,
typename Number>
150 void setNumbers(
const Container &numbers)
153 assignNumbers<Container, Number>(numbers);
156 template<
typename Number>
157 void setNumbers(std::initializer_list<Number> numbers)
159 setNumbers<std::initializer_list<Number>, Number>(numbers);
162 template<
typename Container,
typename Number = qint64>
163 Container numbers()
const
166 for (
int i = 0; i < m_dataLength; ++i)
167 container.append(number<Number>(i));
171 QString string()
const
173 switch (m_dataType) {
175 return QString::fromUtf8(
static_cast<
const char *>(m_data.external), m_dataLength);
177 return QString::fromUtf8(m_data.internalChar, m_dataLength);
179 Q_UNREACHABLE_RETURN(QString());
183 void setString(
const QString &data)
186 assignNumbers<QByteArray,
char>(data.toUtf8());
189 Message rangeStage()
const
191 Q_ASSERT(m_dataType == Inline8Bit);
192 return static_cast<Message>(m_data.internal8bit[0]);
195 void setRangeStage(Message stage)
198 m_dataType = Inline8Bit;
200 m_data.internal8bit[0] = stage;
205 return m_timestamp != -1;
212 External8Bit = Inline8Bit | External,
214 External16Bit = Inline16Bit | External,
216 External32Bit = Inline32Bit | External,
218 External64Bit = Inline64Bit | External
223 static const int s_internalDataLength = 8;
226 char internalChar [s_internalDataLength];
227 qint8 internal8bit [s_internalDataLength];
228 qint16 internal16bit[s_internalDataLength / 2];
229 qint32 internal32bit[s_internalDataLength / 4];
230 qint64 internal64bit[s_internalDataLength / 8];
235 quint16 m_dataLength;
237 void assignData(
const QQmlProfilerEvent &other)
239 if (m_dataType & External) {
240 uint length = m_dataLength * (other.m_dataType / 8);
241 m_data.external = malloc(length);
242 Q_CHECK_PTR(m_data.external);
243 memcpy(m_data.external, other.m_data.external, length);
245 memcpy(&m_data, &other.m_data,
sizeof(m_data));
249 template<
typename Big,
typename Small>
250 bool squeezable(Big source)
252 return static_cast<Small>(source) == source;
255 template<
typename Container,
typename Number>
256 typename std::enable_if<(
sizeof(Number) > 1),
bool>::type
257 squeeze(
const Container &numbers)
259 typedef typename QIntegerForSize<
sizeof(Number) / 2>::Signed Small;
260 for (Number item : numbers) {
261 if (!squeezable<Number, Small>(item))
264 assignNumbers<Container, Small>(numbers);
268 template<
typename Container,
typename Number>
269 typename std::enable_if<(
sizeof(Number) <= 1),
bool>::type
270 squeeze(
const Container &)
275 template<
typename Container,
typename Number>
276 void assignNumbers(
const Container &numbers)
279 m_dataLength = squeezable<size_t, quint16>(
static_cast<size_t>(numbers.size())) ?
280 static_cast<quint16>(numbers.size()) : std::numeric_limits<quint16>::max();
281 if (m_dataLength >
sizeof(m_data) /
sizeof(Number)) {
282 if (squeeze<Container, Number>(numbers))
284 m_dataType =
static_cast<Type>((
sizeof(Number) * 8) | External);
285 m_data.external = malloc(m_dataLength *
sizeof(Number));
286 Q_CHECK_PTR(m_data.external);
287 data =
static_cast<Number *>(m_data.external);
289 m_dataType =
static_cast<Type>(
sizeof(Number) * 8);
290 data =
static_cast<Number *>(m_dataType & External ? m_data.external : &m_data);
293 for (Number item : numbers) {
294 if (i >= m_dataLength)
302 if (m_dataType & External)
303 free(m_data.external);
306 friend QDataStream &operator>>(QDataStream &stream, QQmlProfilerEvent &event);
307 friend QDataStream &operator<<(QDataStream &stream,
const QQmlProfilerEvent &event);