ObjFW  Diff

Differences From Artifact [e14701ced1]:

To Artifact [dfbf2c9e77]:


26
27
28
29
30
31
32
33



34
35
36


37
38
39
40
41




42
43
44
45
46
47









48
49
50
51





52

53
54

55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77

78


79



80
81
82
83
84




85
86
87

88
89
90

91
92
93
94
95
96
97
98

99
100
101
102
103
104
105




106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127




128
129
130


131



132






133
134
135
136

137




138
139
140
141
142
143
26
27
28
29
30
31
32

33
34
35
36


37
38
39




40
41
42
43






44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60

61


62
63











64











65
66
67
68

69
70
71
72




73
74
75
76



77



78






79

80
81






82
83
84
85

86







87













88
89
90
91
92


93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115


116
117







-
+
+
+

-
-
+
+

-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-



+
+
+
+
+
-
+
-
-
+

-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+

+
+
-
+
+
+

-
-
-
-
+
+
+
+
-
-
-
+
-
-
-
+
-
-
-
-
-
-

-
+

-
-
-
-
-
-
+
+
+
+
-

-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+

-
-
+
+

+
+
+
-
+
+
+
+
+
+




+
-
+
+
+
+


-
-


#import "OFLocale.h"
#import "OFString.h"
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFLoadPluginFailedException.h"

typedef OFPlugin *(*PluginInit)(void);
#ifndef RTLD_LAZY
# define RTLD_LAZY 0
#endif

OFPluginHandle
OFDLOpen(OFString *path, OFDLOpenFlags flags)
@implementation OFPlugin
+ (instancetype)pluginWithPath: (OFString *)path
{
#ifndef OF_WINDOWS
	return dlopen([path cStringWithEncoding: [OFLocale encoding]], flags);
#else
	if (path == nil)
	return [[[self alloc] initWithPath: path] autorelease];
}

+ (OFString *)pathForName: (OFString *)name
		return GetModuleHandle(NULL);

	if ([OFSystemInfo isWindowsNT])
		return LoadLibraryW(path.UTF16String);
	else
		return LoadLibraryA(
{
#if defined(OF_MACOS)
	return [name stringByAppendingFormat: @".bundle/Contents/MacOS/%@",
					      name.lastPathComponent];
#elif defined(OF_IOS)
	return [name stringByAppendingFormat: @".bundle/%@",
					      name.lastPathComponent];
#else
	return [name stringByAppendingString: @PLUGIN_SUFFIX];
		    [path cStringWithEncoding: [OFLocale encoding]]);
#endif
}

- (instancetype)initWithPath: (OFString *)path
{
	self = [super init];

	@try {
void *
		void *pool = objc_autoreleasePoolPush();
OFDLSym(OFPluginHandle handle, const char *symbol)
{

#ifndef OF_WINDOWS
	return dlsym(handle, symbol);
#else
	return (void *)(uintptr_t)GetProcAddress(handle, symbol);
#endif
}

void
OFDLClose(OFPluginHandle handle)
{
#ifndef OF_WINDOWS
	dlclose(handle);
		_handle = dlopen(
#else
	FreeLibrary(handle);
#endif
}

OFString *
OFDLError(void)
{
#ifndef OF_WINDOWS
	return [OFString stringWithCString: dlerror()
				  encoding: [OFLocale encoding]];
		    [path cStringWithEncoding: [OFLocale encoding]], RTLD_LAZY);
#else
		if ([OFSystemInfo isWindowsNT])
			_handle = LoadLibraryW(path.UTF16String);
	return nil;
		else
			_handle = LoadLibraryA(
			    [path cStringWithEncoding: [OFLocale encoding]]);
#endif
}

@implementation OFPlugin
+ (id)pluginWithPath: (OFString *)path

		if (_handle == NULL) {
#ifndef OF_WINDOWS
			OFString *error = [OFString
{
	void *pool = objc_autoreleasePoolPush();
	OFPluginHandle handle;
			    stringWithCString: dlerror()
	PluginInit initPlugin;
	OFPlugin *plugin;

				     encoding: [OFLocale encoding]];
#if defined(OF_MACOS)
	path = [path stringByAppendingFormat: @".bundle/Contents/MacOS/%@",
					      path.lastPathComponent];
#elif defined(OF_IOS)
	path = [path stringByAppendingFormat: @".bundle/%@",
					      path.lastPathComponent];
#else
	path = [path stringByAppendingString: @PLUGIN_SUFFIX];
			OFString *error = nil;
#endif

	if ((handle = OFDLOpen(path, OFDLOpenFlagLazy)) == NULL)
		@throw [OFLoadPluginFailedException
		    exceptionWithPath: path
				error: OFDLError()];

			@throw [OFLoadPluginFailedException
			    exceptionWithPath: path
					error: error];
		}
	objc_autoreleasePoolPop(pool);

	initPlugin = (PluginInit)(uintptr_t)OFDLSym(handle, "OFPluginInit");
	if (initPlugin == (PluginInit)0 || (plugin = initPlugin()) == nil) {
		OFDLClose(handle);
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
	}

		objc_autoreleasePoolPop(pool);
	plugin->_pluginHandle = handle;
	return plugin;
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFPlugin class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

		abort();
	}
	return self;
}

- (void *)addressForSymbol: (OFString *)symbol
{
#ifndef OF_WINDOWS
	return [super init];
	return dlsym(_handle,
	    [symbol cStringWithEncoding: [OFLocale encoding]]);
#else
	return (void *)(uintptr_t)GetProcAddress(_handle,
	    [symbol cStringWithEncoding: [OFLocale encoding]]);
#endif
}

- (void)dealloc
{
#ifndef OF_WINDOWS
	OFPluginHandle h = _pluginHandle;
	dlclose(_handle);
#else
	FreeLibrary(_handle);
#endif

	[super dealloc];

	OFDLClose(h);
}
@end