openEventsPlatformApp/plugins/ionic-plugin-keyboard/src/blackberry10/native/public/plugin.cpp
plugins/ionic-plugin-keyboard/src/blackberry10/native/public/plugin.cppRaw
1#include "plugin.h"
2#include "tokenizer.h"
3
4#ifdef _WINDOWS
5#include <windows.h>
6BOOL APIENTRY DllMain( HANDLE hModule,
7 DWORD ul_reason_for_call,
8 LPVOID lpReserved )
9{
10 return TRUE;
11}
12#else
13#include <errno.h>
14#include <string.h>
15
16extern int errno;
17#endif
18
19SendPluginEv SendPluginEvent;
20
21string g_GetSysErrMsg( void )
22{
23 string strError = "Unknown";
24 // Problem loading
25#ifdef _WINDOWS
26 int nErrorCode = GetLastError();
27 LPTSTR s;
28 if ( ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
29 NULL, nErrorCode, 0, ( LPTSTR ) &s, 0, NULL ) )
30 {
31 strError = s;
32 }
33 else
34 {
35 char szBuf[ 20 ];
36 _snprintf_s( szBuf, _countof(szBuf), 19, "%d", nErrorCode );
37 strError = szBuf;
38 }
39#else
40 char szError[80];
41 if ( strerror_r( errno, szError, sizeof(szError) ) )
42 {
43 strError = "no description found";
44 }
45 else
46 {
47 strError = szError;
48 }
49#endif
50 return strError;
51}
52
53void g_sleep( unsigned int mseconds )
54{
55#ifdef _WINDOWS
56 Sleep( mseconds );
57#else
58 usleep( mseconds * 1000 );
59#endif
60}
61
62string& g_trim( string& str )
63{
64 // Whitespace characters
65 char whspc[] = " \t\r\n\v\f";
66
67 // Whack off first part
68 size_t pos = str.find_first_not_of( whspc );
69
70 if ( pos != string::npos )
71 str.replace( 0, pos, "" );
72
73 // Whack off trailing stuff
74 pos = str.find_last_not_of( whspc );
75
76 if ( pos != string::npos )
77 str.replace( pos + 1, str.length() - pos, "" );
78
79 return str;
80}
81
82void g_tokenize( const string& str, const string& delimiters, vector<string>& tokens )
83{
84 tokenize( str, tokens, delimiters );
85}
86
87char* SetEventFunc( SendPluginEv funcPtr )
88{
89 static char * szObjList = onGetObjList();
90 SendPluginEvent = funcPtr;
91 return szObjList;
92}
93
94
95const int nMAXSIZE = 512;
96char* g_pszRetVal = NULL;
97
98//-----------------------------------------------------------
99// Map from an object Id to an object instance
100//-----------------------------------------------------------
101typedef std::map<string, JSExt*> StringToJExt_T;
102
103//-----------------------------------------------------------
104// Map from a browser context to an id mapping
105//-----------------------------------------------------------
106typedef std::map<void*, StringToJExt_T*> VoidToMap_T;
107
108VoidToMap_T g_context2Map;
109
110class GlobalSharedModule
111{
112
113public:
114 GlobalSharedModule( void )
115 {
116 g_pszRetVal = new char[ nMAXSIZE ];
117 }
118
119 ~GlobalSharedModule()
120 {
121 delete [] g_pszRetVal;
122
123 VoidToMap_T::iterator posMaps;
124
125 for ( posMaps = g_context2Map.begin(); posMaps != g_context2Map.end(); ++posMaps )
126 {
127 StringToJExt_T& id2Obj = *posMaps->second;
128 StringToJExt_T::iterator posMap;
129
130 for ( posMap = id2Obj.begin(); posMap != id2Obj.end(); ++posMap )
131 {
132 JSExt* pJSExt = posMap->second;
133
134 if ( pJSExt->CanDelete() )
135 {
136 delete pJSExt;
137 }
138 }
139
140 id2Obj.erase( id2Obj.begin(), id2Obj.end() );
141 }
142
143 g_context2Map.erase( g_context2Map.begin(), g_context2Map.end() );
144 }
145};
146
147GlobalSharedModule g_sharedModule;
148
149char* g_str2global( const string& strRetVal )
150{
151 int nLen = strRetVal.size();
152
153 if ( nLen >= nMAXSIZE )
154 {
155 delete [] g_pszRetVal;
156 g_pszRetVal = new char[ nLen + 1 ];
157 }
158
159 else
160 {
161 // To minimaize the number of memory reallocations, the assumption
162 // is that in most times this will be the case
163 delete [] g_pszRetVal;
164 g_pszRetVal = new char[ nMAXSIZE ];
165 }
166
167 strcpy( g_pszRetVal, strRetVal.c_str() );
168 return g_pszRetVal;
169}
170
171bool g_unregisterObject( const string& strObjId, void* pContext )
172{
173 // Called by the plugin extension implementation
174 // if the extension handles the deletion of its object
175
176 StringToJExt_T * pID2Obj = NULL;
177
178 VoidToMap_T::iterator iter = g_context2Map.find( pContext );
179
180 if ( iter != g_context2Map.end() )
181 {
182 pID2Obj = iter->second;
183 }
184 else
185 {
186 return false;
187 }
188
189 StringToJExt_T& mapID2Obj = *pID2Obj;
190
191 StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
192
193 if ( r == mapID2Obj.end() )
194 {
195 return false;
196 }
197
198 mapID2Obj.erase( strObjId );
199 return true;
200}
201
202char* InvokeFunction( const char* szCommand, void* pContext )
203{
204 StringToJExt_T * pID2Obj = NULL;
205
206 VoidToMap_T::iterator iter = g_context2Map.find( pContext );
207
208 if ( iter != g_context2Map.end() )
209 {
210 pID2Obj = iter->second;
211 }
212 else
213 {
214 pID2Obj = new StringToJExt_T;
215 g_context2Map[ pContext ] = pID2Obj;
216 }
217
218 StringToJExt_T& mapID2Obj = *pID2Obj;
219
220 string strFullCommand = szCommand;
221 vector<string> arParams;
222 g_tokenize( strFullCommand, " ", arParams );
223 string strCommand = arParams[ 0 ];
224 string strRetVal = szERROR;
225
226 if ( strCommand == szCREATE )
227 {
228 string strClassName = arParams[ 1 ];
229 string strObjId = arParams[ 2 ];
230
231 StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
232
233 if ( r != mapID2Obj.end() )
234 {
235 strRetVal += strObjId;
236 strRetVal += " :Object already exists.";
237 return g_str2global( strRetVal );
238 }
239
240 JSExt* pJSExt = onCreateObject( strClassName, strObjId );
241
242 if ( pJSExt == NULL )
243 {
244 strRetVal += strObjId;
245 strRetVal += " :Unknown object type ";
246 strRetVal += strClassName;
247 return g_str2global( strRetVal );
248 }
249
250 pJSExt->m_pContext = pContext;
251 mapID2Obj[ strObjId ] = pJSExt;
252
253 strRetVal = szOK;
254 strRetVal += strObjId;
255 return g_str2global( strRetVal );
256 }
257 else
258 if ( strCommand == szINVOKE )
259 {
260 string strObjId = arParams[ 1 ];
261 string strMethod = arParams[ 2 ];
262
263 StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
264
265 if ( r == mapID2Obj.end() )
266 {
267 strRetVal += strObjId;
268 strRetVal += " :No object found for id.";
269 return g_str2global( strRetVal );
270 }
271
272 JSExt* pJSExt = r->second;
273
274 size_t nLoc = strFullCommand.find( strObjId );
275
276 if ( nLoc == string::npos )
277 {
278 strRetVal += strObjId;
279 strRetVal += " :Internal InvokeMethod error.";
280 return g_str2global( strRetVal );
281 }
282
283 if ( strMethod == szDISPOSE )
284 {
285 StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
286
287 if ( r == mapID2Obj.end() )
288 {
289 strRetVal = szERROR;
290 strRetVal += strObjId;
291 return g_str2global( strRetVal );
292 }
293
294 JSExt * pJSExt = mapID2Obj[ strObjId ];
295
296 if ( pJSExt->CanDelete() )
297 {
298 delete pJSExt;
299 }
300
301 mapID2Obj.erase( strObjId );
302 strRetVal = szOK;
303 strRetVal += strObjId;
304 return g_str2global( strRetVal );
305 }
306
307 size_t nSuffixLoc = nLoc + strObjId.size();
308 string strInvoke = strFullCommand.substr( nSuffixLoc );
309 strInvoke = g_trim( strInvoke );
310 strRetVal = pJSExt->InvokeMethod( strInvoke );
311 return g_str2global( strRetVal );
312 }
313
314 strRetVal += " :Unknown command ";
315 strRetVal += strCommand;
316 return g_str2global( strRetVal );
317}
318
319//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320