1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
/*
* File: DLL_interface.cpp
*
* Author: Beat Forster (bfo@synthesis.ch)
*
*
* General interface to access the routines
* of a DLL.
*
* Copyright (c) 2004-2011 by Synthesis AG + plan44.ch
*
*
*/
#include "sync_include.h"
#include "sync_dbapidef.h"
#include "sync_dbapiconnect.h"
#include "SDK_util.h"
#include "SDK_support.h"
#include "DLL_interface.h"
#ifdef ANDROID
#include "android/log.h"
#endif
#ifdef SYSYNC_ENGINE
#include "syncappbase.h"
#endif
#ifdef JNI_SUPPORT
#include "JNI_interface.h"
#endif
#ifdef __cplusplus
namespace sysync {
#endif
// ------------------------------------------------------------------
#ifdef PLUGIN_DLL
//! derived class for DLL access
bool TDLL::Connect( cAppCharP aModName, ErrReport aReport, void* /* ref */ )
{
fModName= Plugin_MainName( aModName );
return ConnectDLL( fMod, fModName.c_str(), aReport );
} // TDLL::Connect
bool TDLL::GetFunction( cAppCharP aFuncName, cAppCharP /* aParams */,
appPointer &aFunc, ErrMReport aReport, void* ref )
{
appPointer m; /* don't overwrite <aFunc> if "" or in case of error */
if (*aFuncName=='\0') return true;
if (!DLL_Function( fMod, aFuncName, m )) {
aReport( ref, aFuncName,fModName.c_str() ); return false; }
aFunc= m; return true;
} // TDLL::GetFunction
bool TDLL::Disconnect() {
return DisconnectDLL( fMod );
} // TDLL::Disconnect
#endif // PLUGIN_DLL
// ---- Handler for DLL connection reporting ------------------------
static void ReportPuts( cAppCharP aText )
{
#ifdef ANDROiD
__android_log_write( ANDROID_LOG_DEBUG, "ReportError", aText );
#else
ConsolePrintf( aText );
#endif
} // ReportPuts
void Report_Error( cAppCharP aText, ... )
{
const sInt16 maxmsglen=1024;
char msg[maxmsglen];
va_list args;
msg[0]='\0';
va_start(args, aText);
// assemble the message string
vsnprintf(msg, maxmsglen, aText, args);
va_end(args);
// write the string
ReportPuts( msg );
}
void ModuleConnectionError( void* /* ref */, cAppCharP aModName )
{
string s= "Can't connect to library " + Apo( aModName ) + ".";
Report_Error ( s.c_str() );
} // ModuleConnectionError
void FuncConnectionError( void* /* ref */, cAppCharP aFuncName, cAppCharP aModName )
{
string s= "Can't connect to function " + Apo( aFuncName );
if (*aModName!='\0') s+= " of module " + Apo( aModName );
s+= ".";
Report_Error ( s.c_str() );
} // FuncConnectionError
// ------------------------------------------------------------------
static TAccess* AssignedObject( cAppCharP name, bool is_jni )
// Create object for LIB or DLL or JNI
{
TAccess* d = NULL;
bool is_lib= false;
do {
#ifdef JNI_SUPPORT
if (is_jni) { d= static_cast<TAccess*>( new TJNI_Methods ); break; } // JNI (Java)
#endif
is_lib= IsLib( name );
if (is_lib) { d= new TAccess; break; } // LIB direct
#ifdef PLUGIN_DLL
d= static_cast<TAccess*>( new TDLL ); break; // DLL (C/C++)
#endif
} while (false);
if (d==NULL) return NULL;
d->fJNI= is_jni;
d->fLIB= is_lib;
return d;
} // AssignedObject
static void FreeAssignedObject( TAccess* d )
{
do {
#ifdef JNI_SUPPORT
if (d->fJNI) { TJNI_Methods* dj= static_cast<TJNI_Methods*>( d );
delete dj; break; } // JNI (Java)
#endif
if (d->fLIB) { delete d; break; } // LIB direct
#ifdef PLUGIN_DLL
{ TDLL* dd= static_cast<TDLL*>( d );
delete dd; break; } // DLL (C/C++)
#endif
} while (false);
}
// ------------------------------------------------------------------
TSyError ConnectModule( appPointer &aMod, cAppCharP aModName, bool is_jni )
{
TAccess* d= AssignedObject( aModName, is_jni );
if (!d) return DB_Forbidden;
if (d->Connect ( aModName,ModuleConnectionError ))
{ aMod= d; return LOCERR_OK; }
else { aMod= NULL; FreeAssignedObject(d); return DB_NotFound; }
} // ConnectModule
TSyError ConnectFunctions( appPointer aMod, appPointer aField, memSize aFieldSize,
bool aParamInfo, ... )
/* Connect to DLL <aDLLname> (or LIB if <aDLLname> = "") */
{
TSyError err = LOCERR_OK;
TAccess* d = (TAccess*)aMod;
char* p = NULL;
char* q;
appPointer* m = (appPointer*)aField;
bool notEnough= false;
bool tooMany = false;
if (aParamInfo) aFieldSize= 2*aFieldSize;
// do vararg handling
va_list args;
va_start( args, aParamInfo ); // the element before the open param list
// now go thru the list of all functions and put them into the list
uInt32 ii= 0;
while (ii*sizeof(p)<=aFieldSize) {
p= va_arg( args, char* ); if (p==NULL) break;
if (p==(char*)XX)
p= NULL; // XX is equivalent to NULL, but not termination of the list
q= NULL;
// if aParamInfo, treat them as a pair <p>,<q>
if (aParamInfo) {
q= va_arg( args, char* ); if (q==NULL) break;
ii++;
} // if
ii++;
if (!err) {
bool ok= d->GetFunction( p,q, *m, FuncConnectionError );
if (!ok) err= DB_NotFound;
} // if
m++;
} // while
if (err) goto done;
// check if table is too small or too long
while (ii*sizeof(p)<aFieldSize) {
notEnough= true;
*m= NULL; // initialize the rest to zero
m++;
ii++;
if (aParamInfo) ii++;
} // while
tooMany= (p!=NULL);
if (notEnough || tooMany) err = LOCERR_WRONGUSAGE;
done:
va_end( args );
return err;
} // ConnectFunctions
TSyError DisconnectModule( appPointer &aMod )
{
TAccess* d = (TAccess*)aMod;
TSyError err= LOCERR_OK;
if (d==NULL) return err;
if (!d->Disconnect()) err= DB_NotFound;
FreeAssignedObject(d);
aMod= NULL; // no longer access
return err;
} // DisconnectModule
#ifdef __cplusplus
} // namespace
#endif
/* eof */
|