Fixed bug. BMessageBody's assignment operator was making a generic copy of the map which maintains the data -- meaning only pointers to contained BMessageFields were being copied. Added Clone() operation to BMessageField and Copy() to BMessageFieldStoragePolicy, along with a specialization of BMessageFieldStoragePolicy for BDataBuffer; a straight copy of the vector is sufficient for all other data types. This fixes issues with BMessage unittests where BMessage, entry_ref, BFlattenable, and raw data are exercises.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8890 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -79,6 +79,8 @@ class BMessageField
|
|||||||
virtual void PrintToStream(const char* name) const;
|
virtual void PrintToStream(const char* name) const;
|
||||||
virtual const void* DataAt(int32 index, ssize_t* size) const = 0;
|
virtual const void* DataAt(int32 index, ssize_t* size) const = 0;
|
||||||
|
|
||||||
|
virtual BMessageField* Clone() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PrintDataItem(int32 index) const = 0;
|
virtual void PrintDataItem(int32 index) const = 0;
|
||||||
|
|
||||||
@@ -106,6 +108,7 @@ struct BMessageFieldStoragePolicy
|
|||||||
inline const T& operator[](uint index) const { return fData[index]; }
|
inline const T& operator[](uint index) const { return fData[index]; }
|
||||||
inline void Add(const T& data) { fData.push_back(data); }
|
inline void Add(const T& data) { fData.push_back(data); }
|
||||||
inline void Remove(uint index) { fData.erase(fData.begin() + index); }
|
inline void Remove(uint index) { fData.erase(fData.begin() + index); }
|
||||||
|
inline void Copy(const Store& rhs) { fData = rhs.fData; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<T> fData;
|
std::vector<T> fData;
|
||||||
@@ -183,6 +186,9 @@ class BMessageFieldImpl : public BMessageField
|
|||||||
{ fData.Remove(index); };
|
{ fData.Remove(index); };
|
||||||
|
|
||||||
virtual const void* DataAt(int32 index, ssize_t* size) const;
|
virtual const void* DataAt(int32 index, ssize_t* size) const;
|
||||||
|
|
||||||
|
virtual BMessageField* Clone() const;
|
||||||
|
|
||||||
StorageType& Data() { return fData; }
|
StorageType& Data() { return fData; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -396,6 +402,30 @@ template
|
|||||||
class FlattenPolicy,
|
class FlattenPolicy,
|
||||||
class GetDataPolicy
|
class GetDataPolicy
|
||||||
>
|
>
|
||||||
|
BMessageField*
|
||||||
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
|
||||||
|
Clone() const
|
||||||
|
{
|
||||||
|
BMessageFieldImpl<T1>* BMF =
|
||||||
|
new(nothrow) BMessageFieldImpl<T1>(Name(), Type());
|
||||||
|
if (BMF)
|
||||||
|
{
|
||||||
|
BMF->fMaxSize = fMaxSize;
|
||||||
|
BMF->fFlags = fFlags;
|
||||||
|
BMF->fData.Copy(fData);
|
||||||
|
}
|
||||||
|
return BMF;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy,
|
||||||
|
class SizePolicy,
|
||||||
|
class PrintPolicy,
|
||||||
|
class FlattenPolicy,
|
||||||
|
class GetDataPolicy
|
||||||
|
>
|
||||||
void
|
void
|
||||||
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
|
||||||
PrintDataItem(int32 index) const
|
PrintDataItem(int32 index) const
|
||||||
@@ -489,19 +519,61 @@ struct BMessageFieldStoragePolicy<bool>
|
|||||||
{ return fData[index].data; }
|
{ return fData[index].data; }
|
||||||
inline const bool& operator[](uint index) const
|
inline const bool& operator[](uint index) const
|
||||||
{ return fData[index].data; }
|
{ return fData[index].data; }
|
||||||
void Add(const bool& data)
|
inline void Add(const bool& data)
|
||||||
{
|
{
|
||||||
fData.push_back(data);
|
fData.push_back(data);
|
||||||
}
|
}
|
||||||
void Remove(uint index)
|
inline void Remove(uint index)
|
||||||
{
|
{
|
||||||
fData.erase(fData.begin() + index);
|
fData.erase(fData.begin() + index);
|
||||||
}
|
}
|
||||||
|
inline void Copy(const Store& rhs)
|
||||||
|
{
|
||||||
|
if (&fData != &rhs.fData)
|
||||||
|
{
|
||||||
|
fData = rhs.fData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Boolean> fData;
|
std::vector<Boolean> fData;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<>
|
||||||
|
struct BMessageFieldStoragePolicy<BDataBuffer>
|
||||||
|
{
|
||||||
|
class Store
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline size_t Size() const
|
||||||
|
{ return fData.size(); }
|
||||||
|
inline BDataBuffer& operator[](uint index)
|
||||||
|
{ return fData[index]; }
|
||||||
|
inline const BDataBuffer& operator[](uint index) const
|
||||||
|
{ return fData[index]; }
|
||||||
|
inline void Add(const BDataBuffer& data)
|
||||||
|
{ fData.push_back(data); }
|
||||||
|
inline void Remove(uint index)
|
||||||
|
{ fData.erase(fData.begin() + index); }
|
||||||
|
void Copy(const Store& rhs)
|
||||||
|
{
|
||||||
|
if (&fData == &rhs.fData)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fData.clear();
|
||||||
|
for (size_t i = 0; i < rhs.Size(); ++i)
|
||||||
|
{
|
||||||
|
Add(BDataBuffer(rhs[i], true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<BDataBuffer> fData;
|
||||||
|
};
|
||||||
|
};
|
||||||
// Size policy specializations -------------------------------------------------
|
// Size policy specializations -------------------------------------------------
|
||||||
template<> struct BMessageFieldSizePolicy<BString>
|
template<> struct BMessageFieldSizePolicy<BString>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,7 +62,14 @@ BMessageBody& BMessageBody::operator=(const BMessageBody &rhs)
|
|||||||
{
|
{
|
||||||
if (this != &rhs)
|
if (this != &rhs)
|
||||||
{
|
{
|
||||||
fData = rhs.fData;
|
MakeEmpty();
|
||||||
|
for (TMsgDataMap::const_iterator i = rhs.fData.begin();
|
||||||
|
i != rhs.fData.end();
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
BMessageField* BMF = i->second;
|
||||||
|
fData[BMF->Name()] = BMF->Clone();
|
||||||
|
}
|
||||||
fFlattenedSize = rhs.fFlattenedSize;
|
fFlattenedSize = rhs.fFlattenedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +216,8 @@ ssize_t BMessageBody::FlattenedSize() const
|
|||||||
|
|
||||||
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
||||||
{
|
{
|
||||||
size += i->second->FlattenedSize();
|
BMessageField* BMF = i->second;
|
||||||
|
size += BMF->FlattenedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@@ -223,7 +231,8 @@ status_t BMessageBody::Flatten(BDataIO* stream) const
|
|||||||
i != fData.end() && !err;
|
i != fData.end() && !err;
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
err = i->second->Flatten(*stream);
|
BMessageField* BMF = i->second;
|
||||||
|
err = BMF->Flatten(*stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
|
|||||||
Reference in New Issue
Block a user