You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

321 lines
7.4 KiB
C++

#include "plugin.h"
#include "tokenizer.h"
#ifdef _WINDOWS
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}
#else
#include <errno.h>
#include <string.h>
extern int errno;
#endif
SendPluginEv SendPluginEvent;
string g_GetSysErrMsg( void )
{
string strError = "Unknown";
// Problem loading
#ifdef _WINDOWS
int nErrorCode = GetLastError();
LPTSTR s;
if ( ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, nErrorCode, 0, ( LPTSTR ) &s, 0, NULL ) )
{
strError = s;
}
else
{
char szBuf[ 20 ];
_snprintf_s( szBuf, _countof(szBuf), 19, "%d", nErrorCode );
strError = szBuf;
}
#else
char szError[80];
if ( strerror_r( errno, szError, sizeof(szError) ) )
{
strError = "no description found";
}
else
{
strError = szError;
}
#endif
return strError;
}
void g_sleep( unsigned int mseconds )
{
#ifdef _WINDOWS
Sleep( mseconds );
#else
usleep( mseconds * 1000 );
#endif
}
string& g_trim( string& str )
{
// Whitespace characters
char whspc[] = " \t\r\n\v\f";
// Whack off first part
size_t pos = str.find_first_not_of( whspc );
if ( pos != string::npos )
str.replace( 0, pos, "" );
// Whack off trailing stuff
pos = str.find_last_not_of( whspc );
if ( pos != string::npos )
str.replace( pos + 1, str.length() - pos, "" );
return str;
}
void g_tokenize( const string& str, const string& delimiters, vector<string>& tokens )
{
tokenize( str, tokens, delimiters );
}
char* SetEventFunc( SendPluginEv funcPtr )
{
static char * szObjList = onGetObjList();
SendPluginEvent = funcPtr;
return szObjList;
}
const int nMAXSIZE = 512;
char* g_pszRetVal = NULL;
//-----------------------------------------------------------
// Map from an object Id to an object instance
//-----------------------------------------------------------
typedef std::map<string, JSExt*> StringToJExt_T;
//-----------------------------------------------------------
// Map from a browser context to an id mapping
//-----------------------------------------------------------
typedef std::map<void*, StringToJExt_T*> VoidToMap_T;
VoidToMap_T g_context2Map;
class GlobalSharedModule
{
public:
GlobalSharedModule( void )
{
g_pszRetVal = new char[ nMAXSIZE ];
}
~GlobalSharedModule()
{
delete [] g_pszRetVal;
VoidToMap_T::iterator posMaps;
for ( posMaps = g_context2Map.begin(); posMaps != g_context2Map.end(); ++posMaps )
{
StringToJExt_T& id2Obj = *posMaps->second;
StringToJExt_T::iterator posMap;
for ( posMap = id2Obj.begin(); posMap != id2Obj.end(); ++posMap )
{
JSExt* pJSExt = posMap->second;
if ( pJSExt->CanDelete() )
{
delete pJSExt;
}
}
id2Obj.erase( id2Obj.begin(), id2Obj.end() );
}
g_context2Map.erase( g_context2Map.begin(), g_context2Map.end() );
}
};
GlobalSharedModule g_sharedModule;
char* g_str2global( const string& strRetVal )
{
int nLen = strRetVal.size();
if ( nLen >= nMAXSIZE )
{
delete [] g_pszRetVal;
g_pszRetVal = new char[ nLen + 1 ];
}
else
{
// To minimaize the number of memory reallocations, the assumption
// is that in most times this will be the case
delete [] g_pszRetVal;
g_pszRetVal = new char[ nMAXSIZE ];
}
strcpy( g_pszRetVal, strRetVal.c_str() );
return g_pszRetVal;
}
bool g_unregisterObject( const string& strObjId, void* pContext )
{
// Called by the plugin extension implementation
// if the extension handles the deletion of its object
StringToJExt_T * pID2Obj = NULL;
VoidToMap_T::iterator iter = g_context2Map.find( pContext );
if ( iter != g_context2Map.end() )
{
pID2Obj = iter->second;
}
else
{
return false;
}
StringToJExt_T& mapID2Obj = *pID2Obj;
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r == mapID2Obj.end() )
{
return false;
}
mapID2Obj.erase( strObjId );
return true;
}
char* InvokeFunction( const char* szCommand, void* pContext )
{
StringToJExt_T * pID2Obj = NULL;
VoidToMap_T::iterator iter = g_context2Map.find( pContext );
if ( iter != g_context2Map.end() )
{
pID2Obj = iter->second;
}
else
{
pID2Obj = new StringToJExt_T;
g_context2Map[ pContext ] = pID2Obj;
}
StringToJExt_T& mapID2Obj = *pID2Obj;
string strFullCommand = szCommand;
vector<string> arParams;
g_tokenize( strFullCommand, " ", arParams );
string strCommand = arParams[ 0 ];
string strRetVal = szERROR;
if ( strCommand == szCREATE )
{
string strClassName = arParams[ 1 ];
string strObjId = arParams[ 2 ];
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r != mapID2Obj.end() )
{
strRetVal += strObjId;
strRetVal += " :Object already exists.";
return g_str2global( strRetVal );
}
JSExt* pJSExt = onCreateObject( strClassName, strObjId );
if ( pJSExt == NULL )
{
strRetVal += strObjId;
strRetVal += " :Unknown object type ";
strRetVal += strClassName;
return g_str2global( strRetVal );
}
pJSExt->m_pContext = pContext;
mapID2Obj[ strObjId ] = pJSExt;
strRetVal = szOK;
strRetVal += strObjId;
return g_str2global( strRetVal );
}
else
if ( strCommand == szINVOKE )
{
string strObjId = arParams[ 1 ];
string strMethod = arParams[ 2 ];
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r == mapID2Obj.end() )
{
strRetVal += strObjId;
strRetVal += " :No object found for id.";
return g_str2global( strRetVal );
}
JSExt* pJSExt = r->second;
size_t nLoc = strFullCommand.find( strObjId );
if ( nLoc == string::npos )
{
strRetVal += strObjId;
strRetVal += " :Internal InvokeMethod error.";
return g_str2global( strRetVal );
}
if ( strMethod == szDISPOSE )
{
StringToJExt_T::iterator r = mapID2Obj.find( strObjId );
if ( r == mapID2Obj.end() )
{
strRetVal = szERROR;
strRetVal += strObjId;
return g_str2global( strRetVal );
}
JSExt * pJSExt = mapID2Obj[ strObjId ];
if ( pJSExt->CanDelete() )
{
delete pJSExt;
}
mapID2Obj.erase( strObjId );
strRetVal = szOK;
strRetVal += strObjId;
return g_str2global( strRetVal );
}
size_t nSuffixLoc = nLoc + strObjId.size();
string strInvoke = strFullCommand.substr( nSuffixLoc );
strInvoke = g_trim( strInvoke );
strRetVal = pJSExt->InvokeMethod( strInvoke );
return g_str2global( strRetVal );
}
strRetVal += " :Unknown command ";
strRetVal += strCommand;
return g_str2global( strRetVal );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%