19ecf9d1cSIngo Weinhold /* 2*89eb861aSAxel Dörfler * Copyright (c) 2001-2008, Haiku, Inc. 39ecf9d1cSIngo Weinhold * Distributed under the terms of the MIT License. 49ecf9d1cSIngo Weinhold * 59ecf9d1cSIngo Weinhold * Authors: 69ecf9d1cSIngo Weinhold * Erik Jaesler (erik@cgsoftware.com) 79ecf9d1cSIngo Weinhold */ 852a38012Sejakowatz 97bc5a06bSAxel Dörfler /*! BArchivable mix-in class defines the archiving protocol. 107bc5a06bSAxel Dörfler Also some global archiving functions. 117bc5a06bSAxel Dörfler */ 129ecf9d1cSIngo Weinhold 139ecf9d1cSIngo Weinhold 1452a38012Sejakowatz #include <ctype.h> 1552a38012Sejakowatz #include <errno.h> 1652a38012Sejakowatz #include <stdlib.h> 1752a38012Sejakowatz #include <stdio.h> 1852a38012Sejakowatz #include <string> 197bc5a06bSAxel Dörfler #include <syslog.h> 2052a38012Sejakowatz #include <typeinfo> 2152a38012Sejakowatz #include <vector> 2252a38012Sejakowatz 2352a38012Sejakowatz #include <AppFileInfo.h> 2452a38012Sejakowatz #include <Archivable.h> 2552a38012Sejakowatz #include <Entry.h> 2652a38012Sejakowatz #include <List.h> 2752a38012Sejakowatz #include <OS.h> 2852a38012Sejakowatz #include <Path.h> 2952a38012Sejakowatz #include <Roster.h> 3052a38012Sejakowatz #include <String.h> 3152a38012Sejakowatz 3252a38012Sejakowatz 3352a38012Sejakowatz using std::string; 3452a38012Sejakowatz using std::vector; 3552a38012Sejakowatz 3652a38012Sejakowatz const char* B_CLASS_FIELD = "class"; 3752a38012Sejakowatz const char* B_ADD_ON_FIELD = "add_on"; 3852a38012Sejakowatz const int32 FUNC_NAME_LEN = 1024; 3952a38012Sejakowatz 407bc5a06bSAxel Dörfler // TODO: consider moving these to a separate module, and making them more 417bc5a06bSAxel Dörfler // full-featured (e.g., taking NS::ClassName::Function(Param p) instead 427bc5a06bSAxel Dörfler // of just NS::ClassName) 4352a38012Sejakowatz 449ecf9d1cSIngo Weinhold 45*89eb861aSAxel Dörfler static int 469ecf9d1cSIngo Weinhold GetNumber(const char*& name) 4752a38012Sejakowatz { 4852a38012Sejakowatz int val = atoi(name); 499ecf9d1cSIngo Weinhold while (isdigit(*name)) { 5052a38012Sejakowatz ++name; 5152a38012Sejakowatz } 5252a38012Sejakowatz 5352a38012Sejakowatz return val; 5452a38012Sejakowatz } 559ecf9d1cSIngo Weinhold 569ecf9d1cSIngo Weinhold 57*89eb861aSAxel Dörfler static void 58*89eb861aSAxel Dörfler demangle_class_name(const char* name, BString& out) 5952a38012Sejakowatz { 6052a38012Sejakowatz // TODO: add support for template classes 6152a38012Sejakowatz // _find__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCccUlUl 6252a38012Sejakowatz 6352a38012Sejakowatz out = ""; 6452a38012Sejakowatz 6552a38012Sejakowatz // Are we in a namespace? 669ecf9d1cSIngo Weinhold if (*name == 'Q') { 6752a38012Sejakowatz // Yessir, we are; how many deep are we? 6852a38012Sejakowatz int nsCount = 0; 6952a38012Sejakowatz ++name; 709ecf9d1cSIngo Weinhold if (*name == '_') { 719ecf9d1cSIngo Weinhold // more than 10 deep 7252a38012Sejakowatz ++name; 7352a38012Sejakowatz if (!isdigit(*name)) 7452a38012Sejakowatz ; // TODO: error handling 7552a38012Sejakowatz 7652a38012Sejakowatz nsCount = GetNumber(name); 7752a38012Sejakowatz if (*name == '_') // more than 10 deep 7852a38012Sejakowatz ++name; 7952a38012Sejakowatz else 8052a38012Sejakowatz ; // this should be an error condition 819ecf9d1cSIngo Weinhold } else { 8252a38012Sejakowatz nsCount = *name - '0'; 8352a38012Sejakowatz ++name; 8452a38012Sejakowatz } 8552a38012Sejakowatz 8652a38012Sejakowatz int nameLen = 0; 879ecf9d1cSIngo Weinhold for (int i = 0; i < nsCount - 1; ++i) { 8852a38012Sejakowatz if (!isdigit(*name)) 8952a38012Sejakowatz ; // TODO: error handling 9052a38012Sejakowatz 9152a38012Sejakowatz nameLen = GetNumber(name); 9252a38012Sejakowatz out.Append(name, nameLen); 9352a38012Sejakowatz out += "::"; 9452a38012Sejakowatz name += nameLen; 9552a38012Sejakowatz } 9652a38012Sejakowatz } 9752a38012Sejakowatz 9852a38012Sejakowatz out.Append(name, GetNumber(name)); 9952a38012Sejakowatz } 1009ecf9d1cSIngo Weinhold 1019ecf9d1cSIngo Weinhold 102*89eb861aSAxel Dörfler static void 103*89eb861aSAxel Dörfler mangle_class_name(const char* name, BString& out) 10452a38012Sejakowatz { 10552a38012Sejakowatz // TODO: add support for template classes 10652a38012Sejakowatz // _find__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCccUlUl 10752a38012Sejakowatz 10852a38012Sejakowatz // Chop this: 10952a38012Sejakowatz // testthree::testfour::Testthree::Testfour 11052a38012Sejakowatz // up into little bite-sized pieces 11152a38012Sejakowatz int count = 0; 11252a38012Sejakowatz string origName(name); 11352a38012Sejakowatz vector<string> spacenames; 11452a38012Sejakowatz 11552a38012Sejakowatz string::size_type pos = 0; 11652a38012Sejakowatz string::size_type oldpos = 0; 1179ecf9d1cSIngo Weinhold while (pos != string::npos) { 11852a38012Sejakowatz pos = origName.find_first_of("::", oldpos); 11952a38012Sejakowatz spacenames.push_back(string(origName, oldpos, pos - oldpos)); 12052a38012Sejakowatz pos = origName.find_first_not_of("::", pos); 12152a38012Sejakowatz oldpos = pos; 12252a38012Sejakowatz ++count; 12352a38012Sejakowatz } 12452a38012Sejakowatz 12552a38012Sejakowatz // Now mangle it into this: 12652a38012Sejakowatz // Q49testthree8testfour9Testthree8Testfour 12752a38012Sejakowatz out = ""; 1289ecf9d1cSIngo Weinhold if (count > 1) { 12952a38012Sejakowatz out += 'Q'; 13052a38012Sejakowatz if (count > 10) 13152a38012Sejakowatz out += '_'; 13252a38012Sejakowatz out << count; 13352a38012Sejakowatz if (count > 10) 13452a38012Sejakowatz out += '_'; 13552a38012Sejakowatz } 13652a38012Sejakowatz 1379ecf9d1cSIngo Weinhold for (unsigned int i = 0; i < spacenames.size(); ++i) { 13852a38012Sejakowatz out << (int)spacenames[i].length(); 13952a38012Sejakowatz out += spacenames[i].c_str(); 14052a38012Sejakowatz } 14152a38012Sejakowatz } 1429ecf9d1cSIngo Weinhold 1439ecf9d1cSIngo Weinhold 144*89eb861aSAxel Dörfler static void 145*89eb861aSAxel Dörfler build_function_name(const BString& className, BString& funcName) 14652a38012Sejakowatz { 147*89eb861aSAxel Dörfler funcName = ""; 14852a38012Sejakowatz 149*89eb861aSAxel Dörfler // This is what we're after: 150*89eb861aSAxel Dörfler // Instantiate__Q28OpenBeOS11BArchivableP8BMessage 151*89eb861aSAxel Dörfler mangle_class_name(className.String(), funcName); 152*89eb861aSAxel Dörfler #if __GNUC__ >= 4 153*89eb861aSAxel Dörfler funcName.Prepend("_ZN"); 154*89eb861aSAxel Dörfler funcName.Append("11InstantiateE"); 155*89eb861aSAxel Dörfler #else 156*89eb861aSAxel Dörfler funcName.Prepend("Instantiate__"); 15752a38012Sejakowatz #endif 158*89eb861aSAxel Dörfler funcName.Append("P8BMessage"); 15952a38012Sejakowatz } 16052a38012Sejakowatz 161*89eb861aSAxel Dörfler 162*89eb861aSAxel Dörfler static bool 163*89eb861aSAxel Dörfler add_private_namespace(BString& name) 164*89eb861aSAxel Dörfler { 165*89eb861aSAxel Dörfler if (name.Compare("_", 1) != 0) 166*89eb861aSAxel Dörfler return false; 167*89eb861aSAxel Dörfler 168*89eb861aSAxel Dörfler name.Prepend("BPrivate::"); 169*89eb861aSAxel Dörfler return true; 170*89eb861aSAxel Dörfler } 171*89eb861aSAxel Dörfler 172*89eb861aSAxel Dörfler 173*89eb861aSAxel Dörfler static instantiation_func 174*89eb861aSAxel Dörfler find_function_in_image(BString& funcName, image_id id, status_t& err) 175*89eb861aSAxel Dörfler { 176*89eb861aSAxel Dörfler instantiation_func instantiationFunc = NULL; 177*89eb861aSAxel Dörfler err = get_image_symbol(id, funcName.String(), B_SYMBOL_TYPE_TEXT, 178*89eb861aSAxel Dörfler (void**)&instantiationFunc); 179*89eb861aSAxel Dörfler if (err != B_OK) 180*89eb861aSAxel Dörfler return NULL; 181*89eb861aSAxel Dörfler 182*89eb861aSAxel Dörfler return instantiationFunc; 183*89eb861aSAxel Dörfler } 184*89eb861aSAxel Dörfler 185*89eb861aSAxel Dörfler 186*89eb861aSAxel Dörfler static status_t 187*89eb861aSAxel Dörfler check_signature(const char* signature, image_info& info) 188*89eb861aSAxel Dörfler { 189*89eb861aSAxel Dörfler if (signature == NULL) { 190*89eb861aSAxel Dörfler // If it wasn't specified, anything "matches" 191*89eb861aSAxel Dörfler return B_OK; 192*89eb861aSAxel Dörfler } 193*89eb861aSAxel Dörfler 194*89eb861aSAxel Dörfler // Get image signature 195*89eb861aSAxel Dörfler BFile file(info.name, B_READ_ONLY); 196*89eb861aSAxel Dörfler status_t err = file.InitCheck(); 197*89eb861aSAxel Dörfler if (err != B_OK) 198*89eb861aSAxel Dörfler return err; 199*89eb861aSAxel Dörfler 200*89eb861aSAxel Dörfler char imageSignature[B_MIME_TYPE_LENGTH]; 201*89eb861aSAxel Dörfler BAppFileInfo appFileInfo(&file); 202*89eb861aSAxel Dörfler err = appFileInfo.GetSignature(imageSignature); 203*89eb861aSAxel Dörfler if (err != B_OK) { 204*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object - couldn't get mime sig for %s", 205*89eb861aSAxel Dörfler info.name); 206*89eb861aSAxel Dörfler return err; 207*89eb861aSAxel Dörfler } 208*89eb861aSAxel Dörfler 209*89eb861aSAxel Dörfler if (strcmp(signature, imageSignature)) 210*89eb861aSAxel Dörfler return B_MISMATCHED_VALUES; 211*89eb861aSAxel Dörfler 212*89eb861aSAxel Dörfler return B_OK; 213*89eb861aSAxel Dörfler } 214*89eb861aSAxel Dörfler 215*89eb861aSAxel Dörfler 216*89eb861aSAxel Dörfler // #pragma mark - 217*89eb861aSAxel Dörfler 218*89eb861aSAxel Dörfler 219*89eb861aSAxel Dörfler BArchivable::BArchivable() 220*89eb861aSAxel Dörfler { 221*89eb861aSAxel Dörfler } 222*89eb861aSAxel Dörfler 223*89eb861aSAxel Dörfler 224*89eb861aSAxel Dörfler BArchivable::BArchivable(BMessage* from) 225*89eb861aSAxel Dörfler { 226*89eb861aSAxel Dörfler } 227*89eb861aSAxel Dörfler 228*89eb861aSAxel Dörfler 229*89eb861aSAxel Dörfler BArchivable::~BArchivable() 230*89eb861aSAxel Dörfler { 231*89eb861aSAxel Dörfler } 232*89eb861aSAxel Dörfler 233*89eb861aSAxel Dörfler 234*89eb861aSAxel Dörfler status_t 235*89eb861aSAxel Dörfler BArchivable::Archive(BMessage* into, bool deep) const 236*89eb861aSAxel Dörfler { 237*89eb861aSAxel Dörfler if (!into) { 238*89eb861aSAxel Dörfler // TODO: logging/other error reporting? 239*89eb861aSAxel Dörfler return B_BAD_VALUE; 240*89eb861aSAxel Dörfler } 241*89eb861aSAxel Dörfler 242*89eb861aSAxel Dörfler BString name; 243*89eb861aSAxel Dörfler demangle_class_name(typeid(*this).name(), name); 244*89eb861aSAxel Dörfler 245*89eb861aSAxel Dörfler return into->AddString(B_CLASS_FIELD, name); 246*89eb861aSAxel Dörfler } 247*89eb861aSAxel Dörfler 248*89eb861aSAxel Dörfler 249*89eb861aSAxel Dörfler BArchivable* 250*89eb861aSAxel Dörfler BArchivable::Instantiate(BMessage* from) 251*89eb861aSAxel Dörfler { 252*89eb861aSAxel Dörfler debugger("Can't create a plain BArchivable object"); 253*89eb861aSAxel Dörfler return NULL; 254*89eb861aSAxel Dörfler } 255*89eb861aSAxel Dörfler 256*89eb861aSAxel Dörfler 257*89eb861aSAxel Dörfler status_t 258*89eb861aSAxel Dörfler BArchivable::Perform(perform_code d, void* arg) 259*89eb861aSAxel Dörfler { 260*89eb861aSAxel Dörfler // TODO: Check against original 261*89eb861aSAxel Dörfler return B_ERROR; 262*89eb861aSAxel Dörfler } 263*89eb861aSAxel Dörfler 264*89eb861aSAxel Dörfler 265*89eb861aSAxel Dörfler void BArchivable::_ReservedArchivable1() {} 266*89eb861aSAxel Dörfler void BArchivable::_ReservedArchivable2() {} 267*89eb861aSAxel Dörfler void BArchivable::_ReservedArchivable3() {} 268*89eb861aSAxel Dörfler 269*89eb861aSAxel Dörfler 270*89eb861aSAxel Dörfler // #pragma mark - 271*89eb861aSAxel Dörfler 272*89eb861aSAxel Dörfler 273*89eb861aSAxel Dörfler BArchivable* 274*89eb861aSAxel Dörfler instantiate_object(BMessage* archive, image_id* _id) 275*89eb861aSAxel Dörfler { 276*89eb861aSAxel Dörfler status_t statusBuffer; 277*89eb861aSAxel Dörfler status_t* status = &statusBuffer; 278*89eb861aSAxel Dörfler if (_id != NULL) 279*89eb861aSAxel Dörfler status = _id; 280*89eb861aSAxel Dörfler 281*89eb861aSAxel Dörfler // Check our params 282*89eb861aSAxel Dörfler if (archive == NULL) { 283*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: NULL BMessage argument"); 284*89eb861aSAxel Dörfler *status = B_BAD_VALUE; 285*89eb861aSAxel Dörfler return NULL; 286*89eb861aSAxel Dörfler } 287*89eb861aSAxel Dörfler 288*89eb861aSAxel Dörfler // Get class name from archive 289*89eb861aSAxel Dörfler const char* className = NULL; 290*89eb861aSAxel Dörfler status_t err = archive->FindString(B_CLASS_FIELD, &className); 291*89eb861aSAxel Dörfler if (err) { 292*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Failed to find an entry " 293*89eb861aSAxel Dörfler "defining the class name (%s).", strerror(err)); 294*89eb861aSAxel Dörfler *status = B_BAD_VALUE; 295*89eb861aSAxel Dörfler return NULL; 296*89eb861aSAxel Dörfler } 297*89eb861aSAxel Dörfler 298*89eb861aSAxel Dörfler // Get sig from archive 299*89eb861aSAxel Dörfler const char* signature = NULL; 300*89eb861aSAxel Dörfler bool hasSignature = archive->FindString(B_ADD_ON_FIELD, &signature) == B_OK; 301*89eb861aSAxel Dörfler 302*89eb861aSAxel Dörfler instantiation_func instantiationFunc = find_instantiation_func(className, 303*89eb861aSAxel Dörfler signature); 304*89eb861aSAxel Dörfler 305*89eb861aSAxel Dörfler // if find_instantiation_func() can't locate Class::Instantiate() 306*89eb861aSAxel Dörfler // and a signature was specified 307*89eb861aSAxel Dörfler if (!instantiationFunc && hasSignature) { 308*89eb861aSAxel Dörfler // use BRoster::FindApp() to locate an app or add-on with the symbol 309*89eb861aSAxel Dörfler BRoster Roster; 310*89eb861aSAxel Dörfler entry_ref ref; 311*89eb861aSAxel Dörfler err = Roster.FindApp(signature, &ref); 312*89eb861aSAxel Dörfler 313*89eb861aSAxel Dörfler // if an entry_ref is obtained 314*89eb861aSAxel Dörfler BEntry entry; 315*89eb861aSAxel Dörfler if (err == B_OK) 316*89eb861aSAxel Dörfler err = entry.SetTo(&ref); 317*89eb861aSAxel Dörfler 318*89eb861aSAxel Dörfler BPath path; 319*89eb861aSAxel Dörfler if (err == B_OK) 320*89eb861aSAxel Dörfler err = entry.GetPath(&path); 321*89eb861aSAxel Dörfler 322*89eb861aSAxel Dörfler if (err != B_OK) { 323*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Error finding app " 324*89eb861aSAxel Dörfler "with signature \"%s\" (%s)", signature, strerror(err)); 325*89eb861aSAxel Dörfler *status = err; 326*89eb861aSAxel Dörfler return NULL; 327*89eb861aSAxel Dörfler } 328*89eb861aSAxel Dörfler 329*89eb861aSAxel Dörfler // load the app/add-on 330*89eb861aSAxel Dörfler image_id addOn = load_add_on(path.Path()); 331*89eb861aSAxel Dörfler if (addOn < B_OK) { 332*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Could not load " 333*89eb861aSAxel Dörfler "add-on %s: %s.", path.Path(), strerror(addOn)); 334*89eb861aSAxel Dörfler *status = addOn; 335*89eb861aSAxel Dörfler return NULL; 336*89eb861aSAxel Dörfler } 337*89eb861aSAxel Dörfler 338*89eb861aSAxel Dörfler // Save the image_id 339*89eb861aSAxel Dörfler if (_id != NULL) 340*89eb861aSAxel Dörfler *_id = addOn; 341*89eb861aSAxel Dörfler 342*89eb861aSAxel Dörfler BString name = className; 343*89eb861aSAxel Dörfler for (int32 pass = 0; pass < 2; pass++) { 344*89eb861aSAxel Dörfler BString funcName; 345*89eb861aSAxel Dörfler build_function_name(name, funcName); 346*89eb861aSAxel Dörfler 347*89eb861aSAxel Dörfler instantiationFunc = find_function_in_image(funcName, addOn, err); 348*89eb861aSAxel Dörfler if (instantiationFunc != NULL) 349*89eb861aSAxel Dörfler break; 350*89eb861aSAxel Dörfler 351*89eb861aSAxel Dörfler // Check if we have a private class, and add the BPrivate namespace 352*89eb861aSAxel Dörfler // (for backwards compatibility) 353*89eb861aSAxel Dörfler if (!add_private_namespace(name)) 354*89eb861aSAxel Dörfler break; 355*89eb861aSAxel Dörfler } 356*89eb861aSAxel Dörfler 357*89eb861aSAxel Dörfler if (instantiationFunc == NULL) { 358*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Failed to find exported " 359*89eb861aSAxel Dörfler "Instantiate static function for class %s.", className); 360*89eb861aSAxel Dörfler *status = B_NAME_NOT_FOUND; 361*89eb861aSAxel Dörfler return NULL; 362*89eb861aSAxel Dörfler } 363*89eb861aSAxel Dörfler } else if (instantiationFunc == NULL) { 364*89eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: No signature specified " 365*89eb861aSAxel Dörfler "in archive, looking for class \"%s\".", className); 366*89eb861aSAxel Dörfler *status = B_NAME_NOT_FOUND; 367*89eb861aSAxel Dörfler return NULL; 368*89eb861aSAxel Dörfler } 369*89eb861aSAxel Dörfler 370*89eb861aSAxel Dörfler // if Class::Instantiate(BMessage*) was found 371*89eb861aSAxel Dörfler if (instantiationFunc != NULL) { 372*89eb861aSAxel Dörfler // use to create and return an object instance 373*89eb861aSAxel Dörfler return instantiationFunc(archive); 374*89eb861aSAxel Dörfler } 375*89eb861aSAxel Dörfler 376*89eb861aSAxel Dörfler return NULL; 377*89eb861aSAxel Dörfler } 378*89eb861aSAxel Dörfler 379*89eb861aSAxel Dörfler 380*89eb861aSAxel Dörfler BArchivable* 381*89eb861aSAxel Dörfler instantiate_object(BMessage* from) 382*89eb861aSAxel Dörfler { 383*89eb861aSAxel Dörfler return instantiate_object(from, NULL); 38452a38012Sejakowatz } 3859ecf9d1cSIngo Weinhold 3869ecf9d1cSIngo Weinhold 3879ecf9d1cSIngo Weinhold bool 388*89eb861aSAxel Dörfler validate_instantiation(BMessage* from, const char* className) 38952a38012Sejakowatz { 390*89eb861aSAxel Dörfler // Make sure our params are kosher -- original skimped here =P 391*89eb861aSAxel Dörfler if (!from) { 392*89eb861aSAxel Dörfler errno = B_BAD_VALUE; 393*89eb861aSAxel Dörfler return false; 394*89eb861aSAxel Dörfler } 395*89eb861aSAxel Dörfler 396*89eb861aSAxel Dörfler const char* data; 397*89eb861aSAxel Dörfler for (int32 index = 0; from->FindString(B_CLASS_FIELD, index, &data) == B_OK; 398*89eb861aSAxel Dörfler ++index) { 399*89eb861aSAxel Dörfler if (!strcmp(data, className)) 40052a38012Sejakowatz return true; 40152a38012Sejakowatz } 40252a38012Sejakowatz 403*89eb861aSAxel Dörfler errno = B_MISMATCHED_VALUES; 404*89eb861aSAxel Dörfler syslog(LOG_ERR, "validate_instantiation failed on class %s.", className); 40552a38012Sejakowatz 40652a38012Sejakowatz return false; 40752a38012Sejakowatz } 40852a38012Sejakowatz 409*89eb861aSAxel Dörfler 410*89eb861aSAxel Dörfler instantiation_func 411*89eb861aSAxel Dörfler find_instantiation_func(const char* className, const char* signature) 412*89eb861aSAxel Dörfler { 413*89eb861aSAxel Dörfler if (className == NULL) { 414*89eb861aSAxel Dörfler errno = B_BAD_VALUE; 415*89eb861aSAxel Dörfler return NULL; 41652a38012Sejakowatz } 41752a38012Sejakowatz 418*89eb861aSAxel Dörfler thread_info threadInfo; 419*89eb861aSAxel Dörfler status_t err = get_thread_info(find_thread(NULL), &threadInfo); 420*89eb861aSAxel Dörfler if (err != B_OK) { 421*89eb861aSAxel Dörfler errno = err; 422*89eb861aSAxel Dörfler return NULL; 423*89eb861aSAxel Dörfler } 424*89eb861aSAxel Dörfler 425*89eb861aSAxel Dörfler instantiation_func instantiationFunc = NULL; 426*89eb861aSAxel Dörfler image_info imageInfo; 427*89eb861aSAxel Dörfler 428*89eb861aSAxel Dörfler BString name = className; 429*89eb861aSAxel Dörfler for (int32 pass = 0; pass < 2; pass++) { 430*89eb861aSAxel Dörfler BString funcName; 431*89eb861aSAxel Dörfler build_function_name(name, funcName); 432*89eb861aSAxel Dörfler 433*89eb861aSAxel Dörfler // for each image_id in team_id 434*89eb861aSAxel Dörfler int32 cookie = 0; 435*89eb861aSAxel Dörfler while (instantiationFunc == NULL 436*89eb861aSAxel Dörfler && get_next_image_info(threadInfo.team, &cookie, &imageInfo) 437*89eb861aSAxel Dörfler == B_OK) { 438*89eb861aSAxel Dörfler instantiationFunc = find_function_in_image(funcName, imageInfo.id, 439*89eb861aSAxel Dörfler err); 440*89eb861aSAxel Dörfler } 441*89eb861aSAxel Dörfler if (instantiationFunc != NULL) 442*89eb861aSAxel Dörfler break; 443*89eb861aSAxel Dörfler 444*89eb861aSAxel Dörfler // Check if we have a private class, and add the BPrivate namespace 445*89eb861aSAxel Dörfler // (for backwards compatibility) 446*89eb861aSAxel Dörfler if (!add_private_namespace(name)) 447*89eb861aSAxel Dörfler break; 448*89eb861aSAxel Dörfler } 449*89eb861aSAxel Dörfler 450*89eb861aSAxel Dörfler if (instantiationFunc != NULL 451*89eb861aSAxel Dörfler && check_signature(signature, imageInfo) != B_OK) 452*89eb861aSAxel Dörfler return NULL; 453*89eb861aSAxel Dörfler 454*89eb861aSAxel Dörfler return instantiationFunc; 455*89eb861aSAxel Dörfler } 456*89eb861aSAxel Dörfler 457*89eb861aSAxel Dörfler 458*89eb861aSAxel Dörfler instantiation_func 459*89eb861aSAxel Dörfler find_instantiation_func(const char* className) 460*89eb861aSAxel Dörfler { 461*89eb861aSAxel Dörfler return find_instantiation_func(className, NULL); 462*89eb861aSAxel Dörfler } 463*89eb861aSAxel Dörfler 464*89eb861aSAxel Dörfler 465*89eb861aSAxel Dörfler instantiation_func 466*89eb861aSAxel Dörfler find_instantiation_func(BMessage* archive) 467*89eb861aSAxel Dörfler { 468*89eb861aSAxel Dörfler if (archive == NULL) { 469*89eb861aSAxel Dörfler errno = B_BAD_VALUE; 470*89eb861aSAxel Dörfler return NULL; 471*89eb861aSAxel Dörfler } 472*89eb861aSAxel Dörfler 473*89eb861aSAxel Dörfler const char* name = NULL; 474*89eb861aSAxel Dörfler const char* signature = NULL; 475*89eb861aSAxel Dörfler if (archive->FindString(B_CLASS_FIELD, &name) != B_OK 476*89eb861aSAxel Dörfler || archive->FindString(B_ADD_ON_FIELD, &signature)) { 477*89eb861aSAxel Dörfler errno = B_BAD_VALUE; 478*89eb861aSAxel Dörfler return NULL; 479*89eb861aSAxel Dörfler } 480*89eb861aSAxel Dörfler 481*89eb861aSAxel Dörfler return find_instantiation_func(name, signature); 48252a38012Sejakowatz } 48352a38012Sejakowatz 484