summaryrefslogtreecommitdiff
path: root/indra/newview/llsyntaxid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llsyntaxid.cpp')
-rw-r--r--indra/newview/llsyntaxid.cpp292
1 files changed, 205 insertions, 87 deletions
diff --git a/indra/newview/llsyntaxid.cpp b/indra/newview/llsyntaxid.cpp
index 94226b82b1..3ee9859ccd 100644
--- a/indra/newview/llsyntaxid.cpp
+++ b/indra/newview/llsyntaxid.cpp
@@ -34,7 +34,6 @@
#include "llsdserialize.h"
#include "llsyntaxid.h"
-
//-----------------------------------------------------------------------------
// fetchKeywordsFileResponder
//-----------------------------------------------------------------------------
@@ -50,6 +49,7 @@ void fetchKeywordsFileResponder::errorWithContent(U32 status,
const std::string& reason,
const LLSD& content)
{
+ LLSyntaxIdLSL::sLoadFailed = true;
LL_ERRS("SyntaxLSL")
<< "fetchKeywordsFileResponder error [status:"
<< status << "]: " << content
@@ -58,8 +58,43 @@ void fetchKeywordsFileResponder::errorWithContent(U32 status,
void fetchKeywordsFileResponder::result(const LLSD& content_ref)
{
- LLSyntaxIdLSL::setKeywordsXml(content_ref);
+ // Continue only if a valid LLSD object was returned.
+ if (content_ref.isMap())
+ {
+ LL_DEBUGS("SyntaxLSL")
+ << "content_ref isMap so assuming valid XML." << LL_ENDL;
+
+ if (LLSyntaxIdLSL::isSupportedVersion(content_ref))
+ {
+ LL_INFOS("SyntaxLSL")
+ << "Supported verson of syntax file." << LL_ENDL;
+
+ LLSyntaxIdLSL::setKeywordsXml(content_ref);
+ LLSyntaxIdLSL::sInitialised = true;
+ LLSyntaxIdLSL::sLoaded = true;
+ LLSyntaxIdLSL::sLoadFailed = false;
+ cacheFile(content_ref);
+ }
+ else
+ {
+ LLSyntaxIdLSL::sLoaded = false;
+ LLSyntaxIdLSL::sLoadFailed = true;
+ LL_WARNS("SyntaxLSL")
+ << "Unknown or unsupported version of syntax file." << LL_ENDL;
+ }
+ }
+ else
+ {
+ LLSyntaxIdLSL::sLoaded = false;
+ LLSyntaxIdLSL::sLoadFailed = true;
+ LL_ERRS("SyntaxLSL")
+ << "Syntax file '" << mFileSpec << "' contains invalid LLSD!" << LL_ENDL;
+ }
+}
+
+void fetchKeywordsFileResponder::cacheFile(const LLSD& content_ref)
+{
std::stringstream str;
LLSDSerialize::toPrettyXML(content_ref, str);
const std::string xml = str.str();
@@ -70,29 +105,45 @@ void fetchKeywordsFileResponder::result(const LLSD& content_ref)
file.close();
LL_INFOS("SyntaxLSL")
- << "Syntax file received, saving as: '" << mFileSpec << "'" << LL_ENDL;
+ << "Syntax file received, saving as: '" << mFileSpec << "'" << LL_ENDL;
}
//-----------------------------------------------------------------------------
// LLSyntaxIdLSL
//-----------------------------------------------------------------------------
+const std::string LLSyntaxIdLSL::CAPABILITY_NAME = "LSLSyntax";
+const std::string LLSyntaxIdLSL::FILENAME_DEFAULT = "keywords_lsl_default.xml";
+const std::string LLSyntaxIdLSL::SIMULATOR_FEATURE = "LSLSyntaxId";
+
+bool LLSyntaxIdLSL::sInitialised;
+LLSD LLSyntaxIdLSL::sKeywordsXml;
+bool LLSyntaxIdLSL::sLoaded;
+bool LLSyntaxIdLSL::sLoadFailed;
+bool LLSyntaxIdLSL::sVersionChanged;
+
/**
* @brief LLSyntaxIdLSL constructor
*/
-LLSyntaxIdLSL::LLSyntaxIdLSL() :
- // Move these to signature?
- mFileNameDefault("keywords_lsl_default.xml"),
- mSimulatorFeature("LSLSyntaxId"),
- mCapabilityName("LSLSyntax"),
- mCapabilityURL(""),
+LLSyntaxIdLSL::LLSyntaxIdLSL(std::string filenameDefault, std::string simFeatureName, std::string capabilityName) :
mFilePath(LL_PATH_APP_SETTINGS)
{
+ mCapabilityName = capabilityName;
+ mFileNameCurrent = filenameDefault;
+ mFileNameDefault = filenameDefault;
+ mSimulatorFeature = simFeatureName;
mSyntaxIdCurrent = LLUUID();
- mFileNameCurrent = mFileNameDefault;
}
-LLSD LLSyntaxIdLSL::sKeywordsXml;
+LLSyntaxIdLSL::LLSyntaxIdLSL() :
+ mFilePath(LL_PATH_APP_SETTINGS)
+{
+ mCapabilityName = CAPABILITY_NAME;
+ mFileNameCurrent = FILENAME_DEFAULT;
+ mFileNameDefault = FILENAME_DEFAULT;
+ mSimulatorFeature = SIMULATOR_FEATURE;
+ mSyntaxIdCurrent = LLUUID();
+}
std::string LLSyntaxIdLSL::buildFileNameNew()
{
@@ -113,14 +164,15 @@ std::string LLSyntaxIdLSL::buildFullFileSpec()
//-----------------------------------------------------------------------------
bool LLSyntaxIdLSL::checkSyntaxIdChanged()
{
- bool changed = false;
+ sVersionChanged = false;
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
if (!region->capabilitiesReceived())
{ // Shouldn't be possible, but experience shows that it may be needed.
- LL_WARNS("SyntaxLSL")
+ sLoadFailed = true;
+ LL_ERRS("SyntaxLSL")
<< "Region '" << region->getName()
<< "' has not received capabilities yet! Cannot process SyntaxId."
<< LL_ENDL;
@@ -128,46 +180,60 @@ bool LLSyntaxIdLSL::checkSyntaxIdChanged()
else
{
LLSD simFeatures;
- std::string message;
region->getSimulatorFeatures(simFeatures);
- // get and check the hash
- if (simFeatures.has("LSLSyntaxId"))
+ // Does the sim have the required feature
+ if (simFeatures.has(mSimulatorFeature))
{
- mSyntaxIdNew = simFeatures["LSLSyntaxId"].asUUID();
+ // get and check the hash
+ mSyntaxIdNew = simFeatures[mSimulatorFeature].asUUID();
mCapabilityURL = region->getCapability(mCapabilityName);
if (mSyntaxIdCurrent != mSyntaxIdNew)
{
- message = "' it has LSLSyntaxId capability, and the new hash is '"
- + mSyntaxIdNew.asString() + "'";
+ LL_INFOS("SyntaxLSL")
+ << "It has LSLSyntaxId capability, and the new hash is '"
+ << mSyntaxIdNew.asString() << "'" << LL_ENDL;
- changed = true;
+ sVersionChanged = true;
}
else
{
- message = "' it has the same LSLSyntaxId! Leaving hash as '"
- + mSyntaxIdCurrent.asString() + "'";
+ LL_INFOS("SyntaxLSL")
+ << "It has the same LSLSyntaxId! Leaving hash as '"
+ << mSyntaxIdCurrent.asString() << "'" << LL_ENDL;
}
}
else
{
- if ( mSyntaxIdCurrent.isNull() )
+ if ( mSyntaxIdCurrent.isNull() && isInitialised())
{
- message = " it does not have LSLSyntaxId capability, remaining with default keywords file!";
+ LL_INFOS("SyntaxLSL")
+ << "It does not have LSLSyntaxId capability, remaining with default keywords file!"
+ << LL_ENDL;
}
else
{
// The hash is set to NULL_KEY to indicate use of default keywords file
mSyntaxIdNew = LLUUID();
- message = " it does not have LSLSyntaxId capability, using default keywords file!";
- changed = true;
+ LL_INFOS("SyntaxLSL")
+ << "It does not have LSLSyntaxId capability, using default keywords file!"
+ << LL_ENDL;
+ sVersionChanged = true;
}
}
- LL_INFOS("SyntaxLSL")
- << "Region is '" << region->getName() << message << LL_ENDL;
}
}
- return changed;
+ return sVersionChanged;
+}
+
+/**
+ * @brief LLSyntaxIdLSL::fetching
+ * If the XML has not loaded yet and it hasn't failed, then we're still fetching it.
+ * @return bool Whether the file fetch is still in process.
+ */
+bool LLSyntaxIdLSL::fetching()
+{
+ return !(sLoaded || sLoadFailed);
}
//-----------------------------------------------------------------------------
@@ -175,79 +241,118 @@ bool LLSyntaxIdLSL::checkSyntaxIdChanged()
//-----------------------------------------------------------------------------
void LLSyntaxIdLSL::fetchKeywordsFile()
{
- if ( !mCapabilityURL.empty() )
- {
- LLHTTPClient::get(mCapabilityURL,
- new fetchKeywordsFileResponder(mFullFileSpec),
- LLSD(), 30.f
- );
- LL_INFOS("SyntaxLSL")
- << "LSLSyntaxId capability URL is: " << mCapabilityURL
- << ". Filename to use is: '" << mFullFileSpec << "'."
- << LL_ENDL;
- }
- else
- {
- LL_ERRS("SyntaxLSL")
- << "LSLSyntaxId capability URL is empty!!" << LL_ENDL;
- }
+ LLHTTPClient::get(mCapabilityURL,
+ new fetchKeywordsFileResponder(mFullFileSpec),
+ LLSD(), 30.f
+ );
+ LL_INFOS("SyntaxLSL")
+ << "LSLSyntaxId capability URL is: " << mCapabilityURL
+ << ". Filename to use is: '" << mFullFileSpec << "'."
+ << LL_ENDL;
}
+//-----------------------------------------------------------------------------
+// initialise
+//-----------------------------------------------------------------------------
void LLSyntaxIdLSL::initialise()
{
mFileNameNew = mFileNameCurrent;
mSyntaxIdNew = mSyntaxIdCurrent;
+
if (checkSyntaxIdChanged())
{
- LL_INFOS("SyntaxLSL")
- << "LSL version has changed, getting appropriate file."
- << LL_ENDL;
+ sKeywordsXml = LLSD();
+ sLoaded = sLoadFailed = false;
- // Need a full spec regardless of file source, so build it now.
- buildFullFileSpec();
- if ( !mSyntaxIdNew.isNull() )
+ if (mSyntaxIdNew.isNull())
+ { // Need to open the default
+ loadDefaultKeywordsIntoLLSD();
+ }
+ else if (!mCapabilityURL.empty() )
{
- if ( !gDirUtilp->fileExists(mFullFileSpec) )
- { // Does not exist, so fetch it from the capability
- fetchKeywordsFile();
- LL_INFOS("SyntaxLSL")
- << "File is not cached, we will try to download it!"
- << LL_ENDL;
+ LL_INFOS("SyntaxLSL")
+ << "LSL version has changed, getting appropriate file."
+ << LL_ENDL;
+
+ // Need a full spec regardless of file source, so build it now.
+ buildFullFileSpec();
+ if ( !mSyntaxIdNew.isNull())
+ {
+ if ( !gDirUtilp->fileExists(mFullFileSpec) )
+ { // Does not exist, so fetch it from the capability
+ LL_INFOS("SyntaxLSL")
+ << "File is not cached, we will try to download it!"
+ << LL_ENDL;
+ fetchKeywordsFile();
+ }
+ else
+ {
+ LL_INFOS("SyntaxLSL")
+ << "File is cached, no need to download!"
+ << LL_ENDL;
+ loadKeywordsIntoLLSD();
+ }
}
else
- {
- LL_INFOS("SyntaxLSL")
- << "File is cached, no need to download!"
- << LL_ENDL;
- loadKeywordsIntoLLSD();
+ { // Need to open the default
+ loadDefaultKeywordsIntoLLSD();
}
}
else
- { // Need to open the default
- loadDefaultKeywordsIntoLLSD("LSLSyntaxId is null so we will use the default file!");
+ {
+ sLoadFailed = true;
+ LL_ERRS("SyntaxLSL")
+ << "LSLSyntaxId capability URL is empty!!" << LL_ENDL;
+ loadDefaultKeywordsIntoLLSD();
}
}
- else if (sKeywordsXml.isDefined())
+ else if (!isInitialised())
+ {
+ loadDefaultKeywordsIntoLLSD();
+ }
+
+ mFileNameCurrent = mFileNameNew;
+ mSyntaxIdCurrent = mSyntaxIdNew;
+}
+
+//-----------------------------------------------------------------------------
+// isSupportedVersion
+//-----------------------------------------------------------------------------
+bool LLSyntaxIdLSL::isSupportedVersion(const LLSD& content)
+{
+ bool isValid = false;
+ /*
+ * If the schema used to store LSL keywords and hints changes, this value is incremented
+ * Note that it should _not_ be changed if the keywords and hints _content_ changes.
+ */
+ const U32 LLSD_SYNTAX_LSL_VERSION_EXPECTED = 2;
+ const std::string LLSD_SYNTAX_LSL_VERSION_KEY("llsd-lsl-syntax-version");
+
+ if (content.has(LLSD_SYNTAX_LSL_VERSION_KEY))
{
LL_INFOS("SyntaxLSL")
- << "No change to Syntax! Nothing to see. Move along now!"
- << LL_ENDL;
+ << "Syntax file version: " << content[LLSD_SYNTAX_LSL_VERSION_KEY].asString() << LL_ENDL;
+
+ if (content[LLSD_SYNTAX_LSL_VERSION_KEY].asInteger() == LLSD_SYNTAX_LSL_VERSION_EXPECTED)
+ {
+ isValid = true;
+ }
}
else
- { // Need to open the default
- loadDefaultKeywordsIntoLLSD("LSLSyntaxId is null so we will use the default file!");
+ {
+ LL_WARNS("SyntaxLSL") << "No version key available!" << LL_ENDL;
}
- mFileNameCurrent = mFileNameNew;
- mSyntaxIdCurrent = mSyntaxIdNew;
+ return isValid;
}
//-----------------------------------------------------------------------------
// loadDefaultKeywordsIntoLLSD()
//-----------------------------------------------------------------------------
-void LLSyntaxIdLSL::loadDefaultKeywordsIntoLLSD(const std::string message)
+void LLSyntaxIdLSL::loadDefaultKeywordsIntoLLSD()
{
- LL_INFOS("SyntaxLSL") << message << LL_ENDL;
+ LL_INFOS("SyntaxLSL")
+ << "LSLSyntaxId is null so we will use the default file!" << LL_ENDL;
mSyntaxIdNew = LLUUID();
buildFullFileSpec();
loadKeywordsIntoLLSD();
@@ -259,39 +364,52 @@ void LLSyntaxIdLSL::loadDefaultKeywordsIntoLLSD(const std::string message)
/**
* @brief Load xml serialised LLSD
* @desc Opens the specified filespec and attempts to deserialise the
- * contained data to the specified LLSD object.
- * @return Returns boolean true/false indicating success or failure.
+ * contained data to the specified LLSD object. indicate success/failure with
+ * sLoaded/sLoadFailed members.
*/
-bool LLSyntaxIdLSL::loadKeywordsIntoLLSD()
+void LLSyntaxIdLSL::loadKeywordsIntoLLSD()
{
LL_INFOS("SyntaxLSL")
<< "Trying to open cached or default keyword file ;-)"
<< LL_ENDL;
- bool loaded = false;
+ // Is this the right thing to do, or should we leave the old content
+ // even if it isn't entirely accurate anymore?
+ sKeywordsXml = LLSD().emptyMap();
+
LLSD content;
llifstream file;
file.open(mFullFileSpec);
if (file.is_open())
{
- loaded = (bool)LLSDSerialize::fromXML(content, file);
- if (!loaded)
+ sLoaded = (bool)LLSDSerialize::fromXML(content, file);
+ if (!sLoaded)
{
- LL_ERRS("SyntaxLSL") << "Unable to deserialise file: " << mFullFileSpec << LL_ENDL;
-
- // Is this the right thing to do, or should we leave the old content
- // even if it isn't entirely accurate anymore?
- sKeywordsXml = LLSD().emptyMap();
+ LL_ERRS("SyntaxLSL")
+ << "Unable to deserialise file: "
+ << mFullFileSpec << LL_ENDL;
}
else
{
- sKeywordsXml = content;
- LL_INFOS("SyntaxLSL") << "Deserialised file: " << mFullFileSpec << LL_ENDL;
+ if (isSupportedVersion(content))
+ {
+ sKeywordsXml = content;
+ sLoaded = true;
+ sInitialised = true;
+ LL_INFOS("SyntaxLSL")
+ << "Deserialised file: " << mFullFileSpec << LL_ENDL;
+ }
+ else
+ {
+ sLoaded = false;
+ LL_WARNS("SyntaxLSL")
+ << "Unknown or unsupported version of syntax file." << LL_ENDL;
+ }
}
}
else
{
LL_ERRS("SyntaxLSL") << "Unable to open file: " << mFullFileSpec << LL_ENDL;
}
- return loaded;
+ sLoadFailed = !sLoaded;
}