Ok, hopefully fixed all problems with Message3 now. Flat buffers are so fragile...
Also cleaned up Message3.h revert it if you think its a binary compatibility issue. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13920 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+63
-149
@@ -68,7 +68,7 @@ enum
|
|||||||
B_ID_SPECIFIER,
|
B_ID_SPECIFIER,
|
||||||
|
|
||||||
B_SPECIFIERS_END = 128
|
B_SPECIFIERS_END = 128
|
||||||
// app-defined specifiers start at B_SPECIFIERS_END+1
|
// app-defined specifiers start at B_SPECIFIERS_END + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -279,174 +279,88 @@ virtual ~BMessage();
|
|||||||
float FindFloat(const char *, int32 n = 0) const;
|
float FindFloat(const char *, int32 n = 0) const;
|
||||||
double FindDouble(const char *, int32 n = 0) const;
|
double FindDouble(const char *, int32 n = 0) const;
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Header;
|
class Header;
|
||||||
|
|
||||||
friend class BMessageQueue;
|
friend class BMessageQueue;
|
||||||
friend class BMessenger;
|
friend class BMessenger;
|
||||||
friend class BApplication;
|
friend class BApplication;
|
||||||
friend class Header;
|
friend class Header;
|
||||||
friend class Private;
|
friend class Private;
|
||||||
|
|
||||||
friend inline void _set_message_target_(BMessage *, int32, bool);
|
friend inline void _set_message_target_(BMessage *, int32, bool);
|
||||||
friend inline void _set_message_reply_(BMessage *, BMessenger);
|
friend inline void _set_message_reply_(BMessage *, BMessenger);
|
||||||
friend inline int32 _get_message_target_(BMessage *);
|
friend inline int32 _get_message_target_(BMessage *);
|
||||||
friend inline bool _use_preferred_target_(BMessage *);
|
friend inline bool _use_preferred_target_(BMessage *);
|
||||||
|
|
||||||
// deprecated
|
// deprecated
|
||||||
BMessage(BMessage *a_message);
|
BMessage(BMessage *a_message);
|
||||||
|
|
||||||
virtual void _ReservedMessage1();
|
virtual void _ReservedMessage1();
|
||||||
virtual void _ReservedMessage2();
|
virtual void _ReservedMessage2();
|
||||||
virtual void _ReservedMessage3();
|
virtual void _ReservedMessage3();
|
||||||
|
|
||||||
void init_data();
|
void init_data();
|
||||||
status_t flatten_target_info(BDataIO *stream,
|
status_t real_flatten(char *result, ssize_t size) const;
|
||||||
ssize_t size,
|
status_t real_flatten(BDataIO *stream, ssize_t *size) const;
|
||||||
uchar flags) const;
|
char *stack_flatten(char *stack_ptr,
|
||||||
status_t real_flatten(char *result, ssize_t size) const;
|
ssize_t stack_size, bool incl_reply,
|
||||||
status_t real_flatten(BDataIO *stream, ssize_t *size) const;
|
|
||||||
char *stack_flatten(char *stack_ptr,
|
|
||||||
ssize_t stack_size,
|
|
||||||
bool incl_reply,
|
|
||||||
ssize_t *size = NULL) const;
|
ssize_t *size = NULL) const;
|
||||||
|
|
||||||
status_t _UnflattenKMessage(const char *buffer);
|
status_t _UnflattenKMessage(const char *buffer);
|
||||||
|
|
||||||
ssize_t calc_size(uchar flags) const;
|
ssize_t calc_hdr_size() const;
|
||||||
ssize_t calc_hdr_size(uchar flags) const;
|
|
||||||
status_t nfind_data( const char *name,
|
|
||||||
type_code type,
|
|
||||||
int32 index,
|
|
||||||
const void **data,
|
|
||||||
ssize_t *data_size) const;
|
|
||||||
status_t copy_data( const char *name,
|
|
||||||
type_code type,
|
|
||||||
int32 index,
|
|
||||||
void *data,
|
|
||||||
ssize_t data_size) const;
|
|
||||||
|
|
||||||
status_t _send_(port_id port,
|
status_t _send_(port_id port, int32 token,
|
||||||
int32 token,
|
bool preferred, bigtime_t timeout,
|
||||||
bool preferred,
|
bool reply_required,
|
||||||
bigtime_t timeout,
|
BMessenger &reply_to) const;
|
||||||
bool reply_required,
|
status_t send_message(port_id port, team_id port_owner,
|
||||||
BMessenger &reply_to) const;
|
int32 token, bool preferred,
|
||||||
status_t send_message(port_id port,
|
BMessage *reply,
|
||||||
team_id port_owner,
|
bigtime_t send_timeout,
|
||||||
int32 token,
|
bigtime_t reply_timeout) const;
|
||||||
bool preferred,
|
|
||||||
BMessage *reply,
|
|
||||||
bigtime_t send_timeout,
|
|
||||||
bigtime_t reply_timeout) const;
|
|
||||||
static status_t _SendFlattenedMessage(void *data, int32 size,
|
|
||||||
port_id port, int32 token, bool preferred,
|
|
||||||
bigtime_t timeout);
|
|
||||||
|
|
||||||
static void _StaticInit();
|
static status_t _SendFlattenedMessage(void *data, int32 size,
|
||||||
static void _StaticCleanup();
|
port_id port, int32 token, bool preferred,
|
||||||
static void _StaticCacheCleanup();
|
bigtime_t timeout);
|
||||||
|
|
||||||
enum { sNumReplyPorts = 3 };
|
static void _StaticInit();
|
||||||
static port_id sReplyPorts[sNumReplyPorts];
|
static void _StaticCleanup();
|
||||||
static long sReplyPortInUse[sNumReplyPorts];
|
static void _StaticCacheCleanup();
|
||||||
static int32 sGetCachedReplyPort();
|
|
||||||
|
|
||||||
static BBlockCache *sMsgCache;
|
enum { sNumReplyPorts = 3 };
|
||||||
|
static port_id sReplyPorts[sNumReplyPorts];
|
||||||
|
static long sReplyPortInUse[sNumReplyPorts];
|
||||||
|
static int32 sGetCachedReplyPort();
|
||||||
|
|
||||||
struct dyn_array {
|
static BBlockCache *sMsgCache;
|
||||||
int32 fLogicalBytes;
|
|
||||||
int32 fPhysicalBytes;
|
|
||||||
int32 fChunkSize;
|
|
||||||
int32 fCount;
|
|
||||||
int32 fEntryHdrSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct entry_hdr : public dyn_array {
|
BMessage *fUnused1;
|
||||||
entry_hdr *fNext;
|
int32 fTarget;
|
||||||
uint32 fType;
|
BMessage *fOriginal;
|
||||||
uchar fNameLength;
|
uint32 fUnused2;
|
||||||
char fName[1];
|
int32 fCurSpecifier;
|
||||||
};
|
uint32 fReserved[4];
|
||||||
|
|
||||||
struct var_chunk {
|
BPrivate::BMessageBody *fBody;
|
||||||
int32 fDataSize;
|
|
||||||
char fData[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
entry_hdr *entry_find(const char *name, uint32 type,status_t *result=NULL) const;
|
|
||||||
void entry_remove(entry_hdr *entry);
|
|
||||||
|
|
||||||
void *da_create(int32 header_size, int32 chunk_size,
|
|
||||||
bool fixed, int32 nchunks);
|
|
||||||
status_t da_add_data(dyn_array **da, const void *data, int32 size);
|
|
||||||
void *da_find_data(dyn_array *da, int32 index,
|
|
||||||
int32 *size = NULL) const;
|
|
||||||
status_t da_delete_data(dyn_array **pda, int32 index);
|
|
||||||
status_t da_replace_data(dyn_array **pda, int32 index,
|
|
||||||
const void *data, int32 dsize);
|
|
||||||
int32 da_calc_size(int32 hdr_size, int32 chunksize,
|
|
||||||
bool is_fixed, int32 nchunks) const;
|
|
||||||
void *da_grow(dyn_array **pda, int32 increase);
|
|
||||||
void da_dump(dyn_array *da);
|
|
||||||
|
|
||||||
int32 da_chunk_hdr_size() const
|
|
||||||
{ return sizeof(int32); }
|
|
||||||
int32 da_chunk_size(var_chunk *v) const
|
|
||||||
{ return (v->fDataSize + da_chunk_hdr_size() + 7) & ~7; }
|
|
||||||
var_chunk *da_first_chunk(dyn_array *da) const
|
|
||||||
{ return (var_chunk *) da_start_of_data(da); }
|
|
||||||
var_chunk *da_next_chunk(var_chunk *v) const
|
|
||||||
{ return (var_chunk *) (((char*) v) + da_chunk_size(v)); }
|
|
||||||
var_chunk *da_chunk_ptr(void *data) const
|
|
||||||
{ return (var_chunk*) (((char *) data) - da_chunk_hdr_size()); }
|
|
||||||
|
|
||||||
int32 da_pad_8(int32 val) const
|
|
||||||
{ return (val + 7) & ~7; }
|
|
||||||
int32 da_total_size(dyn_array *da) const
|
|
||||||
{ return (int32)sizeof(dyn_array) + da->fEntryHdrSize +
|
|
||||||
da->fPhysicalBytes; }
|
|
||||||
int32 da_total_logical_size(dyn_array *da) const
|
|
||||||
{ return (int32)sizeof(dyn_array) + da->fEntryHdrSize +
|
|
||||||
da->fLogicalBytes; }
|
|
||||||
char *da_start_of_data(dyn_array *da) const
|
|
||||||
{ return ((char *) da) + (sizeof(dyn_array) +
|
|
||||||
da->fEntryHdrSize); }
|
|
||||||
bool da_is_mini_data(dyn_array *da) const
|
|
||||||
{ return ((da->fLogicalBytes <= (int32) UCHAR_MAX) &&
|
|
||||||
(da->fCount <= (int32) UCHAR_MAX));}
|
|
||||||
void da_swap_var_sized(dyn_array *da);
|
|
||||||
void da_swap_fixed_sized(dyn_array *da);
|
|
||||||
|
|
||||||
BMessage *link;
|
|
||||||
int32 fTarget;
|
|
||||||
BMessage *fOriginal;
|
|
||||||
uint32 fChangeCount;
|
|
||||||
int32 fCurSpecifier;
|
|
||||||
uint32 fPtrOffset;
|
|
||||||
|
|
||||||
// ejaesler: Stealing one for my whacky BMessageBody l33tness
|
|
||||||
uint32 _reserved[2];
|
|
||||||
BPrivate::BMessageBody* fBody;
|
|
||||||
|
|
||||||
BMessage::entry_hdr *fEntries;
|
|
||||||
|
|
||||||
struct reply_to_info {
|
struct reply_to_info {
|
||||||
port_id port;
|
port_id port;
|
||||||
int32 target;
|
int32 target;
|
||||||
team_id team;
|
team_id team;
|
||||||
bool preferred;
|
bool preferred;
|
||||||
} fReplyTo;
|
} fReplyTo;
|
||||||
|
|
||||||
bool fPreferred;
|
bool fPreferred;
|
||||||
bool fReplyRequired;
|
bool fReplyRequired;
|
||||||
bool fReplyDone;
|
bool fReplyDone;
|
||||||
bool fIsReply;
|
bool fIsReply;
|
||||||
bool fWasDelivered;
|
bool fWasDelivered;
|
||||||
bool fReadOnly;
|
bool fReadOnly;
|
||||||
bool fHasSpecifiers;
|
bool fHasSpecifiers;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -69,9 +69,10 @@ public:
|
|||||||
void PrintToStream() const;
|
void PrintToStream() const;
|
||||||
|
|
||||||
// flat buffer management
|
// flat buffer management
|
||||||
inline uint8 *FlatBuffer() const { return (uint8 *)fFlatBuffer.Buffer(); };
|
inline uint8 *FlatBuffer() const { return fFlatBuffer; };
|
||||||
uint8 *FlatInsert(int32 offset, ssize_t oldLength,
|
uint8 *FlatInsert(int32 offset, ssize_t oldLength,
|
||||||
ssize_t newLength);
|
ssize_t newLength);
|
||||||
|
void FlatResize(int32 newSize);
|
||||||
|
|
||||||
// hash table support
|
// hash table support
|
||||||
void HashInsert(BMessageField *field);
|
void HashInsert(BMessageField *field);
|
||||||
@@ -91,7 +92,10 @@ private:
|
|||||||
BMessageField **fFieldTable;
|
BMessageField **fFieldTable;
|
||||||
int32 fFieldTableSize;
|
int32 fFieldTableSize;
|
||||||
|
|
||||||
BMallocIO fFlatBuffer;
|
uint8 *fFlatBuffer;
|
||||||
|
int32 fFlatLength;
|
||||||
|
int32 fFlatAllocated;
|
||||||
|
int32 fBlockSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace BPrivate
|
} // namespace BPrivate
|
||||||
|
|||||||
@@ -465,14 +465,9 @@ BMessage::operator=(const BMessage &msg)
|
|||||||
{
|
{
|
||||||
what = msg.what;
|
what = msg.what;
|
||||||
|
|
||||||
link = msg.link;
|
|
||||||
fTarget = msg.fTarget;
|
fTarget = msg.fTarget;
|
||||||
fOriginal = msg.fOriginal;
|
fOriginal = msg.fOriginal;
|
||||||
fChangeCount = msg.fChangeCount;
|
|
||||||
fCurSpecifier = msg.fCurSpecifier;
|
fCurSpecifier = msg.fCurSpecifier;
|
||||||
fPtrOffset = msg.fPtrOffset;
|
|
||||||
|
|
||||||
fEntries = msg.fEntries;
|
|
||||||
|
|
||||||
fReplyTo.port = msg.fReplyTo.port;
|
fReplyTo.port = msg.fReplyTo.port;
|
||||||
fReplyTo.target = msg.fReplyTo.target;
|
fReplyTo.target = msg.fReplyTo.target;
|
||||||
@@ -497,14 +492,9 @@ BMessage::init_data()
|
|||||||
{
|
{
|
||||||
what = 0;
|
what = 0;
|
||||||
|
|
||||||
link = NULL;
|
|
||||||
fTarget = B_NULL_TOKEN;
|
fTarget = B_NULL_TOKEN;
|
||||||
fOriginal = NULL;
|
fOriginal = NULL;
|
||||||
fChangeCount = 0;
|
|
||||||
fCurSpecifier = -1;
|
fCurSpecifier = -1;
|
||||||
fPtrOffset = 0;
|
|
||||||
|
|
||||||
fEntries = NULL;
|
|
||||||
|
|
||||||
fReplyTo.port = -1;
|
fReplyTo.port = -1;
|
||||||
fReplyTo.target = B_NULL_TOKEN;
|
fReplyTo.target = B_NULL_TOKEN;
|
||||||
@@ -593,7 +583,7 @@ BMessage::IsReply() const
|
|||||||
void
|
void
|
||||||
BMessage::PrintToStream() const
|
BMessage::PrintToStream() const
|
||||||
{
|
{
|
||||||
printf("\nBMessage: what = ");
|
printf("BMessage: what = ");
|
||||||
printf("%c%c%c%c", (uint8)(what >> 24), (uint8)(what >> 16),
|
printf("%c%c%c%c", (uint8)(what >> 24), (uint8)(what >> 16),
|
||||||
(uint8)(what >> 8), (uint8)what);
|
(uint8)(what >> 8), (uint8)what);
|
||||||
printf(" (0x%lX or %ld)\n", what, what);
|
printf(" (0x%lX or %ld)\n", what, what);
|
||||||
@@ -794,7 +784,7 @@ BMessage::SendReply(BMessage *the_reply, BMessage *reply_to_reply,
|
|||||||
ssize_t
|
ssize_t
|
||||||
BMessage::FlattenedSize() const
|
BMessage::FlattenedSize() const
|
||||||
{
|
{
|
||||||
return calc_hdr_size(0) + fBody->FlattenedSize();
|
return calc_hdr_size() + fBody->FlattenedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1627,7 +1617,7 @@ char *
|
|||||||
BMessage::stack_flatten(char *stack_ptr, ssize_t stack_size,
|
BMessage::stack_flatten(char *stack_ptr, ssize_t stack_size,
|
||||||
bool /*incl_reply*/, ssize_t *size) const
|
bool /*incl_reply*/, ssize_t *size) const
|
||||||
{
|
{
|
||||||
const ssize_t calcd_size = calc_hdr_size(0) + fBody->FlattenedSize();
|
const ssize_t calcd_size = calc_hdr_size() + fBody->FlattenedSize();
|
||||||
char *new_ptr = NULL;
|
char *new_ptr = NULL;
|
||||||
if (calcd_size > stack_size) {
|
if (calcd_size > stack_size) {
|
||||||
stack_ptr = new char[calcd_size];
|
stack_ptr = new char[calcd_size];
|
||||||
@@ -1657,7 +1647,7 @@ BMessage::_UnflattenKMessage(const char *buffer)
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
BMessage::calc_hdr_size(uchar flags) const
|
BMessage::calc_hdr_size() const
|
||||||
{
|
{
|
||||||
ssize_t size = min_hdr_size();
|
ssize_t size = min_hdr_size();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
/* BMessageBody handles data storage and retrieval for BMessage. */
|
/* BMessageBody handles data storage and retrieval for BMessage. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <DataIO.h>
|
#include <DataIO.h>
|
||||||
#include <TypeConstants.h>
|
#include <TypeConstants.h>
|
||||||
#include "MessageBody3.h"
|
#include "MessageBody3.h"
|
||||||
@@ -17,6 +18,18 @@
|
|||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_raw(uint8 *data, int32 length)
|
||||||
|
{
|
||||||
|
int32 index = 0;
|
||||||
|
while (index < length) {
|
||||||
|
for (int32 line = 0; line < 40 && index < length; line++, index++)
|
||||||
|
printf("%02x ", data[index]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BMessageBody::BMessageBody()
|
BMessageBody::BMessageBody()
|
||||||
{
|
{
|
||||||
InitCommon();
|
InitCommon();
|
||||||
@@ -42,9 +55,8 @@ BMessageBody::operator=(const BMessageBody &other)
|
|||||||
{
|
{
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
MakeEmpty();
|
MakeEmpty();
|
||||||
// the flat buffer has no last entry flag included
|
BMemoryIO memoryIO(other.fFlatBuffer, other.fFlatLength);
|
||||||
BMemoryIO memoryIO(other.FlatBuffer(), other.FlattenedSize() - 1);
|
Unflatten(&memoryIO, other.fFlatLength);
|
||||||
Unflatten(&memoryIO, other.FlattenedSize() - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -54,6 +66,13 @@ BMessageBody::operator=(const BMessageBody &other)
|
|||||||
status_t
|
status_t
|
||||||
BMessageBody::InitCommon()
|
BMessageBody::InitCommon()
|
||||||
{
|
{
|
||||||
|
// use an avarage field size for each block
|
||||||
|
fBlockSize = sizeof(FieldHeader) + 50;
|
||||||
|
fFlatBuffer = (uint8 *)malloc(fBlockSize);
|
||||||
|
fFlatAllocated = fBlockSize;
|
||||||
|
fFlatLength = 0;
|
||||||
|
|
||||||
|
// init hash table
|
||||||
fFieldTableSize = 100;
|
fFieldTableSize = 100;
|
||||||
fFieldTable = new BMessageField *[fFieldTableSize];
|
fFieldTable = new BMessageField *[fFieldTableSize];
|
||||||
HashClear();
|
HashClear();
|
||||||
@@ -203,14 +222,14 @@ ssize_t
|
|||||||
BMessageBody::FlattenedSize() const
|
BMessageBody::FlattenedSize() const
|
||||||
{
|
{
|
||||||
// one more for the last entry flag
|
// one more for the last entry flag
|
||||||
return fFlatBuffer.BufferLength() + 1;
|
return fFlatLength + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMessageBody::Flatten(BDataIO *stream) const
|
BMessageBody::Flatten(BDataIO *stream) const
|
||||||
{
|
{
|
||||||
stream->Write(fFlatBuffer.Buffer(), fFlatBuffer.BufferLength());
|
stream->Write(fFlatBuffer, fFlatLength);
|
||||||
|
|
||||||
uint8 lastField = MSG_LAST_ENTRY;
|
uint8 lastField = MSG_LAST_ENTRY;
|
||||||
status_t error = stream->Write(&lastField, sizeof(lastField));
|
status_t error = stream->Write(&lastField, sizeof(lastField));
|
||||||
@@ -230,14 +249,14 @@ BMessageBody::Unflatten(BDataIO *stream, int32 length)
|
|||||||
if (length <= 0)
|
if (length <= 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
fFlatBuffer.SetSize(length);
|
FlatResize(length);
|
||||||
status_t error = stream->Read((void *)fFlatBuffer.Buffer(), length);
|
status_t error = stream->Read(fFlatBuffer, length);
|
||||||
|
|
||||||
if (error < B_OK)
|
if (error < B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
int32 offset = 0;
|
int32 offset = 0;
|
||||||
uint8 *location = (uint8 *)fFlatBuffer.Buffer();
|
uint8 *location = fFlatBuffer;
|
||||||
while (offset < error && *location & MSG_FLAG_VALID) {
|
while (offset < error && *location & MSG_FLAG_VALID) {
|
||||||
BMessageField *field = new BMessageField(this);
|
BMessageField *field = new BMessageField(this);
|
||||||
int32 fieldLength = field->Unflatten(offset);
|
int32 fieldLength = field->Unflatten(offset);
|
||||||
@@ -257,7 +276,7 @@ BMessageBody::Unflatten(BDataIO *stream, int32 length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set the buffer to the actual size
|
// set the buffer to the actual size
|
||||||
fFlatBuffer.SetSize(offset);
|
FlatResize(offset);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,8 +343,7 @@ BMessageBody::AddData(const char *name, type_code type, status_t &error)
|
|||||||
return foundField;
|
return foundField;
|
||||||
|
|
||||||
// add a new field if it's not yet present
|
// add a new field if it's not yet present
|
||||||
BMessageField *newField = new BMessageField(this,
|
BMessageField *newField = new BMessageField(this, fFlatLength, name, type);
|
||||||
fFlatBuffer.BufferLength(), name, type);
|
|
||||||
|
|
||||||
fFieldList.AddItem(newField);
|
fFieldList.AddItem(newField);
|
||||||
HashInsert(newField);
|
HashInsert(newField);
|
||||||
@@ -430,7 +448,12 @@ BMessageBody::MakeEmpty()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fFieldList.MakeEmpty();
|
fFieldList.MakeEmpty();
|
||||||
fFlatBuffer.SetSize(0);
|
|
||||||
|
free(fFlatBuffer);
|
||||||
|
fFlatBuffer = NULL;
|
||||||
|
fFlatLength = 0;
|
||||||
|
fFlatAllocated = 0;
|
||||||
|
|
||||||
HashClear();
|
HashClear();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -502,6 +525,21 @@ BMessageBody::FindData(const char *name, type_code type, status_t &error) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BMessageBody::FlatResize(int32 newSize)
|
||||||
|
{
|
||||||
|
int32 newLength = (newSize + fBlockSize - 1) / fBlockSize * fBlockSize;
|
||||||
|
if (newLength != fFlatAllocated) {
|
||||||
|
fFlatBuffer = (uint8 *)realloc(fFlatBuffer, newLength);
|
||||||
|
if (newLength > fFlatAllocated)
|
||||||
|
memset(fFlatBuffer + fFlatAllocated, 0, newLength - fFlatAllocated);
|
||||||
|
fFlatAllocated = newLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
fFlatLength = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8 *
|
uint8 *
|
||||||
BMessageBody::FlatInsert(int32 offset, ssize_t oldLength, ssize_t newLength)
|
BMessageBody::FlatInsert(int32 offset, ssize_t oldLength, ssize_t newLength)
|
||||||
{
|
{
|
||||||
@@ -509,10 +547,10 @@ BMessageBody::FlatInsert(int32 offset, ssize_t oldLength, ssize_t newLength)
|
|||||||
return FlatBuffer() + offset;
|
return FlatBuffer() + offset;
|
||||||
|
|
||||||
ssize_t change = newLength - oldLength;
|
ssize_t change = newLength - oldLength;
|
||||||
ssize_t bufferLength = fFlatBuffer.BufferLength();
|
ssize_t bufferLength = fFlatLength;
|
||||||
|
|
||||||
if (change > 0) {
|
if (change > 0) {
|
||||||
fFlatBuffer.SetSize(bufferLength + change);
|
FlatResize(bufferLength + change);
|
||||||
|
|
||||||
// usual case for adds
|
// usual case for adds
|
||||||
if (offset == bufferLength)
|
if (offset == bufferLength)
|
||||||
@@ -526,7 +564,7 @@ BMessageBody::FlatInsert(int32 offset, ssize_t oldLength, ssize_t newLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (change < 0)
|
if (change < 0)
|
||||||
fFlatBuffer.SetSize(bufferLength + change);
|
FlatResize(bufferLength + change);
|
||||||
|
|
||||||
for (int32 index = fFieldList.CountItems() - 1; index >= 0; index--) {
|
for (int32 index = fFieldList.CountItems() - 1; index >= 0; index--) {
|
||||||
BMessageField *field = (BMessageField *)fFieldList.ItemAt(index);
|
BMessageField *field = (BMessageField *)fFieldList.ItemAt(index);
|
||||||
|
|||||||
@@ -71,9 +71,6 @@ BMessageField::Unflatten(int32 _offset)
|
|||||||
fDataOffset = sizeof(FieldHeader) + header->nameLength;
|
fDataOffset = sizeof(FieldHeader) + header->nameLength;
|
||||||
fFixedSize = header->flags & MSG_FLAG_FIXED_SIZE;
|
fFixedSize = header->flags & MSG_FLAG_FIXED_SIZE;
|
||||||
|
|
||||||
if (header->nameLength == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (fFixedSize) {
|
if (fFixedSize) {
|
||||||
if (header->count > 0)
|
if (header->count > 0)
|
||||||
fItemSize = header->dataSize / header->count;
|
fItemSize = header->dataSize / header->count;
|
||||||
@@ -100,14 +97,14 @@ BMessageField::Unflatten(int32 _offset)
|
|||||||
void
|
void
|
||||||
BMessageField::SetName(const char *newName)
|
BMessageField::SetName(const char *newName)
|
||||||
{
|
{
|
||||||
FieldHeader *header = Header();
|
int32 newLength = min_c(strlen(newName), B_FIELD_NAME_LENGTH - 1) + 1;
|
||||||
|
char *buffer = (char *)fParent->FlatInsert(fOffset + sizeof(FieldHeader),
|
||||||
|
Header()->nameLength, newLength);
|
||||||
|
|
||||||
int32 newLength = min_c(strlen(newName), 254) + 1;
|
strncpy(buffer, newName, newLength - 1);
|
||||||
char *buffer = (char *)fParent->FlatInsert(fOffset + sizeof(FieldHeader), header->nameLength, newLength);
|
buffer[newLength - 1] = 0;
|
||||||
strncpy(buffer, newName, newLength);
|
|
||||||
buffer[newLength] = 0;
|
|
||||||
|
|
||||||
header->nameLength = newLength;
|
Header()->nameLength = newLength;
|
||||||
fDataOffset = sizeof(FieldHeader) + newLength;
|
fDataOffset = sizeof(FieldHeader) + newLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,9 +232,9 @@ BMessageField::RemoveItem(int32 index)
|
|||||||
FieldHeader *header = Header();
|
FieldHeader *header = Header();
|
||||||
|
|
||||||
if (fFixedSize) {
|
if (fFixedSize) {
|
||||||
fParent->FlatInsert(DATA_OFFSET + (index * fItemSize), fItemSize, 0);
|
|
||||||
header->dataSize -= fItemSize;
|
|
||||||
header->count--;
|
header->count--;
|
||||||
|
header->dataSize -= fItemSize;
|
||||||
|
fParent->FlatInsert(DATA_OFFSET + (index * fItemSize), fItemSize, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,9 +243,9 @@ BMessageField::RemoveItem(int32 index)
|
|||||||
for (int32 i = index; i < header->count; i++)
|
for (int32 i = index; i < header->count; i++)
|
||||||
((ItemInfo *)fItemInfos.ItemAt(i))->offset -= info->paddedLength;
|
((ItemInfo *)fItemInfos.ItemAt(i))->offset -= info->paddedLength;
|
||||||
|
|
||||||
fParent->FlatInsert(DATA_OFFSET + info->offset, info->paddedLength, 0);
|
|
||||||
header->dataSize -= info->paddedLength;
|
|
||||||
header->count--;
|
header->count--;
|
||||||
|
header->dataSize -= info->paddedLength;
|
||||||
|
fParent->FlatInsert(DATA_OFFSET + info->offset, info->paddedLength, 0);
|
||||||
delete info;
|
delete info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,8 +273,8 @@ void
|
|||||||
BMessageField::RemoveSelf()
|
BMessageField::RemoveSelf()
|
||||||
{
|
{
|
||||||
// remove ourself from the flat buffer
|
// remove ourself from the flat buffer
|
||||||
FieldHeader *header = Header();
|
int32 dataSize = Header()->dataSize;
|
||||||
fParent->FlatInsert(fOffset, fDataOffset + header->dataSize, 0);
|
fParent->FlatInsert(fOffset, fDataOffset + dataSize, 0);
|
||||||
fOffset = 0;
|
fOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user