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:
ejakowatz
2004-09-07 23:25:09 +00:00
parent 02043d35db
commit 974d454507
2 changed files with 86 additions and 5 deletions
+74 -2
View File
@@ -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>
{ {
+12 -3
View File
@@ -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)