AppKit: BMessage Add/Find/Get/Has/ReplaceNodeRef

This allows you to pass node_ref's around like you can entry_ref's.

Added node_ref_flatten(), node_ref_unflatten() and node_ref_swap() to
MessageUtils. These are close cousins to entry_ref_flatten(),
entry_ref_unflatten(), and entry_ref_swap() but for node_ref's.

Added B_NODE_REF_TYPE to TypeConstants.h in the Support Kit.

Added B_NODE_REF_TYPE to Debugger and ByteOrder in Support Kit,
B_NODE_REF_TYPE is treated the same as a B_REF_TYPE (entry_ref).

Add documentation for new NodeRef methods and B_NODE_REF_TYPE.

Change-Id: I32c6ed276bf1a7894a835b9fc9de5a882c35883c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3182
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
John Scipione
2020-09-10 17:18:09 +00:00
committed by Adrien Destugues
parent 19a1dd49cf
commit fe88ae51ec
11 changed files with 288 additions and 7 deletions
+116
View File
@@ -1362,6 +1362,25 @@
*/
/*!
\fn status_t BMessage::AddNodeRef(const char* name, const node_ref* ref)
\brief Convenience method to add a \c node_ref with the label \a name.
This method calls AddData() with the \c B_NODE_REF_TYPE \a type.
\param name The label to associate the data with.
\param ref The node reference to store in the message.
\returns A status code, \c B_OK on success or an error code.
\see AddData() for a more detailed overview of the inner workings.
\see FindNodeRef()
\see ReplaceNodeRef()
\since Haiku R1
*/
/*!
\fn status_t BMessage::AddMessage(const char* name,
const BMessage* message)
@@ -2433,6 +2452,49 @@
*/
/*!
\fn status_t BMessage::FindNodeRef(const char* name, node_ref* ref) const
\brief Find a reference to a node at the label \a name.
This is an overloaded version of
FindNodeRef(const char*, int32, node_ref*) const
where the data is sought at \a index \c 0.
\param name The label to which the data is associated.
\param ref The object into which the data should be copied.
\returns A status code, \c B_OK on success or an error code.
\retval B_OK The object now contains the requested data.
\retval B_NAME_NOT_FOUND There is no field with this \a name.
\since Haiku R1
*/
/*!
\fn status_t BMessage::FindNodeRef(const char* name, int32 index,
node_ref* ref) const
\brief Find a reference to a node at the label \a name at an
\a index.
This method looks for the data with the \c B_NODE_REF_TYPE, and copies
it into a provided buffer.
\param name The label to which the data is associated.
\param index The index from which the data should be copied.
\param ref The object in which the data should be copied.
\returns A status code, \c B_OK on success or an error code.
\retval B_OK The object now contains the requested data.
\retval B_BAD_INDEX The \a index does not exist.
\retval B_NAME_NOT_FOUND There is no field with this \a name.
\see FindNodeRef(const char*, node_ref*) const
\since Haiku R1
*/
/*!
\fn status_t BMessage::FindMessage(const char* name,
BMessage* message) const
@@ -3493,6 +3555,50 @@
*/
/*!
\fn status_t BMessage::ReplaceNodeRef(const char* name,
const node_ref* ref)
\brief Replace a reference to a node at the label \a name.
This method is an overloaded method of
ReplaceNodeRef(const char*, int32, node_ref*).
It replaces the data at \a index \c 0.
\param name The name associated with the data to replace.
\param ref The object to store in the message.
\returns A status code, \c B_OK on success or an error code.
\retval B_OK The operation succeeded.
\retval B_NAME_NOT_FOUND There is no field with this \a name.
\since Haiku R1
*/
/*!
\fn status_t BMessage::ReplaceNodeRef(const char* name, int32 index,
const node_ref* ref)
\brief Replace a reference to a node at the label \a name at a
specified \a index.
The data at the specified \a name and \a index will be replaced, if it
matches the \c B_NODE_REF_TYPE.
\param name The name associated with the data to replace.
\param index The index in the array to replace.
\param ref The object to store in the message.
\returns A status code, \c B_OK on success or an error code.
\retval B_OK The operation succeeded.
\retval B_BAD_INDEX The index was out of range.
\retval B_NAME_NOT_FOUND There is no field with this \a name.
\see ReplaceNodeRef(const char*, node_ref*)
\since Haiku R1
*/
/*!
\fn status_t BMessage::ReplaceMessage(const char* name,
const BMessage* message)
@@ -3843,6 +3949,16 @@
*/
/*!
\fn bool BMessage::HasNodeRef(const char*, int32) const
\brief Deprecated.
\warning This method is deprecated, do not use.
\since Haiku R1.
*/
/*!
\fn bool BMessage::HasMessage(const char*, int32) const
\brief Deprecated.
+8
View File
@@ -220,6 +220,14 @@
*/
/*!
\var B_NODE_REF_TYPE
\brief Represents a \c node_ref structure.
\since Haiku R1
*/
/*!
\var B_RGB_COLOR_TYPE
\brief Represents an \c rgb_color structure.
+13
View File
@@ -13,8 +13,10 @@
#include <BeBuild.h>
#include <DataIO.h>
#include <Entry.h>
#include <Flattenable.h>
#include <OS.h>
#include <Node.h>
#include <Rect.h>
#include <Size.h>
@@ -161,6 +163,8 @@ public:
status_t AddMessenger(const char* name,
BMessenger messenger);
status_t AddRef(const char* name, const entry_ref* ref);
status_t AddNodeRef(const char* name,
const node_ref* ref);
status_t AddMessage(const char* name,
const BMessage* message);
status_t AddFlat(const char* name, BFlattenable* object,
@@ -258,6 +262,10 @@ public:
status_t FindRef(const char* name, entry_ref* ref) const;
status_t FindRef(const char* name, int32 index,
entry_ref* ref) const;
status_t FindNodeRef(const char* name,
node_ref* ref) const;
status_t FindNodeRef(const char* name, int32 index,
node_ref* ref) const;
status_t FindMessage(const char* name,
BMessage* message) const;
status_t FindMessage(const char* name, int32 index,
@@ -346,6 +354,10 @@ public:
const entry_ref* ref);
status_t ReplaceRef(const char* name, int32 index,
const entry_ref* ref);
status_t ReplaceNodeRef(const char* name,
const node_ref* ref);
status_t ReplaceNodeRef(const char* name, int32 index,
const node_ref* ref);
status_t ReplaceMessage(const char* name,
const BMessage* message);
status_t ReplaceMessage(const char* name, int32 index,
@@ -394,6 +406,7 @@ public:
bool HasMessenger(const char* name,
int32 n = 0) const;
bool HasRef(const char* name, int32 n = 0) const;
bool HasNodeRef(const char* name, int32 n = 0) const;
bool HasMessage(const char* name, int32 n = 0) const;
bool HasFlat(const char* name,
const BFlattenable* object) const;
+1
View File
@@ -46,6 +46,7 @@ enum {
B_RAW_TYPE = 'RAWT',
B_RECT_TYPE = 'RECT',
B_REF_TYPE = 'RREF',
B_NODE_REF_TYPE = 'NREF',
B_RGB_32_BIT_TYPE = 'RGBB',
B_RGB_COLOR_TYPE = 'RGBC',
B_SIZE_TYPE = 'SIZE',
+7
View File
@@ -5,15 +5,22 @@
#include <DataIO.h>
#include <Entry.h>
#include <Message.h>
#include <Node.h>
#include <SupportDefs.h>
namespace BPrivate { // Only putting these here because Be did
// entry_ref
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);
// node_ref
status_t node_ref_flatten(char* buffer, size_t* size, const node_ref* ref);
status_t node_ref_unflatten(node_ref* ref, const char* buffer, size_t size);
status_t node_ref_swap(char* buffer, size_t size);
uint32 CalculateChecksum(const uint8 *buffer, int32 size);
} // namespace BPrivate
+75 -2
View File
@@ -21,13 +21,11 @@
#include <Application.h>
#include <AppMisc.h>
#include <BlockCache.h>
#include <Entry.h>
#include <GraphicsDefs.h>
#include <MessageQueue.h>
#include <Messenger.h>
#include <Path.h>
#include <Point.h>
#include <Rect.h>
#include <String.h>
#include <StringList.h>
@@ -720,6 +718,16 @@ BMessage::_PrintToStream(const char* indent) const
break;
}
case B_NODE_REF_TYPE:
{
node_ref ref;
BPrivate::node_ref_unflatten(&ref, (char*)pointer, size);
printf("node_ref(device=%d, node=%" B_PRIdINO ", ",
(int)ref.device, ref.node);
break;
}
case B_MESSAGE_TYPE:
{
char buffer[1024];
@@ -2511,6 +2519,7 @@ DEFINE_HAS_FUNCTION(String, B_STRING_TYPE);
DEFINE_HAS_FUNCTION(Pointer, B_POINTER_TYPE);
DEFINE_HAS_FUNCTION(Messenger, B_MESSENGER_TYPE);
DEFINE_HAS_FUNCTION(Ref, B_REF_TYPE);
DEFINE_HAS_FUNCTION(NodeRef, B_NODE_REF_TYPE);
DEFINE_HAS_FUNCTION(Message, B_MESSAGE_TYPE);
#undef DEFINE_HAS_FUNCTION
@@ -2710,6 +2719,21 @@ BMessage::AddRef(const char* name, const entry_ref* ref)
}
status_t
BMessage::AddNodeRef(const char* name, const node_ref* ref)
{
size_t size = sizeof(node_ref);
char buffer[size];
status_t error = BPrivate::node_ref_flatten(buffer, &size, ref);
if (error >= B_OK)
error = AddData(name, B_NODE_REF_TYPE, buffer, size, false);
return error;
}
status_t
BMessage::AddMessage(const char* name, const BMessage* message)
{
@@ -2989,6 +3013,33 @@ BMessage::FindRef(const char* name, int32 index, entry_ref* ref) const
}
status_t
BMessage::FindNodeRef(const char* name, node_ref* ref) const
{
return FindNodeRef(name, 0, ref);
}
status_t
BMessage::FindNodeRef(const char* name, int32 index, node_ref* ref) const
{
if (ref == NULL)
return B_BAD_VALUE;
void* data = NULL;
ssize_t size = 0;
status_t error = FindData(name, B_NODE_REF_TYPE, index,
(const void**)&data, &size);
if (error == B_OK)
error = BPrivate::node_ref_unflatten(ref, (char*)data, size);
else
*ref = node_ref();
return error;
}
status_t
BMessage::FindMessage(const char* name, BMessage* message) const
{
@@ -3154,6 +3205,28 @@ BMessage::ReplaceRef(const char* name, int32 index, const entry_ref* ref)
}
status_t
BMessage::ReplaceNodeRef(const char* name, const node_ref* ref)
{
return ReplaceNodeRef(name, 0, ref);
}
status_t
BMessage::ReplaceNodeRef(const char* name, int32 index, const node_ref* ref)
{
size_t size = sizeof(node_ref) + B_PATH_NAME_LENGTH;
char buffer[size];
status_t error = BPrivate::node_ref_flatten(buffer, &size, ref);
if (error >= B_OK)
error = ReplaceData(name, B_NODE_REF_TYPE, index, buffer, size);
return error;
}
status_t
BMessage::ReplaceMessage(const char* name, const BMessage* message)
{
+53 -1
View File
@@ -59,6 +59,7 @@ entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref)
}
*size = sizeof(ref->device) + sizeof(ref->directory) + nameLength;
return B_OK;
}
@@ -73,7 +74,8 @@ entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size)
memcpy((void *)&ref->device, (const void *)buffer, sizeof(ref->device));
buffer += sizeof(ref->device);
memcpy((void *)&ref->directory, (const void *)buffer, sizeof(ref->directory));
memcpy((void *)&ref->directory, (const void *)buffer,
sizeof(ref->directory));
buffer += sizeof(ref->directory);
if (ref->device != ~(dev_t)0 && size > sizeof(ref->device)
@@ -106,4 +108,54 @@ entry_ref_swap(char *buffer, size_t size)
return B_OK;
}
/* node_ref support functions */
status_t
node_ref_flatten(char *buffer, size_t *size, const node_ref *ref)
{
if (*size < sizeof(dev_t) + sizeof(ino_t))
return B_BUFFER_OVERFLOW;
memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device));
buffer += sizeof(ref->device);
memcpy((void *)buffer, (const void *)&ref->node, sizeof(ref->node));
buffer += sizeof(ref->node);
return B_OK;
}
status_t
node_ref_unflatten(node_ref *ref, const char *buffer, size_t size)
{
if (size < sizeof(dev_t) + sizeof(ino_t)) {
*ref = node_ref();
return B_BAD_VALUE;
}
memcpy((void *)&ref->device, (const void *)buffer, sizeof(dev_t));
buffer += sizeof(dev_t);
memcpy((void *)&ref->node, (const void *)buffer, sizeof(ino_t));
buffer += sizeof(ino_t);
return B_OK;
}
status_t
node_ref_swap(char *buffer, size_t size)
{
if (size < sizeof(dev_t) + sizeof(ino_t))
return B_BAD_VALUE;
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
@@ -94,6 +94,7 @@ Demangler::Demangle(const BString& mangledName)
demangledName << "void*";
break;
case B_REF_TYPE:
case B_NODE_REF_TYPE:
// TODO: use length as hint on reference type
demangledName << "&";
break;
@@ -478,6 +478,11 @@ BMessageValueNode::_GetTypeForTypeCode(TeamTypeInformation* info,
constraints.SetTypeKind(TYPE_COMPOUND);
break;
case B_NODE_REF_TYPE:
typeName = "node_ref";
constraints.SetTypeKind(TYPE_COMPOUND);
break;
case B_RGB_COLOR_TYPE:
typeName = "rgb_color";
constraints.SetTypeKind(TYPE_COMPOUND);
+1
View File
@@ -143,6 +143,7 @@ is_type_swapped(type_code type)
case B_POINT_TYPE:
case B_RECT_TYPE:
case B_REF_TYPE:
case B_NODE_REF_TYPE:
case B_RGB_32_BIT_TYPE:
case B_RGB_COLOR_TYPE:
case B_SIZE_T_TYPE:
@@ -394,7 +394,11 @@ AttributesView::AttributesView(Model* model)
kTypeColumn);
break;
case B_REF_TYPE:
row->SetField(new BStringField(B_TRANSLATE("Reference")),
row->SetField(new BStringField(B_TRANSLATE("Entry ref")),
kTypeColumn);
break;
case B_NODE_REF_TYPE:
row->SetField(new BStringField(B_TRANSLATE("Node ref")),
kTypeColumn);
break;
case B_RGB_32_BIT_TYPE: