xref: /haiku/src/kits/support/Archivable.cpp (revision 7037b5d9bc71a4f2eeab7d73cb00d124da6fe3b5)
19ecf9d1cSIngo Weinhold /*
229e8fa59SJohn Scipione  * Copyright 2001-2012 Haiku, Inc. All rights reserved.
39ecf9d1cSIngo Weinhold  * Distributed under the terms of the MIT License.
49ecf9d1cSIngo Weinhold  *
59ecf9d1cSIngo Weinhold  * Authors:
636c85ca8SRene Gollent  *		Rene Gollent (rene@gollent.com)
79ecf9d1cSIngo Weinhold  *		Erik Jaesler (erik@cgsoftware.com)
8e5150e28SIngo Weinhold  *		Alex Wilson (yourpalal2@gmail.com)
99ecf9d1cSIngo Weinhold  */
1052a38012Sejakowatz 
117bc5a06bSAxel Dörfler /*!	BArchivable mix-in class defines the archiving protocol.
127bc5a06bSAxel Dörfler 	Also some global archiving functions.
137bc5a06bSAxel Dörfler */
149ecf9d1cSIngo Weinhold 
159ecf9d1cSIngo Weinhold 
1652a38012Sejakowatz #include <ctype.h>
1752a38012Sejakowatz #include <errno.h>
1852a38012Sejakowatz #include <stdlib.h>
1952a38012Sejakowatz #include <stdio.h>
2052a38012Sejakowatz #include <string>
217bc5a06bSAxel Dörfler #include <syslog.h>
2252a38012Sejakowatz #include <typeinfo>
2352a38012Sejakowatz #include <vector>
2452a38012Sejakowatz 
2552a38012Sejakowatz #include <AppFileInfo.h>
2652a38012Sejakowatz #include <Archivable.h>
2752a38012Sejakowatz #include <Entry.h>
2852a38012Sejakowatz #include <List.h>
2952a38012Sejakowatz #include <OS.h>
3052a38012Sejakowatz #include <Path.h>
3152a38012Sejakowatz #include <Roster.h>
3252a38012Sejakowatz #include <String.h>
3352a38012Sejakowatz 
34e5150e28SIngo Weinhold #include <binary_compatibility/Support.h>
35e5150e28SIngo Weinhold 
36e5150e28SIngo Weinhold #include "ArchivingManagers.h"
37e5150e28SIngo Weinhold 
3852a38012Sejakowatz 
3952a38012Sejakowatz using std::string;
4052a38012Sejakowatz using std::vector;
4152a38012Sejakowatz 
42e5150e28SIngo Weinhold using namespace BPrivate::Archiving;
43e5150e28SIngo Weinhold 
4452a38012Sejakowatz const char* B_CLASS_FIELD = "class";
4552a38012Sejakowatz const char* B_ADD_ON_FIELD = "add_on";
4652a38012Sejakowatz const int32 FUNC_NAME_LEN = 1024;
4752a38012Sejakowatz 
487bc5a06bSAxel Dörfler // TODO: consider moving these to a separate module, and making them more
497bc5a06bSAxel Dörfler //	full-featured (e.g., taking NS::ClassName::Function(Param p) instead
507bc5a06bSAxel Dörfler //	of just NS::ClassName)
5152a38012Sejakowatz 
529ecf9d1cSIngo Weinhold 
5313bbfe42SAxel Dörfler static status_t
demangle_class_name(const char * name,BString & out)5489eb861aSAxel Dörfler demangle_class_name(const char* name, BString& out)
5552a38012Sejakowatz {
5652a38012Sejakowatz // TODO: add support for template classes
5752a38012Sejakowatz //	_find__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCccUlUl
5852a38012Sejakowatz 
5952a38012Sejakowatz 	out = "";
6052a38012Sejakowatz 
61c216fe9dSAlex Wilson #if __GNUC__ >= 4
62c216fe9dSAlex Wilson 	if (name[0] == 'N')
63c216fe9dSAlex Wilson 		name++;
64c216fe9dSAlex Wilson 	int nameLen;
65c216fe9dSAlex Wilson 	bool first = true;
66c216fe9dSAlex Wilson 	while ((nameLen = strtoul(name, (char**)&name, 10))) {
67c216fe9dSAlex Wilson 		if (!first)
68c216fe9dSAlex Wilson 			out += "::";
69c216fe9dSAlex Wilson 		else
70c216fe9dSAlex Wilson 			first = false;
71c216fe9dSAlex Wilson 		out.Append(name, nameLen);
72c216fe9dSAlex Wilson 		name += nameLen;
73c216fe9dSAlex Wilson 	}
74c216fe9dSAlex Wilson 	if (first)
75c216fe9dSAlex Wilson 		return B_BAD_VALUE;
76c216fe9dSAlex Wilson 
77c216fe9dSAlex Wilson #else
7813bbfe42SAxel Dörfler 	if (name[0] == 'Q') {
7913bbfe42SAxel Dörfler 		// The name is in a namespace
8013bbfe42SAxel Dörfler 		int namespaceCount = 0;
8113bbfe42SAxel Dörfler 		name++;
8213bbfe42SAxel Dörfler 		if (name[0] == '_') {
8313bbfe42SAxel Dörfler 			// more than 10 namespaces deep
8413bbfe42SAxel Dörfler 			if (!isdigit(*++name))
8513bbfe42SAxel Dörfler 				return B_BAD_VALUE;
8652a38012Sejakowatz 
8713bbfe42SAxel Dörfler 			namespaceCount = strtoul(name, (char**)&name, 10);
8813bbfe42SAxel Dörfler 			if (name[0] != '_')
8913bbfe42SAxel Dörfler 				return B_BAD_VALUE;
9013bbfe42SAxel Dörfler 		} else
9113bbfe42SAxel Dörfler 			namespaceCount = name[0] - '0';
9252a38012Sejakowatz 
9313bbfe42SAxel Dörfler 		name++;
9452a38012Sejakowatz 
9513bbfe42SAxel Dörfler 		for (int i = 0; i < namespaceCount - 1; i++) {
9613bbfe42SAxel Dörfler 			if (!isdigit(name[0]))
9713bbfe42SAxel Dörfler 				return B_BAD_VALUE;
9813bbfe42SAxel Dörfler 
9913bbfe42SAxel Dörfler 			int nameLength = strtoul(name, (char**)&name, 10);
10013bbfe42SAxel Dörfler 			out.Append(name, nameLength);
10152a38012Sejakowatz 			out += "::";
10213bbfe42SAxel Dörfler 			name += nameLength;
10352a38012Sejakowatz 		}
10452a38012Sejakowatz 	}
10552a38012Sejakowatz 
10613bbfe42SAxel Dörfler 	int nameLength = strtoul(name, (char**)&name, 10);
10713bbfe42SAxel Dörfler 	out.Append(name, nameLength);
108c216fe9dSAlex Wilson #endif
10913bbfe42SAxel Dörfler 
11013bbfe42SAxel Dörfler 	return B_OK;
11152a38012Sejakowatz }
1129ecf9d1cSIngo Weinhold 
1139ecf9d1cSIngo Weinhold 
11489eb861aSAxel Dörfler static void
mangle_class_name(const char * name,BString & out)11589eb861aSAxel Dörfler mangle_class_name(const char* name, BString& out)
11652a38012Sejakowatz {
11752a38012Sejakowatz // TODO: add support for template classes
11852a38012Sejakowatz //	_find__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCccUlUl
11952a38012Sejakowatz 
12052a38012Sejakowatz 	//	Chop this:
12152a38012Sejakowatz 	//		testthree::testfour::Testthree::Testfour
12252a38012Sejakowatz 	//	up into little bite-sized pieces
12352a38012Sejakowatz 	int count = 0;
12452a38012Sejakowatz 	string origName(name);
12552a38012Sejakowatz 	vector<string> spacenames;
12652a38012Sejakowatz 
12752a38012Sejakowatz 	string::size_type pos = 0;
12852a38012Sejakowatz 	string::size_type oldpos = 0;
1299ecf9d1cSIngo Weinhold 	while (pos != string::npos) {
13052a38012Sejakowatz 		pos = origName.find_first_of("::", oldpos);
13152a38012Sejakowatz 		spacenames.push_back(string(origName, oldpos, pos - oldpos));
13252a38012Sejakowatz 		pos = origName.find_first_not_of("::", pos);
13352a38012Sejakowatz 		oldpos = pos;
13452a38012Sejakowatz 		++count;
13552a38012Sejakowatz 	}
13652a38012Sejakowatz 
13752a38012Sejakowatz 	//	Now mangle it into this:
138c216fe9dSAlex Wilson 	//		9testthree8testfour9Testthree8Testfour
139c216fe9dSAlex Wilson 	//			(for __GNUC__ > 2)
140c216fe9dSAlex Wilson 	//			this isn't always the proper mangled class name, it should
141c216fe9dSAlex Wilson 	//			actually have an 'N' prefix and 'E' suffix if the name is
142c216fe9dSAlex Wilson 	//			in > 0 namespaces, but these would have to be removed in
143c216fe9dSAlex Wilson 	//			build_function_name() (the only place this function is called)
144c216fe9dSAlex Wilson 	//			so we don't add them.
145c216fe9dSAlex Wilson 	//	or this:
14652a38012Sejakowatz 	//		Q49testthree8testfour9Testthree8Testfour
147c216fe9dSAlex Wilson 	//			(for __GNUC__ == 2)
148c216fe9dSAlex Wilson 
14952a38012Sejakowatz 	out = "";
150c216fe9dSAlex Wilson #if __GNUC__ == 2
1519ecf9d1cSIngo Weinhold 	if (count > 1) {
15252a38012Sejakowatz 		out += 'Q';
15352a38012Sejakowatz 		if (count > 10)
15452a38012Sejakowatz 			out += '_';
15552a38012Sejakowatz 		out << count;
15652a38012Sejakowatz 		if (count > 10)
15752a38012Sejakowatz 			out += '_';
15852a38012Sejakowatz 	}
159c216fe9dSAlex Wilson #endif
16052a38012Sejakowatz 
1619ecf9d1cSIngo Weinhold 	for (unsigned int i = 0; i < spacenames.size(); ++i) {
16252a38012Sejakowatz 		out << (int)spacenames[i].length();
16352a38012Sejakowatz 		out += spacenames[i].c_str();
16452a38012Sejakowatz 	}
16552a38012Sejakowatz }
1669ecf9d1cSIngo Weinhold 
1679ecf9d1cSIngo Weinhold 
16889eb861aSAxel Dörfler static void
build_function_name(const BString & className,BString & funcName)16989eb861aSAxel Dörfler build_function_name(const BString& className, BString& funcName)
17052a38012Sejakowatz {
17189eb861aSAxel Dörfler 	funcName = "";
17252a38012Sejakowatz 
17389eb861aSAxel Dörfler 	//	This is what we're after:
17489eb861aSAxel Dörfler 	//		Instantiate__Q28OpenBeOS11BArchivableP8BMessage
17589eb861aSAxel Dörfler 	mangle_class_name(className.String(), funcName);
17689eb861aSAxel Dörfler #if __GNUC__ >= 4
17789eb861aSAxel Dörfler 	funcName.Prepend("_ZN");
17889eb861aSAxel Dörfler 	funcName.Append("11InstantiateE");
17989eb861aSAxel Dörfler #else
18089eb861aSAxel Dörfler 	funcName.Prepend("Instantiate__");
18152a38012Sejakowatz #endif
18289eb861aSAxel Dörfler 	funcName.Append("P8BMessage");
18352a38012Sejakowatz }
18452a38012Sejakowatz 
18589eb861aSAxel Dörfler 
18689eb861aSAxel Dörfler static bool
add_private_namespace(BString & name)18789eb861aSAxel Dörfler add_private_namespace(BString& name)
18889eb861aSAxel Dörfler {
18989eb861aSAxel Dörfler 	if (name.Compare("_", 1) != 0)
19089eb861aSAxel Dörfler 		return false;
19189eb861aSAxel Dörfler 
19289eb861aSAxel Dörfler 	name.Prepend("BPrivate::");
19389eb861aSAxel Dörfler 	return true;
19489eb861aSAxel Dörfler }
19589eb861aSAxel Dörfler 
19689eb861aSAxel Dörfler 
19789eb861aSAxel Dörfler static instantiation_func
find_function_in_image(BString & funcName,image_id id,status_t & err)19889eb861aSAxel Dörfler find_function_in_image(BString& funcName, image_id id, status_t& err)
19989eb861aSAxel Dörfler {
20089eb861aSAxel Dörfler 	instantiation_func instantiationFunc = NULL;
20189eb861aSAxel Dörfler 	err = get_image_symbol(id, funcName.String(), B_SYMBOL_TYPE_TEXT,
20289eb861aSAxel Dörfler 		(void**)&instantiationFunc);
20389eb861aSAxel Dörfler 	if (err != B_OK)
20489eb861aSAxel Dörfler 		return NULL;
20589eb861aSAxel Dörfler 
20689eb861aSAxel Dörfler 	return instantiationFunc;
20789eb861aSAxel Dörfler }
20889eb861aSAxel Dörfler 
20989eb861aSAxel Dörfler 
21089eb861aSAxel Dörfler static status_t
check_signature(const char * signature,image_info & info)21189eb861aSAxel Dörfler check_signature(const char* signature, image_info& info)
21289eb861aSAxel Dörfler {
21389eb861aSAxel Dörfler 	if (signature == NULL) {
21489eb861aSAxel Dörfler 		// If it wasn't specified, anything "matches"
21589eb861aSAxel Dörfler 		return B_OK;
21689eb861aSAxel Dörfler 	}
21789eb861aSAxel Dörfler 
21889eb861aSAxel Dörfler 	// Get image signature
21989eb861aSAxel Dörfler 	BFile file(info.name, B_READ_ONLY);
22089eb861aSAxel Dörfler 	status_t err = file.InitCheck();
22189eb861aSAxel Dörfler 	if (err != B_OK)
22289eb861aSAxel Dörfler 		return err;
22389eb861aSAxel Dörfler 
22489eb861aSAxel Dörfler 	char imageSignature[B_MIME_TYPE_LENGTH];
22589eb861aSAxel Dörfler 	BAppFileInfo appFileInfo(&file);
22689eb861aSAxel Dörfler 	err = appFileInfo.GetSignature(imageSignature);
22789eb861aSAxel Dörfler 	if (err != B_OK) {
22889eb861aSAxel Dörfler 		syslog(LOG_ERR, "instantiate_object - couldn't get mime sig for %s",
22989eb861aSAxel Dörfler 			info.name);
23089eb861aSAxel Dörfler 		return err;
23189eb861aSAxel Dörfler 	}
23289eb861aSAxel Dörfler 
2332f863948SAdrien Destugues 	if (strcmp(signature, imageSignature) != 0)
23489eb861aSAxel Dörfler 		return B_MISMATCHED_VALUES;
23589eb861aSAxel Dörfler 
23689eb861aSAxel Dörfler 	return B_OK;
23789eb861aSAxel Dörfler }
23889eb861aSAxel Dörfler 
23989eb861aSAxel Dörfler 
24029e8fa59SJohn Scipione namespace BPrivate {
24136c85ca8SRene Gollent 
24236c85ca8SRene Gollent instantiation_func
find_instantiation_func(const char * className,const char * signature,image_id * id)24336c85ca8SRene Gollent find_instantiation_func(const char* className, const char* signature,
24436c85ca8SRene Gollent 	image_id* id)
24536c85ca8SRene Gollent {
24636c85ca8SRene Gollent 	if (className == NULL) {
24736c85ca8SRene Gollent 		errno = B_BAD_VALUE;
24836c85ca8SRene Gollent 		return NULL;
24936c85ca8SRene Gollent 	}
25036c85ca8SRene Gollent 
25136c85ca8SRene Gollent 	thread_info threadInfo;
25236c85ca8SRene Gollent 	status_t err = get_thread_info(find_thread(NULL), &threadInfo);
25336c85ca8SRene Gollent 	if (err != B_OK) {
25436c85ca8SRene Gollent 		errno = err;
25536c85ca8SRene Gollent 		return NULL;
25636c85ca8SRene Gollent 	}
25736c85ca8SRene Gollent 
25836c85ca8SRene Gollent 	instantiation_func instantiationFunc = NULL;
25936c85ca8SRene Gollent 	image_info imageInfo;
26036c85ca8SRene Gollent 
26136c85ca8SRene Gollent 	BString name = className;
26236c85ca8SRene Gollent 	for (int32 pass = 0; pass < 2; pass++) {
26336c85ca8SRene Gollent 		BString funcName;
26436c85ca8SRene Gollent 		build_function_name(name, funcName);
26536c85ca8SRene Gollent 
26636c85ca8SRene Gollent 		// for each image_id in team_id
26736c85ca8SRene Gollent 		int32 cookie = 0;
26836c85ca8SRene Gollent 		while (instantiationFunc == NULL
26936c85ca8SRene Gollent 			&& get_next_image_info(threadInfo.team, &cookie, &imageInfo)
27036c85ca8SRene Gollent 				== B_OK) {
27136c85ca8SRene Gollent 			instantiationFunc = find_function_in_image(funcName, imageInfo.id,
27236c85ca8SRene Gollent 				err);
27336c85ca8SRene Gollent 		}
27436c85ca8SRene Gollent 		if (instantiationFunc != NULL) {
27536c85ca8SRene Gollent 			// if requested, save the image id in
27636c85ca8SRene Gollent 			// which the function was found
27736c85ca8SRene Gollent 			if (id != NULL)
27836c85ca8SRene Gollent 				*id = imageInfo.id;
27936c85ca8SRene Gollent 			break;
28036c85ca8SRene Gollent 		}
28136c85ca8SRene Gollent 
28236c85ca8SRene Gollent 		// Check if we have a private class, and add the BPrivate namespace
28336c85ca8SRene Gollent 		// (for backwards compatibility)
28436c85ca8SRene Gollent 		if (!add_private_namespace(name))
28536c85ca8SRene Gollent 			break;
28636c85ca8SRene Gollent 	}
28736c85ca8SRene Gollent 
28836c85ca8SRene Gollent 	if (instantiationFunc != NULL
28936c85ca8SRene Gollent 		&& check_signature(signature, imageInfo) != B_OK)
29036c85ca8SRene Gollent 		return NULL;
29136c85ca8SRene Gollent 
29236c85ca8SRene Gollent 	return instantiationFunc;
29336c85ca8SRene Gollent }
29436c85ca8SRene Gollent 
29529e8fa59SJohn Scipione }	// namespace BPrivate
29636c85ca8SRene Gollent 
29736c85ca8SRene Gollent 
29829e8fa59SJohn Scipione //	#pragma mark - BArchivable
29989eb861aSAxel Dörfler 
30089eb861aSAxel Dörfler 
BArchivable()30189eb861aSAxel Dörfler BArchivable::BArchivable()
302b137ab3eSIngo Weinhold 	:
303b137ab3eSIngo Weinhold 	fArchivingToken(NULL_TOKEN)
30489eb861aSAxel Dörfler {
30589eb861aSAxel Dörfler }
30689eb861aSAxel Dörfler 
30789eb861aSAxel Dörfler 
BArchivable(BMessage * from)30889eb861aSAxel Dörfler BArchivable::BArchivable(BMessage* from)
309b137ab3eSIngo Weinhold 	:
310b137ab3eSIngo Weinhold 	fArchivingToken(NULL_TOKEN)
31189eb861aSAxel Dörfler {
312e5150e28SIngo Weinhold 	if (BUnarchiver::IsArchiveManaged(from)) {
313e5150e28SIngo Weinhold 		BUnarchiver::PrepareArchive(from);
314e5150e28SIngo Weinhold 		BUnarchiver(from).RegisterArchivable(this);
315e5150e28SIngo Weinhold 	}
31689eb861aSAxel Dörfler }
31789eb861aSAxel Dörfler 
31889eb861aSAxel Dörfler 
~BArchivable()31989eb861aSAxel Dörfler BArchivable::~BArchivable()
32089eb861aSAxel Dörfler {
32189eb861aSAxel Dörfler }
32289eb861aSAxel Dörfler 
32389eb861aSAxel Dörfler 
32489eb861aSAxel Dörfler status_t
Archive(BMessage * into,bool deep) const32589eb861aSAxel Dörfler BArchivable::Archive(BMessage* into, bool deep) const
32689eb861aSAxel Dörfler {
32789eb861aSAxel Dörfler 	if (!into) {
32889eb861aSAxel Dörfler 		// TODO: logging/other error reporting?
32989eb861aSAxel Dörfler 		return B_BAD_VALUE;
33089eb861aSAxel Dörfler 	}
33189eb861aSAxel Dörfler 
332e5150e28SIngo Weinhold 	if (BManagerBase::ArchiveManager(into))
333e5150e28SIngo Weinhold 		BArchiver(into).RegisterArchivable(this);
334e5150e28SIngo Weinhold 
33589eb861aSAxel Dörfler 	BString name;
33613bbfe42SAxel Dörfler 	status_t status = demangle_class_name(typeid(*this).name(), name);
33713bbfe42SAxel Dörfler 	if (status != B_OK)
33813bbfe42SAxel Dörfler 		return status;
33989eb861aSAxel Dörfler 
34089eb861aSAxel Dörfler 	return into->AddString(B_CLASS_FIELD, name);
34189eb861aSAxel Dörfler }
34289eb861aSAxel Dörfler 
34389eb861aSAxel Dörfler 
34489eb861aSAxel Dörfler BArchivable*
Instantiate(BMessage * from)34589eb861aSAxel Dörfler BArchivable::Instantiate(BMessage* from)
34689eb861aSAxel Dörfler {
34789eb861aSAxel Dörfler 	debugger("Can't create a plain BArchivable object");
34889eb861aSAxel Dörfler 	return NULL;
34989eb861aSAxel Dörfler }
35089eb861aSAxel Dörfler 
35189eb861aSAxel Dörfler 
35289eb861aSAxel Dörfler status_t
Perform(perform_code d,void * arg)35389eb861aSAxel Dörfler BArchivable::Perform(perform_code d, void* arg)
35489eb861aSAxel Dörfler {
355e5150e28SIngo Weinhold 	switch (d) {
356e5150e28SIngo Weinhold 		case PERFORM_CODE_ALL_UNARCHIVED:
357e5150e28SIngo Weinhold 		{
358e5150e28SIngo Weinhold 			perform_data_all_unarchived* data =
359e5150e28SIngo Weinhold 				(perform_data_all_unarchived*)arg;
360e5150e28SIngo Weinhold 
361e5150e28SIngo Weinhold 			data->return_value = BArchivable::AllUnarchived(data->archive);
362e5150e28SIngo Weinhold 			return B_OK;
363e5150e28SIngo Weinhold 		}
364e5150e28SIngo Weinhold 
365e5150e28SIngo Weinhold 		case PERFORM_CODE_ALL_ARCHIVED:
366e5150e28SIngo Weinhold 		{
367e5150e28SIngo Weinhold 			perform_data_all_archived* data =
368e5150e28SIngo Weinhold 				(perform_data_all_archived*)arg;
369e5150e28SIngo Weinhold 
370e5150e28SIngo Weinhold 			data->return_value = BArchivable::AllArchived(data->archive);
371e5150e28SIngo Weinhold 			return B_OK;
372e5150e28SIngo Weinhold 		}
373e5150e28SIngo Weinhold 	}
37429e8fa59SJohn Scipione 
375e5150e28SIngo Weinhold 	return B_NAME_NOT_FOUND;
37689eb861aSAxel Dörfler }
37789eb861aSAxel Dörfler 
37889eb861aSAxel Dörfler 
379e5150e28SIngo Weinhold status_t
AllUnarchived(const BMessage * archive)380e5150e28SIngo Weinhold BArchivable::AllUnarchived(const BMessage* archive)
381e5150e28SIngo Weinhold {
382e5150e28SIngo Weinhold 	return B_OK;
383e5150e28SIngo Weinhold }
384e5150e28SIngo Weinhold 
385e5150e28SIngo Weinhold 
386e5150e28SIngo Weinhold status_t
AllArchived(BMessage * archive) const387e5150e28SIngo Weinhold BArchivable::AllArchived(BMessage* archive) const
388e5150e28SIngo Weinhold {
389e5150e28SIngo Weinhold 	return B_OK;
390e5150e28SIngo Weinhold }
391e5150e28SIngo Weinhold 
392fbb6335dSIngo Weinhold 
39329e8fa59SJohn Scipione // #pragma mark - BArchiver
394e5150e28SIngo Weinhold 
395fbb6335dSIngo Weinhold 
BArchiver(BMessage * archive)396e5150e28SIngo Weinhold BArchiver::BArchiver(BMessage* archive)
397e5150e28SIngo Weinhold 	:
398e5150e28SIngo Weinhold 	fManager(BManagerBase::ArchiveManager(archive)),
399e5150e28SIngo Weinhold 	fArchive(archive),
400e5150e28SIngo Weinhold 	fFinished(false)
401e5150e28SIngo Weinhold {
40229e8fa59SJohn Scipione 	if (fManager == NULL)
403e5150e28SIngo Weinhold 		fManager = new BArchiveManager(this);
404e5150e28SIngo Weinhold }
405e5150e28SIngo Weinhold 
406e5150e28SIngo Weinhold 
~BArchiver()407e5150e28SIngo Weinhold BArchiver::~BArchiver()
408e5150e28SIngo Weinhold {
409e5150e28SIngo Weinhold 	if (!fFinished)
410b137ab3eSIngo Weinhold 		fManager->ArchiverLeaving(this, B_OK);
411e5150e28SIngo Weinhold }
412e5150e28SIngo Weinhold 
413e5150e28SIngo Weinhold 
414e5150e28SIngo Weinhold status_t
AddArchivable(const char * name,BArchivable * archivable,bool deep)415e5150e28SIngo Weinhold BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep)
416e5150e28SIngo Weinhold {
417e5150e28SIngo Weinhold 	int32 token;
418b137ab3eSIngo Weinhold 	status_t err = GetTokenForArchivable(archivable, deep, token);
419e5150e28SIngo Weinhold 
420e5150e28SIngo Weinhold 	if (err != B_OK)
421e5150e28SIngo Weinhold 		return err;
422e5150e28SIngo Weinhold 
423e5150e28SIngo Weinhold 	return fArchive->AddInt32(name, token);
424e5150e28SIngo Weinhold }
425e5150e28SIngo Weinhold 
426e5150e28SIngo Weinhold 
427e5150e28SIngo Weinhold status_t
GetTokenForArchivable(BArchivable * archivable,bool deep,int32 & _token)428e5150e28SIngo Weinhold BArchiver::GetTokenForArchivable(BArchivable* archivable,
429b137ab3eSIngo Weinhold 	bool deep, int32& _token)
430e5150e28SIngo Weinhold {
431b137ab3eSIngo Weinhold 	return fManager->ArchiveObject(archivable, deep, _token);
432e5150e28SIngo Weinhold }
433e5150e28SIngo Weinhold 
434e5150e28SIngo Weinhold 
435e5150e28SIngo Weinhold bool
IsArchived(BArchivable * archivable)436e5150e28SIngo Weinhold BArchiver::IsArchived(BArchivable* archivable)
437e5150e28SIngo Weinhold {
438e5150e28SIngo Weinhold 	return fManager->IsArchived(archivable);
439e5150e28SIngo Weinhold }
440e5150e28SIngo Weinhold 
441e5150e28SIngo Weinhold 
442e5150e28SIngo Weinhold status_t
Finish(status_t err)443b137ab3eSIngo Weinhold BArchiver::Finish(status_t err)
444e5150e28SIngo Weinhold {
445e5150e28SIngo Weinhold 	if (fFinished)
446e5150e28SIngo Weinhold 		debugger("Finish() called multiple times on same BArchiver.");
447e5150e28SIngo Weinhold 
448e5150e28SIngo Weinhold 	fFinished = true;
449b137ab3eSIngo Weinhold 
450b137ab3eSIngo Weinhold 	return fManager->ArchiverLeaving(this, err);
451e5150e28SIngo Weinhold }
452e5150e28SIngo Weinhold 
453e5150e28SIngo Weinhold 
454e5150e28SIngo Weinhold BMessage*
ArchiveMessage() const455e5150e28SIngo Weinhold BArchiver::ArchiveMessage() const
456e5150e28SIngo Weinhold {
457e5150e28SIngo Weinhold 	return fArchive;
458e5150e28SIngo Weinhold }
459e5150e28SIngo Weinhold 
460e5150e28SIngo Weinhold 
461e5150e28SIngo Weinhold void
RegisterArchivable(const BArchivable * archivable)462e5150e28SIngo Weinhold BArchiver::RegisterArchivable(const BArchivable* archivable)
463e5150e28SIngo Weinhold {
464e5150e28SIngo Weinhold 	fManager->RegisterArchivable(archivable);
465e5150e28SIngo Weinhold }
466e5150e28SIngo Weinhold 
467e5150e28SIngo Weinhold 
46829e8fa59SJohn Scipione // #pragma mark - BUnarchiver
469e5150e28SIngo Weinhold 
470e5150e28SIngo Weinhold 
BUnarchiver(const BMessage * archive)471e5150e28SIngo Weinhold BUnarchiver::BUnarchiver(const BMessage* archive)
472e5150e28SIngo Weinhold 	:
473e5150e28SIngo Weinhold 	fManager(BManagerBase::UnarchiveManager(archive)),
474e5150e28SIngo Weinhold 	fArchive(archive),
475e5150e28SIngo Weinhold 	fFinished(false)
476e5150e28SIngo Weinhold {
477e5150e28SIngo Weinhold }
478e5150e28SIngo Weinhold 
479e5150e28SIngo Weinhold 
~BUnarchiver()480e5150e28SIngo Weinhold BUnarchiver::~BUnarchiver()
481e5150e28SIngo Weinhold {
482e5150e28SIngo Weinhold 	if (!fFinished && fManager)
483b137ab3eSIngo Weinhold 		fManager->UnarchiverLeaving(this, B_OK);
484e5150e28SIngo Weinhold }
485e5150e28SIngo Weinhold 
486e5150e28SIngo Weinhold 
487b137ab3eSIngo Weinhold template<>
488e5150e28SIngo Weinhold status_t
GetObject(int32 token,ownership_policy owning,BArchivable * & object)489b137ab3eSIngo Weinhold BUnarchiver::GetObject<BArchivable>(int32 token,
490b137ab3eSIngo Weinhold 	ownership_policy owning, BArchivable*& object)
491e5150e28SIngo Weinhold {
492e5150e28SIngo Weinhold 	_CallDebuggerIfManagerNull();
493b137ab3eSIngo Weinhold 	return fManager->GetArchivableForToken(token, owning, object);
494e5150e28SIngo Weinhold }
495e5150e28SIngo Weinhold 
496e5150e28SIngo Weinhold 
497b137ab3eSIngo Weinhold template<>
498e5150e28SIngo Weinhold status_t
FindObject(const char * name,int32 index,ownership_policy owning,BArchivable * & archivable)499b137ab3eSIngo Weinhold BUnarchiver::FindObject<BArchivable>(const char* name,
500b137ab3eSIngo Weinhold 	int32 index, ownership_policy owning, BArchivable*& archivable)
501e5150e28SIngo Weinhold {
502b137ab3eSIngo Weinhold 	archivable = NULL;
503e5150e28SIngo Weinhold 	int32 token;
504e5150e28SIngo Weinhold 	status_t err = fArchive->FindInt32(name, index, &token);
505e5150e28SIngo Weinhold 	if (err != B_OK)
506e5150e28SIngo Weinhold 		return err;
507e5150e28SIngo Weinhold 
508b137ab3eSIngo Weinhold 	return GetObject(token, owning, archivable);
509e5150e28SIngo Weinhold }
510e5150e28SIngo Weinhold 
511e5150e28SIngo Weinhold 
512e5150e28SIngo Weinhold bool
IsInstantiated(int32 token)513e5150e28SIngo Weinhold BUnarchiver::IsInstantiated(int32 token)
514e5150e28SIngo Weinhold {
51545a167a9SAlex Wilson 	_CallDebuggerIfManagerNull();
516e5150e28SIngo Weinhold 	return fManager->IsInstantiated(token);
517e5150e28SIngo Weinhold }
518e5150e28SIngo Weinhold 
519b137ab3eSIngo Weinhold 
520e5150e28SIngo Weinhold bool
IsInstantiated(const char * field,int32 index)521e5150e28SIngo Weinhold BUnarchiver::IsInstantiated(const char* field, int32 index)
522e5150e28SIngo Weinhold {
523e5150e28SIngo Weinhold 	int32 token;
524e5150e28SIngo Weinhold 	if (fArchive->FindInt32(field, index, &token) == B_OK)
525e5150e28SIngo Weinhold 		return IsInstantiated(token);
52629e8fa59SJohn Scipione 
527e5150e28SIngo Weinhold 	return false;
528e5150e28SIngo Weinhold }
529e5150e28SIngo Weinhold 
530b137ab3eSIngo Weinhold 
531e5150e28SIngo Weinhold status_t
Finish(status_t err)532b137ab3eSIngo Weinhold BUnarchiver::Finish(status_t err)
533e5150e28SIngo Weinhold {
534e5150e28SIngo Weinhold 	if (fFinished)
535e5150e28SIngo Weinhold 		debugger("Finish() called multiple times on same BArchiver.");
536e5150e28SIngo Weinhold 
537e5150e28SIngo Weinhold 	fFinished = true;
538b137ab3eSIngo Weinhold 	if (fManager)
539b137ab3eSIngo Weinhold 		return fManager->UnarchiverLeaving(this, err);
540b137ab3eSIngo Weinhold 	else
541b137ab3eSIngo Weinhold 		return B_OK;
542e5150e28SIngo Weinhold }
543e5150e28SIngo Weinhold 
544e5150e28SIngo Weinhold 
545e5150e28SIngo Weinhold const BMessage*
ArchiveMessage() const546e5150e28SIngo Weinhold BUnarchiver::ArchiveMessage() const
547e5150e28SIngo Weinhold {
548e5150e28SIngo Weinhold 	return fArchive;
549e5150e28SIngo Weinhold }
550e5150e28SIngo Weinhold 
551e5150e28SIngo Weinhold 
552b137ab3eSIngo Weinhold void
AssumeOwnership(BArchivable * archivable)553b137ab3eSIngo Weinhold BUnarchiver::AssumeOwnership(BArchivable* archivable)
554b137ab3eSIngo Weinhold {
555b137ab3eSIngo Weinhold 	_CallDebuggerIfManagerNull();
556b137ab3eSIngo Weinhold 	fManager->AssumeOwnership(archivable);
557b137ab3eSIngo Weinhold }
558b137ab3eSIngo Weinhold 
559b137ab3eSIngo Weinhold 
560b137ab3eSIngo Weinhold void
RelinquishOwnership(BArchivable * archivable)561b137ab3eSIngo Weinhold BUnarchiver::RelinquishOwnership(BArchivable* archivable)
562b137ab3eSIngo Weinhold {
563b137ab3eSIngo Weinhold 	_CallDebuggerIfManagerNull();
564b137ab3eSIngo Weinhold 	fManager->RelinquishOwnership(archivable);
565b137ab3eSIngo Weinhold }
566b137ab3eSIngo Weinhold 
567b137ab3eSIngo Weinhold 
568e5150e28SIngo Weinhold bool
IsArchiveManaged(const BMessage * archive)56945a167a9SAlex Wilson BUnarchiver::IsArchiveManaged(const BMessage* archive)
570e5150e28SIngo Weinhold {
571e5150e28SIngo Weinhold 	// managed child archives will return here
572e5150e28SIngo Weinhold 	if (BManagerBase::ManagerPointer(archive))
573e5150e28SIngo Weinhold 		return true;
574e5150e28SIngo Weinhold 
57529e8fa59SJohn Scipione 	if (archive == NULL)
576aa818be6SAlex Wilson 		return false;
577aa818be6SAlex Wilson 
578e5150e28SIngo Weinhold 	// managed top level archives return here
579b137ab3eSIngo Weinhold 	bool dummy;
580b137ab3eSIngo Weinhold 	if (archive->FindBool(kManagedField, &dummy) == B_OK)
581e5150e28SIngo Weinhold 		return true;
582e5150e28SIngo Weinhold 
583e5150e28SIngo Weinhold 	return false;
584e5150e28SIngo Weinhold }
585e5150e28SIngo Weinhold 
586e5150e28SIngo Weinhold 
587b137ab3eSIngo Weinhold template<>
588b137ab3eSIngo Weinhold status_t
InstantiateObject(BMessage * from,BArchivable * & object)589b137ab3eSIngo Weinhold BUnarchiver::InstantiateObject<BArchivable>(BMessage* from,
590b137ab3eSIngo Weinhold 	BArchivable* &object)
591b137ab3eSIngo Weinhold {
592b137ab3eSIngo Weinhold 	BUnarchiver unarchiver(BUnarchiver::PrepareArchive(from));
593b137ab3eSIngo Weinhold 	object = instantiate_object(from);
594b137ab3eSIngo Weinhold 	return unarchiver.Finish();
595b137ab3eSIngo Weinhold }
596b137ab3eSIngo Weinhold 
597b137ab3eSIngo Weinhold 
598e5150e28SIngo Weinhold BMessage*
PrepareArchive(BMessage * & archive)599e5150e28SIngo Weinhold BUnarchiver::PrepareArchive(BMessage* &archive)
600e5150e28SIngo Weinhold {
601e5150e28SIngo Weinhold 	// this check allows PrepareArchive to be
602e5150e28SIngo Weinhold 	// called on new or old-style archives
603e5150e28SIngo Weinhold 	if (BUnarchiver::IsArchiveManaged(archive)) {
604e5150e28SIngo Weinhold 		BUnarchiveManager* manager = BManagerBase::UnarchiveManager(archive);
605e5150e28SIngo Weinhold 		if (!manager)
606e5150e28SIngo Weinhold 			manager = new BUnarchiveManager(archive);
60729e8fa59SJohn Scipione 
608e5150e28SIngo Weinhold 		manager->Acquire();
609e5150e28SIngo Weinhold 	}
61029e8fa59SJohn Scipione 
611e5150e28SIngo Weinhold 	return archive;
612e5150e28SIngo Weinhold }
613e5150e28SIngo Weinhold 
614e5150e28SIngo Weinhold 
615e5150e28SIngo Weinhold void
RegisterArchivable(BArchivable * archivable)616e5150e28SIngo Weinhold BUnarchiver::RegisterArchivable(BArchivable* archivable)
617e5150e28SIngo Weinhold {
618e5150e28SIngo Weinhold 	_CallDebuggerIfManagerNull();
619e5150e28SIngo Weinhold 	fManager->RegisterArchivable(archivable);
620e5150e28SIngo Weinhold }
621e5150e28SIngo Weinhold 
622e5150e28SIngo Weinhold 
623e5150e28SIngo Weinhold void
_CallDebuggerIfManagerNull()624e5150e28SIngo Weinhold BUnarchiver::_CallDebuggerIfManagerNull()
625e5150e28SIngo Weinhold {
626e5150e28SIngo Weinhold 	if (!fManager)
627e5150e28SIngo Weinhold 		debugger("BUnarchiver used with legacy or unprepared archive.");
628e5150e28SIngo Weinhold }
62989eb861aSAxel Dörfler 
63089eb861aSAxel Dörfler 
63189eb861aSAxel Dörfler // #pragma mark -
63289eb861aSAxel Dörfler 
63389eb861aSAxel Dörfler 
63489eb861aSAxel Dörfler BArchivable*
instantiate_object(BMessage * archive,image_id * _id)63589eb861aSAxel Dörfler instantiate_object(BMessage* archive, image_id* _id)
63689eb861aSAxel Dörfler {
63789eb861aSAxel Dörfler 	status_t statusBuffer;
63889eb861aSAxel Dörfler 	status_t* status = &statusBuffer;
63989eb861aSAxel Dörfler 	if (_id != NULL)
64089eb861aSAxel Dörfler 		status = _id;
64189eb861aSAxel Dörfler 
64289eb861aSAxel Dörfler 	// Check our params
64389eb861aSAxel Dörfler 	if (archive == NULL) {
64489eb861aSAxel Dörfler 		syslog(LOG_ERR, "instantiate_object failed: NULL BMessage argument");
64589eb861aSAxel Dörfler 		*status = B_BAD_VALUE;
64689eb861aSAxel Dörfler 		return NULL;
64789eb861aSAxel Dörfler 	}
64889eb861aSAxel Dörfler 
64989eb861aSAxel Dörfler 	// Get class name from archive
65089eb861aSAxel Dörfler 	const char* className = NULL;
65189eb861aSAxel Dörfler 	status_t err = archive->FindString(B_CLASS_FIELD, &className);
65289eb861aSAxel Dörfler 	if (err) {
65389eb861aSAxel Dörfler 		syslog(LOG_ERR, "instantiate_object failed: Failed to find an entry "
65489eb861aSAxel Dörfler 			"defining the class name (%s).", strerror(err));
65589eb861aSAxel Dörfler 		*status = B_BAD_VALUE;
65689eb861aSAxel Dörfler 		return NULL;
65789eb861aSAxel Dörfler 	}
65889eb861aSAxel Dörfler 
65989eb861aSAxel Dörfler 	// Get sig from archive
66089eb861aSAxel Dörfler 	const char* signature = NULL;
66189eb861aSAxel Dörfler 	bool hasSignature = archive->FindString(B_ADD_ON_FIELD, &signature) == B_OK;
66289eb861aSAxel Dörfler 
66336c85ca8SRene Gollent 	instantiation_func instantiationFunc = BPrivate::find_instantiation_func(
66436c85ca8SRene Gollent 		className, signature, _id);
66589eb861aSAxel Dörfler 
66689eb861aSAxel Dörfler 	// if find_instantiation_func() can't locate Class::Instantiate()
66789eb861aSAxel Dörfler 	// and a signature was specified
66889eb861aSAxel Dörfler 	if (!instantiationFunc && hasSignature) {
66989eb861aSAxel Dörfler 		// use BRoster::FindApp() to locate an app or add-on with the symbol
67089eb861aSAxel Dörfler 		BRoster Roster;
67189eb861aSAxel Dörfler 		entry_ref ref;
67289eb861aSAxel Dörfler 		err = Roster.FindApp(signature, &ref);
67389eb861aSAxel Dörfler 
67489eb861aSAxel Dörfler 		// if an entry_ref is obtained
67589eb861aSAxel Dörfler 		BEntry entry;
67689eb861aSAxel Dörfler 		if (err == B_OK)
67789eb861aSAxel Dörfler 			err = entry.SetTo(&ref);
67889eb861aSAxel Dörfler 
67989eb861aSAxel Dörfler 		BPath path;
68089eb861aSAxel Dörfler 		if (err == B_OK)
68189eb861aSAxel Dörfler 			err = entry.GetPath(&path);
68289eb861aSAxel Dörfler 
68389eb861aSAxel Dörfler 		if (err != B_OK) {
68489eb861aSAxel Dörfler 			syslog(LOG_ERR, "instantiate_object failed: Error finding app "
68589eb861aSAxel Dörfler 				"with signature \"%s\" (%s)", signature, strerror(err));
68689eb861aSAxel Dörfler 			*status = err;
68789eb861aSAxel Dörfler 			return NULL;
68889eb861aSAxel Dörfler 		}
68989eb861aSAxel Dörfler 
69089eb861aSAxel Dörfler 		// load the app/add-on
69189eb861aSAxel Dörfler 		image_id addOn = load_add_on(path.Path());
69289eb861aSAxel Dörfler 		if (addOn < B_OK) {
69389eb861aSAxel Dörfler 			syslog(LOG_ERR, "instantiate_object failed: Could not load "
69489eb861aSAxel Dörfler 				"add-on %s: %s.", path.Path(), strerror(addOn));
69589eb861aSAxel Dörfler 			*status = addOn;
69689eb861aSAxel Dörfler 			return NULL;
69789eb861aSAxel Dörfler 		}
69889eb861aSAxel Dörfler 
69989eb861aSAxel Dörfler 		// Save the image_id
70089eb861aSAxel Dörfler 		if (_id != NULL)
70189eb861aSAxel Dörfler 			*_id = addOn;
70289eb861aSAxel Dörfler 
70389eb861aSAxel Dörfler 		BString name = className;
70489eb861aSAxel Dörfler 		for (int32 pass = 0; pass < 2; pass++) {
70589eb861aSAxel Dörfler 			BString funcName;
70689eb861aSAxel Dörfler 			build_function_name(name, funcName);
70789eb861aSAxel Dörfler 
70889eb861aSAxel Dörfler 			instantiationFunc = find_function_in_image(funcName, addOn, err);
70989eb861aSAxel Dörfler 			if (instantiationFunc != NULL)
71089eb861aSAxel Dörfler 				break;
71189eb861aSAxel Dörfler 
71289eb861aSAxel Dörfler 			// Check if we have a private class, and add the BPrivate namespace
71389eb861aSAxel Dörfler 			// (for backwards compatibility)
71489eb861aSAxel Dörfler 			if (!add_private_namespace(name))
71589eb861aSAxel Dörfler 				break;
71689eb861aSAxel Dörfler 		}
71789eb861aSAxel Dörfler 
71889eb861aSAxel Dörfler 		if (instantiationFunc == NULL) {
71989eb861aSAxel Dörfler 			syslog(LOG_ERR, "instantiate_object failed: Failed to find exported "
72089eb861aSAxel Dörfler 				"Instantiate static function for class %s.", className);
72189eb861aSAxel Dörfler 			*status = B_NAME_NOT_FOUND;
72289eb861aSAxel Dörfler 			return NULL;
72389eb861aSAxel Dörfler 		}
72489eb861aSAxel Dörfler 	} else if (instantiationFunc == NULL) {
72589eb861aSAxel Dörfler 		syslog(LOG_ERR, "instantiate_object failed: No signature specified "
72689eb861aSAxel Dörfler 			"in archive, looking for class \"%s\".", className);
72789eb861aSAxel Dörfler 		*status = B_NAME_NOT_FOUND;
72889eb861aSAxel Dörfler 		return NULL;
72989eb861aSAxel Dörfler 	}
73089eb861aSAxel Dörfler 
73189eb861aSAxel Dörfler 	// if Class::Instantiate(BMessage*) was found
73289eb861aSAxel Dörfler 	if (instantiationFunc != NULL) {
73389eb861aSAxel Dörfler 		// use to create and return an object instance
73489eb861aSAxel Dörfler 		return instantiationFunc(archive);
73589eb861aSAxel Dörfler 	}
73689eb861aSAxel Dörfler 
73789eb861aSAxel Dörfler 	return NULL;
73889eb861aSAxel Dörfler }
73989eb861aSAxel Dörfler 
74089eb861aSAxel Dörfler 
74189eb861aSAxel Dörfler BArchivable*
instantiate_object(BMessage * from)74289eb861aSAxel Dörfler instantiate_object(BMessage* from)
74389eb861aSAxel Dörfler {
74489eb861aSAxel Dörfler 	return instantiate_object(from, NULL);
74552a38012Sejakowatz }
7469ecf9d1cSIngo Weinhold 
7479ecf9d1cSIngo Weinhold 
74829e8fa59SJohn Scipione //	#pragma mark - support_globals
74929e8fa59SJohn Scipione 
75029e8fa59SJohn Scipione 
7519ecf9d1cSIngo Weinhold bool
validate_instantiation(BMessage * from,const char * className)75289eb861aSAxel Dörfler validate_instantiation(BMessage* from, const char* className)
75352a38012Sejakowatz {
75489eb861aSAxel Dörfler 	// Make sure our params are kosher -- original skimped here =P
75589eb861aSAxel Dörfler 	if (!from) {
75689eb861aSAxel Dörfler 		errno = B_BAD_VALUE;
75789eb861aSAxel Dörfler 		return false;
75889eb861aSAxel Dörfler 	}
75989eb861aSAxel Dörfler 
76013bbfe42SAxel Dörfler 	BString name = className;
76113bbfe42SAxel Dörfler 	for (int32 pass = 0; pass < 2; pass++) {
76213bbfe42SAxel Dörfler 		const char* archiveClassName;
76313bbfe42SAxel Dörfler 		for (int32 index = 0; from->FindString(B_CLASS_FIELD, index,
76413bbfe42SAxel Dörfler 				&archiveClassName) == B_OK; ++index) {
765*7037b5d9SKyle Ambroff-Kao 			if (name == archiveClassName) {
766*7037b5d9SKyle Ambroff-Kao 				errno = B_OK;
76752a38012Sejakowatz 				return true;
76852a38012Sejakowatz 			}
769*7037b5d9SKyle Ambroff-Kao 		}
77052a38012Sejakowatz 
77113bbfe42SAxel Dörfler 		if (!add_private_namespace(name))
77213bbfe42SAxel Dörfler 			break;
77313bbfe42SAxel Dörfler 	}
77413bbfe42SAxel Dörfler 
77589eb861aSAxel Dörfler 	errno = B_MISMATCHED_VALUES;
77689eb861aSAxel Dörfler 	syslog(LOG_ERR, "validate_instantiation failed on class %s.", className);
77752a38012Sejakowatz 
77852a38012Sejakowatz 	return false;
77952a38012Sejakowatz }
78052a38012Sejakowatz 
78189eb861aSAxel Dörfler 
78289eb861aSAxel Dörfler instantiation_func
find_instantiation_func(const char * className,const char * signature)78389eb861aSAxel Dörfler find_instantiation_func(const char* className, const char* signature)
78489eb861aSAxel Dörfler {
78536c85ca8SRene Gollent 	return BPrivate::find_instantiation_func(className, signature, NULL);
78689eb861aSAxel Dörfler }
78789eb861aSAxel Dörfler 
78889eb861aSAxel Dörfler 
78989eb861aSAxel Dörfler instantiation_func
find_instantiation_func(const char * className)79089eb861aSAxel Dörfler find_instantiation_func(const char* className)
79189eb861aSAxel Dörfler {
79289eb861aSAxel Dörfler 	return find_instantiation_func(className, NULL);
79389eb861aSAxel Dörfler }
79489eb861aSAxel Dörfler 
79589eb861aSAxel Dörfler 
79689eb861aSAxel Dörfler instantiation_func
find_instantiation_func(BMessage * archive)79789eb861aSAxel Dörfler find_instantiation_func(BMessage* archive)
79889eb861aSAxel Dörfler {
79989eb861aSAxel Dörfler 	if (archive == NULL) {
80089eb861aSAxel Dörfler 		errno = B_BAD_VALUE;
80189eb861aSAxel Dörfler 		return NULL;
80289eb861aSAxel Dörfler 	}
80389eb861aSAxel Dörfler 
80489eb861aSAxel Dörfler 	const char* name = NULL;
80589eb861aSAxel Dörfler 	const char* signature = NULL;
80689eb861aSAxel Dörfler 	if (archive->FindString(B_CLASS_FIELD, &name) != B_OK
80789eb861aSAxel Dörfler 		|| archive->FindString(B_ADD_ON_FIELD, &signature)) {
80889eb861aSAxel Dörfler 		errno = B_BAD_VALUE;
80989eb861aSAxel Dörfler 		return NULL;
81089eb861aSAxel Dörfler 	}
81189eb861aSAxel Dörfler 
81289eb861aSAxel Dörfler 	return find_instantiation_func(name, signature);
81352a38012Sejakowatz }
81452a38012Sejakowatz 
815fbb6335dSIngo Weinhold 
81629e8fa59SJohn Scipione //	#pragma mark - BArchivable binary compatibility
817e5150e28SIngo Weinhold 
818fbb6335dSIngo Weinhold 
81929e8fa59SJohn Scipione #if __GNUC__ == 2
82029e8fa59SJohn Scipione 
821e5150e28SIngo Weinhold extern "C" status_t
_ReservedArchivable1__11BArchivable(BArchivable * archivable,const BMessage * archive)822e5150e28SIngo Weinhold _ReservedArchivable1__11BArchivable(BArchivable* archivable,
823e5150e28SIngo Weinhold 	const BMessage* archive)
824e5150e28SIngo Weinhold {
825e5150e28SIngo Weinhold 	// AllUnarchived
826e5150e28SIngo Weinhold 	perform_data_all_unarchived performData;
827e5150e28SIngo Weinhold 	performData.archive = archive;
828e5150e28SIngo Weinhold 
829e5150e28SIngo Weinhold 	archivable->Perform(PERFORM_CODE_ALL_UNARCHIVED, &performData);
830e5150e28SIngo Weinhold 	return performData.return_value;
831e5150e28SIngo Weinhold }
832e5150e28SIngo Weinhold 
833fbb6335dSIngo Weinhold 
834e5150e28SIngo Weinhold extern "C" status_t
_ReservedArchivable2__11BArchivable(BArchivable * archivable,BMessage * archive)835e5150e28SIngo Weinhold _ReservedArchivable2__11BArchivable(BArchivable* archivable,
836e5150e28SIngo Weinhold 	BMessage* archive)
837e5150e28SIngo Weinhold {
838e5150e28SIngo Weinhold 	// AllArchived
839e5150e28SIngo Weinhold 	perform_data_all_archived performData;
840e5150e28SIngo Weinhold 	performData.archive = archive;
841e5150e28SIngo Weinhold 
842e5150e28SIngo Weinhold 	archivable->Perform(PERFORM_CODE_ALL_ARCHIVED, &performData);
843e5150e28SIngo Weinhold 	return performData.return_value;
844e5150e28SIngo Weinhold }
845e5150e28SIngo Weinhold 
846fbb6335dSIngo Weinhold 
847e5150e28SIngo Weinhold #elif __GNUC__ > 2
848e5150e28SIngo Weinhold 
849e5150e28SIngo Weinhold extern "C" status_t
_ZN11BArchivable20_ReservedArchivable1Ev(BArchivable * archivable,const BMessage * archive)850e5150e28SIngo Weinhold _ZN11BArchivable20_ReservedArchivable1Ev(BArchivable* archivable,
851e5150e28SIngo Weinhold 	const BMessage* archive)
852e5150e28SIngo Weinhold {
853e5150e28SIngo Weinhold 	// AllUnarchived
854e5150e28SIngo Weinhold 	perform_data_all_unarchived performData;
855e5150e28SIngo Weinhold 	performData.archive = archive;
856e5150e28SIngo Weinhold 
857e5150e28SIngo Weinhold 	archivable->Perform(PERFORM_CODE_ALL_UNARCHIVED, &performData);
858e5150e28SIngo Weinhold 	return performData.return_value;
859e5150e28SIngo Weinhold }
860e5150e28SIngo Weinhold 
861fbb6335dSIngo Weinhold 
862e5150e28SIngo Weinhold extern "C" status_t
_ZN11BArchivable20_ReservedArchivable2Ev(BArchivable * archivable,BMessage * archive)863e5150e28SIngo Weinhold _ZN11BArchivable20_ReservedArchivable2Ev(BArchivable* archivable,
864e5150e28SIngo Weinhold 	BMessage* archive)
865e5150e28SIngo Weinhold {
866e5150e28SIngo Weinhold 	// AllArchived
867e5150e28SIngo Weinhold 	perform_data_all_archived performData;
868e5150e28SIngo Weinhold 	performData.archive = archive;
869e5150e28SIngo Weinhold 
870e5150e28SIngo Weinhold 	archivable->Perform(PERFORM_CODE_ALL_ARCHIVED, &performData);
871e5150e28SIngo Weinhold 	return performData.return_value;
872e5150e28SIngo Weinhold }
873e5150e28SIngo Weinhold 
874e5150e28SIngo Weinhold #endif // _GNUC__ > 2
875e5150e28SIngo Weinhold 
876fbb6335dSIngo Weinhold 
_ReservedArchivable3()877e5150e28SIngo Weinhold void BArchivable::_ReservedArchivable3() {}
878