platform/shared/common/RhodesApp.cpp in rhodes-2.2.6 vs platform/shared/common/RhodesApp.cpp in rhodes-2.3.0.beta.1
- old
+ new
@@ -12,11 +12,14 @@
#include "net/HttpServer.h"
#include "ruby/ext/rho/rhoruby.h"
#include "net/AsyncHttp.h"
#include "rubyext/WebView.h"
#include "rubyext/GeoLocation.h"
+#include "common/app_build_configs.h"
+#include <algorithm>
+
#ifdef OS_WINCE
#include <winsock.h>
#endif
using rho::net::HttpHeader;
@@ -32,11 +35,197 @@
namespace rho {
namespace common{
IMPLEMENT_LOGCLASS(CRhodesApp,"RhodesApp");
+String CRhodesApp::m_strStartParameters;
+class CAppCallbacksQueue : public CThreadQueue
+{
+ DEFINE_LOGCLASS;
+public:
+ enum callback_t
+ {
+ app_deactivated,
+ local_server_restart,
+ local_server_started,
+ ui_created,
+ app_activated
+ };
+
+public:
+ CAppCallbacksQueue(IRhoClassFactory *factory);
+ ~CAppCallbacksQueue();
+
+ //void call(callback_t type);
+
+ friend class Command;
+ struct Command : public IQueueCommand
+ {
+ callback_t type;
+ Command(callback_t t) :type(t) {}
+
+ boolean equals(IQueueCommand const &) {return false;}
+ String toString() {return CAppCallbacksQueue::toString(type);}
+ };
+
+private:
+
+ void processCommand(IQueueCommand* pCmd);
+
+ static char const *toString(int type);
+
+private:
+ callback_t m_expected;
+ Vector<int> m_commands;
+};
+IMPLEMENT_LOGCLASS(CAppCallbacksQueue,"AppCallbacks");
+
+char const *CAppCallbacksQueue::toString(int type)
+{
+ switch (type)
+ {
+ case local_server_started:
+ return "LOCAL-SERVER-STARTED";
+ case ui_created:
+ return "UI-CREATED";
+ case app_activated:
+ return "APP-ACTIVATED";
+ case app_deactivated:
+ return "APP-DEACTIVATED";
+ case local_server_restart:
+ return "LOCAL-SERVER-RESTART";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+CAppCallbacksQueue::CAppCallbacksQueue(IRhoClassFactory *factory)
+ :CThreadQueue(factory), m_expected(local_server_started)
+{
+ CThreadQueue::setLogCategory(getLogCategory());
+ //setPollInterval(1);
+ start(epNormal);
+}
+
+CAppCallbacksQueue::~CAppCallbacksQueue()
+{
+}
+/*
+void CAppCallbacksQueue::call(CAppCallbacksQueue::callback_t type)
+{
+ addQueueCommand(new Command(type));
+}*/
+
+void CAppCallbacksQueue::processCommand(IQueueCommand* pCmd)
+{
+ Command *cmd = (Command *)pCmd;
+ if (!cmd)
+ return;
+/*
+ if (cmd->type < m_expected)
+ {
+ LOG(ERROR) + "received command " + toString(cmd->type) + " which is less than expected "+toString(m_expected)+" - ignore it";
+ return;
+ }
+*/
+ if ( m_expected == app_deactivated && cmd->type == app_activated )
+ {
+ LOG(INFO) + "received duplicate activate skip it";
+ return;
+ }
+
+ if ( m_expected == local_server_restart )
+ {
+ RHODESAPP().restartLocalServer(*this);
+ m_expected = local_server_started;
+ }
+
+ if (cmd->type > m_expected)
+ {
+ boolean bDuplicate = false;
+ for( int i = 0; i < m_commands.size() ; i++)
+ {
+ if ( m_commands.elementAt(i) == cmd->type )
+ {
+ bDuplicate = true;
+ break;
+ }
+ }
+
+ if ( bDuplicate )
+ {
+ LOG(INFO) + "Received duplicate command " + toString(cmd->type) + "skip it";
+ }else
+ {
+ // Don't do that now
+ LOG(INFO) + "Received command " + toString(cmd->type) + " which is greater than expected (" + toString(m_expected) + ") - postpone it";
+ m_commands.push_back(cmd->type);
+ std::sort(m_commands.begin(), m_commands.end());
+ }
+ return;
+ }
+
+ m_commands.insert(m_commands.begin(), cmd->type);
+ for (Vector<int>::const_iterator it = m_commands.begin(), lim = m_commands.end(); it != lim; ++it)
+ {
+ int type = *it;
+ LOG(INFO) + "process command: " + toString(type);
+ switch (type)
+ {
+ case app_deactivated:
+#if !defined( OS_WINCE ) && !defined (OS_WINDOWS)
+ m_expected = local_server_restart;
+#else
+ m_expected = app_activated;
+#endif
+ break;
+
+ case local_server_started:
+ // Nothing
+ break;
+ case ui_created:
+ {
+ common::CAutoPtr<common::IRhoClassFactory> factory = rho_impl_createClassFactory();
+ common::CAutoPtr<net::INetRequest> pNetRequest = factory->createNetRequest();
+ String strUrl = RHODESAPP().getBaseUrl();
+ strUrl += "/system/uicreated";
+ NetResponse(resp, pNetRequest->pullData( strUrl, null ) );
+ if ( !resp.isOK() )
+ LOG(ERROR) + "activate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
+
+ m_expected = app_activated;
+ }
+ break;
+ case app_activated:
+ {
+/* static bool navigatedToStartUrl = false;
+ if (!navigatedToStartUrl)
+ {
+ LOG(INFO) + "navigate to first start url";
+ RHODESAPP().navigateToUrl(RHODESAPP().getFirstStartUrl());
+ navigatedToStartUrl = true;
+ }*/
+
+ common::CAutoPtr<common::IRhoClassFactory> factory = rho_impl_createClassFactory();
+ common::CAutoPtr<net::INetRequest> pNetRequest = factory->createNetRequest();
+ String strUrl = RHODESAPP().getBaseUrl();
+ strUrl += "/system/activateapp";
+ NetResponse(resp, pNetRequest->pullData( strUrl, null ) );
+ if ( !resp.isOK() )
+ LOG(ERROR) + "activate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
+
+ m_expected = app_deactivated;
+ }
+ break;
+ }
+ //if (type < app_activated && type != app_deactivated)
+ // m_expected = (callback_t)(type + 1);
+ }
+ m_commands.clear();
+}
+
/*static*/ CRhodesApp* CRhodesApp::Create(const String& strRootPath)
{
if ( m_pInstance != null)
return (CRhodesApp*)m_pInstance;
@@ -50,18 +239,21 @@
delete m_pInstance;
m_pInstance = 0;
}
-CRhodesApp::CRhodesApp(const String& strRootPath) : CRhodesAppBase(strRootPath)
+CRhodesApp::CRhodesApp(const String& strRootPath)
+ :CRhodesAppBase(strRootPath)
{
m_bExit = false;
m_bDeactivationMode = false;
- m_activateCounter = 0;
+ m_bRestartServer = false;
+ //m_activateCounter = 0;
m_ptrFactory = rho_impl_createClassFactory();
m_NetRequest = m_ptrFactory->createNetRequest();
+ m_appCallbacksQueue = new CAppCallbacksQueue(rho_impl_createClassFactory());
#if defined( OS_WINCE ) || defined (OS_WINDOWS)
//initializing winsock
WSADATA WsaData;
int result = WSAStartup(MAKEWORD(2,2),&WsaData);
@@ -90,23 +282,24 @@
LOG(INFO) + "Starting sync engine...";
sync::CSyncThread::Create(rho_impl_createClassFactory());
LOG(INFO) + "RhoRubyInitApp...";
RhoRubyInitApp();
+ rho_ruby_call_config_conflicts();
+ RHOCONF().conflictsResolved();
-
- //rho_clientregister_create("iphone_client");
-#if defined( OS_WINCE ) || defined( OS_WINDOWS )
- LOG(INFO) + "navigate to first start url";
- RHODESAPP().navigateToUrl(RHODESAPP().getFirstStartUrl());
-#endif
-
while (!m_bExit) {
m_httpServer->run();
if (m_bExit)
break;
- wait(-1);
+
+ if ( !m_bRestartServer )
+ {
+ LOG(INFO) + "RhodesApp thread wait.";
+ wait(-1);
+ }
+ m_bRestartServer = false;
}
LOG(INFO) + "RhodesApp thread shutdown";
rubyext::CGeoLocation::Destroy();
@@ -122,12 +315,21 @@
WSACleanup();
#endif
}
+void CRhodesApp::restartLocalServer(common::CThreadQueue& waitThread)
+{
+ LOG(INFO) + "restart local server.";
+ m_bRestartServer = true;
+ m_httpServer->stop();
+}
+
void CRhodesApp::stopApp()
{
+ m_appCallbacksQueue->stop(1000);
+
if (!m_bExit)
{
m_bExit = true;
m_httpServer->stop();
stopWait();
@@ -197,61 +399,74 @@
rho_ruby_deactivateApp();
String strMsg;
rho_http_sendresponse(arg, strMsg.c_str());
}
+static void callback_uicreated(void *arg, String const &strQuery)
+{
+ rho_ruby_uiCreated();
+ rho_http_sendresponse(arg, "");
+}
+
+static void callback_uidestroyed(void *arg, String const &strQuery)
+{
+ rho_ruby_uiDestroyed();
+ rho_http_sendresponse(arg, "");
+}
+
static void callback_loadserversources(void *arg, String const &strQuery)
{
RhoAppAdapter.loadServerSources(strQuery);
String strMsg;
rho_http_sendresponse(arg, strMsg.c_str());
}
-class CRhoActivateApp
+static void callback_loadallsyncsources(void *arg, String const &strQuery)
{
- String m_strUrl;
-public:
- CRhoActivateApp(const String& strUrl) :m_strUrl(strUrl) {}
- void run(common::CRhoThread &thisThread)
- {
- while (!rho_is_local_server_started())
- thisThread.wait(1);
+ RhoAppAdapter.loadAllSyncSources();
+ String strMsg;
+ rho_http_sendresponse(arg, strMsg.c_str());
+}
- static bool navigated = false;
- if (!navigated)
- {
- LOG(INFO) + "navigate to first start url";
- RHODESAPP().navigateToUrl(RHODESAPP().getFirstStartUrl());
- navigated = true;
- }
- // RHODESAPP().getSplashScreen().hide();
+static void callback_resetDBOnSyncUserChanged(void *arg, String const &strQuery)
+{
+ RhoAppAdapter.resetDBOnSyncUserChanged();
+ String strMsg;
+ rho_http_sendresponse(arg, strMsg.c_str());
+}
- common::CAutoPtr<common::IRhoClassFactory> factory = rho_impl_createClassFactory();
- common::CAutoPtr<net::INetRequest> pNetRequest = factory->createNetRequest();
- NetResponse(resp, pNetRequest->pullData( m_strUrl, null ) );
- if ( !resp.isOK() )
- LOG(ERROR) + "activate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
+void CRhodesApp::callUiCreatedCallback()
+{
+ m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::ui_created));
+}
+
+void CRhodesApp::callUiDestroyedCallback()
+{
+ String strUrl = m_strHomeUrl + "/system/uidestroyed";
+ NetResponse(resp,getNet().pullData( strUrl, null ));
+ if ( !resp.isOK() )
+ {
+ LOG(ERROR) + "UI destroy callback failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
}
-};
+}
void CRhodesApp::callAppActiveCallback(boolean bActive)
{
LOG(INFO) + "callAppActiveCallback";
if (bActive)
{
// Restart server each time when we go to foreground
- if (m_activateCounter++ > 0)
+/* if (m_activateCounter++ > 0)
{
+#if !defined( OS_WINCE ) && !defined (OS_WINDOWS)
m_httpServer->stop();
+#endif
this->stopWait();
- }
-
- String strUrl = m_strHomeUrl + "/system/activateapp";
- // Activation callback need to be runned in separate thread
- // Otherwise UI thread will be blocked. This can cause deadlock if user defined
- // activate callback contains code which need to hold UI thread for execute
- rho_rhodesapp_call_in_thread( new CRhoActivateApp( strUrl ) );
+
+ } */
+
+ m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::app_activated));
}
else
{
// Deactivation callback must be called in place (not in separate thread!)
// This is because system can kill application at any time after this callback finished
@@ -259,10 +474,12 @@
// until application finish executing of user-defined deactivation callback.
// However, blocking UI thread can cause problem with API refering to UI (such as WebView.navigate etc)
// To fix this problem, new mode 'deactivation' introduced. When this mode active, no UI operations allowed.
// All such operation will throw exception in ruby code when calling in 'deactivate' mode.
m_bDeactivationMode = true;
+ m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::app_deactivated));
+
String strUrl = m_strHomeUrl + "/system/deactivateapp";
NetResponse(resp,getNet().pullData( strUrl, null ));
if ( !resp.isOK() )
{
LOG(ERROR) + "deactivate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
@@ -448,11 +665,15 @@
m_httpServer->register_uri("/system/shared", callback_shared);
m_httpServer->register_uri("/AppManager/loader/load", callback_AppManager_load);
m_httpServer->register_uri("/system/getrhomessage", callback_getrhomessage);
m_httpServer->register_uri("/system/activateapp", callback_activateapp);
m_httpServer->register_uri("/system/deactivateapp", callback_deactivateapp);
+ m_httpServer->register_uri("/system/uicreated", callback_uicreated);
+ m_httpServer->register_uri("/system/uidestroyed", callback_uidestroyed);
m_httpServer->register_uri("/system/loadserversources", callback_loadserversources);
+ m_httpServer->register_uri("/system/resetDBOnSyncUserChanged", callback_resetDBOnSyncUserChanged);
+ m_httpServer->register_uri("/system/loadallsyncsources", callback_loadallsyncsources);
}
const char* CRhodesApp::getFreeListeningPort()
{
int sockfd = -1;
@@ -593,12 +814,11 @@
size_t nFragment = strUrl.find('#');
if ( nFragment != String::npos )
strUrl = strUrl.substr(0, nFragment);
- RHOCONF().setString("LastVisitedPage",strUrl);
- RHOCONF().saveToFile();
+ RHOCONF().setString("LastVisitedPage",strUrl, true);
}
}
void CRhodesApp::setAppBackUrl(const String& url)
{
@@ -612,59 +832,101 @@
m_strAppBackUrlOrig = "";
m_strAppBackUrl = "";
}
}
-String CRhodesApp::getAppTitle()
+String CRhodesApp::getAppName()
{
- String strTitle = RHOCONF().getString("title_text");
- if ( strTitle.length() == 0 )
- {
+ String strAppName;
#ifdef OS_WINCE
- String path = rho_native_rhopath();
- int last, pre_last;
+ String path = rho_native_rhopath();
+ int last, pre_last;
- last = path.find_last_of('\\');
- pre_last = path.substr(0, last).find_last_of('\\');
- strTitle = path.substr(pre_last + 1, last - pre_last - 1);
+ last = path.find_last_of('\\');
+ pre_last = path.substr(0, last).find_last_of('\\');
+ strAppName = path.substr(pre_last + 1, last - pre_last - 1);
#else
- strTitle = "Rhodes";
+ strAppName = "Rhodes";
#endif
- }
+ return strAppName;
+}
+
+StringW CRhodesApp::getAppNameW()
+{
+ return convertToStringW( RHODESAPP().getAppName() );
+}
+
+String CRhodesApp::getAppTitle()
+{
+ String strTitle = RHOCONF().getString("title_text");
+ if ( strTitle.length() == 0 )
+ strTitle = getAppName();
+
return strTitle;
}
const String& CRhodesApp::getStartUrl()
{
m_strStartUrl = canonicalizeRhoUrl( RHOCONF().getString("start_path") );
return m_strStartUrl;
}
+boolean CRhodesApp::isOnStartPage()
+{
+ String strStart = getStartUrl();
+ String strCurUrl = getCurrentUrl(0);
+
+ if ( strStart.compare(strCurUrl) == 0 )
+ return true;
+
+ //check for index
+ int nIndexLen = CHttpServer::isIndex(strStart);
+ if ( nIndexLen > 0 && String_startsWith(strStart, strCurUrl) )
+ {
+ return strncmp(strStart.c_str(), strCurUrl.c_str(), strStart.length() - nIndexLen - 1) == 0;
+ }
+
+ nIndexLen = CHttpServer::isIndex(strCurUrl);
+ if ( nIndexLen > 0 && String_startsWith(strCurUrl, strStart) )
+ {
+ return strncmp(strCurUrl.c_str(), strStart.c_str(), strCurUrl.length() - nIndexLen - 1) == 0;
+ }
+
+ return false;
+
+}
+
+const String& CRhodesApp::getBaseUrl()
+{
+ return m_strHomeUrl;
+}
+
const String& CRhodesApp::getOptionsUrl()
{
m_strOptionsUrl = canonicalizeRhoUrl( RHOCONF().getString("options_path") );
return m_strOptionsUrl;
}
const String& CRhodesApp::getCurrentUrl(int /*index*/)
{
return m_currentUrls[m_currentTabIndex];
}
-
+/*
const String& CRhodesApp::getFirstStartUrl()
{
m_strFirstStartUrl = getStartUrl();
if ( RHOCONF().getBool("KeepTrackOfLastVisitedPage") )
{
rho::String strLastPage = RHOCONF().getString("LastVisitedPage");
if (strLastPage.length() > 0)
m_strFirstStartUrl = canonicalizeRhoUrl(strLastPage);
}
+ LOG(INFO) + "Start url: " + m_strFirstStartUrl;
return m_strFirstStartUrl;
-}
+}*/
const String& CRhodesApp::getRhobundleReloadUrl()
{
m_strRhobundleReloadUrl = RHOCONF().getString("rhobundle_zip_url");
return m_strRhobundleReloadUrl;
@@ -830,19 +1092,38 @@
}
}
void CRhodesApp::loadUrl(String url)
{
+ if ( url.length() == 0 )
+ return;
+
boolean callback = false;
if (String_startsWith(url, "callback:") )
{
callback = true;
url = url.substr(9);
}else if ( strcasecmp(url.c_str(), "exit")==0 || strcasecmp(url.c_str(), "close") == 0 )
{
rho_sys_app_exit();
return;
+ }else if ( strcasecmp(url.c_str(), "options")==0 )
+ {
+ rho_webview_navigate(getOptionsUrl().c_str(), 0);
+ return;
+ }else if ( strcasecmp(url.c_str(), "home")==0 )
+ {
+ rho_webview_navigate(getStartUrl().c_str(), 0);
+ return;
+ }else if ( strcasecmp(url.c_str(), "refresh")==0 )
+ {
+ rho_webview_refresh(0);
+ return;
+ }else if ( strcasecmp(url.c_str(), "back")==0 )
+ {
+ navigateBack();
+ return;
}
url = canonicalizeRhoUrl(url);
if (callback)
{
@@ -852,22 +1133,21 @@
}
else
navigateToUrl(url);
}
-boolean CRhodesApp::isLocalServerStarted()
+void CRhodesApp::notifyLocalServerStarted()
{
- if (!m_httpServer)
- return false;
- return m_httpServer->started();
+ m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::local_server_started));
}
} //namespace common
} //namespace rho
extern "C" {
+using namespace rho;
using namespace rho::common;
unsigned long rho_rhodesapp_GetCallbackObject(int nIndex)
{
return RHODESAPP().getCallbackObject(nIndex);
}
@@ -968,15 +1248,15 @@
void rho_rhodesapp_destroy()
{
rho::common::CRhodesApp::Destroy();
}
-
+/*
const char* rho_rhodesapp_getfirststarturl()
{
return RHODESAPP().getFirstStartUrl().c_str();
-}
+}*/
const char* rho_rhodesapp_getstarturl()
{
return RHODESAPP().getStartUrl().c_str();
}
@@ -1046,10 +1326,22 @@
{
if ( rho::common::CRhodesApp::getInstance() )
RHODESAPP().callAppActiveCallback(nActive!=0);
}
+void rho_rhodesapp_callUiCreatedCallback()
+{
+ if ( rho::common::CRhodesApp::getInstance() )
+ RHODESAPP().callUiCreatedCallback();
+}
+
+void rho_rhodesapp_callUiDestroyedCallback()
+{
+ if ( rho::common::CRhodesApp::getInstance() )
+ RHODESAPP().callUiDestroyedCallback();
+}
+
void rho_rhodesapp_setViewMenu(unsigned long valMenu)
{
RHODESAPP().getAppMenu().setAppMenu(valMenu);
}
@@ -1091,81 +1383,10 @@
int rho_conf_send_log()
{
return RHODESAPP().sendLog();
}
-static const char table64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-int rho_base64_encode(const char *src, int srclen, char *dst)
-{
- if (srclen < 0)
- srclen = strlen(src);
- if (!dst)
- return (srclen/3)*4 + (srclen%3 ? 4 : 0) + 1;
-
- int out = 0;
- for(int in = 0; in < srclen; in += 3, out += 4) {
-
- unsigned x = 0;
- int actual = 0;
- for (int i = 0; i < 3; ++i) {
- char c;
- if (in + i >= srclen)
- c = 0;
- else {
- c = src[in + i];
- actual += 8;
- }
- x = (x << 8) + (unsigned char)c;
- }
-
- for (int i = 0; i < 4; ++i) {
- if (actual <= 0) {
- dst[out + i] = '=';
- }
- else {
- dst[out + i] = table64[(x >> 18) & 0x3F];
- x <<= 6;
- actual -= 6;
- }
- }
- }
-
- dst[out++] = '\0';
- return out;
-}
-
-int rho_base64_decode(const char *src, int srclen, char *dst)
-{
- if (srclen < 0)
- srclen = strlen(src);
- // Do not decode in case if srclen can not be divided by 4
- if (srclen%4)
- return 0;
- if (!dst)
- return srclen*3/4 + 1;
-
- char *found;
- int out = 0;
- for (int in = 0; in < srclen; in += 4, out += 3) {
- unsigned x = 0;
- for (int i = 0; i < 4; ++i) {
- if ((found = strchr(const_cast<char*>(table64), src[in + i])) != NULL)
- x = (x << 6) + (unsigned int)(found - table64);
- else if (src[in + i] == '=')
- x <<= 6;
- }
-
- for (int i = 0; i < 3; ++i) {
- dst[out + i] = (unsigned char)((x >> 16) & 0xFF);
- x <<= 8;
- }
- }
- dst[out++] = '\0';
- return out;
-}
-
void rho_net_request(const char *url)
{
rho::common::CAutoPtr<rho::common::IRhoClassFactory> factory = rho_impl_createClassFactory();
rho::common::CAutoPtr<rho::net::INetRequest> request = factory->createNetRequest();
request->pullData(url, null);
@@ -1175,11 +1396,10 @@
rho::common::CAutoPtr<rho::common::IRhoClassFactory> factory = rho_impl_createClassFactory();
rho::common::CAutoPtr<rho::net::INetRequest> request = factory->createNetRequest();
request->pushData(url, str_body, null);
}
-
void rho_rhodesapp_load_url(const char *url)
{
RHODESAPP().loadUrl(url);
}
@@ -1191,15 +1411,10 @@
return 0;
}
return 1;
}
-int rho_is_local_server_started()
-{
- return RHODESAPP().isLocalServerStarted();
-}
-
#if defined(OS_ANDROID) && defined(RHO_LOG_ENABLED)
int rho_log(const char *fmt, ...)
{
va_list vl;
va_start(vl, fmt);
@@ -1218,7 +1433,34 @@
void rho_free_callbackdata(void* pData)
{
//It is used in SyncClient.
}
-
+
+int rho_rhodesapp_canstartapp(const char* szCmdLine, const char* szSeparators)
+{
+ CRhodesApp::setStartParameters(szCmdLine);
+
+ const char* szAppSecToken = get_app_build_config_item("security_token");
+ if ( !szAppSecToken || !*szAppSecToken)
+ return 1;
+
+ String strCmdLineSecToken;
+ String security_key = "security_token=";
+ String strCmdLine = szCmdLine ? szCmdLine : "";
+
+ int skpos = strCmdLine.find(security_key);
+ if ((String::size_type)skpos != String::npos)
+ {
+ String tmp = strCmdLine.substr(skpos+security_key.length(), strCmdLine.length() - security_key.length() - skpos);
+
+ int divider = tmp.find_first_of(szSeparators);
+ if ((String::size_type)divider != String::npos)
+ strCmdLineSecToken = tmp.substr(0, divider);
+ else
+ strCmdLineSecToken = tmp;
+ }
+
+ return strCmdLineSecToken.compare(szAppSecToken) != 0 ? 0 : 1;
+}
+
} //extern "C"