xref: /haiku/src/kits/support/Archivable.cpp (revision 89eb861a3e15748d432ed7fd2b1a4eb1e6542bdc)
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