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 ------------------------------------------------------------
|
// Project Includes ------------------------------------------------------------
|
||||||
#include <DataBuffer.h>
|
#include <DataBuffer.h>
|
||||||
|
#include <MessageUtils.h>
|
||||||
|
|
||||||
// Local Includes --------------------------------------------------------------
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
@ -127,6 +128,7 @@ struct BMessageFieldSizePolicy
|
|||||||
}
|
}
|
||||||
inline static bool Fixed() { return true; }
|
inline static bool Fixed() { return true; }
|
||||||
inline static size_t Padding(const T&) { return 0; }
|
inline static size_t Padding(const T&) { return 0; }
|
||||||
|
inline static size_t Padding(const Store& data) { return 0; }
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -220,23 +222,38 @@ FlattenedSize() const
|
|||||||
ssize_t 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;
|
{
|
||||||
|
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)
|
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||||
++size; // data length byte for mini data
|
++size; // data length byte for mini data
|
||||||
else
|
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 byte
|
||||||
size += Name().length(); // name length
|
size += Name().length(); // name length
|
||||||
|
|
||||||
// data length and item size bytes
|
// item data length
|
||||||
size += SizePolicy::Size(fData);
|
size += SizePolicy::Size(fData);
|
||||||
|
|
||||||
|
// Calculate any necessary padding
|
||||||
if (!SizePolicy::Fixed())
|
if (!SizePolicy::Fixed())
|
||||||
{
|
{
|
||||||
|
size += 4 * fData.Size();
|
||||||
|
size += SizePolicy::Padding(fData);
|
||||||
|
#if 0
|
||||||
for (uint32 i = 0; i < fData.Size(); ++i)
|
for (uint32 i = 0; i < fData.Size(); ++i)
|
||||||
{
|
{
|
||||||
size += SizePolicy::Padding(fData[i]); // pad to 8-byte boundary
|
// pad to 8-byte boundary, including size bytes in calculation
|
||||||
size += 4; // item size bytes
|
size += calc_padding(SizePolicy::Size(fData[i]) + 4, 8);
|
||||||
|
// item size bytes
|
||||||
|
size += 4;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -257,20 +274,10 @@ 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();
|
uint32 count = fData.Size();
|
||||||
uint8 nameLen = Name().length();
|
uint8 nameLen = Name().length();
|
||||||
size_t size = SizePolicy::Size(fData);
|
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));
|
err = stream.Write(&fFlags, sizeof (fFlags));
|
||||||
|
|
||||||
// Field type_code
|
// Field type_code
|
||||||
@ -279,11 +286,27 @@ 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, 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
|
// Data length
|
||||||
if (err >= 0)
|
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)
|
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||||
{
|
{
|
||||||
uint8 miniSize = size;
|
uint8 miniSize = size;
|
||||||
@ -308,16 +331,17 @@ Flatten(BDataIO& stream) const
|
|||||||
{
|
{
|
||||||
if (!SizePolicy::Fixed())
|
if (!SizePolicy::Fixed())
|
||||||
{
|
{
|
||||||
int32 size = (int32)SizePolicy::Size(fData[i]);
|
size = (int32)SizePolicy::Size(fData[i]);
|
||||||
err = stream.Write(&size, sizeof (size));
|
err = stream.Write(&size, sizeof (size));
|
||||||
}
|
}
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
{
|
{
|
||||||
err = FlattenPolicy::Flatten(stream, fData[i]);
|
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]));
|
SizePolicy::Padding(fData[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,8 +385,17 @@ AddItem(const T1& data)
|
|||||||
fMaxSize = SizePolicy::Size(data);
|
fMaxSize = SizePolicy::Size(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fData.Size() > 256 || fMaxSize > 256)
|
if (fFlags & MSG_FLAG_MINI_DATA)
|
||||||
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)
|
if (fData.Size() > 1)
|
||||||
fFlags &= ~MSG_FLAG_SINGLE_ITEM;
|
fFlags &= ~MSG_FLAG_SINGLE_ITEM;
|
||||||
@ -587,18 +620,25 @@ template<> struct BMessageFieldSizePolicy<BString>
|
|||||||
{
|
{
|
||||||
size += Size(data[i]);
|
size += Size(data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
inline static bool Fixed() { return false; }
|
inline static bool Fixed() { return false; }
|
||||||
inline static size_t Padding(const BString& s)
|
inline static size_t Padding(const BString& s)
|
||||||
{
|
{
|
||||||
size_t temp = (Size(s) + 4) % 8;
|
// Padding calculations are only done for variable-sized items,
|
||||||
if (temp)
|
// 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 bool Fixed() { return false; }
|
||||||
inline static size_t Padding(const BDataBuffer& db)
|
inline static size_t Padding(const BDataBuffer& db)
|
||||||
{
|
{
|
||||||
size_t temp = (Size(db) + 4) % 8;
|
// Padding calculations are only done for variable-sized items,
|
||||||
if (temp)
|
// 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 bool Fixed() { return false; }
|
||||||
inline static size_t Padding(const BMessage* msg)
|
inline static size_t Padding(const BMessage* msg)
|
||||||
{
|
{
|
||||||
size_t temp = (Size(msg) + 4) % 8;
|
// Padding calculations are only done for variable-sized items,
|
||||||
if (temp)
|
// 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 ----------------------------------------------
|
// Flatten policy specializations ----------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user