[haiku-commits] r42365 - haiku/trunk/src/apps/debugger/value/value_nodes

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 2 Jul 2011 22:11:55 +0200 (CEST)

Author: anevilyak
Date: 2011-07-02 22:11:54 +0200 (Sat, 02 Jul 2011)
New Revision: 42365
Changeset: https://dev.haiku-os.org/changeset/42365

Modified:
   haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp
   haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.h
Log:
* Restructure things a bit so we store the message's message and field headers
  after resolving them. This allows us to reuse BMessage's logic for computing
  the offsets of values in the data buffer.
* Resolve fields to their types and correctly resolve the locations of their
  data. This means we can now see the values of fields inside the message, with
  some caveats: string types aren't yet handled properly, and we don't yet
  properly deal with fields that have multiple indices.



Modified: haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp       
2011-07-02 16:01:54 UTC (rev 42364)
+++ haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp       
2011-07-02 20:11:54 UTC (rev 42365)
@@ -15,6 +15,7 @@
 #include "StringValue.h"
 #include "Tracing.h"
 #include "Type.h"
+#include "TypeLookupConstraints.h"
 #include "ValueLoader.h"
 #include "ValueLocation.h"
 #include "ValueNodeContainer.h"
@@ -92,7 +93,10 @@
        ValueNode(nodeChild),
        fType(type),
        fMessageType(NULL),
-       fMessage()
+       fLoader(NULL),
+       fHeader(NULL),
+       fFields(NULL),
+       fData(NULL)
 {
        fType->AcquireReference();
 }
@@ -103,6 +107,11 @@
        fType->ReleaseReference();
        for (int32 i = 0; i < fChildren.CountItems(); i++)
                fChildren.ItemAt(i)->ReleaseReference();
+
+       delete fLoader;
+       delete fHeader;
+       delete[] fFields;
+       delete[] fData;
 }
 
 
@@ -162,7 +171,6 @@
 
        BVariant headerAddress;
        BVariant fieldAddress;
-       BVariant dataAddress;
        BVariant what;
 
        for (int32 i = 0; i < baseType->CountDataMembers(); i++) {
@@ -224,7 +232,7 @@
                                return error;
                        }
                        error = valueLoader->LoadValue(memberLocation, 
valueType,
-                               false, dataAddress);
+                               false, fDataLocation);
                        delete memberLocation;
                        if (error != B_OK)
                                return error;
@@ -235,61 +243,66 @@
        TRACE_LOCALS("BMessage: what: 0x%" B_PRIx32 ", result: %ld\n",
                what.ToUInt32(), error);
 
-       uint8 headerBuffer[sizeof(BMessage::message_header)];
-       error = valueLoader->LoadRawValue(headerAddress, sizeof(headerBuffer),
-               headerBuffer);
+
+       fHeader = new(std::nothrow) BMessage::message_header();
+       if (fHeader == NULL)
+               return B_NO_MEMORY;
+       error = valueLoader->LoadRawValue(headerAddress, sizeof(
+               BMessage::message_header), fHeader);
        TRACE_LOCALS("BMessage: Header Address: 0x%" B_PRIx64 ", result: %ld\n",
                headerAddress.ToUInt64(), error);
        if (error != B_OK)
                return error;
+       fHeader->what = what.ToUInt32();
 
-       BMessage::message_header* header = 
(BMessage::message_header*)headerBuffer;
-       header->what = what.ToUInt32();
-       size_t fieldsSize = header->field_count * 
sizeof(BMessage::field_header);
-       size_t totalMessageSize = sizeof(BMessage::message_header)
-               + fieldsSize + header->data_size;
-
-       uint8* messageBuffer = new(std::nothrow)uint8[totalMessageSize];
+       size_t fieldsSize = fHeader->field_count * sizeof(
+               BMessage::field_header);
+       size_t totalSize = sizeof(BMessage::message_header) + fieldsSize + 
fHeader->data_size;
+       uint8* messageBuffer = new(std::nothrow) uint8[totalSize];
        if (messageBuffer == NULL)
                return B_NO_MEMORY;
