31struct QQmlProfilerEvent {
33 m_timestamp(-1), m_typeIndex(-1), m_dataType(Inline8Bit), m_dataLength(0)
36 template<
typename Number>
37 QQmlProfilerEvent(qint64 timestamp,
int typeIndex, std::initializer_list<Number> list)
38 : m_timestamp(timestamp), m_typeIndex(typeIndex)
40 assignNumbers<std::initializer_list<Number>, Number>(list);
43 QQmlProfilerEvent(qint64 timestamp,
int typeIndex,
const QString &data)
44 : m_timestamp(timestamp), m_typeIndex(typeIndex)
46 assignNumbers<QByteArray, qint8>(data.toUtf8());
49 template<
typename Number>
50 QQmlProfilerEvent(qint64 timestamp,
int typeIndex,
const QVector<Number> &data)
51 : m_timestamp(timestamp), m_typeIndex(typeIndex)
53 assignNumbers<QVector<Number>, Number>(data);
56 QQmlProfilerEvent(
const QQmlProfilerEvent &other)
57 : m_timestamp(other.m_timestamp), m_typeIndex(other.m_typeIndex),
58 m_dataType(other.m_dataType), m_dataLength(other.m_dataLength)
63 QQmlProfilerEvent(QQmlProfilerEvent &&other)
65 memcpy(
static_cast<
void *>(
this),
static_cast<
const void *>(&other),
sizeof(QQmlProfilerEvent));
66 other.m_dataType = Inline8Bit;
69 QQmlProfilerEvent &operator=(
const QQmlProfilerEvent &other)
73 m_timestamp = other.m_timestamp;
74 m_typeIndex = other.m_typeIndex;
75 m_dataType = other.m_dataType;
76 m_dataLength = other.m_dataLength;
82 QQmlProfilerEvent &operator=(QQmlProfilerEvent &&other)
85 memcpy(
static_cast<
void *>(
this),
static_cast<
const void *>(&other),
sizeof(QQmlProfilerEvent));
86 other.m_dataType = Inline8Bit;
96 qint64 timestamp()
const {
return m_timestamp; }
97 void setTimestamp(qint64 timestamp) { m_timestamp = timestamp; }
99 int typeIndex()
const {
return m_typeIndex; }
100 void setTypeIndex(
int typeIndex) { m_typeIndex = typeIndex; }
102 template<
typename Number>
103 Number number(
int i)
const
106 if (i >= m_dataLength)
108 switch (m_dataType) {
110 return m_data.internal8bit[i];
112QT_WARNING_DISABLE_GCC(
"-Warray-bounds")
114 return m_data.internal16bit[i];
116 return m_data.internal32bit[i];
118 return m_data.internal64bit[i];
121 return static_cast<
const qint8 *>(m_data.external)[i];
123 return static_cast<
const qint16 *>(m_data.external)[i];
125 return static_cast<
const qint32 *>(m_data.external)[i];
127 return static_cast<
const qint64 *>(m_data.external)[i];
133 template<
typename Number>
134 void setNumber(
int i, Number number)
136 QVarLengthArray<Number> nums = numbers<QVarLengthArray<Number>, Number>();
137 int prevSize = nums.size();
142 nums[prevSize++] = 0;
145 setNumbers<QVarLengthArray<Number>, Number>(nums);
148 template<
typename Container,
typename Number>
149 void setNumbers(
const Container &numbers)
152 assignNumbers<Container, Number>(numbers);
155 template<
typename Number>
156 void setNumbers(std::initializer_list<Number> numbers)
158 setNumbers<std::initializer_list<Number>, Number>(numbers);
161 template<
typename Container,
typename Number = qint64>
162 Container numbers()
const
165 for (
int i = 0; i < m_dataLength; ++i)
166 container.append(number<Number>(i));
170 QString string()
const
172 switch (m_dataType) {
174 return QString::fromUtf8(
static_cast<
const char *>(m_data.external), m_dataLength);
176 return QString::fromUtf8(m_data.internalChar, m_dataLength);
178 Q_UNREACHABLE_RETURN(QString());
182 void setString(
const QString &data)
185 assignNumbers<QByteArray,
char>(data.toUtf8());
188 Message rangeStage()
const
190 Q_ASSERT(m_dataType == Inline8Bit);
191 return static_cast<Message>(m_data.internal8bit[0]);
194 void setRangeStage(Message stage)
197 m_dataType = Inline8Bit;
199 m_data.internal8bit[0] = stage;
204 return m_timestamp != -1;
211 External8Bit = Inline8Bit | External,
213 External16Bit = Inline16Bit | External,
215 External32Bit = Inline32Bit | External,
217 External64Bit = Inline64Bit | External
222 static const int s_internalDataLength = 8;
225 char internalChar [s_internalDataLength];
226 qint8 internal8bit [s_internalDataLength];
227 qint16 internal16bit[s_internalDataLength / 2];
228 qint32 internal32bit[s_internalDataLength / 4];
229 qint64 internal64bit[s_internalDataLength / 8];
234 quint16 m_dataLength;
236 void assignData(
const QQmlProfilerEvent &other)
238 if (m_dataType & External) {
239 uint length = m_dataLength * (other.m_dataType / 8);
240 m_data.external = malloc(length);
241 Q_CHECK_PTR(m_data.external);
242 memcpy(m_data.external, other.m_data.external, length);
244 memcpy(&m_data, &other.m_data,
sizeof(m_data));
248 template<
typename Big,
typename Small>
249 bool squeezable(Big source)
251 return static_cast<Small>(source) == source;
254 template<
typename Container,
typename Number>
255 typename std::enable_if<(
sizeof(Number) > 1),
bool>::type
256 squeeze(
const Container &numbers)
258 typedef typename QIntegerForSize<
sizeof(Number) / 2>::Signed Small;
259 for (Number item : numbers) {
260 if (!squeezable<Number, Small>(item))
263 assignNumbers<Container, Small>(numbers);
267 template<
typename Container,
typename Number>
268 typename std::enable_if<(
sizeof(Number) <= 1),
bool>::type
269 squeeze(
const Container &)
274 template<
typename Container,
typename Number>
275 void assignNumbers(
const Container &numbers)
278 m_dataLength = squeezable<size_t, quint16>(
static_cast<size_t>(numbers.size())) ?
279 static_cast<quint16>(numbers.size()) : std::numeric_limits<quint16>::max();
280 if (m_dataLength >
sizeof(m_data) /
sizeof(Number)) {
281 if (squeeze<Container, Number>(numbers))
283 m_dataType =
static_cast<Type>((
sizeof(Number) * 8) | External);
284 m_data.external = malloc(m_dataLength *
sizeof(Number));
285 Q_CHECK_PTR(m_data.external);
286 data =
static_cast<Number *>(m_data.external);
288 m_dataType =
static_cast<Type>(
sizeof(Number) * 8);
289 data =
static_cast<Number *>(m_dataType & External ? m_data.external : &m_data);
292 for (Number item : numbers) {
293 if (i >= m_dataLength)
301 if (m_dataType & External)
302 free(m_data.external);
305 friend QDataStream &operator>>(QDataStream &stream, QQmlProfilerEvent &event);
306 friend QDataStream &operator<<(QDataStream &stream,
const QQmlProfilerEvent &event);