Fixed bugs in (un)flattening code.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4403 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -123,6 +123,7 @@ struct BMessageFieldSizePolicy
|
|||||||
return sizeof (T) * data.Size();
|
return sizeof (T) * data.Size();
|
||||||
}
|
}
|
||||||
inline static bool Fixed() { return true; }
|
inline static bool Fixed() { return true; }
|
||||||
|
inline static size_t Padding(const T&) { return 0; }
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -209,18 +210,28 @@ ssize_t
|
|||||||
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
|
||||||
FlattenedSize() const
|
FlattenedSize() const
|
||||||
{
|
{
|
||||||
ssize_t size = 0;
|
|
||||||
|
|
||||||
// Mandatory stuff
|
// Mandatory stuff
|
||||||
size += 1; // field flags byte
|
ssize_t size = 1; // field flags byte
|
||||||
size += sizeof (type_code); // field type bytes
|
size += sizeof (type_code); // field type bytes
|
||||||
if (!(fFlags & MSG_FLAG_SINGLE_ITEM)) // item count byte
|
if (!(fFlags & MSG_FLAG_SINGLE_ITEM)) // item count byte
|
||||||
++size;
|
++size;
|
||||||
++size; // data length byte
|
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||||
|
++size; // data length byte for mini data
|
||||||
|
else
|
||||||
|
size += sizeof (size_t); // data length bytes for maxi data
|
||||||
++size; // name length byte
|
++size; // name length byte
|
||||||
size += Name().length(); // name length
|
size += Name().length(); // name length
|
||||||
|
|
||||||
size += SizePolicy::Size(fData); // data length and item size bytes
|
// data length and item size bytes
|
||||||
|
size += SizePolicy::Size(fData);
|
||||||
|
if (!SizePolicy::Fixed())
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < fData.Size(); ++i)
|
||||||
|
{
|
||||||
|
size += SizePolicy::Padding(fData[i]); // pad to 8-byte boundary
|
||||||
|
size += 4; // item size bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -241,10 +252,20 @@ Flatten(BDataIO& stream) const
|
|||||||
status_t err = B_OK;
|
status_t err = B_OK;
|
||||||
type_code type = Type();
|
type_code type = Type();
|
||||||
uint8 count = fData.Size();
|
uint8 count = fData.Size();
|
||||||
uint8 size = SizePolicy::Size(fData);
|
|
||||||
uint8 nameLen = Name().length();
|
uint8 nameLen = Name().length();
|
||||||
|
size_t size = SizePolicy::Size(fData);
|
||||||
|
|
||||||
err = stream.Write(&fFlags, 1);
|
// Calculate any necessary padding
|
||||||
|
if (!SizePolicy::Fixed())
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < fData.Size(); ++i)
|
||||||
|
{
|
||||||
|
size += SizePolicy::Padding(fData[i]); // pad to 8-byte boundary
|
||||||
|
size += 4; // item size bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = stream.Write(&fFlags, sizeof (fFlags));
|
||||||
|
|
||||||
// Field type_code
|
// Field type_code
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
@@ -252,15 +273,25 @@ Flatten(BDataIO& stream) const
|
|||||||
|
|
||||||
// Item count, if more than one
|
// Item count, if more than one
|
||||||
if (err >= 0 && !(fFlags & MSG_FLAG_SINGLE_ITEM))
|
if (err >= 0 && !(fFlags & MSG_FLAG_SINGLE_ITEM))
|
||||||
err = stream.Write(&count, 1);
|
err = stream.Write(&count, sizeof (count));
|
||||||
|
|
||||||
// Data length
|
// Data length
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
err = stream.Write(&size, 1);
|
{
|
||||||
|
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||||
|
{
|
||||||
|
uint8 miniSize = size;
|
||||||
|
err = stream.Write(&miniSize, sizeof (miniSize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = stream.Write(&size, sizeof (size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Name length
|
// Name length
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
err = stream.Write(&nameLen, 1);
|
err = stream.Write(&nameLen, sizeof (nameLen));
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
@@ -269,7 +300,20 @@ Flatten(BDataIO& stream) const
|
|||||||
// Actual data items
|
// Actual data items
|
||||||
for (uint32 i = 0; i < fData.Size() && err >= 0; ++i)
|
for (uint32 i = 0; i < fData.Size() && err >= 0; ++i)
|
||||||
{
|
{
|
||||||
err = FlattenPolicy::Flatten(stream, fData[i]);
|
if (!SizePolicy::Fixed())
|
||||||
|
{
|
||||||
|
int32 size = (int32)SizePolicy::Size(fData[i]);
|
||||||
|
err = stream.Write(&size, sizeof (size));
|
||||||
|
}
|
||||||
|
if (err >= 0)
|
||||||
|
{
|
||||||
|
err = FlattenPolicy::Flatten(stream, fData[i]);
|
||||||
|
}
|
||||||
|
if (err >= 0)
|
||||||
|
{
|
||||||
|
err = stream.Write(&BMessageField::sNullData[size],
|
||||||
|
SizePolicy::Padding(fData[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
@@ -465,18 +509,23 @@ template<> struct BMessageFieldSizePolicy<BString>
|
|||||||
inline static size_t Size(const Store& data)
|
inline static size_t Size(const Store& data)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t temp;
|
|
||||||
for (uint32 i = 0; i < data.Size(); ++i)
|
for (uint32 i = 0; i < data.Size(); ++i)
|
||||||
{
|
{
|
||||||
temp = Size(data[i]) + 4; // Four extra bytes for size info
|
size += Size(data[i]);
|
||||||
// Calculate padding
|
|
||||||
temp += 8 - (temp % 8);
|
|
||||||
size += temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
inline static bool Fixed() { return false; }
|
inline static bool Fixed() { return false; }
|
||||||
|
inline static size_t Padding(const BString& s)
|
||||||
|
{
|
||||||
|
size_t temp = (Size(s) + 4) % 8;
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
temp = 8 - temp;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
template<> struct BMessageFieldSizePolicy<BDataBuffer>
|
template<> struct BMessageFieldSizePolicy<BDataBuffer>
|
||||||
@@ -488,18 +537,23 @@ template<> struct BMessageFieldSizePolicy<BDataBuffer>
|
|||||||
inline static size_t Size(const Store& data)
|
inline static size_t Size(const Store& data)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t temp;
|
|
||||||
for (uint32 i = 0; i < data.Size(); ++i)
|
for (uint32 i = 0; i < data.Size(); ++i)
|
||||||
{
|
{
|
||||||
temp = Size(data[i]) + 4; // Four extra bytes for size info
|
size += Size(data[i]);
|
||||||
// Calculate padding
|
|
||||||
temp += 8 - (temp % 8);
|
|
||||||
size += temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
inline static bool Fixed() { return false; }
|
inline static bool Fixed() { return false; }
|
||||||
|
inline static size_t Padding(const BDataBuffer& db)
|
||||||
|
{
|
||||||
|
size_t temp = (Size(db) + 4) % 8;
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
temp = 8 - temp;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
template<> struct BMessageFieldSizePolicy<BMessage*>
|
template<> struct BMessageFieldSizePolicy<BMessage*>
|
||||||
@@ -511,18 +565,23 @@ template<> struct BMessageFieldSizePolicy<BMessage*>
|
|||||||
inline static size_t Size(const Store& data)
|
inline static size_t Size(const Store& data)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t temp;
|
|
||||||
for (uint32 i = 0; i < data.Size(); ++i)
|
for (uint32 i = 0; i < data.Size(); ++i)
|
||||||
{
|
{
|
||||||
temp = Size(data[i]) + 4; // Four extra bytes for size info
|
size += Size(data[i]);
|
||||||
// Calculate padding
|
|
||||||
temp += 8 - (temp % 8);
|
|
||||||
size += temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
inline static bool Fixed() { return false; }
|
inline static bool Fixed() { return false; }
|
||||||
|
inline static size_t Padding(const BMessage* msg)
|
||||||
|
{
|
||||||
|
size_t temp = (Size(msg) + 4) % 8;
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
temp = 8 - temp;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Flatten policy specializations ----------------------------------------------
|
// Flatten policy specializations ----------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
@@ -533,23 +592,9 @@ struct BMessageFieldFlattenPolicy<BString>
|
|||||||
static status_t Flatten(BDataIO& stream, const BString& data)
|
static status_t Flatten(BDataIO& stream, const BString& data)
|
||||||
{
|
{
|
||||||
size_t size = SizePolicy::Size(data);
|
size_t size = SizePolicy::Size(data);
|
||||||
status_t err = stream.Write(&size, 4);
|
status_t err = stream.Write((const void*)data.String(), size);
|
||||||
|
|
||||||
if (err >= 0)
|
if (err > 0)
|
||||||
err = stream.Write((const void*)data.String(), size);
|
|
||||||
|
|
||||||
if (err >= 0)
|
|
||||||
{
|
|
||||||
// Pad data to 8-byte boundary
|
|
||||||
size += 4; // Account for the stored size of size
|
|
||||||
size %= 8;
|
|
||||||
if (size)
|
|
||||||
{
|
|
||||||
err = stream.Write(&BMessageField::sNullData[size], 8 - (size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err >= 0)
|
|
||||||
err = B_OK;
|
err = B_OK;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -562,24 +607,24 @@ struct BMessageFieldFlattenPolicy<BMessage*>
|
|||||||
|
|
||||||
static status_t Flatten(BDataIO& stream, const BMessage* data)
|
static status_t Flatten(BDataIO& stream, const BMessage* data)
|
||||||
{
|
{
|
||||||
size_t size = SizePolicy::Size(data);
|
status_t err = data->Flatten(&stream);
|
||||||
status_t err = stream.Write(&size, 4);
|
|
||||||
|
|
||||||
if (err >= 0)
|
if (err > 0)
|
||||||
err = data->Flatten(&stream);
|
err = B_OK;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<>
|
||||||
|
struct BMessageFieldFlattenPolicy<BDataBuffer>
|
||||||
|
{
|
||||||
|
typedef BMessageFieldSizePolicy<BDataBuffer> SizePolicy;
|
||||||
|
|
||||||
if (err >= 0)
|
static status_t Flatten(BDataIO& stream, const BDataBuffer& db)
|
||||||
{
|
{
|
||||||
// Pad data to 8-byte boundary
|
size_t size = SizePolicy::Size(db);
|
||||||
size += 4; // Account for the stored size of size
|
status_t err = stream.Write(db.Buffer(), size);
|
||||||
size %= 8;
|
if (err > 0)
|
||||||
if (size)
|
|
||||||
{
|
|
||||||
err = stream.Write(&BMessageField::sNullData[size], 8 - (size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err >= 0)
|
|
||||||
err = B_OK;
|
err = B_OK;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ bool BMessageBody::IsEmpty() const
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void BMessageBody::PrintToStream() const
|
void BMessageBody::PrintToStream() const
|
||||||
{
|
{
|
||||||
// TODO: implement
|
// TODO: test
|
||||||
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
||||||
{
|
{
|
||||||
i->second->PrintToStream(i->first.c_str());
|
i->second->PrintToStream(i->first.c_str());
|
||||||
|
|||||||
Reference in New Issue
Block a user