+       memset(messageBuffer, 0, totalSize);
+       memcpy(messageBuffer, fHeader, sizeof(BMessage::message_header));
+       uint8* tempBuffer = messageBuffer + sizeof(BMessage::message_header);
+       if (fieldsSize > 0) {
+               fFields = new(std::nothrow)
+                       BMessage::field_header[fHeader->field_count];
+               if (fFields == NULL)
+                       return B_NO_MEMORY;
 
-       memset(messageBuffer, 0, totalMessageSize);
-
-       ArrayDeleter<uint8> deleter(messageBuffer);
-
-       // This more or less follows the logic of BMessage::Flatten
-       // in order to reconstruct the flattened buffer ; thus if the
-       // internal representation of that changes, this will have to
-       // follow suit
-       uint8* currentBuffer = messageBuffer;
-       memcpy(currentBuffer, header,
-               sizeof(BMessage::message_header));
-
-       if (fieldsSize > 0) {
-               currentBuffer += sizeof(BMessage::message_header);
                error = valueLoader->LoadRawValue(fieldAddress, fieldsSize,
-                       currentBuffer);
+                       fFields);
                TRACE_LOCALS("BMessage: Field Header Address: 0x%" B_PRIx64
                        ", result: %ld\n",      headerAddress.ToUInt64(), 
error);
                if (error != B_OK)
                        return error;
 
-               headerAddress.SetTo(dataAddress);
-               currentBuffer += fieldsSize;
-               error = valueLoader->LoadRawValue(dataAddress, 
header->data_size,
-                       currentBuffer);
-               TRACE_LOCALS("BMessage: Data Address: 0x%" B_PRIx64 ", result: 
%ld\n",
-                       headerAddress.ToUInt64(), error);
+               fData = new(std::nothrow) uint8[fHeader->data_size];
+               if (fData == NULL)
+                       return B_NO_MEMORY;
+
+               error = valueLoader->LoadRawValue(fDataLocation, 
fHeader->data_size,
+                       fData);
+               TRACE_LOCALS("BMessage: Data Address: 0x%" B_PRIx64
+                       ", result: %ld\n",      fDataLocation.ToUInt64(), 
error);
                if (error != B_OK)
-                       return B_ERROR;
+                       return error;
+               memcpy(tempBuffer, fFields, fieldsSize);
+               tempBuffer += fieldsSize;
+               memcpy(tempBuffer, fData, fHeader->data_size);
        }
 
-       error = fMessage.Unflatten((const char *)messageBuffer);
-       TRACE_LOCALS("BMessage: Unflatten result: %s\n", strerror(error));
-
+       error = fMessage.Unflatten((const char*)messageBuffer);
+       delete[] messageBuffer;
        if (error != B_OK)
                return error;
 
+       if (fLoader == NULL) {
+               fLoader = new(std::nothrow)ValueLoader(*valueLoader);
+               if (fLoader == NULL)
+                       return B_NO_MEMORY;
+       }
+
        return B_OK;
 }
 
@@ -303,7 +316,6 @@
        if (fMessageType == NULL)
                return B_BAD_VALUE;
 
-
        DataMember* member = NULL;
        Type* whatType = NULL;
 
@@ -326,13 +338,16 @@
        char* name;
        type_code type;
        int32 count;
