diff --git a/headers/os/app/Message.h b/headers/os/app/Message.h index 723e81ab6c..20701a0fbc 100644 --- a/headers/os/app/Message.h +++ b/headers/os/app/Message.h @@ -260,6 +260,7 @@ virtual ~BMessage(); const void *data, ssize_t data_size); void *operator new(size_t size); + void *operator new(size_t, void* p); void operator delete(void *ptr, size_t size); // Private, reserved, or obsolete ---------------------------------------------- diff --git a/headers/private/app/MessageField.h b/headers/private/app/MessageField.h index 6ffacc3e70..89b3e2c6fd 100644 --- a/headers/private/app/MessageField.h +++ b/headers/private/app/MessageField.h @@ -141,6 +141,13 @@ struct BMessageFieldFlattenPolicy } }; //------------------------------------------------------------------------------ +template +struct BMessageFieldGetDataPolicy +{ + inline static const void* GetData(const T* data) + { return (const void*)data; } +}; +//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ template @@ -149,7 +156,8 @@ template class StoragePolicy = BMessageFieldStoragePolicy, class SizePolicy = BMessageFieldSizePolicy, class PrintPolicy = BMessageFieldPrintPolicy, - class FlattenPolicy = BMessageFieldFlattenPolicy + class FlattenPolicy = BMessageFieldFlattenPolicy, + class GetDataPolicy = BMessageFieldGetDataPolicy > class BMessageFieldImpl : public BMessageField { @@ -192,10 +200,11 @@ template class StoragePolicy, class SizePolicy, class PrintPolicy, - class FlattenPolicy + class FlattenPolicy, + class GetDataPolicy > ssize_t -BMessageFieldImpl:: +BMessageFieldImpl:: FlattenedSize() const { ssize_t size = 0; @@ -220,10 +229,11 @@ template class StoragePolicy, class SizePolicy, class PrintPolicy, - class FlattenPolicy + class FlattenPolicy, + class GetDataPolicy > status_t -BMessageFieldImpl:: +BMessageFieldImpl:: Flatten(BDataIO& stream) const { status_t err = B_OK; @@ -271,10 +281,11 @@ template class StoragePolicy, class SizePolicy, class PrintPolicy, - class FlattenPolicy + class FlattenPolicy, + class GetDataPolicy > void -BMessageFieldImpl:: +BMessageFieldImpl:: AddItem(const T1& data) { fData.Add(data); @@ -311,10 +322,11 @@ template class StoragePolicy, class SizePolicy, class PrintPolicy, - class FlattenPolicy + class FlattenPolicy, + class GetDataPolicy > const void* -BMessageFieldImpl:: +BMessageFieldImpl:: DataAt(int32 index, ssize_t* size) const { if (index > CountItems()) @@ -323,8 +335,8 @@ DataAt(int32 index, ssize_t* size) const *size = SizePolicy::Size(fData[index]); const T1& ref = fData[index]; const T1* data = &ref; - - return (const void*)data; + + return GetDataPolicy::GetData(data);//(const void*)data; } //------------------------------------------------------------------------------ template @@ -333,10 +345,11 @@ template class StoragePolicy, class SizePolicy, class PrintPolicy, - class FlattenPolicy + class FlattenPolicy, + class GetDataPolicy > void -BMessageFieldImpl:: +BMessageFieldImpl:: PrintDataItem(int32 index) const { if (index && FixedSize()) @@ -569,6 +582,13 @@ struct BMessageFieldFlattenPolicy return err; } }; +// GetData policy specializations ---------------------------------------------- +template<> +struct BMessageFieldGetDataPolicy +{ + inline static const void* GetData(const BDataBuffer* data) + { return data->Buffer(); } +}; //------------------------------------------------------------------------------ } // namespace BPrivate diff --git a/headers/private/app/MessageUtils.h b/headers/private/app/MessageUtils.h index 0d747c3a43..6607dbc1e6 100644 --- a/headers/private/app/MessageUtils.h +++ b/headers/private/app/MessageUtils.h @@ -26,6 +26,14 @@ uint32 _checksum_(const uchar *buf, int32 size); +namespace BPrivate { // Only putting these here because Be did + +status_t entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref); +status_t entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size); +status_t entry_ref_swap(char* buffer, size_t size); + +} // namespace BPrivate + //------------------------------------------------------------------------------ // _set_message_target_ /*! \brief Sets the target of a message. diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index 7a4fc952c2..5096565f57 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -77,7 +77,7 @@ // Globals --------------------------------------------------------------------- #ifdef USING_TEMPLATE_MADNESS -using BPrivate::BDataBuffer; +using namespace BPrivate; #endif // USING_TEMPLATE_MADNESS const char* B_SPECIFIER_ENTRY = "specifiers"; const char* B_PROPERTY_ENTRY = "property"; @@ -740,17 +740,43 @@ status_t BMessage::AddMessenger(const char* name, BMessenger messenger) //------------------------------------------------------------------------------ status_t BMessage::AddRef(const char* name, const entry_ref* ref) { +#if 0 return fBody->AddData(name, *ref, B_REF_TYPE); +#endif + char* buffer = new(nothrow) char[sizeof (entry_ref) + B_PATH_NAME_LENGTH]; + size_t size; + status_t err = entry_ref_flatten(buffer, &size, ref); + if (!err) + { + BDataBuffer DB((void*)buffer, size); + err = fBody->AddData(name, DB, B_REF_TYPE); + } + + return err; } //------------------------------------------------------------------------------ status_t BMessage::AddMessage(const char* name, const BMessage* msg) { - BMessage* data = new BMessage(*msg); - status_t err = fBody->AddData(name, msg, B_MESSAGE_TYPE); - if (err) +#if 0 + return fBody->AddData(name, *msg, B_MESSAGE_TYPE); +#endif + status_t err = B_OK; + ssize_t size = msg->FlattenedSize(); + char* buffer = new(nothrow) char[size]; + if (buffer) { - delete data; + err = msg->Flatten(buffer, size); + if (!err) + { + BDataBuffer DB((void*)buffer, size); + err = fBody->AddData(name, DB, B_MESSAGE_TYPE); + } } + else + { + err = B_NO_MEMORY; + } + return err; } //------------------------------------------------------------------------------ @@ -765,6 +791,10 @@ status_t BMessage::AddFlat(const char* name, BFlattenable* obj, int32 count) obj->IsFixedSize(), count); delete[] buffer; } + else + { + err = B_NO_MEMORY; + } return err; } @@ -825,14 +855,19 @@ status_t BMessage::AddData(const char* name, type_code type, const void* data, break; case B_REF_TYPE: { - err = AddRef(name, (entry_ref*)data); +// err = AddRef(name, (entry_ref*)data); + BDataBuffer DB((void*)data, numBytes, true); + err = fBody->AddData(name, DB, type); break; } case B_MESSAGE_TYPE: { - BMessage msg; - msg.Unflatten((const char*)data); - err = AddMessage(name, &msg); +// BMessage msg; +// msg.Unflatten((const char*)data); +// err = AddMessage(name, &msg); +// err = AddMessage(name, (BMessage*)data); + BDataBuffer DB((void*)data, numBytes, true); + err = fBody->AddData(name, DB, type); break; } case B_MESSENGER_TYPE: @@ -847,7 +882,7 @@ status_t BMessage::AddData(const char* name, type_code type, const void* data, default: // TODO: test // Using the mythical BDataBuffer - BDataBuffer DB((void*)data, numBytes); + BDataBuffer DB((void*)data, numBytes, true); err = fBody->AddData(name, DB, type); break; } @@ -927,7 +962,18 @@ status_t BMessage::FindRef(const char* name, entry_ref* ref) const //------------------------------------------------------------------------------ status_t BMessage::FindRef(const char* name, int32 index, entry_ref* ref) const { +#if 0 return fBody->FindData(name, index, ref, B_REF_TYPE); +#endif + void* data = NULL; + ssize_t size = 0; + status_t err = FindData(name, B_REF_TYPE, index, (const void**)&data, &size); + if (!err) + { + err = entry_ref_unflatten(ref, (char*)data, size); + } + + return err; } //------------------------------------------------------------------------------ status_t BMessage::FindMessage(const char* name, BMessage* msg) const @@ -937,7 +983,19 @@ status_t BMessage::FindMessage(const char* name, BMessage* msg) const //------------------------------------------------------------------------------ status_t BMessage::FindMessage(const char* name, int32 index, BMessage* msg) const { +#if 0 return fBody->FindData(name, index, msg, B_MESSAGE_TYPE); +#endif + void* data = NULL; + ssize_t size = 0; + status_t err = FindData(name, B_MESSAGE_TYPE, index, + (const void**)&data, &size); + if (!err) + { + err = msg->Unflatten((const char*)data); + } + + return err; } //------------------------------------------------------------------------------ status_t BMessage::FindFlat(const char* name, BFlattenable* obj) const @@ -1028,7 +1086,19 @@ status_t BMessage::ReplaceRef(const char* name, int32 index, const entry_ref* re { // TODO: test // Use voidref's theoretical BDataBuffer +#if 0 return fBody->ReplaceData(name, index, *ref, B_REF_TYPE); +#endif + char* buffer = new(nothrow) char[sizeof (entry_ref) + B_PATH_NAME_LENGTH]; + size_t size; + status_t err = entry_ref_flatten(buffer, &size, ref); + if (!err) + { + BDataBuffer DB((void*)buffer, size); + err = fBody->ReplaceData(name, index, DB, B_REF_TYPE); + } + + return err; } //------------------------------------------------------------------------------ status_t BMessage::ReplaceMessage(const char* name, const BMessage* msg) @@ -1039,7 +1109,28 @@ status_t BMessage::ReplaceMessage(const char* name, const BMessage* msg) status_t BMessage::ReplaceMessage(const char* name, int32 index, const BMessage* msg) { +#if 0 return fBody->ReplaceData(name, index, *msg, B_MESSAGE_TYPE); +#endif + status_t err = B_OK; + ssize_t size = msg->FlattenedSize(); + char* buffer = new(nothrow) char[size]; + if (buffer) + { + err = msg->Flatten(buffer, size); + if (!err) + { + BDataBuffer DB((void*)buffer, size); + err = fBody->ReplaceData(name, index, DB, + B_MESSAGE_TYPE); + } + } + else + { + err = B_NO_MEMORY; + } + + return err; } //------------------------------------------------------------------------------ status_t BMessage::ReplaceFlat(const char* name, BFlattenable* obj) @@ -1121,7 +1212,7 @@ status_t BMessage::ReplaceData(const char* name, type_code type, int32 index, default: // TODO: test // Using the mythical BDataBuffer - BDataBuffer DB((void*)data, data_size); + BDataBuffer DB((void*)data, data_size, true); err = fBody->ReplaceData(name, index, DB, type); break; } @@ -1134,6 +1225,11 @@ void* BMessage::operator new(size_t size) return ::new char[size]; } //------------------------------------------------------------------------------ +void* BMessage::operator new(size_t, void* p) +{ + return p; +} +//------------------------------------------------------------------------------ void BMessage::operator delete(void* ptr, size_t size) { ::delete(ptr); @@ -1282,10 +1378,19 @@ status_t BMessage::unflatten_hdr(BDataIO* stream, bool& swap) { swap = true; } - else + else if (data == 'FOB1') { swap = false; } + else + { + // This is *not* a message + return B_NOT_A_MESSAGE; + } + + // Make way for the new data + MakeEmpty(); + read_helper.SetSwap(swap); // get the checksum diff --git a/src/kits/app/MessageUtils.cpp b/src/kits/app/MessageUtils.cpp index 9c64687fd3..a82f7dd9d6 100644 --- a/src/kits/app/MessageUtils.cpp +++ b/src/kits/app/MessageUtils.cpp @@ -6,6 +6,7 @@ // Standard Includes ----------------------------------------------------------- // System Includes ------------------------------------------------------------- +#include // Project Includes ------------------------------------------------------------ #include @@ -42,6 +43,81 @@ uint32 _checksum_(const uchar* buf, int32 size) return sum; } //------------------------------------------------------------------------------ + + +namespace BPrivate { // Only putting these here because Be did +//------------------------------------------------------------------------------ +status_t entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref) +{ + memcpy((void*)buffer, (const void*)&ref->device, sizeof (ref->device)); + buffer += sizeof (ref->device); + memcpy((void*)buffer, (const void*)&ref->directory, sizeof (ref->directory)); + buffer += sizeof (ref->directory); + + size_t len = 0; + if (ref->name) + { + len = strlen(ref->name) + 1; // extra for NULL terminator + memcpy((void*)buffer, (const void*)ref->name, len); + } + + *size = sizeof (ref->device) + sizeof (ref->directory) + len; + return B_OK; +} +//------------------------------------------------------------------------------ +status_t entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size) +{ + if (size < (sizeof (ref->device) + sizeof (ref->directory))) + { + *ref = entry_ref(); + return B_BAD_VALUE; + } + + memcpy((void*)&ref->device, (const void*)buffer, sizeof (ref->device)); + buffer += sizeof (ref->device); + memcpy((void*)&ref->directory, (const void*)buffer, + sizeof (ref->directory)); + buffer += sizeof (ref->directory); + + if (ref->device != -1 && + size > (sizeof (ref->device) + sizeof (ref->directory))) + { + ref->set_name(buffer); + if (ref->name == NULL) + { + *ref = entry_ref(); + return B_NO_MEMORY; + } + } + else + { + ref->set_name(NULL); + } + + return B_OK; +} +//------------------------------------------------------------------------------ +status_t entry_ref_swap(char* buffer, size_t size) +{ + if (size < (sizeof (dev_t) + sizeof (ino_t))) + { + return B_BAD_DATA; + } + + dev_t* dev = (dev_t*)buffer; + *dev = B_SWAP_INT32(*dev); + buffer += sizeof (dev_t); + + ino_t* ino = (ino_t*)buffer; + *ino = B_SWAP_INT64(*ino); + + return B_OK; +} +//------------------------------------------------------------------------------ + +} // namespace BPrivate + +//------------------------------------------------------------------------------ int32 TChecksumHelper::CheckSum() { return _checksum_(fBuffer, fBufPtr - fBuffer);