From 5b25b917f9716d088424b5602a6c5c3a7d3f4997 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Thu, 16 Oct 2008 15:55:36 +0000 Subject: [PATCH] Introduce BMessage::CompareData() which is a Haiku API extension. It compares the data of two BMessages and allows recursive comparison (BMessage inside BMessage). Note that using this API might require you to recompile your app in the path to R1. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28174 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/app/Message.h | 4 +++ src/kits/app/Message.cpp | 59 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/headers/os/app/Message.h b/headers/os/app/Message.h index dd272e12df..3b0feb073d 100644 --- a/headers/os/app/Message.h +++ b/headers/os/app/Message.h @@ -216,6 +216,10 @@ class BMessage { status_t ReplaceData(const char *name, type_code type, int32 index, const void *data, ssize_t numBytes); + // Compareing data (only) - Haiku experimental API + bool CompareData(const BMessage &other, + bool ignoreFieldOrder = true, bool deep = false) const; + void *operator new(size_t size); void *operator new(size_t, void *pointer); void operator delete(void *pointer, size_t size); diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index e5aa6397af..fe807d0556 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -220,6 +220,65 @@ BMessage::operator delete(void *pointer, size_t size) } +bool +BMessage::CompareData(const BMessage &other, bool ignoreFieldOrder, + bool deep) const +{ + if (this == &other) + return true; + + if (fHeader->field_count != other.fHeader->field_count) + return false; + + for (int32 i = 0; i < fHeader->field_count; i++) { + field_header *field = &fFields[i]; + field_header *otherField = NULL; + + const char *name = (const char *)fData + field->offset; + if (ignoreFieldOrder) { + if (other._FindField(name, B_ANY_TYPE, &otherField) != B_OK) + return false; + } else { + otherField = &other.fFields[i]; + if (otherField->name_length != field->name_length) + return false; + + const char *otherName = (const char *)other.fData + + otherField->offset; + if (strncmp(name, otherName, field->name_length) != 0) + return false; + } + + if (otherField->type != field->type || otherField->count != field->count) + return false; + + uint8 *data = fData + field->offset + field->name_length; + uint8 *otherData = other.fData + otherField->offset + + otherField->name_length; + + bool needsMemCompare = true; + if (deep && field->type == B_MESSAGE_TYPE) { + BMessage message, otherMessage; + if (message.Unflatten((const char *)data) == B_OK + && otherMessage.Unflatten((const char *)otherData) == B_OK) { + if (!message.CompareData(ignoreFieldOrder, deep)) + return false; + needsMemCompare = false; + } + } + + if (needsMemCompare) { + if (otherField->data_size != field->data_size) + return false; + if (memcmp(data, otherData, field->data_size) != 0) + return false; + } + } + + return true; +} + + status_t BMessage::_InitCommon(bool initHeader) {