-       for (int32 i = 0;
-                       fMessage.GetInfo(B_ANY_TYPE, i, &name, &type, &count) 
== B_OK;
-                       i++) {
-               // TODO: split FieldHeaderNode into two variants in order to
-               // present fields with a count of 1 without subindices.
+       Type* fieldType = NULL;
+       for (int32 i = 0; fMessage.GetInfo(B_ANY_TYPE, i, &name, &type,
+               &count) == B_OK; i++) {
+               fieldType = NULL;
+
+               _GetTypeForTypeCode(type, fieldType);
+
                BMessageFieldNodeChild* node = new(std::nothrow)
-                       BMessageFieldNodeChild(this, name, type, count);
+                       BMessageFieldNodeChild(this, fieldType != NULL ? 
fieldType : fType,
+                       name, type, count);
                if (node == NULL)
                        return B_NO_MEMORY;
 
@@ -361,15 +376,220 @@
 }
 
 
+status_t
+BMessageValueNode::_GetTypeForTypeCode(type_code type,
+       Type*& _type)
+{
+       BString typeName;
+       TypeLookupConstraints constraints;
+
+       switch(type) {
+               case B_BOOL_TYPE:
+                       typeName = "bool";
+                       constraints.SetTypeKind(TYPE_PRIMITIVE);
+                       break;
+
+               case B_INT8_TYPE:
+                       typeName = "int8";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_UINT8_TYPE:
+                       typeName = "uint8";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_INT16_TYPE:
+                       typeName = "int16";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_UINT16_TYPE:
+                       typeName = "uint16";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_INT32_TYPE:
+                       typeName = "int32";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_UINT32_TYPE:
+                       typeName = "uint32";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_INT64_TYPE:
+                       typeName = "int64";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_UINT64_TYPE:
+                       typeName = "uint64";
+                       constraints.SetTypeKind(TYPE_TYPEDEF);
+                       break;
+
+               case B_FLOAT_TYPE:
+                       typeName = "float";
+                       constraints.SetTypeKind(TYPE_PRIMITIVE);
+                       break;
+
+               case B_DOUBLE_TYPE:
+                       typeName = "double";
+                       constraints.SetTypeKind(TYPE_PRIMITIVE);
+                       break;
+
+               case B_MESSAGE_TYPE:
+                       typeName = "BMessage";
+                       constraints.SetTypeKind(TYPE_COMPOUND);
+                       break;
+
+               case B_MESSENGER_TYPE:
+                       typeName = "BMessenger";
+                       constraints.SetTypeKind(TYPE_COMPOUND);
+                       break;
+
+               case B_POINT_TYPE:
+                       typeName = "BPoint";
+                       constraints.SetTypeKind(TYPE_COMPOUND);
+                       break;
+
+               case B_POINTER_TYPE:
+                       typeName = "void";
+                       constraints.SetTypeKind(TYPE_ADDRESS);
+                       break;
+
+               case B_RECT_TYPE:
+                       typeName = "BRect";
+                       constraints.SetTypeKind(TYPE_COMPOUND);
+                       break;
+
+               case B_REF_TYPE:
+                       typeName = "entry_ref";
+                       constraints.SetTypeKind(TYPE_COMPOUND);
+                       break;
+
+               case B_RGB_COLOR_TYPE:
+                       typeName = "rgb_color";
+                       constraints.SetTypeKind(TYPE_COMPOUND);
+                       break;
+
+               case B_STRING_TYPE:
+                       typeName = "char";
+                       constraints.SetTypeKind(TYPE_ARRAY);
+                       break;
+
+               default:
+                       return B_BAD_VALUE;
+                       break;
+       }
+
+       return fLoader->LookupTypeByName(typeName, constraints, _type);
+}
+
+
+status_t
+BMessageValueNode::_FindField(const char* name, type_code type,
+       BMessage::field_header** result) const
+{
+       if (name == NULL)
+               return B_BAD_VALUE;
+
+       if (fHeader == NULL)
+               return B_NO_INIT;
+
+       if (fHeader->field_count == 0 || fFields == NULL || fData == NULL)
+               return B_NAME_NOT_FOUND;
+
+       uint32 hash = _HashName(name) % fHeader->hash_table_size;
+       int32 nextField = fHeader->hash_table[hash];
+
+       while (nextField >= 0) {
+               BMessage::field_header* field = &fFields[nextField];
+               if ((field->flags & FIELD_FLAG_VALID) == 0)
+                       break;
+
+               if (strncmp((const char*)(fData + field->offset), name,
+                       field->name_length) == 0) {
+                       if (type != B_ANY_TYPE && field->type != type)
+                               return B_BAD_TYPE;
+
+                       *result = field;
+                       return B_OK;
+               }
+
+               nextField = field->next_field;
+       }
+
+       return B_NAME_NOT_FOUND;
+}
+
+
+uint32
+BMessageValueNode::_HashName(const char* name) const
+{
+       char ch;
+       uint32 result = 0;
+
+       while ((ch = *name++) != 0) {
+               result = (result << 7) ^ (result >> 24);
+               result ^= ch;
+       }
+
+       result ^= result << 12;
+       return result;
+}
+
+
+status_t
+BMessageValueNode::_FindDataLocation(const char* name, type_code type,
+       int32 index, ValueLocation& location) const
+{
+       BMessage::field_header* field = NULL;
+       int32 offset = 0;
+       int32 size = 0;
+       status_t result = _FindField(name, type, &field);
+       if (result != B_OK)
+               return result;
+
+       if (index < 0 || (uint32)index >= field->count)
+               return B_BAD_INDEX;
+
+       if ((field->flags & FIELD_FLAG_FIXED_SIZE) != 0) {
+               size = field->data_size / field->count;
+               offset = field->offset + field->name_length + index * size;
+       } else {
+               offset = field->offset + field->name_length;
+               uint8 *pointer = fData + field->offset + field->name_length;
+               for (int32 i = 0; i < index; i++) {
+                       pointer += *(uint32*)pointer + sizeof(uint32);
+                       offset += *(uint32*)pointer + sizeof(uint32);
+               }
+
+               size = *(uint32*)pointer;
+               offset += sizeof(uint32);
+       }
+
+       ValuePieceLocation piece;
+       piece.SetToMemory(fDataLocation.ToUInt64() + offset);
+       piece.SetSize(size);
+       location.Clear();
+       location.AddPiece(piece);
+
+       return B_OK;
+}
+
+
 // #pragma mark - BMessageValueNode::BMessageFieldNode
 
+
 BMessageValueNode::BMessageFieldNode::BMessageFieldNode(
        BMessageFieldNodeChild *child, BMessageValueNode* parent,
        const BString &name, type_code type, int32 count)
        :
        ValueNode(child),
        fName(name),
-       fType(parent->GetType()),
+       fType(parent->fMessageType),
        fParent(parent),
        fFieldType(type),
        fFieldCount(count)
@@ -428,12 +648,12 @@
 
 
 BMessageValueNode::BMessageFieldNodeChild::BMessageFieldNodeChild(
-       BMessageValueNode* parent, const BString &name, type_code type,
-       int32 count)
+       BMessageValueNode* parent, Type* nodeType, const BString &name,
+       type_code type, int32 count)
        :
        ValueNodeChild(),
        fName(name),
