From 0d1fab522bfcb2635a8071761cebf28963a6bb40 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 20 Nov 2009 13:52:23 +0000 Subject: [PATCH] * Added flag KMESSAGE_CLONE_BUFFER, which will cause buffer passed to SetTo() to be cloned. * Added "flags" parameter to the SetTo(const void*,...) version. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34155 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/util/KMessage.h | 9 ++++-- src/system/kernel/messaging/KMessage.cpp | 36 +++++++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/headers/private/kernel/util/KMessage.h b/headers/private/kernel/util/KMessage.h index 215c343444..5e6903bf52 100644 --- a/headers/private/kernel/util/KMessage.h +++ b/headers/private/kernel/util/KMessage.h @@ -29,7 +29,8 @@ public: enum { KMESSAGE_OWNS_BUFFER = 0x01, KMESSAGE_INIT_FROM_BUFFER = 0x02, - KMESSAGE_READ_ONLY = 0x04, + KMESSAGE_CLONE_BUFFER = 0x04, + KMESSAGE_READ_ONLY = 0x08, KMESSAGE_FLAG_MASK = 0x07, }; @@ -42,8 +43,10 @@ public: status_t SetTo(uint32 what, uint32 flags = 0); status_t SetTo(void* buffer, int32 bufferSize, uint32 what, uint32 flags = 0); - status_t SetTo(const void* buffer, - int32 bufferSize = -1); + status_t SetTo(const void* buffer, int32 bufferSize = -1, + uint32 flags = 0); + // KMESSAGE_INIT_FROM_BUFFER and + // KMESSAGE_READ_ONLY are implied void Unset(); void SetWhat(uint32 what); diff --git a/src/system/kernel/messaging/KMessage.cpp b/src/system/kernel/messaging/KMessage.cpp index 00197cafec..b58e041a1b 100644 --- a/src/system/kernel/messaging/KMessage.cpp +++ b/src/system/kernel/messaging/KMessage.cpp @@ -177,8 +177,16 @@ KMessage::SetTo(void* buffer, int32 bufferSize, uint32 what, uint32 flags) return B_BAD_VALUE; // if read-only, we need to init from the buffer, too - if (flags & KMESSAGE_READ_ONLY && !(flags & KMESSAGE_INIT_FROM_BUFFER)) + if ((flags & KMESSAGE_READ_ONLY) != 0 + && (flags & KMESSAGE_INIT_FROM_BUFFER) == 0) { return B_BAD_VALUE; + } + + // if not initializing from the given buffer, cloning it doesn't make sense + if ((flags & KMESSAGE_INIT_FROM_BUFFER) == 0 + && (flags & KMESSAGE_CLONE_BUFFER) != 0) { + return B_BAD_VALUE; + } fBuffer = buffer; fBufferCapacity = bufferSize; @@ -198,10 +206,10 @@ KMessage::SetTo(void* buffer, int32 bufferSize, uint32 what, uint32 flags) status_t -KMessage::SetTo(const void* buffer, int32 bufferSize) +KMessage::SetTo(const void* buffer, int32 bufferSize, uint32 flags) { return SetTo(const_cast(buffer), bufferSize, 0, - KMESSAGE_INIT_FROM_BUFFER | KMESSAGE_READ_ONLY); + KMESSAGE_INIT_FROM_BUFFER | KMESSAGE_READ_ONLY | flags); } @@ -805,7 +813,27 @@ KMessage::_AddFieldData(KMessageField* field, const void* data, status_t KMessage::_InitFromBuffer(bool sizeFromBuffer) { - if (!fBuffer || _Align(fBuffer) != fBuffer) + if (fBuffer == NULL) + return B_BAD_DATA; + + // clone the buffer, if requested + if ((fFlags & KMESSAGE_CLONE_BUFFER) != 0) { + if (sizeFromBuffer) { + int32 size = fBufferCapacity; + memcpy(&size, &_Header()->size, 4); + fBufferCapacity = size; + } + + void* buffer = malloc(fBufferCapacity); + if (buffer == NULL) + return B_NO_MEMORY; + + memcpy(buffer, fBuffer, fBufferCapacity); + fBuffer = buffer; + fFlags &= ~(uint32)(KMESSAGE_READ_ONLY | KMESSAGE_CLONE_BUFFER); + } + + if (_Align(fBuffer) != fBuffer) return B_BAD_DATA; Header* header = _Header();