* validate_instantiation() also needs to add the BPrivate namespace in case

it couldn't find the class on first try. This fixes the problems mentioned
  by Shinta as part of bug #2086.
* Got rid of GetNumber() - there is a POSIX function strtoul() for exactly
  this purpose.
* demangle_class_name() can now fail.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25179 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-04-26 14:28:16 +00:00
parent b735dc91eb
commit 13bbfe422b
+39 -45
View File
@@ -42,19 +42,7 @@ const int32 FUNC_NAME_LEN = 1024;
// of just NS::ClassName) // of just NS::ClassName)
static int static status_t
GetNumber(const char*& name)
{
int val = atoi(name);
while (isdigit(*name)) {
++name;
}
return val;
}
static void
demangle_class_name(const char* name, BString& out) demangle_class_name(const char* name, BString& out)
{ {
// TODO: add support for template classes // TODO: add support for template classes
@@ -62,40 +50,38 @@ demangle_class_name(const char* name, BString& out)
out = ""; out = "";
// Are we in a namespace? if (name[0] == 'Q') {
if (*name == 'Q') { // The name is in a namespace
// Yessir, we are; how many deep are we? int namespaceCount = 0;
int nsCount = 0; name++;
++name; if (name[0] == '_') {
if (*name == '_') { // more than 10 namespaces deep
// more than 10 deep if (!isdigit(*++name))
++name; return B_BAD_VALUE;
if (!isdigit(*name))
; // TODO: error handling
nsCount = GetNumber(name); namespaceCount = strtoul(name, (char**)&name, 10);
if (*name == '_') // more than 10 deep if (name[0] != '_')
++name; return B_BAD_VALUE;
else } else
; // this should be an error condition namespaceCount = name[0] - '0';
} else {
nsCount = *name - '0';
++name;
}
int nameLen = 0; name++;
for (int i = 0; i < nsCount - 1; ++i) {
if (!isdigit(*name))
; // TODO: error handling
nameLen = GetNumber(name); for (int i = 0; i < namespaceCount - 1; i++) {
out.Append(name, nameLen); if (!isdigit(name[0]))
return B_BAD_VALUE;
int nameLength = strtoul(name, (char**)&name, 10);
out.Append(name, nameLength);
out += "::"; out += "::";
name += nameLen; name += nameLength;
} }
} }
out.Append(name, GetNumber(name)); int nameLength = strtoul(name, (char**)&name, 10);
out.Append(name, nameLength);
return B_OK;
} }
@@ -240,7 +226,9 @@ BArchivable::Archive(BMessage* into, bool deep) const
} }
BString name; BString name;
demangle_class_name(typeid(*this).name(), name); status_t status = demangle_class_name(typeid(*this).name(), name);
if (status != B_OK)
return status;
return into->AddString(B_CLASS_FIELD, name); return into->AddString(B_CLASS_FIELD, name);
} }
@@ -393,13 +381,19 @@ validate_instantiation(BMessage* from, const char* className)
return false; return false;
} }
const char* data; BString name = className;
for (int32 index = 0; from->FindString(B_CLASS_FIELD, index, &data) == B_OK; for (int32 pass = 0; pass < 2; pass++) {
++index) { const char* archiveClassName;
if (!strcmp(data, className)) for (int32 index = 0; from->FindString(B_CLASS_FIELD, index,
&archiveClassName) == B_OK; ++index) {
if (name == archiveClassName)
return true; return true;
} }
if (!add_private_namespace(name))
break;
}
errno = B_MISMATCHED_VALUES; errno = B_MISMATCHED_VALUES;
syslog(LOG_ERR, "validate_instantiation failed on class %s.", className); syslog(LOG_ERR, "validate_instantiation failed on class %s.", className);