Bug 1991899 - Use RecordedEventArray for variable-sized recording data. r=aosmond a=RyanVM
Differential Revision: https://phabricator.services.mozilla.com/D267087
This commit is contained in:
committed by
rvandermeulen@mozilla.com
parent
dcb678f865
commit
9121587c58
@@ -518,6 +518,85 @@ class RecordedStrokeOptionsMixin {
|
||||
UniquePtr<Float[]> mDashPatternStorage;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class RecordedEventArray {
|
||||
public:
|
||||
T* data() { return mData.get(); }
|
||||
const T* data() const { return mData.get(); }
|
||||
size_t size() const { return mSize; }
|
||||
bool empty() const { return !mSize; }
|
||||
|
||||
void Assign(const T* aData, size_t aSize) {
|
||||
mSize = aSize;
|
||||
mData = MakeUnique<T[]>(aSize);
|
||||
PodCopy(mData.get(), aData, aSize);
|
||||
}
|
||||
|
||||
bool TryAlloc(size_t aSize) {
|
||||
if (mSize > 0) {
|
||||
MOZ_ASSERT_UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
mData = MakeUniqueFallible<T[]>(aSize);
|
||||
if (!mData) {
|
||||
return false;
|
||||
}
|
||||
mSize = aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
void Write(S& aStream) const {
|
||||
if (mSize) {
|
||||
aStream.write(reinterpret_cast<const char*>(mData.get()),
|
||||
sizeof(T) * mSize);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
bool Read(S& aStream, size_t aSize) {
|
||||
if (!aStream.good() || !TryAlloc(aSize)) {
|
||||
return false;
|
||||
}
|
||||
aStream.read(reinterpret_cast<char*>(mData.get()), sizeof(T) * mSize);
|
||||
if (!aStream.good()) {
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
mSize = 0;
|
||||
mData.reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t mSize = 0;
|
||||
UniquePtr<T[]> mData;
|
||||
};
|
||||
|
||||
class RecordedEventCString : public RecordedEventArray<char> {
|
||||
public:
|
||||
explicit RecordedEventCString(const char* aStr = nullptr) {
|
||||
if (aStr) {
|
||||
if (size_t len = strlen(aStr)) {
|
||||
Assign(aStr, len + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
bool Read(S& aStream, size_t aSize) {
|
||||
if (!RecordedEventArray<char>::Read(aStream, aSize) ||
|
||||
(size() > 0 && !memchr(data(), '\0', size()))) {
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Derived>
|
||||
class RecordedEventDerived : public RecordedEvent {
|
||||
using RecordedEvent::RecordedEvent;
|
||||
|
||||
@@ -1520,7 +1520,7 @@ class RecordedFontDescriptor
|
||||
bool mHasDesc;
|
||||
|
||||
FontType mType;
|
||||
std::vector<uint8_t> mData;
|
||||
RecordedEventArray<uint8_t> mData;
|
||||
uint32_t mIndex;
|
||||
ReferencePtr mRefPtr;
|
||||
|
||||
@@ -1563,7 +1563,7 @@ class RecordedUnscaledFontCreation
|
||||
ReferencePtr mRefPtr;
|
||||
uint64_t mFontDataKey;
|
||||
uint32_t mIndex;
|
||||
std::vector<uint8_t> mInstanceData;
|
||||
RecordedEventArray<uint8_t> mInstanceData;
|
||||
|
||||
template <class S>
|
||||
MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
|
||||
@@ -1630,8 +1630,8 @@ class RecordedScaledFontCreation
|
||||
ReferencePtr mRefPtr;
|
||||
ReferencePtr mUnscaledFont;
|
||||
Float mGlyphSize;
|
||||
std::vector<uint8_t> mInstanceData;
|
||||
std::vector<FontVariation> mVariations;
|
||||
RecordedEventArray<uint8_t> mInstanceData;
|
||||
RecordedEventArray<FontVariation> mVariations;
|
||||
|
||||
template <class S>
|
||||
MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
|
||||
@@ -1719,8 +1719,7 @@ class RecordedFilterNodeSetAttribute
|
||||
mNode(aNode),
|
||||
mIndex(aIndex),
|
||||
mArgType(aArgType) {
|
||||
mPayload.resize(sizeof(T));
|
||||
memcpy(&mPayload.front(), &aArgument, sizeof(T));
|
||||
mPayload.Assign(reinterpret_cast<const uint8_t*>(&aArgument), sizeof(T));
|
||||
}
|
||||
|
||||
RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
|
||||
@@ -1729,8 +1728,8 @@ class RecordedFilterNodeSetAttribute
|
||||
mNode(aNode),
|
||||
mIndex(aIndex),
|
||||
mArgType(ARGTYPE_FLOAT_ARRAY) {
|
||||
mPayload.resize(sizeof(Float) * aSize);
|
||||
memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
|
||||
mPayload.Assign(reinterpret_cast<const uint8_t*>(aFloat),
|
||||
sizeof(Float) * aSize);
|
||||
}
|
||||
|
||||
bool PlayEvent(Translator* aTranslator) const override;
|
||||
@@ -1747,7 +1746,7 @@ class RecordedFilterNodeSetAttribute
|
||||
|
||||
uint32_t mIndex;
|
||||
ArgType mArgType;
|
||||
std::vector<uint8_t> mPayload;
|
||||
RecordedEventArray<uint8_t> mPayload;
|
||||
|
||||
template <class S>
|
||||
MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
|
||||
@@ -1809,8 +1808,8 @@ class RecordedLink : public RecordedEventDerived<RecordedLink> {
|
||||
private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
std::string mLocalDest;
|
||||
std::string mURI;
|
||||
RecordedEventCString mLocalDest;
|
||||
RecordedEventCString mURI;
|
||||
Rect mRect;
|
||||
|
||||
template <class S>
|
||||
@@ -1834,7 +1833,7 @@ class RecordedDestination : public RecordedEventDerived<RecordedDestination> {
|
||||
private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
std::string mDestination;
|
||||
RecordedEventCString mDestination;
|
||||
Point mPoint;
|
||||
|
||||
template <class S>
|
||||
@@ -4104,10 +4103,8 @@ void RecordedFontDescriptor::Record(S& aStream) const {
|
||||
WriteElement(aStream, mType);
|
||||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mIndex);
|
||||
WriteElement(aStream, (size_t)mData.size());
|
||||
if (mData.size()) {
|
||||
aStream.write((char*)mData.data(), mData.size());
|
||||
}
|
||||
WriteElement(aStream, mData.size());
|
||||
mData.Write(aStream);
|
||||
}
|
||||
|
||||
inline void RecordedFontDescriptor::OutputSimpleEventInfo(
|
||||
@@ -4118,7 +4115,7 @@ inline void RecordedFontDescriptor::OutputSimpleEventInfo(
|
||||
inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
|
||||
uint32_t aSize,
|
||||
uint32_t aIndex) {
|
||||
mData.assign(aData, aData + aSize);
|
||||
mData.Assign(aData, aSize);
|
||||
mIndex = aIndex;
|
||||
}
|
||||
|
||||
@@ -4129,14 +4126,14 @@ RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
|
||||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mIndex);
|
||||
|
||||
size_t size;
|
||||
size_t size = 0;
|
||||
ReadElement(aStream, size);
|
||||
if (!aStream.good()) {
|
||||
return;
|
||||
}
|
||||
if (size) {
|
||||
mData.resize(size);
|
||||
aStream.read((char*)mData.data(), size);
|
||||
if (size && !mData.Read(aStream, size)) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4162,10 +4159,8 @@ void RecordedUnscaledFontCreation::Record(S& aStream) const {
|
||||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mFontDataKey);
|
||||
WriteElement(aStream, mIndex);
|
||||
WriteElement(aStream, (size_t)mInstanceData.size());
|
||||
if (mInstanceData.size()) {
|
||||
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
||||
}
|
||||
WriteElement(aStream, mInstanceData.size());
|
||||
mInstanceData.Write(aStream);
|
||||
}
|
||||
|
||||
inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
|
||||
@@ -4176,7 +4171,7 @@ inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
|
||||
inline void RecordedUnscaledFontCreation::SetFontInstanceData(
|
||||
const uint8_t* aData, uint32_t aSize) {
|
||||
if (aSize) {
|
||||
mInstanceData.assign(aData, aData + aSize);
|
||||
mInstanceData.Assign(aData, aSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4187,14 +4182,14 @@ RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
|
||||
ReadElement(aStream, mFontDataKey);
|
||||
ReadElement(aStream, mIndex);
|
||||
|
||||
size_t size;
|
||||
size_t size = 0;
|
||||
ReadElement(aStream, size);
|
||||
if (!aStream.good()) {
|
||||
return;
|
||||
}
|
||||
if (size) {
|
||||
mInstanceData.resize(size);
|
||||
aStream.read((char*)mInstanceData.data(), size);
|
||||
if (size && !mInstanceData.Read(aStream, size)) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4243,15 +4238,10 @@ void RecordedScaledFontCreation::Record(S& aStream) const {
|
||||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mUnscaledFont);
|
||||
WriteElement(aStream, mGlyphSize);
|
||||
WriteElement(aStream, (size_t)mInstanceData.size());
|
||||
if (mInstanceData.size()) {
|
||||
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
||||
}
|
||||
WriteElement(aStream, (size_t)mVariations.size());
|
||||
if (mVariations.size()) {
|
||||
aStream.write((char*)mVariations.data(),
|
||||
sizeof(FontVariation) * mVariations.size());
|
||||
}
|
||||
WriteElement(aStream, mInstanceData.size());
|
||||
mInstanceData.Write(aStream);
|
||||
WriteElement(aStream, mVariations.size());
|
||||
mVariations.Write(aStream);
|
||||
}
|
||||
|
||||
inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
|
||||
@@ -4263,10 +4253,10 @@ inline void RecordedScaledFontCreation::SetFontInstanceData(
|
||||
const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
|
||||
uint32_t aNumVariations) {
|
||||
if (aSize) {
|
||||
mInstanceData.assign(aData, aData + aSize);
|
||||
mInstanceData.Assign(aData, aSize);
|
||||
}
|
||||
if (aNumVariations) {
|
||||
mVariations.assign(aVariations, aVariations + aNumVariations);
|
||||
mVariations.Assign(aVariations, aNumVariations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4277,25 +4267,24 @@ RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
|
||||
ReadElement(aStream, mUnscaledFont);
|
||||
ReadElement(aStream, mGlyphSize);
|
||||
|
||||
size_t size;
|
||||
size_t size = 0;
|
||||
ReadElement(aStream, size);
|
||||
if (!aStream.good()) {
|
||||
return;
|
||||
}
|
||||
if (size) {
|
||||
mInstanceData.resize(size);
|
||||
aStream.read((char*)mInstanceData.data(), size);
|
||||
if (size && !mInstanceData.Read(aStream, size)) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t numVariations;
|
||||
size_t numVariations = 0;
|
||||
ReadElement(aStream, numVariations);
|
||||
if (!aStream.good()) {
|
||||
return;
|
||||
}
|
||||
if (numVariations) {
|
||||
mVariations.resize(numVariations);
|
||||
aStream.read((char*)mVariations.data(),
|
||||
sizeof(FontVariation) * numVariations);
|
||||
if (numVariations && !mVariations.Read(aStream, numVariations)) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4373,9 +4362,12 @@ inline bool RecordedFilterNodeSetAttribute::PlayEvent(
|
||||
return false;
|
||||
}
|
||||
|
||||
#define REPLAY_SET_ATTRIBUTE(type, argtype) \
|
||||
case ARGTYPE_##argtype: \
|
||||
ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
|
||||
#define REPLAY_SET_ATTRIBUTE(type, argtype) \
|
||||
case ARGTYPE_##argtype: \
|
||||
if (mPayload.size() < sizeof(type)) { \
|
||||
return false; \
|
||||
} \
|
||||
ReplaySetAttribute(node, mIndex, *(type*)mPayload.data()); \
|
||||
break
|
||||
|
||||
switch (mArgType) {
|
||||
@@ -4394,7 +4386,7 @@ inline bool RecordedFilterNodeSetAttribute::PlayEvent(
|
||||
REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
|
||||
case ARGTYPE_FLOAT_ARRAY:
|
||||
node->SetAttribute(mIndex,
|
||||
reinterpret_cast<const Float*>(&mPayload.front()),
|
||||
reinterpret_cast<const Float*>(mPayload.data()),
|
||||
mPayload.size() / sizeof(Float));
|
||||
break;
|
||||
}
|
||||
@@ -4407,8 +4399,8 @@ void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
|
||||
WriteElement(aStream, mNode);
|
||||
WriteElement(aStream, mIndex);
|
||||
WriteElement(aStream, mArgType);
|
||||
WriteElement(aStream, uint64_t(mPayload.size()));
|
||||
aStream.write((const char*)&mPayload.front(), mPayload.size());
|
||||
WriteElement(aStream, mPayload.size());
|
||||
mPayload.Write(aStream);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
@@ -4418,14 +4410,16 @@ RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
|
||||
ReadElement(aStream, mIndex);
|
||||
ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
|
||||
ArgType::ARGTYPE_FLOAT_ARRAY);
|
||||
uint64_t size;
|
||||
size_t size = 0;
|
||||
ReadElement(aStream, size);
|
||||
if (!aStream.good()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPayload.resize(size_t(size));
|
||||
aStream.read((char*)&mPayload.front(), size);
|
||||
if (size && !mPayload.Read(aStream, size)) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
|
||||
@@ -4484,48 +4478,44 @@ inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
|
||||
if (!dt) {
|
||||
return false;
|
||||
}
|
||||
dt->Link(mLocalDest.c_str(), mURI.c_str(), mRect);
|
||||
dt->Link(mLocalDest.data(), mURI.data(), mRect);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class S>
|
||||
void RecordedLink::Record(S& aStream) const {
|
||||
WriteElement(aStream, mRect);
|
||||
uint32_t len = mLocalDest.length();
|
||||
WriteElement(aStream, len);
|
||||
if (len) {
|
||||
aStream.write(mLocalDest.data(), len);
|
||||
}
|
||||
len = mURI.length();
|
||||
WriteElement(aStream, len);
|
||||
if (len) {
|
||||
aStream.write(mURI.data(), len);
|
||||
}
|
||||
WriteElement(aStream, mLocalDest.size());
|
||||
mLocalDest.Write(aStream);
|
||||
WriteElement(aStream, mURI.size());
|
||||
mURI.Write(aStream);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) {
|
||||
ReadElement(aStream, mRect);
|
||||
uint32_t len;
|
||||
ReadElement(aStream, len);
|
||||
mLocalDest.resize(size_t(len));
|
||||
if (len && aStream.good()) {
|
||||
aStream.read(&mLocalDest.front(), len);
|
||||
size_t localDestLen = 0;
|
||||
ReadElement(aStream, localDestLen);
|
||||
if (!aStream.good() ||
|
||||
(localDestLen && !mLocalDest.Read(aStream, localDestLen))) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
ReadElement(aStream, len);
|
||||
mURI.resize(size_t(len));
|
||||
if (len && aStream.good()) {
|
||||
aStream.read(&mURI.front(), len);
|
||||
size_t uriLen = 0;
|
||||
ReadElement(aStream, uriLen);
|
||||
if (!aStream.good() || (uriLen && !mURI.Read(aStream, uriLen))) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void RecordedLink::OutputSimpleEventInfo(
|
||||
std::stringstream& aStringStream) const {
|
||||
if (mLocalDest.empty()) {
|
||||
aStringStream << "Link [" << mURI << " @ " << mRect << "]";
|
||||
aStringStream << "Link [" << mURI.data() << " @ " << mRect << "]";
|
||||
} else {
|
||||
aStringStream << "Link [" << mLocalDest << " / " << mURI << " @ " << mRect
|
||||
<< "]";
|
||||
aStringStream << "Link [" << mLocalDest.data() << " / " << mURI.data()
|
||||
<< " @ " << mRect << "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4534,35 +4524,33 @@ inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
|
||||
if (!dt) {
|
||||
return false;
|
||||
}
|
||||
dt->Destination(mDestination.c_str(), mPoint);
|
||||
dt->Destination(mDestination.data(), mPoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class S>
|
||||
void RecordedDestination::Record(S& aStream) const {
|
||||
WriteElement(aStream, mPoint);
|
||||
uint32_t len = mDestination.length();
|
||||
WriteElement(aStream, len);
|
||||
if (len) {
|
||||
aStream.write(mDestination.data(), len);
|
||||
}
|
||||
WriteElement(aStream, mDestination.size());
|
||||
mDestination.Write(aStream);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
RecordedDestination::RecordedDestination(S& aStream)
|
||||
: RecordedEventDerived(DESTINATION) {
|
||||
ReadElement(aStream, mPoint);
|
||||
uint32_t len;
|
||||
size_t len = 0;
|
||||
ReadElement(aStream, len);
|
||||
mDestination.resize(size_t(len));
|
||||
if (len && aStream.good()) {
|
||||
aStream.read(&mDestination.front(), len);
|
||||
if (!aStream.good() || (len && !mDestination.Read(aStream, len))) {
|
||||
aStream.SetIsBad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void RecordedDestination::OutputSimpleEventInfo(
|
||||
std::stringstream& aStringStream) const {
|
||||
aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
|
||||
aStringStream << "Destination [" << mDestination.data() << " @ " << mPoint
|
||||
<< "]";
|
||||
}
|
||||
|
||||
#define FOR_EACH_EVENT(f) \
|
||||
|
||||
Reference in New Issue
Block a user