-       fType(parent->GetType()),
+       fType(nodeType),
        fParent(parent),
        fFieldType(type),
        fFieldCount(count)
@@ -474,7 +694,7 @@
 bool
 BMessageValueNode::BMessageFieldNodeChild::IsInternal() const
 {
-       return true;
+       return fFieldCount > 1;
 }
 
 
@@ -496,7 +716,10 @@
 BMessageValueNode::BMessageFieldNodeChild::ResolveLocation(
        ValueLoader* valueLoader, ValueLocation*& _location)
 {
-       _location = fParent->Location();
+       _location = new(std::nothrow)ValueLocation();
 
-       return B_OK;
+       if (_location == NULL)
+               return B_NO_MEMORY;
+
+       return fParent->_FindDataLocation(fName, fFieldType, 0, *_location);
 }

Modified: haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.h
===================================================================
--- haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.h 
2011-07-02 16:01:54 UTC (rev 42364)
+++ haiku/trunk/src/apps/debugger/value/value_nodes/BMessageValueNode.h 
2011-07-02 20:11:54 UTC (rev 42365)
@@ -6,8 +6,11 @@
 #define BMESSAGE_VALUE_NODE_H
 
 #include <Message.h>
+#include <MessagePrivate.h>
 #include <ObjectList.h>
+#include <Variant.h>
 
+#include "ValueLocation.h"
 #include "ValueNode.h"
 
 
@@ -36,6 +39,17 @@
                                                                                
{ return fMessageType; }
 
 private:
+                       status_t                                
_GetTypeForTypeCode(type_code type,
+                                                                               
Type*& _type);
+                       status_t                                
_FindField(const char* name,
+                                                                               
type_code type,
+                                                                               
BMessage::field_header** result) const;
+                       uint32                                  _HashName(const 
char* name) const;
+                       status_t                                
_FindDataLocation(const char* name,
+                                                                               
type_code type, int32 index,
+                                                                               
ValueLocation& location) const;
+
+private:
                        class BMessageFieldNode;
                        class BMessageFieldNodeChild;
 
@@ -48,8 +62,14 @@
 private:
                        Type*                                   fType;
                        CompoundType*                   fMessageType;
+                       ChildNodeList                   fChildren;
+                       ValueLoader*                    fLoader;
+                       BVariant                                fDataLocation;
+                       BMessage::message_header*
+                                                                       fHeader;
+                       BMessage::field_header* fFields;
+                       uint8*                                  fData;
                        BMessage                                fMessage;
-                       ChildNodeList                   fChildren;
 };
 
 
@@ -65,15 +85,15 @@
 
        virtual Type*                                   GetType() const;
 
-       virtual status_t                                CreateChildren();
-       virtual int32                                   CountChildren() const;
-       virtual ValueNodeChild*                 ChildAt(int32 index) const;
-
        virtual status_t                                
ResolvedLocationAndValue(
                                                                                
ValueLoader* loader,
                                                                                
ValueLocation *& _location,
                                                                                
Value*& _value);
 
+       virtual status_t                                CreateChildren();
+       virtual int32                                   CountChildren() const;
+       virtual ValueNodeChild*                 ChildAt(int32 index) const;
+
 private:
                        BString                                 fName;
                        Type*                                   fType;
@@ -87,6 +107,7 @@
 public:
                                                                        
BMessageFieldNodeChild(
                                                                                
BMessageValueNode* parent,
+                                                                               
Type* nodeType,
                                                                                
const BString &name,
                                                                                
type_code type, int32 count);
 


Other related posts:

  • » [haiku-commits] r42365 - haiku/trunk/src/apps/debugger/value/value_nodes - anevilyak