A number of bug fixes. In particular:
- only one byte was being used for total data length in a data field which had 'maxi' size data (total data > 255 bytes), rather than the correct four bytes. - Seem to have finally nailed the proper algorithm for calculating data item padding (four size bytes + bytes of data, padded to 8-byte boundary) in all places. - Was passing the address of the padding string, rather than the string itself, when writing out NULL padding bytes - Was incorrectly clearing the MSG_FLAG_MINI_DATA bit when the number of data items or the size of the largest data item exceeding 256 bytes. Bit is now cleared when total size of all item data (including size bytes and padding, if applicable) exceeds 256 bytes - Modified SizePolicy::Padding(const T&) to use calc_padding() from MessageUtils.h/.cpp - Added SizePolicy::Padding(const Store&) to calculate padding for data field's entire data store git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9743 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
380156b567
commit
f936fa1261
@ -44,6 +44,7 @@
|
||||
|
||||
// Project Includes ------------------------------------------------------------
|
||||
#include <DataBuffer.h>
|
||||
#include <MessageUtils.h>
|
||||
|
||||
// Local Includes --------------------------------------------------------------
|
||||
|
||||
@ -127,6 +128,7 @@ struct BMessageFieldSizePolicy
|
||||
}
|
||||
inline static bool Fixed() { return true; }
|
||||
inline static size_t Padding(const T&) { return 0; }
|
||||
inline static size_t Padding(const Store& data) { return 0; }
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
template<class T>
|
||||
@ -220,23 +222,38 @@ FlattenedSize() const
|
||||
ssize_t size = 1; // field flags byte
|
||||
size += sizeof (type_code); // field type bytes
|
||||
if (!(fFlags & MSG_FLAG_SINGLE_ITEM)) // item count byte
|
||||
++size;
|
||||
{
|
||||
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||
++size; // item count byte for mini data
|
||||
else
|
||||
size += 4; // item count bytes for maxi data
|
||||
}
|
||||
|
||||
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 += 4; // data length bytes for maxi data
|
||||
|
||||
++size; // name length byte
|
||||
size += Name().length(); // name length
|
||||
|
||||
// data length and item size bytes
|
||||
// item data length
|
||||
size += SizePolicy::Size(fData);
|
||||
|
||||
// Calculate any necessary padding
|
||||
if (!SizePolicy::Fixed())
|
||||
{
|
||||
size += 4 * fData.Size();
|
||||
size += SizePolicy::Padding(fData);
|
||||
#if 0
|
||||
for (uint32 i = 0; i < fData.Size(); ++i)
|
||||
{
|
||||
size += SizePolicy::Padding(fData[i]); // pad to 8-byte boundary
|
||||
size += 4; // item size bytes
|
||||
// pad to 8-byte boundary, including size bytes in calculation
|
||||
size += calc_padding(SizePolicy::Size(fData[i]) + 4, 8);
|
||||
// item size bytes
|
||||
size += 4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return size;
|
||||
@ -257,20 +274,10 @@ Flatten(BDataIO& stream) const
|
||||
{
|
||||
status_t err = B_OK;
|
||||
type_code type = Type();
|
||||
uint8 count = fData.Size();
|
||||
uint32 count = fData.Size();
|
||||
uint8 nameLen = Name().length();
|
||||
size_t size = SizePolicy::Size(fData);
|
||||
|
||||
// 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
|
||||
@ -279,11 +286,27 @@ Flatten(BDataIO& stream) const
|
||||
|
||||
// Item count, if more than one
|
||||
if (err >= 0 && !(fFlags & MSG_FLAG_SINGLE_ITEM))
|
||||
err = stream.Write(&count, sizeof (count));
|
||||
{
|
||||
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||
{
|
||||
uint8 miniCount = count;
|
||||
err = stream.Write(&miniCount, sizeof (miniCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
err = stream.Write(&count, sizeof (count));
|
||||
}
|
||||
}
|
||||
|
||||
// Data length
|
||||
if (err >= 0)
|
||||
{
|
||||
if (!(fFlags & MSG_FLAG_FIXED_SIZE))
|
||||
{
|
||||
// Add the bytes for holding the item size for each item
|
||||
size += 4 * fData.Size();
|
||||
size += SizePolicy::Padding(fData);
|
||||
}
|
||||
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||
{
|
||||
uint8 miniSize = size;
|
||||
@ -308,16 +331,17 @@ Flatten(BDataIO& stream) const
|
||||
{
|
||||
if (!SizePolicy::Fixed())
|
||||
{
|
||||
int32 size = (int32)SizePolicy::Size(fData[i]);
|
||||
size = (int32)SizePolicy::Size(fData[i]);
|
||||
err = stream.Write(&size, sizeof (size));
|
||||
}
|
||||
if (err >= 0)
|
||||
{
|
||||
err = FlattenPolicy::Flatten(stream, fData[i]);
|
||||
}
|
||||
if (err >= 0)
|
||||
if (err >= 0 && !SizePolicy::Fixed())
|
||||
{
|
||||
err = stream.Write(&BMessageField::sNullData[size],
|
||||
// Add any necessary padding
|
||||
err = stream.Write(BMessageField::sNullData,
|
||||
SizePolicy::Padding(fData[i]));
|
||||
}
|
||||
}
|
||||
@ -361,8 +385,17 @@ AddItem(const T1& data)
|
||||
fMaxSize = SizePolicy::Size(data);
|
||||
}
|
||||
|
||||
if (fData.Size() > 256 || fMaxSize > 256)
|
||||
fFlags &= ~MSG_FLAG_MINI_DATA;
|
||||
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||
{
|
||||
int32 size = SizePolicy::Size(fData);
|
||||
if (!(fFlags & MSG_FLAG_FIXED_SIZE))
|
||||
{
|
||||
size += 4 * fData.Size();
|
||||
size += SizePolicy::Padding(fData);
|
||||
}
|
||||
if (size > 255)
|
||||
fFlags &= ~MSG_FLAG_MINI_DATA;
|
||||
}
|
||||
|
||||
if (fData.Size() > 1)
|
||||
fFlags &= ~MSG_FLAG_SINGLE_ITEM;
|
||||
@ -587,18 +620,25 @@ template<> struct BMessageFieldSizePolicy<BString>
|
||||
{
|
||||
size += Size(data[i]);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
inline static bool Fixed() { return false; }
|
||||
inline static size_t Padding(const BString& s)
|
||||
{
|
||||
size_t temp = (Size(s) + 4) % 8;
|
||||
if (temp)
|
||||
// Padding calculations are only done for variable-sized items,
|
||||
// which by definition have four bytes of size info preceeding the
|
||||
// actual data; those four bytes are included in the padding
|
||||
// calculation. Padding is calculated to an 8-byte boundary
|
||||
return calc_padding(Size(s) + 4, 8);
|
||||
}
|
||||
inline static size_t Padding(const Store& data)
|
||||
{
|
||||
size_t size = 0;
|
||||
for (uint32 i = 0; i < data.Size(); ++i)
|
||||
{
|
||||
temp = 8 - temp;
|
||||
size += Padding(data[i]);
|
||||
}
|
||||
return temp;
|
||||
return size;
|
||||
}
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
@ -621,12 +661,20 @@ template<> struct BMessageFieldSizePolicy<BDataBuffer>
|
||||
inline static bool Fixed() { return false; }
|
||||
inline static size_t Padding(const BDataBuffer& db)
|
||||
{
|
||||
size_t temp = (Size(db) + 4) % 8;
|
||||
if (temp)
|
||||
// Padding calculations are only done for variable-sized items,
|
||||
// which by definition have four bytes of size info preceeding the
|
||||
// actual data; those four bytes are included in the padding
|
||||
// calculation. Padding is calculated to an 8-byte boundary
|
||||
return calc_padding(Size(db) + 4, 8);
|
||||
}
|
||||
inline static size_t Padding(const Store& data)
|
||||
{
|
||||
size_t size = 0;
|
||||
for (uint32 i = 0; i < data.Size(); ++i)
|
||||
{
|
||||
temp = 8 - temp;
|
||||
size += Padding(data[i]);
|
||||
}
|
||||
return temp;
|
||||
return size;
|
||||
}
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
@ -649,12 +697,20 @@ template<> struct BMessageFieldSizePolicy<BMessage*>
|
||||
inline static bool Fixed() { return false; }
|
||||
inline static size_t Padding(const BMessage* msg)
|
||||
{
|
||||
size_t temp = (Size(msg) + 4) % 8;
|
||||
if (temp)
|
||||
// Padding calculations are only done for variable-sized items,
|
||||
// which by definition have four bytes of size info preceeding the
|
||||
// actual data; those four bytes are included in the padding
|
||||
// calculation. Padding is calculated to an 8-byte boundary
|
||||
return calc_padding(Size(msg) + 4, 8);
|
||||
}
|
||||
inline static size_t Padding(const Store& data)
|
||||
{
|
||||
size_t size = 0;
|
||||
for (uint32 i = 0; i < data.Size(); ++i)
|
||||
{
|
||||
temp = 8 - temp;
|
||||
size += Padding(data[i]);
|
||||
}
|
||||
return temp;
|
||||
return size;
|
||||
}
|
||||
};
|
||||
// Flatten policy specializations ----------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user