Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git
Conflicts: indra/llrender/llpostprocess.cpp
This commit is contained in:
@@ -69,6 +69,7 @@ set(llcommon_SOURCE_FILES
|
||||
llmetrics.cpp
|
||||
llmortician.cpp
|
||||
lloptioninterface.cpp
|
||||
llpredicate.cpp
|
||||
llprocesslauncher.cpp
|
||||
llprocessor.cpp
|
||||
llptrto.cpp
|
||||
@@ -177,7 +178,6 @@ set(llcommon_HEADER_FILES
|
||||
llformat.h
|
||||
llframetimer.h
|
||||
llhandle.h
|
||||
llhash.h
|
||||
llheartbeat.h
|
||||
llhttpstatuscodes.h
|
||||
llindexedqueue.h
|
||||
@@ -199,6 +199,7 @@ set(llcommon_HEADER_FILES
|
||||
llnametable.h
|
||||
lloptioninterface.h
|
||||
llpointer.h
|
||||
llpredicate.h
|
||||
llpreprocessor.h
|
||||
llpriqueuemap.h
|
||||
llprocesslauncher.h
|
||||
@@ -241,7 +242,6 @@ set(llcommon_HEADER_FILES
|
||||
lltypeinfolookup.h
|
||||
lluri.h
|
||||
lluuid.h
|
||||
sguuidhash.h
|
||||
llversionviewer.h.in
|
||||
llworkerthread.h
|
||||
metaclass.h
|
||||
|
||||
@@ -140,10 +140,6 @@ const U32 DEFAULT_CGI_SERVICES_PORT = 12045;
|
||||
// on a single host for map tile generation. JC
|
||||
const U32 DEFAULT_MAPSERVER_PORT = 12124;
|
||||
|
||||
// For automatic port discovery when running multiple viewers on one host
|
||||
const U32 PORT_DISCOVERY_RANGE_MIN = 13000;
|
||||
const U32 PORT_DISCOVERY_RANGE_MAX = PORT_DISCOVERY_RANGE_MIN + 50;
|
||||
|
||||
const char LAND_LAYER_CODE = 'L';
|
||||
const char WATER_LAYER_CODE = 'W';
|
||||
const char WIND_LAYER_CODE = '7';
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include "boost/atomic.hpp"
|
||||
template<typename T>
|
||||
struct impl_atomic_type { typedef boost::atomic<T> type; };
|
||||
#elif defined(USE_STD_ATOMIC) && (__cplusplus >= 201103L || _MSC_VER >= 1800)
|
||||
#elif defined(USE_STD_ATOMIC) && defined(LL_CPP11)
|
||||
#include <atomic>
|
||||
template<typename T>
|
||||
struct impl_atomic_type { typedef std::atomic<T> type; };
|
||||
|
||||
@@ -3,31 +3,25 @@
|
||||
* @brief base32 encoding that returns a std::string
|
||||
* @author James Cook
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2007-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,31 +3,25 @@
|
||||
* @brief Wrapper for apr base64 encoding that returns a std::string
|
||||
* @author James Cook
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2007-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -36,32 +30,72 @@
|
||||
#include "llbase64.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "apr_base64.h"
|
||||
|
||||
|
||||
// static
|
||||
std::string LLBase64::encode(const U8* input, size_t input_size)
|
||||
{
|
||||
std::string output;
|
||||
if (input
|
||||
&& input_size > 0)
|
||||
{
|
||||
// Yes, it returns int.
|
||||
int b64_buffer_length = apr_base64_encode_len(input_size);
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
|
||||
// This is faster than apr_base64_encode() if you know
|
||||
// you're not on an EBCDIC machine. Also, the output is
|
||||
// null terminated, even though the documentation doesn't
|
||||
// specify. See apr_base64.c for details. JC
|
||||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
input,
|
||||
input_size);
|
||||
output.assign(b64_buffer);
|
||||
delete[] b64_buffer;
|
||||
}
|
||||
return output;
|
||||
if (!(input && input_size > 0)) return LLStringUtil::null;
|
||||
|
||||
// Yes, it returns int.
|
||||
int b64_buffer_length = apr_base64_encode_len(input_size);
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
|
||||
// This is faster than apr_base64_encode() if you know
|
||||
// you're not on an EBCDIC machine. Also, the output is
|
||||
// null terminated, even though the documentation doesn't
|
||||
// specify. See apr_base64.c for details. JC
|
||||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
input,
|
||||
input_size);
|
||||
std::string result;
|
||||
result.assign(b64_buffer);
|
||||
delete[] b64_buffer;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLBase64::encode(const std::string& in_str)
|
||||
{
|
||||
size_t data_size = in_str.size();
|
||||
std::vector<U8> data;
|
||||
data.resize(data_size);
|
||||
memcpy(&data[0], in_str.c_str(), data_size);
|
||||
return encode(&data[0], data_size);
|
||||
}
|
||||
|
||||
// static
|
||||
size_t LLBase64::decode(const std::string& input, U8 * buffer, size_t buffer_size)
|
||||
{
|
||||
if (input.empty()) return 0;
|
||||
|
||||
size_t bytes_written = apr_base64_decode_binary(buffer, input.data());
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
std::string LLBase64::decode(const std::string& input)
|
||||
{
|
||||
U32 buffer_len = LLBase64::requiredDecryptionSpace(input);
|
||||
std::vector<U8> buffer(buffer_len);
|
||||
buffer_len = LLBase64::decode(input, &buffer[0], buffer_len);
|
||||
buffer.resize(buffer_len);
|
||||
return std::string(reinterpret_cast<const char*>(&buffer[0]), buffer_len);
|
||||
}
|
||||
|
||||
// static
|
||||
size_t LLBase64::requiredDecryptionSpace(const std::string& str)
|
||||
{
|
||||
size_t len = str.length();
|
||||
U32 padding = 0;
|
||||
|
||||
if (str[len - 1] == '=' && str[len - 2] == '=') //last two chars are =
|
||||
padding = 2;
|
||||
else if (str[len - 1] == '=') //last char is =
|
||||
padding = 1;
|
||||
|
||||
return len * 0.75 - padding;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,31 +3,25 @@
|
||||
* @brief Wrapper for apr base64 encoding that returns a std::string
|
||||
* @author James Cook
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2007-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -37,7 +31,11 @@
|
||||
class LL_COMMON_API LLBase64
|
||||
{
|
||||
public:
|
||||
static std::string encode(const std::string& in_str);
|
||||
static std::string encode(const U8* input, size_t input_size);
|
||||
static size_t decode(const std::string& input, U8 * buffer, size_t buffer_size);
|
||||
static std::string decode(const std::string& input);
|
||||
static size_t requiredDecryptionSpace(const std::string& str);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/**
|
||||
* @file llhash.h
|
||||
* @brief Wrapper for a hash function.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLHASH_H
|
||||
#define LL_LLHASH_H
|
||||
|
||||
#include "llpreprocessor.h" // for GCC_VERSION
|
||||
|
||||
#if (LL_WINDOWS)
|
||||
#include <hash_map>
|
||||
#include <algorithm>
|
||||
#elif LL_DARWIN || LL_LINUX
|
||||
#if GCC_VERSION >= 40300 || LL_ICC || LL_CLANG// gcc 4.3 or icc 11 and up
|
||||
# include <backward/hashtable.h>
|
||||
#elif GCC_VERSION >= 30400 // gcc 3.4 and up
|
||||
# include <ext/hashtable.h>
|
||||
#elif __GNUC__ >= 3
|
||||
# include <ext/stl_hashtable.h>
|
||||
#else
|
||||
# include <hashtable.h>
|
||||
#endif
|
||||
#elif LL_SOLARIS
|
||||
#include <ext/hashtable.h>
|
||||
#else
|
||||
#error Please define your platform.
|
||||
#endif
|
||||
|
||||
// Warning - an earlier template-based version of this routine did not do
|
||||
// the correct thing on Windows. Since this is only used to get
|
||||
// a string hash, it was converted to a regular routine and
|
||||
// unit tests added.
|
||||
|
||||
inline size_t llhash( const char * value )
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
return stdext::hash_value(value);
|
||||
#elif ( (defined _STLPORT_VERSION) || ((LL_LINUX) && (__GNUC__ <= 2)) )
|
||||
std::hash<const char *> H;
|
||||
return H(value);
|
||||
#elif LL_DARWIN || LL_LINUX || LL_SOLARIS
|
||||
__gnu_cxx::hash<const char *> H;
|
||||
return H(value);
|
||||
#else
|
||||
#error Please define your platform.
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,10 +28,17 @@
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llinitparam.h"
|
||||
#include "llformat.h"
|
||||
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
|
||||
predicate_rule_t default_parse_rules()
|
||||
{
|
||||
return ll_make_predicate(PROVIDED) && !ll_make_predicate(EMPTY);
|
||||
}
|
||||
|
||||
//
|
||||
// Param
|
||||
//
|
||||
@@ -196,6 +203,9 @@ namespace LLInitParam
|
||||
|
||||
bool BaseBlock::validateBlock(bool emit_errors) const
|
||||
{
|
||||
// only validate block when it hasn't already passed validation with current data
|
||||
if (!mValidated)
|
||||
{
|
||||
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
|
||||
for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
|
||||
{
|
||||
@@ -209,11 +219,18 @@ namespace LLInitParam
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
mValidated = true;
|
||||
}
|
||||
return mValidated;
|
||||
}
|
||||
|
||||
void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
|
||||
bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const LLInitParam::BaseBlock* diff_block) const
|
||||
{
|
||||
bool serialized = false;
|
||||
if (!predicate_rule.check(ll_make_predicate(PROVIDED, isProvided())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// named param is one like LLView::Params::follows
|
||||
// unnamed param is like LLView::Params::rect - implicit
|
||||
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
|
||||
@@ -225,10 +242,10 @@ namespace LLInitParam
|
||||
param_handle_t param_handle = (*it)->mParamHandle;
|
||||
const Param* param = getParamFromHandle(param_handle);
|
||||
ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
|
||||
if (serialize_func)
|
||||
if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))
|
||||
{
|
||||
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
|
||||
serialize_func(*param, parser, name_stack, diff_param);
|
||||
serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +256,7 @@ namespace LLInitParam
|
||||
param_handle_t param_handle = it->second->mParamHandle;
|
||||
const Param* param = getParamFromHandle(param_handle);
|
||||
ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
|
||||
if (serialize_func && param->anyProvided())
|
||||
if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))
|
||||
{
|
||||
// Ensure this param has not already been serialized
|
||||
// Prevents <rect> from being serialized as its own tag.
|
||||
@@ -264,10 +281,17 @@ namespace LLInitParam
|
||||
|
||||
name_stack.push_back(std::make_pair(it->first, !duplicate));
|
||||
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
|
||||
serialize_func(*param, parser, name_stack, diff_param);
|
||||
serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
|
||||
name_stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!serialized && predicate_rule.check(ll_make_predicate(EMPTY)))
|
||||
{
|
||||
serialized |= parser.writeValue(Flag(), name_stack);
|
||||
}
|
||||
// was anything serialized in this block?
|
||||
return serialized;
|
||||
}
|
||||
|
||||
bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
|
||||
|
||||
@@ -29,14 +29,17 @@
|
||||
#define LL_LLPARAM_H
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llstl.h"
|
||||
#include "llpredicate.h"
|
||||
#include "llsd.h"
|
||||
|
||||
namespace LLTypeTags
|
||||
{
|
||||
@@ -195,6 +198,8 @@ namespace LLInitParam
|
||||
return mValue;
|
||||
}
|
||||
|
||||
bool isValid() const { return true; }
|
||||
|
||||
protected:
|
||||
T mValue;
|
||||
};
|
||||
@@ -209,13 +214,11 @@ namespace LLInitParam
|
||||
typedef T value_t;
|
||||
|
||||
ParamValue()
|
||||
: T(),
|
||||
mValidated(false)
|
||||
: T()
|
||||
{}
|
||||
|
||||
ParamValue(const default_value_t& other)
|
||||
: T(other),
|
||||
mValidated(false)
|
||||
: T(other)
|
||||
{}
|
||||
|
||||
void setValue(const value_t& val)
|
||||
@@ -232,9 +235,6 @@ namespace LLInitParam
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
};
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ namespace LLInitParam
|
||||
typedef self_t type_value_t;
|
||||
|
||||
TypeValuesHelper(const std::string& val)
|
||||
: base_t(val)
|
||||
: base_t::TypeValuesHelper(val) // <alchemy/> Fix invalid blah gcc
|
||||
{}
|
||||
|
||||
void operator ()(const std::string& name)
|
||||
@@ -579,6 +579,19 @@ namespace LLInitParam
|
||||
|
||||
class Param;
|
||||
|
||||
enum ESerializePredicates
|
||||
{
|
||||
PROVIDED,
|
||||
REQUIRED,
|
||||
VALID,
|
||||
HAS_DEFAULT_VALUE,
|
||||
EMPTY
|
||||
};
|
||||
|
||||
typedef LLPredicate::Rule<ESerializePredicates> predicate_rule_t;
|
||||
|
||||
LL_COMMON_API predicate_rule_t default_parse_rules();
|
||||
|
||||
// various callbacks and constraints associated with an individual param
|
||||
struct LL_COMMON_API ParamDescriptor
|
||||
{
|
||||
@@ -589,7 +602,7 @@ namespace LLInitParam
|
||||
|
||||
typedef bool(*merge_func_t)(Param&, const Param&, bool);
|
||||
typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);
|
||||
typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
|
||||
typedef bool(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const predicate_rule_t rules, const Param* diff_param);
|
||||
typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
|
||||
typedef bool(*validation_func_t)(const Param*);
|
||||
|
||||
@@ -829,12 +842,28 @@ namespace LLInitParam
|
||||
LOG_CLASS(BaseBlock);
|
||||
friend class Param;
|
||||
|
||||
BaseBlock()
|
||||
: mValidated(false),
|
||||
mParamProvided(false)
|
||||
{}
|
||||
|
||||
virtual ~BaseBlock() {}
|
||||
bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
|
||||
|
||||
param_handle_t getHandleFromParam(const Param* param) const;
|
||||
bool validateBlock(bool emit_errors = true) const;
|
||||
|
||||
bool isProvided() const
|
||||
{
|
||||
return mParamProvided;
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return validateBlock(false);
|
||||
}
|
||||
|
||||
|
||||
Param* getParamFromHandle(const param_handle_t param_handle)
|
||||
{
|
||||
if (param_handle == 0) return NULL;
|
||||
@@ -852,10 +881,19 @@ namespace LLInitParam
|
||||
void addSynonym(Param& param, const std::string& synonym);
|
||||
|
||||
// Blocks can override this to do custom tracking of changes
|
||||
virtual void paramChanged(const Param& changed_param, bool user_provided) {}
|
||||
virtual void paramChanged(const Param& changed_param, bool user_provided)
|
||||
{
|
||||
if (user_provided)
|
||||
{
|
||||
// a child param has been explicitly changed
|
||||
// so *some* aspect of this block is now provided
|
||||
mValidated = false;
|
||||
mParamProvided = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
|
||||
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
|
||||
bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule, const BaseBlock* diff_block = NULL) const;
|
||||
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
|
||||
|
||||
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
|
||||
@@ -893,6 +931,9 @@ namespace LLInitParam
|
||||
return mergeBlock(block_data, source, overwrite);
|
||||
}
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
bool mParamProvided;
|
||||
|
||||
private:
|
||||
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
|
||||
};
|
||||
@@ -986,6 +1027,8 @@ namespace LLInitParam
|
||||
|
||||
bool isProvided() const { return Param::anyProvided(); }
|
||||
|
||||
bool isValid() const { return true; }
|
||||
|
||||
static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
|
||||
{
|
||||
self_t& typed_param = static_cast<self_t&>(param);
|
||||
@@ -1014,10 +1057,23 @@ namespace LLInitParam
|
||||
return false;
|
||||
}
|
||||
|
||||
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
|
||||
static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
|
||||
{
|
||||
bool serialized = false;
|
||||
const self_t& typed_param = static_cast<const self_t&>(param);
|
||||
if (!typed_param.isProvided()) return;
|
||||
const self_t* diff_typed_param = static_cast<const self_t*>(diff_param);
|
||||
|
||||
LLPredicate::Value<ESerializePredicates> predicate;
|
||||
if (diff_typed_param && ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
|
||||
{
|
||||
predicate.set(HAS_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
predicate.set(VALID, typed_param.isValid());
|
||||
predicate.set(PROVIDED, typed_param.anyProvided());
|
||||
predicate.set(EMPTY, false);
|
||||
|
||||
if (!predicate_rule.check(predicate)) return false;
|
||||
|
||||
if (!name_stack.empty())
|
||||
{
|
||||
@@ -1030,25 +1086,27 @@ namespace LLInitParam
|
||||
|
||||
if (!key.empty())
|
||||
{
|
||||
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
|
||||
if (!diff_typed_param || !ParamCompare<std::string>::equals(diff_typed_param->getValueName(), key))
|
||||
{
|
||||
parser.writeValue(key, name_stack);
|
||||
serialized = parser.writeValue(key, name_stack);
|
||||
}
|
||||
}
|
||||
// then try to serialize value directly
|
||||
else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
|
||||
else if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
|
||||
{
|
||||
if (!parser.writeValue(typed_param.getValue(), name_stack))
|
||||
serialized = parser.writeValue(typed_param.getValue(), name_stack);
|
||||
if (!serialized)
|
||||
{
|
||||
std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
|
||||
if (calculated_key.size()
|
||||
&& (!diff_param
|
||||
&& (!diff_typed_param
|
||||
|| !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))
|
||||
{
|
||||
parser.writeValue(calculated_key, name_stack);
|
||||
serialized = parser.writeValue(calculated_key, name_stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
|
||||
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
|
||||
@@ -1065,7 +1123,7 @@ namespace LLInitParam
|
||||
void set(const value_t& val, bool flag_as_provided = true)
|
||||
{
|
||||
named_value_t::clearValueName();
|
||||
this->setValue(val);
|
||||
named_value_t::setValue(val);
|
||||
setProvided(flag_as_provided);
|
||||
}
|
||||
|
||||
@@ -1113,15 +1171,15 @@ namespace LLInitParam
|
||||
};
|
||||
|
||||
// parameter that is a block
|
||||
template <typename T, typename NAME_VALUE_LOOKUP>
|
||||
class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
|
||||
template <typename BLOCK_T, typename NAME_VALUE_LOOKUP>
|
||||
class TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
|
||||
: public Param,
|
||||
public NAME_VALUE_LOOKUP::type_value_t
|
||||
{
|
||||
protected:
|
||||
typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
|
||||
typedef ParamValue<typename LLTypeTags::Sorted<BLOCK_T>::value_t> param_value_t;
|
||||
typedef typename param_value_t::default_value_t default_value_t;
|
||||
typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
|
||||
typedef TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
|
||||
typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
|
||||
public:
|
||||
using named_value_t::operator();
|
||||
@@ -1166,10 +1224,16 @@ namespace LLInitParam
|
||||
return false;
|
||||
}
|
||||
|
||||
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
|
||||
static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
|
||||
{
|
||||
const self_t& typed_param = static_cast<const self_t&>(param);
|
||||
if (!typed_param.isProvided()) return;
|
||||
|
||||
LLPredicate::Value<ESerializePredicates> predicate;
|
||||
|
||||
predicate.set(VALID, typed_param.isValid());
|
||||
predicate.set(PROVIDED, typed_param.anyProvided());
|
||||
|
||||
if (!predicate_rule.check(predicate)) return false;
|
||||
|
||||
if (!name_stack.empty())
|
||||
{
|
||||
@@ -1182,12 +1246,15 @@ namespace LLInitParam
|
||||
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
|
||||
{
|
||||
parser.writeValue(key, name_stack);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
|
||||
return typed_param.serializeBlock(parser, name_stack, predicate_rule, static_cast<const self_t*>(diff_param));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
|
||||
@@ -1209,23 +1276,19 @@ namespace LLInitParam
|
||||
// *and* the block as a whole validates
|
||||
bool isProvided() const
|
||||
{
|
||||
// only validate block when it hasn't already passed validation with current data
|
||||
if (Param::anyProvided() && !param_value_t::mValidated)
|
||||
{
|
||||
// a sub-block is "provided" when it has been filled in enough to be valid
|
||||
param_value_t::mValidated = param_value_t::validateBlock(false);
|
||||
}
|
||||
return Param::anyProvided() && param_value_t::mValidated;
|
||||
return Param::anyProvided() && isValid();
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return param_value_t::isValid();
|
||||
}
|
||||
|
||||
// assign block contents to this param-that-is-a-block
|
||||
void set(const value_t& val, bool flag_as_provided = true)
|
||||
{
|
||||
this->setValue(val);
|
||||
named_value_t::setValue(val);
|
||||
named_value_t::clearValueName();
|
||||
// force revalidation of block
|
||||
// next call to isProvided() will update provision status based on validity
|
||||
param_value_t::mValidated = false;
|
||||
setProvided(flag_as_provided);
|
||||
}
|
||||
|
||||
@@ -1242,9 +1305,6 @@ namespace LLInitParam
|
||||
|
||||
if (user_provided)
|
||||
{
|
||||
// a child param has been explicitly changed
|
||||
// so *some* aspect of this block is now provided
|
||||
param_value_t::mValidated = false;
|
||||
setProvided();
|
||||
named_value_t::clearValueName();
|
||||
}
|
||||
@@ -1296,13 +1356,13 @@ namespace LLInitParam
|
||||
};
|
||||
|
||||
// list of non-block parameters
|
||||
template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
|
||||
class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
|
||||
template <typename MULTI_VALUE_T, typename NAME_VALUE_LOOKUP>
|
||||
class TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
|
||||
: public Param
|
||||
{
|
||||
protected:
|
||||
typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
|
||||
typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
|
||||
typedef TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
|
||||
typedef ParamValue<typename LLTypeTags::Sorted<MULTI_VALUE_T>::value_t> param_value_t;
|
||||
typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
|
||||
typedef container_t default_value_t;
|
||||
typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
|
||||
@@ -1311,7 +1371,9 @@ namespace LLInitParam
|
||||
typedef typename param_value_t::value_t value_t;
|
||||
|
||||
TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
|
||||
: Param(block_descriptor.mCurrentBlockPtr)
|
||||
: Param(block_descriptor.mCurrentBlockPtr),
|
||||
mMinCount(min_count),
|
||||
mMaxCount(max_count)
|
||||
{
|
||||
std::copy(value.begin(), value.end(), std::back_inserter(mValues));
|
||||
|
||||
@@ -1322,7 +1384,13 @@ namespace LLInitParam
|
||||
}
|
||||
}
|
||||
|
||||
bool isProvided() const { return Param::anyProvided(); }
|
||||
bool isProvided() const { return Param::anyProvided() && isValid(); }
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
size_t num_elements = numValidElements();
|
||||
return mMinCount < num_elements && num_elements < mMaxCount;
|
||||
}
|
||||
|
||||
static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
|
||||
{
|
||||
@@ -1337,7 +1405,7 @@ namespace LLInitParam
|
||||
}
|
||||
|
||||
// no further names in stack, attempt to parse value now
|
||||
if (name_stack_range.first == name_stack_range.second)
|
||||
if (new_name_stack_range.first == new_name_stack_range.second)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
@@ -1359,10 +1427,19 @@ namespace LLInitParam
|
||||
return false;
|
||||
}
|
||||
|
||||
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
|
||||
static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
|
||||
{
|
||||
bool serialized = false;
|
||||
const self_t& typed_param = static_cast<const self_t&>(param);
|
||||
if (!typed_param.isProvided()) return;
|
||||
|
||||
LLPredicate::Value<ESerializePredicates> predicate;
|
||||
|
||||
predicate.set(REQUIRED, typed_param.mMinCount > 0);
|
||||
predicate.set(VALID, typed_param.isValid());
|
||||
predicate.set(PROVIDED, typed_param.anyProvided());
|
||||
predicate.set(EMPTY, typed_param.mValues.empty());
|
||||
|
||||
if (!predicate_rule.check(predicate)) return false;
|
||||
|
||||
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
|
||||
it != end_it;
|
||||
@@ -1378,7 +1455,11 @@ namespace LLInitParam
|
||||
if (!value_written)
|
||||
{
|
||||
std::string calculated_key = it->calcValueName(it->getValue());
|
||||
if (!parser.writeValue(calculated_key, name_stack))
|
||||
if (parser.writeValue(calculated_key, name_stack))
|
||||
{
|
||||
serialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1386,19 +1467,23 @@ namespace LLInitParam
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!parser.writeValue(key, name_stack))
|
||||
if(parser.writeValue(key, name_stack))
|
||||
{
|
||||
serialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
name_stack.pop_back();
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
|
||||
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
|
||||
{
|
||||
parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
|
||||
parser.inspectValue<MULTI_VALUE_T>(name_stack, min_count, max_count, NULL);
|
||||
if (named_value_t::getPossibleValues())
|
||||
{
|
||||
parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
|
||||
@@ -1453,7 +1538,7 @@ namespace LLInitParam
|
||||
bool empty() const { return mValues.empty(); }
|
||||
size_t size() const { return mValues.size(); }
|
||||
|
||||
U32 numValidElements() const
|
||||
size_t numValidElements() const
|
||||
{
|
||||
return mValues.size();
|
||||
}
|
||||
@@ -1483,6 +1568,8 @@ namespace LLInitParam
|
||||
}
|
||||
|
||||
container_t mValues;
|
||||
size_t mMinCount,
|
||||
mMaxCount;
|
||||
|
||||
private:
|
||||
void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
|
||||
@@ -1500,13 +1587,13 @@ namespace LLInitParam
|
||||
};
|
||||
|
||||
// list of block parameters
|
||||
template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
|
||||
class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
|
||||
template <typename MULTI_BLOCK_T, typename NAME_VALUE_LOOKUP>
|
||||
class TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
|
||||
: public Param
|
||||
{
|
||||
protected:
|
||||
typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
|
||||
typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
|
||||
typedef TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
|
||||
typedef ParamValue<typename LLTypeTags::Sorted<MULTI_BLOCK_T>::value_t> param_value_t;
|
||||
typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
|
||||
typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
|
||||
typedef container_t default_value_t;
|
||||
@@ -1516,7 +1603,9 @@ namespace LLInitParam
|
||||
typedef typename param_value_t::value_t value_t;
|
||||
|
||||
TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
|
||||
: Param(block_descriptor.mCurrentBlockPtr)
|
||||
: Param(block_descriptor.mCurrentBlockPtr),
|
||||
mMinCount(min_count),
|
||||
mMaxCount(max_count)
|
||||
{
|
||||
std::copy(value.begin(), value.end(), back_inserter(mValues));
|
||||
|
||||
@@ -1526,7 +1615,14 @@ namespace LLInitParam
|
||||
}
|
||||
}
|
||||
|
||||
bool isProvided() const { return Param::anyProvided(); }
|
||||
bool isProvided() const { return Param::anyProvided() && isValid(); }
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
size_t num_elements = numValidElements();
|
||||
return mMinCount < num_elements && num_elements < mMaxCount;
|
||||
}
|
||||
|
||||
|
||||
static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
|
||||
{
|
||||
@@ -1549,7 +1645,7 @@ namespace LLInitParam
|
||||
}
|
||||
param_value_t& value = typed_param.mValues.back();
|
||||
|
||||
if (name_stack_range.first == name_stack_range.second)
|
||||
if (new_name_stack_range.first == new_name_stack_range.second)
|
||||
{ // try to parse a known named value
|
||||
std::string name;
|
||||
|
||||
@@ -1559,6 +1655,10 @@ namespace LLInitParam
|
||||
{
|
||||
typed_param.mValues.back().setValueName(name);
|
||||
typed_param.setProvided();
|
||||
if (new_array_value)
|
||||
{
|
||||
name_stack_range.first->second = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1583,10 +1683,18 @@ namespace LLInitParam
|
||||
return false;
|
||||
}
|
||||
|
||||
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
|
||||
static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
|
||||
{
|
||||
bool serialized = false;
|
||||
const self_t& typed_param = static_cast<const self_t&>(param);
|
||||
if (!typed_param.isProvided()) return;
|
||||
LLPredicate::Value<ESerializePredicates> predicate;
|
||||
|
||||
predicate.set(REQUIRED, typed_param.mMinCount > 0);
|
||||
predicate.set(VALID, typed_param.isValid());
|
||||
predicate.set(PROVIDED, typed_param.anyProvided());
|
||||
predicate.set(EMPTY, typed_param.mValues.empty());
|
||||
|
||||
if (!predicate_rule.check(predicate)) return false;
|
||||
|
||||
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
|
||||
it != end_it;
|
||||
@@ -1597,17 +1705,24 @@ namespace LLInitParam
|
||||
std::string key = it->getValueName();
|
||||
if (!key.empty())
|
||||
{
|
||||
parser.writeValue(key, name_stack);
|
||||
serialized |= parser.writeValue(key, name_stack);
|
||||
}
|
||||
// Not parsed via named values, write out value directly
|
||||
// NOTE: currently we don't worry about removing default values in Multiple
|
||||
// NOTE: currently we don't do diffing of Multiples
|
||||
else
|
||||
{
|
||||
it->serializeBlock(parser, name_stack, NULL);
|
||||
serialized = it->serializeBlock(parser, name_stack, predicate_rule, NULL);
|
||||
}
|
||||
|
||||
name_stack.pop_back();
|
||||
}
|
||||
|
||||
if (!serialized && predicate_rule.check(ll_make_predicate(EMPTY)))
|
||||
{
|
||||
serialized |= parser.writeValue(Flag(), name_stack);
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
|
||||
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
|
||||
@@ -1670,14 +1785,14 @@ namespace LLInitParam
|
||||
bool empty() const { return mValues.empty(); }
|
||||
size_t size() const { return mValues.size(); }
|
||||
|
||||
U32 numValidElements() const
|
||||
size_t numValidElements() const
|
||||
{
|
||||
U32 count = 0;
|
||||
size_t count = 0;
|
||||
for (const_iterator it = mValues.begin(), end_it = mValues.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if(it->validateBlock(false)) count++;
|
||||
if(it->isValid()) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -1709,6 +1824,8 @@ namespace LLInitParam
|
||||
}
|
||||
|
||||
container_t mValues;
|
||||
size_t mMinCount,
|
||||
mMaxCount;
|
||||
|
||||
private:
|
||||
void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
|
||||
@@ -1937,7 +2054,7 @@ namespace LLInitParam
|
||||
|
||||
Optional& operator =(const value_t& val)
|
||||
{
|
||||
this->set(val);
|
||||
super_t::set(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1967,7 +2084,7 @@ namespace LLInitParam
|
||||
|
||||
Mandatory& operator =(const value_t& val)
|
||||
{
|
||||
this->set(val);
|
||||
super_t::set(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -2003,7 +2120,7 @@ namespace LLInitParam
|
||||
|
||||
Multiple& operator =(const container_t& val)
|
||||
{
|
||||
set(val);
|
||||
super_t::set(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -2015,7 +2132,7 @@ namespace LLInitParam
|
||||
|
||||
static bool validate(const Param* paramp)
|
||||
{
|
||||
U32 num_valid = ((super_t*)paramp)->numValidElements();
|
||||
size_t num_valid = ((super_t*)paramp)->numValidElements();
|
||||
return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
|
||||
}
|
||||
};
|
||||
@@ -2158,13 +2275,11 @@ namespace LLInitParam
|
||||
typedef T default_value_t;
|
||||
|
||||
ParamValue()
|
||||
: mValue(),
|
||||
mValidated(false)
|
||||
: mValue()
|
||||
{}
|
||||
|
||||
ParamValue(const default_value_t& value)
|
||||
: mValue(value),
|
||||
mValidated(false)
|
||||
: mValue(value)
|
||||
{}
|
||||
|
||||
void setValue(const value_t& val)
|
||||
@@ -2191,12 +2306,12 @@ namespace LLInitParam
|
||||
return mValue.deserializeBlock(p, name_stack_range, new_name);
|
||||
}
|
||||
|
||||
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
|
||||
bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const
|
||||
{
|
||||
const BaseBlock* base_block = diff_block
|
||||
? &(diff_block->mValue)
|
||||
: NULL;
|
||||
mValue.serializeBlock(p, name_stack, base_block);
|
||||
return mValue.serializeBlock(p, name_stack, predicate_rule, base_block);
|
||||
}
|
||||
|
||||
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
|
||||
@@ -2213,8 +2328,6 @@ namespace LLInitParam
|
||||
resetToDefault();
|
||||
return mValue.mergeBlock(block_data, source.getValue(), overwrite);
|
||||
}
|
||||
|
||||
|
||||
return mValue.mergeBlock(block_data, source.getValue(), overwrite);
|
||||
}
|
||||
|
||||
@@ -2223,14 +2336,17 @@ namespace LLInitParam
|
||||
return mValue.validateBlock(emit_errors);
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return validateBlock(false);
|
||||
}
|
||||
|
||||
static BlockDescriptor& getBlockDescriptor()
|
||||
{
|
||||
return value_t::getBlockDescriptor();
|
||||
}
|
||||
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
|
||||
private:
|
||||
void resetToDefault()
|
||||
{
|
||||
@@ -2251,15 +2367,13 @@ namespace LLInitParam
|
||||
typedef T default_value_t;
|
||||
|
||||
ParamValue()
|
||||
: mValue(),
|
||||
mValidated(false)
|
||||
: mValue()
|
||||
{
|
||||
mCurParam = getBlockDescriptor().mAllParams.begin();
|
||||
}
|
||||
|
||||
ParamValue(const default_value_t& value)
|
||||
: mValue(value),
|
||||
mValidated(false)
|
||||
: mValue(value)
|
||||
{
|
||||
mCurParam = getBlockDescriptor().mAllParams.begin();
|
||||
}
|
||||
@@ -2311,12 +2425,12 @@ namespace LLInitParam
|
||||
}
|
||||
}
|
||||
|
||||
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
|
||||
bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const
|
||||
{
|
||||
const BaseBlock* base_block = diff_block
|
||||
? &(diff_block->mValue)
|
||||
: NULL;
|
||||
mValue.serializeBlock(p, name_stack, base_block);
|
||||
return mValue.serializeBlock(p, name_stack, predicate_rule, base_block);
|
||||
}
|
||||
|
||||
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
|
||||
@@ -2334,13 +2448,16 @@ namespace LLInitParam
|
||||
return mValue.validateBlock(emit_errors);
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return validateBlock(false);
|
||||
}
|
||||
|
||||
static BlockDescriptor& getBlockDescriptor()
|
||||
{
|
||||
return value_t::getBlockDescriptor();
|
||||
}
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
|
||||
private:
|
||||
|
||||
BlockDescriptor::all_params_list_t::iterator mCurParam;
|
||||
@@ -2358,16 +2475,14 @@ namespace LLInitParam
|
||||
typedef T default_value_t;
|
||||
|
||||
ParamValue()
|
||||
: T(),
|
||||
mValidated(false)
|
||||
: T()
|
||||
{}
|
||||
|
||||
ParamValue(const default_value_t& value)
|
||||
: T(value.getValue()),
|
||||
mValidated(false)
|
||||
: T(value.getValue())
|
||||
{}
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
bool isValid() const { return true; }
|
||||
};
|
||||
|
||||
template<typename T, typename BLOCK_T>
|
||||
@@ -2380,18 +2495,15 @@ namespace LLInitParam
|
||||
typedef LazyValue<T> default_value_t;
|
||||
|
||||
ParamValue()
|
||||
: mValue(),
|
||||
mValidated(false)
|
||||
: mValue()
|
||||
{}
|
||||
|
||||
ParamValue(const default_value_t& other)
|
||||
: mValue(other),
|
||||
mValidated(false)
|
||||
: mValue(other)
|
||||
{}
|
||||
|
||||
ParamValue(const T& value)
|
||||
: mValue(value),
|
||||
mValidated(false)
|
||||
: mValue(value)
|
||||
{}
|
||||
|
||||
void setValue(const value_t& val)
|
||||
@@ -2414,14 +2526,14 @@ namespace LLInitParam
|
||||
return mValue.get().deserializeBlock(p, name_stack_range, new_name);
|
||||
}
|
||||
|
||||
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
|
||||
bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const
|
||||
{
|
||||
if (mValue.empty()) return;
|
||||
if (mValue.empty()) return false;
|
||||
|
||||
const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
|
||||
? &(diff_block->mValue.get().getValue())
|
||||
: NULL;
|
||||
mValue.get().serializeBlock(p, name_stack, base_block);
|
||||
return mValue.get().serializeBlock(p, name_stack, predicate_rule, base_block);
|
||||
}
|
||||
|
||||
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
|
||||
@@ -2439,13 +2551,16 @@ namespace LLInitParam
|
||||
return mValue.empty() || mValue.get().validateBlock(emit_errors);
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return validateBlock(false);
|
||||
}
|
||||
|
||||
static BlockDescriptor& getBlockDescriptor()
|
||||
{
|
||||
return value_t::getBlockDescriptor();
|
||||
}
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
|
||||
private:
|
||||
LazyValue<T> mValue;
|
||||
};
|
||||
@@ -2460,18 +2575,15 @@ namespace LLInitParam
|
||||
typedef LazyValue<T> default_value_t;
|
||||
|
||||
ParamValue()
|
||||
: mValue(),
|
||||
mValidated(false)
|
||||
: mValue()
|
||||
{}
|
||||
|
||||
ParamValue(const default_value_t& other)
|
||||
: mValue(other),
|
||||
mValidated(false)
|
||||
: mValue(other)
|
||||
{}
|
||||
|
||||
ParamValue(const T& value)
|
||||
: mValue(value),
|
||||
mValidated(false)
|
||||
: mValue(value)
|
||||
{}
|
||||
|
||||
void setValue(const value_t& val)
|
||||
@@ -2489,7 +2601,10 @@ namespace LLInitParam
|
||||
return mValue.get().getValue();
|
||||
}
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
bool isValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
LazyValue<T> mValue;
|
||||
@@ -2504,12 +2619,10 @@ namespace LLInitParam
|
||||
typedef LLSD default_value_t;
|
||||
|
||||
ParamValue()
|
||||
: mValidated(false)
|
||||
{}
|
||||
|
||||
ParamValue(const default_value_t& other)
|
||||
: mValue(other),
|
||||
mValidated(false)
|
||||
: mValue(other)
|
||||
{}
|
||||
|
||||
void setValue(const value_t& val) { mValue = val; }
|
||||
@@ -2519,16 +2632,13 @@ namespace LLInitParam
|
||||
|
||||
// block param interface
|
||||
LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
|
||||
LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
|
||||
LL_COMMON_API bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const;
|
||||
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
|
||||
{
|
||||
//TODO: implement LLSD params as schema type Any
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
|
||||
private:
|
||||
static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
|
||||
|
||||
@@ -2547,9 +2657,9 @@ namespace LLInitParam
|
||||
BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
|
||||
} EValueAge;
|
||||
|
||||
typedef ParamValue<T> derived_t;
|
||||
typedef TypeValues<T> derived_t;
|
||||
typedef CustomParamValue<T> self_t;
|
||||
typedef Block<derived_t> block_t;
|
||||
typedef Block<ParamValue<T> > block_t;
|
||||
typedef T default_value_t;
|
||||
typedef T value_t;
|
||||
typedef void baseblock_base_class_t;
|
||||
@@ -2557,8 +2667,7 @@ namespace LLInitParam
|
||||
|
||||
CustomParamValue(const default_value_t& value = T())
|
||||
: mValue(value),
|
||||
mValueAge(VALUE_AUTHORITATIVE),
|
||||
mValidated(false)
|
||||
mValueAge(VALUE_AUTHORITATIVE)
|
||||
{}
|
||||
|
||||
bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
|
||||
@@ -2580,16 +2689,30 @@ namespace LLInitParam
|
||||
return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
|
||||
}
|
||||
|
||||
void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
|
||||
bool serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const
|
||||
{
|
||||
const derived_t& typed_param = static_cast<const derived_t&>(*this);
|
||||
const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
|
||||
|
||||
//std::string key = typed_param.getValueName();
|
||||
|
||||
//// first try to write out name of name/value pair
|
||||
//if (!key.empty())
|
||||
//{
|
||||
// if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
|
||||
// {
|
||||
// return parser.writeValue(key, name_stack);
|
||||
// }
|
||||
//}
|
||||
// then try to serialize value directly
|
||||
if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
|
||||
{
|
||||
|
||||
if (!parser.writeValue(typed_param.getValue(), name_stack))
|
||||
if (parser.writeValue(typed_param.getValue(), name_stack))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
|
||||
// since these tend to be viewed as the constructor arguments for the value T. It seems
|
||||
@@ -2606,14 +2729,15 @@ namespace LLInitParam
|
||||
// and serialize those params
|
||||
derived_t copy(typed_param);
|
||||
copy.updateBlockFromValue(true);
|
||||
copy.block_t::serializeBlock(parser, name_stack, NULL);
|
||||
return copy.block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
block_t::serializeBlock(parser, name_stack, NULL);
|
||||
return block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool validateBlock(bool emit_errors = true) const
|
||||
@@ -2705,8 +2829,6 @@ namespace LLInitParam
|
||||
return block_t::mergeBlock(block_data, source, overwrite);
|
||||
}
|
||||
|
||||
mutable bool mValidated; // lazy validation flag
|
||||
|
||||
private:
|
||||
mutable T mValue;
|
||||
mutable EValueAge mValueAge;
|
||||
|
||||
41
indra/llcommon/llpredicate.cpp
Normal file
41
indra/llcommon/llpredicate.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file llpredicate.cpp
|
||||
* @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpredicate.h"
|
||||
|
||||
namespace LLPredicate
|
||||
{
|
||||
const U32 cPredicateFlagsFromEnum[5] =
|
||||
{
|
||||
0xAAAAaaaa, // 10101010101010101010101010101010
|
||||
0xCCCCcccc, // 11001100110011001100110011001100
|
||||
0xF0F0F0F0, // 11110000111100001111000011110000
|
||||
0xFF00FF00, // 11111111000000001111111100000000
|
||||
0xFFFF0000 // 11111111111111110000000000000000
|
||||
};
|
||||
}
|
||||
|
||||
210
indra/llcommon/llpredicate.h
Normal file
210
indra/llcommon/llpredicate.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* @file llpredicate.h
|
||||
* @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPREDICATE_H
|
||||
#define LL_LLPREDICATE_H
|
||||
|
||||
#include "llerror.h"
|
||||
|
||||
namespace LLPredicate
|
||||
{
|
||||
template<typename ENUM> class Rule;
|
||||
|
||||
extern LL_COMMON_API const U32 cPredicateFlagsFromEnum[5];
|
||||
|
||||
template<typename ENUM>
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
typedef U32 predicate_flag_t;
|
||||
static const S32 cMaxEnum = 5;
|
||||
|
||||
Value(ENUM e, bool predicate_value = true)
|
||||
: mPredicateFlags(predicate_value ? cPredicateFlagsFromEnum[e] : ~cPredicateFlagsFromEnum[e])
|
||||
{
|
||||
llassert(0 <= e && e < cMaxEnum);
|
||||
}
|
||||
|
||||
Value()
|
||||
: mPredicateFlags(0xFFFFffff)
|
||||
{}
|
||||
|
||||
Value operator!() const
|
||||
{
|
||||
Value new_value;
|
||||
new_value.mPredicateFlags = ~mPredicateFlags;
|
||||
return new_value;
|
||||
}
|
||||
|
||||
Value operator &&(const Value other) const
|
||||
{
|
||||
Value new_value;
|
||||
new_value.mPredicateFlags = mPredicateFlags & other.mPredicateFlags;
|
||||
return new_value;
|
||||
}
|
||||
|
||||
Value operator ||(const Value other) const
|
||||
{
|
||||
Value new_value;
|
||||
new_value.mPredicateFlags = mPredicateFlags | other.mPredicateFlags;
|
||||
return new_value;
|
||||
}
|
||||
|
||||
void set(ENUM e, bool value = true)
|
||||
{
|
||||
llassert(0 <= e && e < cMaxEnum);
|
||||
predicate_flag_t flags_to_modify;
|
||||
predicate_flag_t mask = cPredicateFlagsFromEnum[e];
|
||||
if (value)
|
||||
{ // add predicate "e" to flags that don't contain it already
|
||||
flags_to_modify = (mPredicateFlags & ~mask);
|
||||
// clear flags not containing e
|
||||
mPredicateFlags &= mask;
|
||||
// add back flags shifted to contain e
|
||||
mPredicateFlags |= flags_to_modify << (0x1 << e);
|
||||
}
|
||||
else
|
||||
{ // remove predicate "e" from flags that contain it
|
||||
flags_to_modify = (mPredicateFlags & mask);
|
||||
// clear flags containing e
|
||||
mPredicateFlags &= ~mask;
|
||||
// add back flags shifted to not contain e
|
||||
mPredicateFlags |= flags_to_modify >> (0x1 << e);
|
||||
}
|
||||
}
|
||||
|
||||
void forget(ENUM e)
|
||||
{
|
||||
set(e, true);
|
||||
U32 flags_with_predicate = mPredicateFlags;
|
||||
set(e, false);
|
||||
// ambiguous value is result of adding and removing predicate at the same time!
|
||||
mPredicateFlags |= flags_with_predicate;
|
||||
}
|
||||
|
||||
bool allSet() const
|
||||
{
|
||||
return mPredicateFlags == ~0;
|
||||
}
|
||||
|
||||
bool noneSet() const
|
||||
{
|
||||
return mPredicateFlags == 0;
|
||||
}
|
||||
|
||||
bool someSet() const
|
||||
{
|
||||
return mPredicateFlags != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
predicate_flag_t mPredicateFlags;
|
||||
};
|
||||
|
||||
template<typename ENUM>
|
||||
class Rule
|
||||
{
|
||||
public:
|
||||
Rule(ENUM value)
|
||||
: mRule(value)
|
||||
{}
|
||||
|
||||
Rule(const Value<ENUM> other)
|
||||
: mRule(other)
|
||||
{}
|
||||
|
||||
Rule()
|
||||
{}
|
||||
|
||||
void require(ENUM e, bool match)
|
||||
{
|
||||
mRule.set(e, match);
|
||||
}
|
||||
|
||||
void allow(ENUM e)
|
||||
{
|
||||
mRule.forget(e);
|
||||
}
|
||||
|
||||
bool check(const Value<ENUM> value) const
|
||||
{
|
||||
return (mRule && value).someSet();
|
||||
}
|
||||
|
||||
bool requires(const Value<ENUM> value) const
|
||||
{
|
||||
return (mRule && value).someSet() && (!mRule && value).noneSet();
|
||||
}
|
||||
|
||||
bool isAmbivalent(const Value<ENUM> value) const
|
||||
{
|
||||
return (mRule && value).someSet() && (!mRule && value).someSet();
|
||||
}
|
||||
|
||||
bool acceptsAll() const
|
||||
{
|
||||
return mRule.allSet();
|
||||
}
|
||||
|
||||
bool acceptsNone() const
|
||||
{
|
||||
return mRule.noneSet();
|
||||
}
|
||||
|
||||
Rule operator!() const
|
||||
{
|
||||
Rule new_rule;
|
||||
new_rule.mRule = !mRule;
|
||||
return new_rule;
|
||||
}
|
||||
|
||||
Rule operator &&(const Rule other) const
|
||||
{
|
||||
Rule new_rule;
|
||||
new_rule.mRule = mRule && other.mRule;
|
||||
return new_rule;
|
||||
}
|
||||
|
||||
Rule operator ||(const Rule other) const
|
||||
{
|
||||
Rule new_rule;
|
||||
new_rule.mRule = mRule || other.mRule;
|
||||
return new_rule;
|
||||
}
|
||||
|
||||
private:
|
||||
Value<ENUM> mRule;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ENUM>
|
||||
LLPredicate::Value<ENUM> ll_make_predicate(ENUM e, bool predicate_value = true)
|
||||
{
|
||||
return LLPredicate::Value<ENUM>(e, predicate_value);
|
||||
}
|
||||
|
||||
|
||||
#endif // LL_LLPREDICATE_H
|
||||
@@ -80,8 +80,8 @@
|
||||
#define LL_CLANG 1
|
||||
#endif
|
||||
#elif defined (__ICC)
|
||||
#ifndef LL_ICC
|
||||
#define LL_ICC 1
|
||||
#ifndef LL_INTELC
|
||||
#define LL_INTELC 1
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
||||
@@ -94,9 +94,6 @@
|
||||
#ifndef LL_MSVC
|
||||
#define LL_MSVC 1
|
||||
#endif
|
||||
#if _MSC_VER < 1400
|
||||
#define LL_MSVC7 //Visual C++ 2003 or earlier
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Deal with minor differences on Unixy OSes.
|
||||
@@ -112,6 +109,16 @@
|
||||
|
||||
#endif
|
||||
|
||||
// Check for C++11 support
|
||||
#if __cplusplus >= 201100L || _MSC_VER >= 1800
|
||||
# define LL_CPP11
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
# define LL_THREAD_LOCAL __declspec(thread)
|
||||
#else
|
||||
# define LL_THREAD_LOCAL __thread
|
||||
#endif
|
||||
|
||||
// Static linking with apr on windows needs to be declared.
|
||||
#if LL_WINDOWS && !LL_COMMON_LINK_SHARED
|
||||
@@ -142,7 +149,7 @@
|
||||
#pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual"
|
||||
#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden
|
||||
#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
|
||||
#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
|
||||
//#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
|
||||
#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
|
||||
#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#pragma warning( disable : 4996 ) // warning: deprecated
|
||||
@@ -161,6 +168,12 @@
|
||||
|
||||
#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
|
||||
#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
|
||||
//#pragma warning (disable : 4018) // '<' : signed/unsigned mismatch
|
||||
|
||||
#if _WIN64
|
||||
#pragma warning (disable : 4267) // member needs to have dll-interface to be used by clients of class
|
||||
#endif
|
||||
|
||||
#endif // LL_MSVC
|
||||
|
||||
#if LL_WINDOWS
|
||||
@@ -198,4 +211,23 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LL_WINDOWS) || __cplusplus >= 201103L
|
||||
# define LL_TYPEOF(exp) decltype(exp)
|
||||
#else
|
||||
# define LL_TYPEOF(exp) typeof(exp)
|
||||
#endif
|
||||
|
||||
#define LL_TO_STRING_HELPER(x) #x
|
||||
#define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
|
||||
#define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
|
||||
#define LL_GLUE_IMPL(x, y) x##y
|
||||
#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
|
||||
|
||||
#if LL_WINDOWS
|
||||
#define LL_COMPILE_TIME_MESSAGE(msg) __pragma(message(LL_FILE_LINENO_MSG(msg)))
|
||||
#else
|
||||
// no way to get gcc 4.2 to print a user-defined diagnostic message only when a macro is used
|
||||
#define LL_COMPILE_TIME_MESSAGE(msg)
|
||||
#endif
|
||||
|
||||
#endif // not LL_LINDEN_PREPROCESSOR_H
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
# define LL_X86 1
|
||||
#elif LL_MSVC && _M_IX86
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC || LL_ICC || LL_CLANG && ( defined(__amd64__) || defined(__x86_64__) )
|
||||
#elif LL_GNUC || LL_CLANG || LL_INTELC && ( defined(__amd64__) || defined(__x86_64__) )
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC || LL_ICC || LL_CLANG && ( defined(__i386__) )
|
||||
#elif LL_GNUC || LL_CLANG || LL_INTELC && ( defined(__i386__) )
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) )
|
||||
# define LL_PPC 1
|
||||
@@ -202,6 +202,7 @@ namespace
|
||||
case 6: return "AMD K7";
|
||||
case 0xF: return "AMD K8";
|
||||
case 0x10: return "AMD K8L";
|
||||
case 0x15: return "AMD Bulldozer";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -418,8 +419,8 @@ static F64 calculate_cpu_frequency(U32 measure_msecs)
|
||||
HANDLE hThread = GetCurrentThread();
|
||||
unsigned long dwCurPriorityClass = GetPriorityClass(hProcess);
|
||||
int iCurThreadPriority = GetThreadPriority(hThread);
|
||||
unsigned long dwProcessMask, dwSystemMask, dwNewMask = 1;
|
||||
GetProcessAffinityMask(hProcess, (PDWORD_PTR)&dwProcessMask, (PDWORD_PTR)&dwSystemMask);
|
||||
DWORD_PTR dwProcessMask, dwSystemMask, dwNewMask = 1; // <alchemy/>
|
||||
GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSystemMask);
|
||||
|
||||
SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS);
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Must turn on conditional declarations in header file so definitions end up
|
||||
// with proper linkage.
|
||||
#define LLSD_DEBUG_INFO
|
||||
#include "linden_common.h"
|
||||
#include "llsd.h"
|
||||
|
||||
@@ -31,6 +34,7 @@
|
||||
#include "../llmath/llmath.h"
|
||||
#include "llformat.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "stringize.h"
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
#define NAME_UNNAMED_NAMESPACE
|
||||
@@ -50,6 +54,18 @@ namespace
|
||||
using namespace LLSDUnnamedNamespace;
|
||||
#endif
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
// statics
|
||||
S32 sLLSDAllocationCount = 0;
|
||||
S32 sLLSDNetObjects = 0;
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
#define ALLOC_LLSD_OBJECT { llsd::sLLSDNetObjects++; llsd::sLLSDAllocationCount++; }
|
||||
#define FREE_LLSD_OBJECT { llsd::sLLSDNetObjects--; }
|
||||
|
||||
class LLSD::Impl
|
||||
/**< This class is the abstract base class of the implementation of LLSD
|
||||
It provides the reference counting implementation, and the default
|
||||
@@ -58,13 +74,10 @@ class LLSD::Impl
|
||||
|
||||
*/
|
||||
{
|
||||
private:
|
||||
U32 mUseCount;
|
||||
|
||||
protected:
|
||||
Impl();
|
||||
|
||||
enum StaticAllocationMarker { STATIC };
|
||||
enum StaticAllocationMarker { STATIC_USAGE_COUNT = 0xFFFFFFFF };
|
||||
Impl(StaticAllocationMarker);
|
||||
///< This constructor is used for static objects and causes the
|
||||
// suppresses adjusting the debugging counters when they are
|
||||
@@ -72,8 +85,10 @@ protected:
|
||||
|
||||
virtual ~Impl();
|
||||
|
||||
bool shared() const { return mUseCount > 1; }
|
||||
bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); }
|
||||
|
||||
U32 mUseCount;
|
||||
|
||||
public:
|
||||
static void reset(Impl*& var, Impl* impl);
|
||||
///< safely set var to refer to the new impl (possibly shared)
|
||||
@@ -111,7 +126,9 @@ public:
|
||||
virtual UUID asUUID() const { return LLUUID(); }
|
||||
virtual Date asDate() const { return LLDate(); }
|
||||
virtual URI asURI() const { return LLURI(); }
|
||||
virtual Binary asBinary() const { return std::vector<U8>(); }
|
||||
virtual const Binary& asBinary() const { static const std::vector<U8> empty; return empty; }
|
||||
|
||||
virtual const String& asStringRef() const { static const std::string empty; return empty; }
|
||||
|
||||
virtual bool has(const String&) const { return false; }
|
||||
virtual LLSD get(const String&) const { return LLSD(); }
|
||||
@@ -128,6 +145,18 @@ public:
|
||||
virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
|
||||
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
|
||||
|
||||
virtual void dumpStats() const;
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
// Container subclasses contain LLSD objects, rather than directly
|
||||
// containing Impl objects. This helper forwards through LLSD.
|
||||
void calcStats(const LLSD& llsd, S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
safe(llsd.impl).calcStats(type_counts, share_counts);
|
||||
}
|
||||
|
||||
static const Impl& getImpl(const LLSD& llsd) { return safe(llsd.impl); }
|
||||
static Impl& getImpl(LLSD& llsd) { return safe(llsd.impl); }
|
||||
|
||||
static const LLSD& undef();
|
||||
|
||||
static U32 sAllocationCount;
|
||||
@@ -242,6 +271,8 @@ namespace
|
||||
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); }
|
||||
virtual LLSD::Date asDate() const { return LLDate(mValue); }
|
||||
virtual LLSD::URI asURI() const { return LLURI(mValue); }
|
||||
virtual int size() const { return mValue.size(); }
|
||||
virtual const LLSD::String& asStringRef() const { return mValue; }
|
||||
};
|
||||
|
||||
LLSD::Integer ImplString::asInteger() const
|
||||
@@ -320,7 +351,7 @@ namespace
|
||||
public:
|
||||
ImplBinary(const LLSD::Binary& v) : Base(v) { }
|
||||
|
||||
virtual LLSD::Binary asBinary() const{ return mValue; }
|
||||
virtual const LLSD::Binary& asBinary() const{ return mValue; }
|
||||
};
|
||||
|
||||
|
||||
@@ -360,6 +391,9 @@ namespace
|
||||
LLSD::map_iterator endMap() { return mData.end(); }
|
||||
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
|
||||
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
|
||||
|
||||
virtual void dumpStats() const;
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
};
|
||||
|
||||
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
|
||||
@@ -414,6 +448,34 @@ namespace
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void ImplMap::dumpStats() const
|
||||
{
|
||||
std::cout << "Map size: " << mData.size() << std::endl;
|
||||
|
||||
std::cout << "LLSD Net Objects: " << llsd::sLLSDNetObjects << std::endl;
|
||||
std::cout << "LLSD allocations: " << llsd::sLLSDAllocationCount << std::endl;
|
||||
|
||||
std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl;
|
||||
std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl;
|
||||
|
||||
Impl::dumpStats();
|
||||
}
|
||||
|
||||
void ImplMap::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
LLSD::map_const_iterator iter = beginMap();
|
||||
while (iter != endMap())
|
||||
{
|
||||
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
|
||||
Impl::calcStats((*iter).second, type_counts, share_counts);
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Add in the values for this map
|
||||
Impl::calcStats(type_counts, share_counts);
|
||||
}
|
||||
|
||||
|
||||
class ImplArray : public LLSD::Impl
|
||||
{
|
||||
private:
|
||||
@@ -447,8 +509,12 @@ namespace
|
||||
|
||||
LLSD::array_iterator beginArray() { return mData.begin(); }
|
||||
LLSD::array_iterator endArray() { return mData.end(); }
|
||||
LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
|
||||
LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
|
||||
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
|
||||
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
|
||||
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
};
|
||||
|
||||
ImplArray& ImplArray::makeArray(Impl*& var)
|
||||
@@ -544,6 +610,19 @@ namespace
|
||||
|
||||
return mData[index];
|
||||
}
|
||||
|
||||
void ImplArray::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
LLSD::array_const_iterator iter = beginArray();
|
||||
while (iter != endArray())
|
||||
{ // Add values for all items held in the array
|
||||
Impl::calcStats((*iter), type_counts, share_counts);
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Add in the values for this array
|
||||
Impl::calcStats(type_counts, share_counts);
|
||||
}
|
||||
}
|
||||
|
||||
LLSD::Impl::Impl()
|
||||
@@ -565,8 +644,11 @@ LLSD::Impl::~Impl()
|
||||
|
||||
void LLSD::Impl::reset(Impl*& var, Impl* impl)
|
||||
{
|
||||
if (impl) ++impl->mUseCount;
|
||||
if (var && --var->mUseCount == 0)
|
||||
if (impl && impl->mUseCount != STATIC_USAGE_COUNT)
|
||||
{
|
||||
++impl->mUseCount;
|
||||
}
|
||||
if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
|
||||
{
|
||||
delete var;
|
||||
}
|
||||
@@ -575,13 +657,13 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl)
|
||||
|
||||
LLSD::Impl& LLSD::Impl::safe(Impl* impl)
|
||||
{
|
||||
static Impl theUndefined(STATIC);
|
||||
static Impl theUndefined(STATIC_USAGE_COUNT);
|
||||
return impl ? *impl : theUndefined;
|
||||
}
|
||||
|
||||
const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
|
||||
{
|
||||
static Impl theUndefined(STATIC);
|
||||
static Impl theUndefined(STATIC_USAGE_COUNT);
|
||||
return impl ? *impl : theUndefined;
|
||||
}
|
||||
|
||||
@@ -657,6 +739,43 @@ const LLSD& LLSD::Impl::undef()
|
||||
return immutableUndefined;
|
||||
}
|
||||
|
||||
void LLSD::Impl::dumpStats() const
|
||||
{
|
||||
S32 type_counts[LLSD::TypeLLSDNumTypes + 1];
|
||||
memset(&type_counts, 0, sizeof(type_counts));
|
||||
|
||||
S32 share_counts[LLSD::TypeLLSDNumTypes + 1];
|
||||
memset(&share_counts, 0, sizeof(share_counts));
|
||||
|
||||
// Add info from all the values this object has
|
||||
calcStats(type_counts, share_counts);
|
||||
|
||||
S32 type_index = LLSD::TypeLLSDTypeBegin;
|
||||
while (type_index != LLSD::TypeLLSDTypeEnd)
|
||||
{
|
||||
std::cout << LLSD::typeString((LLSD::Type)type_index) << " type "
|
||||
<< type_counts[type_index] << " objects, "
|
||||
<< share_counts[type_index] << " shared"
|
||||
<< std::endl;
|
||||
type_index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
S32 tp = S32(type());
|
||||
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
|
||||
{
|
||||
type_counts[tp]++;
|
||||
if (shared())
|
||||
{
|
||||
share_counts[tp]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U32 LLSD::Impl::sAllocationCount = 0;
|
||||
U32 LLSD::Impl::sOutstandingCount = 0;
|
||||
|
||||
@@ -682,10 +801,10 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
LLSD::LLSD() : impl(0) { }
|
||||
LLSD::~LLSD() { Impl::reset(impl, 0); }
|
||||
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
|
||||
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
|
||||
|
||||
LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); }
|
||||
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
|
||||
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
|
||||
|
||||
|
||||
@@ -693,18 +812,18 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
|
||||
|
||||
LLSD::Type LLSD::type() const { return safe(impl).type(); }
|
||||
|
||||
// Scaler Constructors
|
||||
LLSD::LLSD(Boolean v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(0) { assign(v); }
|
||||
// Scalar Constructors
|
||||
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
|
||||
// Convenience Constructors
|
||||
LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); }
|
||||
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
|
||||
|
||||
// Scalar Assignment
|
||||
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
|
||||
@@ -724,10 +843,12 @@ LLSD::String LLSD::asString() const { return safe(impl).asString(); }
|
||||
LLSD::UUID LLSD::asUUID() const { return safe(impl).asUUID(); }
|
||||
LLSD::Date LLSD::asDate() const { return safe(impl).asDate(); }
|
||||
LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); }
|
||||
LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); }
|
||||
const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
|
||||
|
||||
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
|
||||
|
||||
// const char * helpers
|
||||
LLSD::LLSD(const char* v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
void LLSD::assign(const char* v)
|
||||
{
|
||||
if(v) assign(std::string(v));
|
||||
@@ -785,9 +906,6 @@ LLSD& LLSD::operator[](Integer i)
|
||||
const LLSD& LLSD::operator[](Integer i) const
|
||||
{ return safe(impl).ref(i); }
|
||||
|
||||
U32 LLSD::allocationCount() { return Impl::sAllocationCount; }
|
||||
U32 LLSD::outstandingCount() { return Impl::sOutstandingCount; }
|
||||
|
||||
static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
|
||||
{
|
||||
// sStorage is used to hold the string representation of the llsd last
|
||||
@@ -802,15 +920,9 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
|
||||
{
|
||||
std::ostringstream out;
|
||||
if (useXMLFormat)
|
||||
{
|
||||
LLSDXMLStreamer xml_streamer(llsd);
|
||||
out << xml_streamer;
|
||||
}
|
||||
out << LLSDXMLStreamer(llsd);
|
||||
else
|
||||
{
|
||||
LLSDNotationStreamer notation_streamer(llsd);
|
||||
out << notation_streamer;
|
||||
}
|
||||
out << LLSDNotationStreamer(llsd);
|
||||
out_string = out.str();
|
||||
}
|
||||
int len = out_string.length();
|
||||
@@ -841,3 +953,41 @@ LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray();
|
||||
LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
|
||||
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
|
||||
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }
|
||||
|
||||
LLSD::reverse_array_iterator LLSD::rbeginArray() { return makeArray(impl).rbeginArray(); }
|
||||
LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl).rendArray(); }
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
U32 allocationCount() { return LLSD::Impl::sAllocationCount; }
|
||||
U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; }
|
||||
|
||||
// Diagnostic dump of contents in an LLSD object
|
||||
void dumpStats(const LLSD& llsd) { LLSD::Impl::getImpl(llsd).dumpStats(); }
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
// static
|
||||
std::string LLSD::typeString(Type type)
|
||||
{
|
||||
static const char * sTypeNameArray[] = {
|
||||
"Undefined",
|
||||
"Boolean",
|
||||
"Integer",
|
||||
"Real",
|
||||
"String",
|
||||
"UUID",
|
||||
"Date",
|
||||
"URI",
|
||||
"Binary",
|
||||
"Map",
|
||||
"Array"
|
||||
};
|
||||
|
||||
if (0 <= type && type < LL_ARRAY_SIZE(sTypeNameArray))
|
||||
{
|
||||
return sTypeNameArray[type];
|
||||
}
|
||||
return STRINGIZE("** invalid type value " << type);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,10 @@ public:
|
||||
UUID asUUID() const;
|
||||
Date asDate() const;
|
||||
URI asURI() const;
|
||||
Binary asBinary() const;
|
||||
const Binary& asBinary() const;
|
||||
|
||||
// asStringRef on any non-string type will return a ref to an empty string.
|
||||
const String& asStringRef() const;
|
||||
|
||||
operator Boolean() const { return asBoolean(); }
|
||||
operator Integer() const { return asInteger(); }
|
||||
@@ -323,11 +326,15 @@ public:
|
||||
|
||||
typedef std::vector<LLSD>::iterator array_iterator;
|
||||
typedef std::vector<LLSD>::const_iterator array_const_iterator;
|
||||
typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator;
|
||||
|
||||
array_iterator beginArray();
|
||||
array_iterator endArray();
|
||||
array_const_iterator beginArray() const;
|
||||
array_const_iterator endArray() const;
|
||||
|
||||
reverse_array_iterator rbeginArray();
|
||||
reverse_array_iterator rendArray();
|
||||
//@}
|
||||
|
||||
/** @name Type Testing */
|
||||
@@ -390,13 +397,7 @@ public:
|
||||
class Impl;
|
||||
private:
|
||||
Impl* impl;
|
||||
//@}
|
||||
|
||||
/** @name Unit Testing Interface */
|
||||
//@{
|
||||
public:
|
||||
static U32 allocationCount(); ///< how many Impls have been made
|
||||
static U32 outstandingCount(); ///< how many Impls are still alive
|
||||
friend class LLSD::Impl;
|
||||
//@}
|
||||
|
||||
private:
|
||||
@@ -408,6 +409,10 @@ private:
|
||||
/// Returns Notation version of llsd -- only to be called from debugger
|
||||
static const char *dump(const LLSD &llsd);
|
||||
//@}
|
||||
|
||||
public:
|
||||
|
||||
static std::string typeString(Type type); // Return human-readable type as a string
|
||||
};
|
||||
|
||||
struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean>
|
||||
@@ -455,6 +460,29 @@ struct llsd_select_string : public std::unary_function<LLSD, LLSD::String>
|
||||
|
||||
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd);
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
#ifdef LLSD_DEBUG_INFO
|
||||
/** @name Unit Testing Interface */
|
||||
//@{
|
||||
LL_COMMON_API void dumpStats(const LLSD&); ///< Output information on object and usage
|
||||
|
||||
/// @warn THE FOLLOWING COUNTS WILL NOT BE ACCURATE IN A MULTI-THREADED
|
||||
/// ENVIRONMENT.
|
||||
///
|
||||
/// These counts track LLSD::Impl (hidden) objects.
|
||||
LL_COMMON_API U32 allocationCount(); ///< how many Impls have been made
|
||||
LL_COMMON_API U32 outstandingCount(); ///< how many Impls are still alive
|
||||
|
||||
/// These counts track LLSD (public) objects.
|
||||
LL_COMMON_API extern S32 sLLSDAllocationCount; ///< Number of LLSD objects ever created
|
||||
LL_COMMON_API extern S32 sLLSDNetObjects; ///< Number of LLSD objects that exist
|
||||
#endif
|
||||
//@}
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
/** QUESTIONS & TO DOS
|
||||
- Would Binary be more convenient as unsigned char* buffer semantics?
|
||||
- Should Binary be convertible to/from String, and if so how?
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
// Project includes
|
||||
#include "llsdparam.h"
|
||||
#include "llsdutil.h"
|
||||
#include "boost/bind.hpp"
|
||||
|
||||
static LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
|
||||
static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
|
||||
@@ -42,7 +43,8 @@ LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR("LLSD to LLInitParam conversion")
|
||||
// LLParamSDParser
|
||||
//
|
||||
LLParamSDParser::LLParamSDParser()
|
||||
: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs)
|
||||
: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs),
|
||||
mCurReadSD(NULL), mCurWriteSD(NULL), mWriteRootSD(NULL)
|
||||
{
|
||||
using boost::bind;
|
||||
|
||||
@@ -102,13 +104,13 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool
|
||||
//readSDValues(sd, block);
|
||||
}
|
||||
|
||||
void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
|
||||
void LLParamSDParser::writeSDImpl(LLSD& sd, const LLInitParam::BaseBlock& block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block)
|
||||
{
|
||||
mNameStack.clear();
|
||||
mWriteRootSD = &sd;
|
||||
|
||||
name_stack_t name_stack;
|
||||
block.serializeBlock(*this, name_stack);
|
||||
block.serializeBlock(*this, name_stack, rules, diff_block);
|
||||
}
|
||||
|
||||
/*virtual*/ std::string LLParamSDParser::getCurrentElementName()
|
||||
@@ -329,13 +331,14 @@ namespace LLInitParam
|
||||
p.writeValue<LLSD::String>(sd.asString(), name_stack);
|
||||
}
|
||||
|
||||
void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
|
||||
bool ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack_range, const predicate_rule_t predicate_rule, const BaseBlock* diff_block) const
|
||||
{
|
||||
// attempt to write LLSD out directly
|
||||
if (!p.writeValue<LLSD>(mValue, name_stack))
|
||||
if (!p.writeValue<LLSD>(mValue, name_stack_range))
|
||||
{
|
||||
// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
|
||||
LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
|
||||
LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack_range);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "llinitparam.h"
|
||||
#include "boost/function.hpp"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
struct LL_COMMON_API LLParamSDParserUtilities
|
||||
{
|
||||
@@ -50,11 +51,28 @@ typedef LLInitParam::Parser parser_t;
|
||||
public:
|
||||
LLParamSDParser();
|
||||
void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
|
||||
void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
|
||||
template<typename BLOCK>
|
||||
void writeSD(LLSD& sd,
|
||||
const BLOCK& block,
|
||||
const LLInitParam::predicate_rule_t rules = LLInitParam::default_parse_rules(),
|
||||
const LLInitParam::BaseBlock* diff_block = NULL)
|
||||
{
|
||||
if (!diff_block
|
||||
&& !rules.isAmbivalent(LLInitParam::HAS_DEFAULT_VALUE))
|
||||
{
|
||||
diff_block = &LLInitParam::defaultValue<BLOCK>();
|
||||
}
|
||||
writeSDImpl(sd, block, rules, diff_block);
|
||||
}
|
||||
|
||||
/*virtual*/ std::string getCurrentElementName();
|
||||
|
||||
private:
|
||||
void writeSDImpl(LLSD& sd,
|
||||
const LLInitParam::BaseBlock& block,
|
||||
const LLInitParam::predicate_rule_t,
|
||||
const LLInitParam::BaseBlock* diff_block);
|
||||
|
||||
void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack);
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
#include "llsdserialize.h"
|
||||
#include "llpointer.h"
|
||||
#include "llstreamtools.h" // for fullread
|
||||
#include "llbase64.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "apr_base64.h"
|
||||
|
||||
#ifdef LL_STANDALONE
|
||||
# include <zlib.h>
|
||||
@@ -43,6 +43,7 @@
|
||||
#if !LL_WINDOWS
|
||||
#include <netinet/in.h> // htonl & ntohl
|
||||
#endif
|
||||
#include "apr_general.h" // for strncasecmp
|
||||
|
||||
#include "lldate.h"
|
||||
#include "llsd.h"
|
||||
@@ -648,7 +649,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
|
||||
default:
|
||||
parse_count = PARSE_FAILURE;
|
||||
llinfos << "Unrecognized character while parsing: int(" << (int)c
|
||||
<< ")" << llendl;
|
||||
<< ")" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
if(PARSE_FAILURE == parse_count)
|
||||
@@ -807,12 +808,12 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
|
||||
get(istr, *(coded_stream.rdbuf()), '\"');
|
||||
c = get(istr);
|
||||
std::string encoded(coded_stream.str());
|
||||
S32 len = apr_base64_decode_len(encoded.c_str());
|
||||
size_t len = LLBase64::requiredDecryptionSpace(encoded);
|
||||
std::vector<U8> value;
|
||||
if(len)
|
||||
{
|
||||
value.resize(len);
|
||||
len = apr_base64_decode_binary(&value[0], encoded.c_str());
|
||||
len = LLBase64::decode(encoded, &value[0], len);
|
||||
value.resize(len);
|
||||
}
|
||||
data = value;
|
||||
@@ -873,7 +874,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
|
||||
{
|
||||
/**
|
||||
* Undefined: '!'<br>
|
||||
* Boolean: 't' for true 'f' for false<br>
|
||||
* Boolean: '1' for true '0' for false<br>
|
||||
* Integer: 'i' + 4 bytes network byte order<br>
|
||||
* Real: 'r' + 8 bytes IEEE double<br>
|
||||
* UUID: 'u' + 16 byte unsigned integer<br>
|
||||
@@ -999,7 +1000,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
|
||||
if(istr.fail())
|
||||
{
|
||||
llinfos << "STREAM FAILURE reading binary (notation-style) string."
|
||||
<< llendl;
|
||||
<< LL_ENDL;
|
||||
parse_count = PARSE_FAILURE;
|
||||
}
|
||||
break;
|
||||
@@ -1088,7 +1089,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
|
||||
default:
|
||||
parse_count = PARSE_FAILURE;
|
||||
llinfos << "Unrecognized character while parsing: int(" << (int)c
|
||||
<< ")" << llendl;
|
||||
<< ")" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
if(PARSE_FAILURE == parse_count)
|
||||
@@ -1260,13 +1261,38 @@ std::string LLSDNotationFormatter::escapeString(const std::string& in)
|
||||
|
||||
// virtual
|
||||
S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
|
||||
{
|
||||
S32 rv = format_impl(data, ostr, options, 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const
|
||||
{
|
||||
S32 format_count = 1;
|
||||
std::string pre;
|
||||
std::string post;
|
||||
|
||||
if (options & LLSDFormatter::OPTIONS_PRETTY)
|
||||
{
|
||||
for (U32 i = 0; i < level; i++)
|
||||
{
|
||||
pre += " ";
|
||||
}
|
||||
post = "\n";
|
||||
}
|
||||
|
||||
switch(data.type())
|
||||
{
|
||||
case LLSD::TypeMap:
|
||||
{
|
||||
if (0 != level) ostr << post << pre;
|
||||
ostr << "{";
|
||||
std::string inner_pre;
|
||||
if (options & LLSDFormatter::OPTIONS_PRETTY)
|
||||
{
|
||||
inner_pre = pre + " ";
|
||||
}
|
||||
|
||||
bool need_comma = false;
|
||||
LLSD::map_const_iterator iter = data.beginMap();
|
||||
LLSD::map_const_iterator end = data.endMap();
|
||||
@@ -1274,18 +1300,18 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
{
|
||||
if(need_comma) ostr << ",";
|
||||
need_comma = true;
|
||||
ostr << '\'';
|
||||
ostr << post << inner_pre << '\'';
|
||||
serialize_string((*iter).first, ostr);
|
||||
ostr << "':";
|
||||
format_count += format((*iter).second, ostr);
|
||||
format_count += format_impl((*iter).second, ostr, options, level + 2);
|
||||
}
|
||||
ostr << "}";
|
||||
ostr << post << pre << "}";
|
||||
break;
|
||||
}
|
||||
|
||||
case LLSD::TypeArray:
|
||||
{
|
||||
ostr << "[";
|
||||
ostr << post << pre << "[";
|
||||
bool need_comma = false;
|
||||
LLSD::array_const_iterator iter = data.beginArray();
|
||||
LLSD::array_const_iterator end = data.endArray();
|
||||
@@ -1293,7 +1319,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
{
|
||||
if(need_comma) ostr << ",";
|
||||
need_comma = true;
|
||||
format_count += format(*iter, ostr);
|
||||
format_count += format_impl(*iter, ostr, options, level + 1);
|
||||
}
|
||||
ostr << "]";
|
||||
break;
|
||||
@@ -1343,7 +1369,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
|
||||
case LLSD::TypeString:
|
||||
ostr << '\'';
|
||||
serialize_string(data.asString(), ostr);
|
||||
serialize_string(data.asStringRef(), ostr);
|
||||
ostr << '\'';
|
||||
break;
|
||||
|
||||
@@ -1360,9 +1386,26 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
case LLSD::TypeBinary:
|
||||
{
|
||||
// *FIX: memory inefficient.
|
||||
std::vector<U8> buffer = data.asBinary();
|
||||
const std::vector<U8>& buffer = data.asBinary();
|
||||
ostr << "b(" << buffer.size() << ")\"";
|
||||
if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
|
||||
if(buffer.size())
|
||||
{
|
||||
if (options & LLSDFormatter::OPTIONS_PRETTY_BINARY)
|
||||
{
|
||||
std::ios_base::fmtflags old_flags = ostr.flags();
|
||||
ostr.setf( std::ios::hex, std::ios::basefield );
|
||||
ostr << "0x";
|
||||
for (size_t i = 0; i < buffer.size(); i++)
|
||||
{
|
||||
ostr << (int) buffer[i];
|
||||
}
|
||||
ostr.flags(old_flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
ostr.write((const char*)&buffer[0], buffer.size());
|
||||
}
|
||||
}
|
||||
ostr << "\"";
|
||||
break;
|
||||
}
|
||||
@@ -1460,7 +1503,7 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
|
||||
|
||||
case LLSD::TypeString:
|
||||
ostr.put('s');
|
||||
formatString(data.asString(), ostr);
|
||||
formatString(data.asStringRef(), ostr);
|
||||
break;
|
||||
|
||||
case LLSD::TypeDate:
|
||||
@@ -1478,9 +1521,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
|
||||
|
||||
case LLSD::TypeBinary:
|
||||
{
|
||||
// *FIX: memory inefficient.
|
||||
ostr.put('b');
|
||||
std::vector<U8> buffer = data.asBinary();
|
||||
const std::vector<U8>& buffer = data.asBinary();
|
||||
U32 size_nbo = htonl(buffer.size());
|
||||
ostr.write((const char*)(&size_nbo), sizeof(U32));
|
||||
if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
|
||||
@@ -2080,6 +2122,7 @@ std::string zip_llsd(LLSD& data)
|
||||
return result;
|
||||
}
|
||||
|
||||
// <alchemy>
|
||||
//decompress a block of LLSD from provided istream
|
||||
// not very efficient -- creats a copy of decompressed LLSD block in memory
|
||||
// and deserializes from that copy using LLSDSerialize
|
||||
@@ -2109,13 +2152,6 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
@@ -2123,6 +2159,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
ret = Z_DATA_ERROR;
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
@@ -2172,6 +2209,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
free(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
//This unzip function will only work with a gzip header and trailer - while the contents
|
||||
//of the actual compressed data is the same for either format (gzip vs zlib ), the headers
|
||||
//and trailers are different for the formats.
|
||||
@@ -2201,27 +2239,19 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR;
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
valid = false;
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
|
||||
result = (U8*) realloc(result, cur_size + have);
|
||||
@@ -2248,5 +2278,5 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// </alchemy>
|
||||
|
||||
|
||||
@@ -4,31 +4,25 @@
|
||||
* @date 2006-02-26
|
||||
* @brief Declaration of parsers and formatters for LLSD
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -306,7 +300,7 @@ public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
LLSDXMLParser();
|
||||
LLSDXMLParser(bool emit_errors=true);
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -422,7 +416,8 @@ public:
|
||||
typedef enum e_formatter_options_type
|
||||
{
|
||||
OPTIONS_NONE = 0,
|
||||
OPTIONS_PRETTY = 1
|
||||
OPTIONS_PRETTY = 1,
|
||||
OPTIONS_PRETTY_BINARY = 2
|
||||
} EFormatterOptions;
|
||||
|
||||
/**
|
||||
@@ -513,6 +508,17 @@ public:
|
||||
* @return Returns The number of LLSD objects fomatted out
|
||||
*/
|
||||
virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief Implementation to format the data. This is called recursively.
|
||||
*
|
||||
* @param data The data to write.
|
||||
* @param ostr The destination stream for the data.
|
||||
* @return Returns The number of LLSD objects fomatted out
|
||||
*/
|
||||
S32 format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -638,6 +644,11 @@ protected:
|
||||
* params << "[{'version':i1}," << LLSDOStreamer<LLSDNotationFormatter>(sd)
|
||||
* << "]";
|
||||
* </code>
|
||||
*
|
||||
* *NOTE - formerly this class inherited from its template parameter Formatter,
|
||||
* but all instantiations passed in LLRefCount subclasses. This conflicted with
|
||||
* the auto allocation intended for this class template (demonstrated in the
|
||||
* example above). -brad
|
||||
*/
|
||||
template <class Formatter>
|
||||
class LLSDOStreamer
|
||||
@@ -721,6 +732,18 @@ public:
|
||||
LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
|
||||
return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
|
||||
}
|
||||
static S32 toPrettyNotation(const LLSD& sd, std::ostream& str)
|
||||
{
|
||||
LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
|
||||
return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
|
||||
}
|
||||
static S32 toPrettyBinaryNotation(const LLSD& sd, std::ostream& str)
|
||||
{
|
||||
LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
|
||||
return f->format(sd, str,
|
||||
LLSDFormatter::OPTIONS_PRETTY |
|
||||
LLSDFormatter::OPTIONS_PRETTY_BINARY);
|
||||
}
|
||||
static S32 fromNotation(LLSD& sd, std::istream& str, S32 max_bytes)
|
||||
{
|
||||
LLPointer<LLSDNotationParser> p = new LLSDNotationParser;
|
||||
@@ -748,25 +771,25 @@ public:
|
||||
return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
|
||||
}
|
||||
|
||||
static S32 fromXMLEmbedded(LLSD& sd, std::istream& str)
|
||||
static S32 fromXMLEmbedded(LLSD& sd, std::istream& str, bool emit_errors=true)
|
||||
{
|
||||
// no need for max_bytes since xml formatting is not
|
||||
// subvertable by bad sizes.
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
|
||||
return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
|
||||
}
|
||||
// Line oriented parser, 30% faster than fromXML(), but can
|
||||
// only be used when you know you have the complete XML
|
||||
// document available in the stream.
|
||||
static S32 fromXMLDocument(LLSD& sd, std::istream& str)
|
||||
static S32 fromXMLDocument(LLSD& sd, std::istream& str, bool emit_errors=true)
|
||||
{
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
|
||||
return p->parseLines(str, sd);
|
||||
}
|
||||
static S32 fromXML(LLSD& sd, std::istream& str)
|
||||
static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors=true)
|
||||
{
|
||||
return fromXMLEmbedded(sd, str);
|
||||
// return fromXMLDocument(sd, str);
|
||||
return fromXMLEmbedded(sd, str, emit_errors);
|
||||
// return fromXMLDocument(sd, str, emit_errors);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llsdserialize_xml.h"
|
||||
#include "llbase64.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
|
||||
#include "apr_base64.h"
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
extern "C"
|
||||
@@ -133,11 +133,7 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
case LLSD::TypeBoolean:
|
||||
ostr << pre << "<boolean>";
|
||||
if(mBoolAlpha ||
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
(ostr.flags() & std::ios::boolalpha)
|
||||
#else
|
||||
(ostr.flags() & 0x0100)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ostr << (data.asBoolean() ? "true" : "false");
|
||||
@@ -172,8 +168,8 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
break;
|
||||
|
||||
case LLSD::TypeString:
|
||||
if(data.asString().empty()) ostr << pre << "<string />" << post;
|
||||
else ostr << pre << "<string>" << escapeString(data.asString()) <<"</string>" << post;
|
||||
if(data.asStringRef().empty()) ostr << pre << "<string />" << post;
|
||||
else ostr << pre << "<string>" << escapeString(data.asStringRef()) <<"</string>" << post;
|
||||
break;
|
||||
|
||||
case LLSD::TypeDate:
|
||||
@@ -186,24 +182,15 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
|
||||
|
||||
case LLSD::TypeBinary:
|
||||
{
|
||||
LLSD::Binary buffer = data.asBinary();
|
||||
const LLSD::Binary& buffer = data.asBinary();
|
||||
if(buffer.empty())
|
||||
{
|
||||
ostr << pre << "<binary />" << post;
|
||||
}
|
||||
else
|
||||
{
|
||||
// *FIX: memory inefficient.
|
||||
// *TODO: convert to use LLBase64
|
||||
ostr << pre << "<binary encoding=\"base64\">";
|
||||
int b64_buffer_length = apr_base64_encode_len(buffer.size());
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
&buffer[0],
|
||||
buffer.size());
|
||||
ostr.write(b64_buffer, b64_buffer_length - 1);
|
||||
delete[] b64_buffer;
|
||||
ostr << LLBase64::encode(&buffer[0], buffer.size());
|
||||
ostr << "</binary>" << post;
|
||||
}
|
||||
break;
|
||||
@@ -254,7 +241,7 @@ std::string LLSDXMLFormatter::escapeString(const std::string& in)
|
||||
class LLSDXMLParser::Impl
|
||||
{
|
||||
public:
|
||||
Impl();
|
||||
Impl(bool emit_errors);
|
||||
~Impl();
|
||||
|
||||
S32 parse(std::istream& input, LLSD& data);
|
||||
@@ -298,6 +285,7 @@ private:
|
||||
|
||||
static const XML_Char* findAttribute(const XML_Char* name, const XML_Char** pairs);
|
||||
|
||||
bool mEmitErrors;
|
||||
|
||||
XML_Parser mParser;
|
||||
|
||||
@@ -319,7 +307,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
LLSDXMLParser::Impl::Impl()
|
||||
LLSDXMLParser::Impl::Impl(bool emit_errors)
|
||||
: mEmitErrors(emit_errors)
|
||||
{
|
||||
mParser = XML_ParserCreate(NULL);
|
||||
reset();
|
||||
@@ -348,9 +337,10 @@ void clear_eol(std::istream& input)
|
||||
static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize)
|
||||
{
|
||||
unsigned count = 0;
|
||||
char c;
|
||||
while (count < bufsize && input.good())
|
||||
{
|
||||
char c = input.get();
|
||||
input.get(c);
|
||||
buf[count++] = c;
|
||||
if (is_eol(c))
|
||||
break;
|
||||
@@ -377,13 +367,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
|
||||
{
|
||||
break;
|
||||
}
|
||||
count = get_till_eol(input, (char *)buffer, BUFFER_SIZE);
|
||||
if (!count)
|
||||
{
|
||||
|
||||
count = get_till_eol(input, (char *)buffer, BUFFER_SIZE);
|
||||
if (!count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
status = XML_ParseBuffer(mParser, count, false);
|
||||
|
||||
@@ -406,7 +393,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
|
||||
{
|
||||
((char*) buffer)[count ? count - 1 : 0] = '\0';
|
||||
}
|
||||
llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
|
||||
if (mEmitErrors)
|
||||
{
|
||||
llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
|
||||
}
|
||||
data = LLSD();
|
||||
return LLSDParser::PARSE_FAILURE;
|
||||
}
|
||||
@@ -484,7 +474,10 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
|
||||
if (status == XML_STATUS_ERROR
|
||||
&& !mGracefullStop)
|
||||
{
|
||||
llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
|
||||
if (mEmitErrors)
|
||||
{
|
||||
llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
|
||||
}
|
||||
return LLSDParser::PARSE_FAILURE;
|
||||
}
|
||||
|
||||
@@ -508,12 +501,7 @@ void LLSDXMLParser::Impl::reset()
|
||||
|
||||
mSkipping = false;
|
||||
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
mCurrentKey.clear();
|
||||
#else
|
||||
mCurrentKey = std::string();
|
||||
#endif
|
||||
|
||||
|
||||
XML_ParserReset(mParser, "utf-8");
|
||||
XML_SetUserData(mParser, this);
|
||||
@@ -641,11 +629,7 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch
|
||||
LLSD& newElement = map[mCurrentKey];
|
||||
mStack.push_back(&newElement);
|
||||
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
mCurrentKey.clear();
|
||||
#else
|
||||
mCurrentKey = std::string();
|
||||
#endif
|
||||
}
|
||||
else if (mStack.back()->isArray())
|
||||
{
|
||||
@@ -787,10 +771,10 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
|
||||
boost::regex r;
|
||||
r.assign("\\s");
|
||||
std::string stripped = boost::regex_replace(mCurrentContent, r, "");
|
||||
S32 len = apr_base64_decode_len(stripped.c_str());
|
||||
size_t len = LLBase64::requiredDecryptionSpace(stripped);
|
||||
std::vector<U8> data;
|
||||
data.resize(len);
|
||||
len = apr_base64_decode_binary(&data[0], stripped.c_str());
|
||||
len = LLBase64::decode(stripped, &data[0], len);
|
||||
data.resize(len);
|
||||
value = data;
|
||||
break;
|
||||
@@ -910,7 +894,7 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na
|
||||
/**
|
||||
* LLSDXMLParser
|
||||
*/
|
||||
LLSDXMLParser::LLSDXMLParser() : impl(* new Impl)
|
||||
LLSDXMLParser::LLSDXMLParser(bool emit_errors /* = true */) : impl(* new Impl(emit_errors))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -4,31 +4,25 @@
|
||||
* @date 2006-05-24
|
||||
* @brief Implementation of classes, functions, etc, for using structured data.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -188,7 +182,7 @@ char* ll_pretty_print_sd_ptr(const LLSD* sd)
|
||||
|
||||
char* ll_pretty_print_sd(const LLSD& sd)
|
||||
{
|
||||
const U32 bufferSize = 10 * 1024;
|
||||
const U32 bufferSize = 100 * 1024;
|
||||
static char buffer[bufferSize];
|
||||
std::ostringstream stream;
|
||||
//stream.rdbuf()->pubsetbuf(buffer, bufferSize);
|
||||
@@ -578,7 +572,7 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str
|
||||
return match_types(prototype.type(), TypeVector(), data.type(), pfx);
|
||||
}
|
||||
|
||||
bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits)
|
||||
bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
|
||||
{
|
||||
// We're comparing strict equality of LLSD representation rather than
|
||||
// performing any conversions. So if the types aren't equal, the LLSD
|
||||
@@ -598,7 +592,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits)
|
||||
case LLSD::TypeReal:
|
||||
// This is where the 'bits' argument comes in handy. If passed
|
||||
// explicitly, it means to use is_approx_equal_fraction() to compare.
|
||||
if (bits != -1)
|
||||
if (bits >= 0)
|
||||
{
|
||||
return is_approx_equal_fraction(lhs.asReal(), rhs.asReal(), bits);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#ifndef LL_LLSDUTIL_H
|
||||
#define LL_LLSDUTIL_H
|
||||
|
||||
class LLSD;
|
||||
#include "llsd.h"
|
||||
|
||||
// U32
|
||||
LL_COMMON_API LLSD ll_sd_from_U32(const U32);
|
||||
@@ -126,7 +126,7 @@ LL_COMMON_API std::string llsd_matches(const LLSD& prototype, const LLSD& data,
|
||||
/// Deep equality. If you want to compare LLSD::Real values for approximate
|
||||
/// equality rather than bitwise equality, pass @a bits as for
|
||||
/// is_approx_equal_fraction().
|
||||
LL_COMMON_API bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits=-1);
|
||||
LL_COMMON_API bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits=-1);
|
||||
|
||||
// Simple function to copy data out of input & output iterators if
|
||||
// there is no need for casting.
|
||||
|
||||
@@ -102,10 +102,10 @@ private:
|
||||
// stores pointer to singleton instance
|
||||
struct SingletonLifetimeManager
|
||||
{
|
||||
SingletonLifetimeManager()
|
||||
/*SingletonLifetimeManager()
|
||||
{
|
||||
construct();
|
||||
}
|
||||
}*/
|
||||
|
||||
static void construct()
|
||||
{
|
||||
@@ -115,14 +115,14 @@ private:
|
||||
sData.mInitState = INITIALIZING;
|
||||
}
|
||||
|
||||
~SingletonLifetimeManager()
|
||||
/*~SingletonLifetimeManager()
|
||||
{
|
||||
SingletonData& sData(getData());
|
||||
if (sData.mInitState != DELETED)
|
||||
{
|
||||
deleteSingleton();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -178,33 +178,28 @@ public:
|
||||
|
||||
static DERIVED_TYPE* getInstance()
|
||||
{
|
||||
static SingletonLifetimeManager sLifeTimeMgr;
|
||||
//static SingletonLifetimeManager sLifeTimeMgr;
|
||||
SingletonData& sData(getData());
|
||||
|
||||
switch (sData.mInitState)
|
||||
{
|
||||
case UNINITIALIZED:
|
||||
// should never be uninitialized at this point
|
||||
llassert(false);
|
||||
return NULL;
|
||||
case CONSTRUCTING:
|
||||
llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << LL_ENDL;
|
||||
return NULL;
|
||||
case INITIALIZING:
|
||||
// go ahead and flag ourselves as initialized so we can be reentrant during initialization
|
||||
sData.mInitState = INITIALIZED;
|
||||
// initialize singleton after constructing it so that it can reference other singletons which in turn depend on it,
|
||||
// thus breaking cyclic dependencies
|
||||
sData.mInstance->initSingleton();
|
||||
llwarns << "Using singleton " << typeid(DERIVED_TYPE).name() << " during its own initialization, before its initialization completed!" << LL_ENDL;
|
||||
return sData.mInstance;
|
||||
case INITIALIZED:
|
||||
return sData.mInstance;
|
||||
case DELETED:
|
||||
llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << LL_ENDL;
|
||||
case UNINITIALIZED:
|
||||
// This must be the first time we get here.
|
||||
SingletonLifetimeManager::construct();
|
||||
// same as first time construction
|
||||
sData.mInitState = INITIALIZED;
|
||||
// Singu note: LL sets the state to INITIALIZED here *already* - which avoids the warning below, but is clearly total bullshit.
|
||||
sData.mInstance->initSingleton();
|
||||
sData.mInitState = INITIALIZED;
|
||||
return sData.mInstance;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "llprocessor.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "llevents.h"
|
||||
#include "llformat.h"
|
||||
#include "lltimer.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
@@ -80,6 +81,7 @@ using namespace llsd;
|
||||
# include <sys/sysinfo.h>
|
||||
# include <stdexcept>
|
||||
const char MEMINFO_FILE[] = "/proc/meminfo";
|
||||
# include <gnu/libc-version.h>
|
||||
#elif LL_SOLARIS
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
@@ -107,6 +109,9 @@ static const F32 MEM_INFO_THROTTLE = 20;
|
||||
static const F32 MEM_INFO_WINDOW = 10*60;
|
||||
|
||||
#if LL_WINDOWS
|
||||
// We cannot trust GetVersionEx function on Win8.1 , we should check this value when creating OS string
|
||||
static const U32 WINNT_WINBLUE = 0x0603;
|
||||
|
||||
#ifndef DLLVERSIONINFO
|
||||
typedef struct _DllVersionInfo
|
||||
{
|
||||
@@ -175,13 +180,67 @@ bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number)
|
||||
}
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
// Wrap boost::regex_match() with a function that doesn't throw.
|
||||
template <typename S, typename M, typename R>
|
||||
static bool regex_match_no_exc(const S& string, M& match, const R& regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::regex_match(string, match, regex);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
|
||||
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap boost::regex_search() with a function that doesn't throw.
|
||||
template <typename S, typename M, typename R>
|
||||
static bool regex_search_no_exc(const S& string, M& match, const R& regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::regex_search(string, match, regex);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
|
||||
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
// GetVersionEx should not works correct with Windows 8.1 and the later version. We need to check this case
|
||||
static bool check_for_version(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
|
||||
DWORDLONG const dwlConditionMask = VerSetConditionMask(
|
||||
VerSetConditionMask(
|
||||
VerSetConditionMask(
|
||||
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
|
||||
VER_MINORVERSION, VER_GREATER_EQUAL),
|
||||
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
|
||||
osvi.dwMajorVersion = wMajorVersion;
|
||||
osvi.dwMinorVersion = wMinorVersion;
|
||||
osvi.wServicePackMajor = wServicePackMajor;
|
||||
|
||||
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
LLOSInfo::LLOSInfo() :
|
||||
mMajorVer(0), mMinorVer(0), mBuild(0)
|
||||
mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")
|
||||
{
|
||||
|
||||
#if LL_WINDOWS
|
||||
OSVERSIONINFOEX osvi;
|
||||
BOOL bOsVersionInfoEx;
|
||||
BOOL bShouldUseShellVersion = false;
|
||||
|
||||
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||
@@ -244,10 +303,18 @@ LLOSInfo::LLOSInfo() :
|
||||
}
|
||||
else if(osvi.dwMinorVersion == 2)
|
||||
{
|
||||
if (check_for_version(HIBYTE(WINNT_WINBLUE), LOBYTE(WINNT_WINBLUE), 0))
|
||||
{
|
||||
mOSStringSimple = "Microsoft Windows 8.1 ";
|
||||
bShouldUseShellVersion = true; // GetVersionEx failed, going to use shell version
|
||||
}
|
||||
else
|
||||
{
|
||||
if(osvi.wProductType == VER_NT_WORKSTATION)
|
||||
mOSStringSimple = "Microsoft Windows 8 ";
|
||||
else
|
||||
mOSStringSimple = "Windows Server 2012 ";
|
||||
}
|
||||
}
|
||||
|
||||
///get native system info if available..
|
||||
@@ -314,9 +381,8 @@ LLOSInfo::LLOSInfo() :
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpstr = llformat("%s (Build %d)",
|
||||
csdversion.c_str(),
|
||||
(osvi.dwBuildNumber & 0xffff));
|
||||
tmpstr = !bShouldUseShellVersion ? llformat("%s (Build %d)", csdversion.c_str(), (osvi.dwBuildNumber & 0xffff)):
|
||||
llformat("%s (Build %d)", csdversion.c_str(), shell32_build);
|
||||
}
|
||||
|
||||
mOSString = mOSStringSimple + tmpstr;
|
||||
@@ -352,7 +418,7 @@ LLOSInfo::LLOSInfo() :
|
||||
std::string compatibility_mode;
|
||||
if(got_shell32_version)
|
||||
{
|
||||
if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor)
|
||||
if((osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) && !bShouldUseShellVersion)
|
||||
{
|
||||
compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)",
|
||||
shell32_major,
|
||||
@@ -412,6 +478,102 @@ LLOSInfo::LLOSInfo() :
|
||||
mOSString = mOSStringSimple;
|
||||
}
|
||||
|
||||
#elif LL_LINUX
|
||||
|
||||
struct utsname un;
|
||||
if(uname(&un) != -1)
|
||||
{
|
||||
mOSStringSimple.append(un.sysname);
|
||||
mOSStringSimple.append(" ");
|
||||
mOSStringSimple.append(un.release);
|
||||
|
||||
mOSString = mOSStringSimple;
|
||||
mOSString.append(" ");
|
||||
mOSString.append(un.version);
|
||||
mOSString.append(" ");
|
||||
mOSString.append(un.machine);
|
||||
|
||||
// Simplify 'Simple'
|
||||
std::string ostype = mOSStringSimple.substr(0, mOSStringSimple.find_first_of(" ", 0));
|
||||
if (ostype == "Linux")
|
||||
{
|
||||
// Only care about major and minor Linux versions, truncate at second '.'
|
||||
std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0);
|
||||
std::string::size_type idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos;
|
||||
std::string simple = mOSStringSimple.substr(0, idx2);
|
||||
if (simple.length() > 0)
|
||||
mOSStringSimple = simple;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mOSStringSimple.append("Unable to collect OS info");
|
||||
mOSString = mOSStringSimple;
|
||||
}
|
||||
|
||||
const char OS_VERSION_MATCH_EXPRESSION[] = "([0-9]+)\\.([0-9]+)(\\.([0-9]+))?";
|
||||
boost::regex os_version_parse(OS_VERSION_MATCH_EXPRESSION);
|
||||
boost::smatch matched;
|
||||
|
||||
std::string glibc_version(gnu_get_libc_version());
|
||||
if ( regex_match_no_exc(glibc_version, matched, os_version_parse) )
|
||||
{
|
||||
LL_INFOS("AppInit") << "Using glibc version '" << glibc_version << "' as OS version" << LL_ENDL;
|
||||
|
||||
std::string version_value;
|
||||
|
||||
if ( matched[1].matched ) // Major version
|
||||
{
|
||||
version_value.assign(matched[1].first, matched[1].second);
|
||||
if (sscanf(version_value.c_str(), "%d", &mMajorVer) != 1)
|
||||
{
|
||||
LL_WARNS("AppInit") << "failed to parse major version '" << version_value << "' as a number" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS("AppInit")
|
||||
<< "OS version regex '" << OS_VERSION_MATCH_EXPRESSION
|
||||
<< "' returned true, but major version [1] did not match"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
if ( matched[2].matched ) // Minor version
|
||||
{
|
||||
version_value.assign(matched[2].first, matched[2].second);
|
||||
if (sscanf(version_value.c_str(), "%d", &mMinorVer) != 1)
|
||||
{
|
||||
LL_ERRS("AppInit") << "failed to parse minor version '" << version_value << "' as a number" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS("AppInit")
|
||||
<< "OS version regex '" << OS_VERSION_MATCH_EXPRESSION
|
||||
<< "' returned true, but minor version [1] did not match"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
if ( matched[4].matched ) // Build version (optional) - note that [3] includes the '.'
|
||||
{
|
||||
version_value.assign(matched[4].first, matched[4].second);
|
||||
if (sscanf(version_value.c_str(), "%d", &mBuild) != 1)
|
||||
{
|
||||
LL_ERRS("AppInit") << "failed to parse build version '" << version_value << "' as a number" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("AppInit")
|
||||
<< "OS build version not provided; using zero"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("AppInit") << "glibc version '" << glibc_version << "' cannot be parsed to three numbers; using all zeros" << LL_ENDL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct utsname un;
|
||||
@@ -444,8 +606,13 @@ LLOSInfo::LLOSInfo() :
|
||||
mOSStringSimple.append("Unable to collect OS info");
|
||||
mOSString = mOSStringSimple;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::stringstream dotted_version_string;
|
||||
dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild;
|
||||
mOSVersionString.append(dotted_version_string.str());
|
||||
|
||||
}
|
||||
|
||||
#ifndef LL_WINDOWS
|
||||
@@ -496,6 +663,11 @@ const std::string& LLOSInfo::getOSStringSimple() const
|
||||
return mOSStringSimple;
|
||||
}
|
||||
|
||||
const std::string& LLOSInfo::getOSVersionString() const
|
||||
{
|
||||
return mOSVersionString;
|
||||
}
|
||||
|
||||
const S32 STATUS_SIZE = 8192;
|
||||
|
||||
//static
|
||||
@@ -687,38 +859,6 @@ private:
|
||||
LLSD mStats;
|
||||
};
|
||||
|
||||
// Wrap boost::regex_match() with a function that doesn't throw.
|
||||
template <typename S, typename M, typename R>
|
||||
static bool regex_match_no_exc(const S& string, M& match, const R& regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::regex_match(string, match, regex);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
|
||||
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap boost::regex_search() with a function that doesn't throw.
|
||||
template <typename S, typename M, typename R>
|
||||
static bool regex_search_no_exc(const S& string, M& match, const R& regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::regex_search(string, match, regex);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
|
||||
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LLMemoryInfo::LLMemoryInfo()
|
||||
{
|
||||
refresh();
|
||||
@@ -1288,9 +1428,14 @@ public:
|
||||
LL_CONT << "slowest framerate for last " << int(prevSize * MEM_INFO_THROTTLE)
|
||||
<< " seconds ";
|
||||
}
|
||||
LL_CONT << std::fixed << std::setprecision(1) << framerate << std::setprecision(6) << '\n'
|
||||
<< LLMemoryInfo() << LL_ENDL;
|
||||
|
||||
std::streamsize precision = LL_CONT.precision(); // <alchemy/>
|
||||
|
||||
LL_CONT << std::fixed << std::setprecision(1) << framerate << '\n'
|
||||
<< LLMemoryInfo();
|
||||
|
||||
LL_CONT.precision(precision);
|
||||
LL_CONT << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@
|
||||
// use an LLCPUInfo object:
|
||||
//
|
||||
// LLCPUInfo info;
|
||||
// llinfos << info << llendl;
|
||||
// LL_INFOS() << info << LL_ENDL;
|
||||
//
|
||||
|
||||
#include "llsd.h"
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
@@ -48,6 +49,8 @@ public:
|
||||
const std::string& getOSString() const;
|
||||
const std::string& getOSStringSimple() const;
|
||||
|
||||
const std::string& getOSVersionString() const;
|
||||
|
||||
S32 mMajorVer;
|
||||
S32 mMinorVer;
|
||||
S32 mBuild;
|
||||
@@ -61,6 +64,7 @@ public:
|
||||
private:
|
||||
std::string mOSString;
|
||||
std::string mOSStringSimple;
|
||||
std::string mOSVersionString;
|
||||
};
|
||||
|
||||
|
||||
@@ -101,7 +105,7 @@ class LL_COMMON_API LLMemoryInfo
|
||||
Here's how you use an LLMemoryInfo:
|
||||
|
||||
LLMemoryInfo info;
|
||||
<br> llinfos << info << llendl;
|
||||
<br> LL_INFOS() << info << LL_ENDL;
|
||||
*/
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -201,7 +201,7 @@ protected:
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
typedef boost::recursive_mutex LLMutexImpl;
|
||||
typedef boost::condition_variable_any LLConditionVariableImpl;
|
||||
#elif defined(USE_STD_MUTEX) && (__cplusplus >= 201103L || _MSC_VER >= 1800)
|
||||
#elif defined(USE_STD_MUTEX) && LL_CPP11
|
||||
#include <mutex>
|
||||
typedef std::recursive_mutex LLMutexImpl;
|
||||
typedef std::condition_variable_any LLConditionVariableImpl;
|
||||
@@ -224,6 +224,7 @@ typedef apr_thread_cond_t* impl_cond_handle_type;
|
||||
#define NEEDS_MUTEX_RECURSION
|
||||
//END
|
||||
#endif
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#ifdef NEEDS_MUTEX_IMPL
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
#include "u64.h"
|
||||
|
||||
#include "lldate.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <winsock2.h>
|
||||
@@ -192,7 +190,7 @@ U64 get_clock_count()
|
||||
return clock_count.QuadPart - offset;
|
||||
}
|
||||
|
||||
F64 calc_clock_frequency(void)
|
||||
F64 calc_clock_frequency()
|
||||
{
|
||||
__int64 freq;
|
||||
QueryPerformanceFrequency((LARGE_INTEGER *) &freq);
|
||||
@@ -203,9 +201,9 @@ F64 calc_clock_frequency(void)
|
||||
|
||||
#if LL_LINUX || LL_DARWIN || LL_SOLARIS
|
||||
// Both Linux and Mac use gettimeofday for accurate time
|
||||
F64 calc_clock_frequency(void)
|
||||
F64 calc_clock_frequency()
|
||||
{
|
||||
return 1000000.0; // microseconds, so 1 Mhz.
|
||||
return 1000000.0; // microseconds, so 1 MHz.
|
||||
}
|
||||
|
||||
U64 get_clock_count()
|
||||
@@ -229,7 +227,7 @@ void update_clock_frequencies()
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// returns a U64 number that represents the number of
|
||||
// microseconds since the unix epoch - Jan 1, 1970
|
||||
// microseconds since the Unix epoch - Jan 1, 1970
|
||||
U64 totalTime()
|
||||
{
|
||||
U64 current_clock_count = get_clock_count();
|
||||
@@ -450,7 +448,7 @@ BOOL LLTimer::knownBadTimer()
|
||||
{
|
||||
if (!wcscmp(pci_id, bad_pci_list[check]))
|
||||
{
|
||||
// llwarns << "unreliable PCI chipset found!! " << pci_id << endl;
|
||||
// LL_WARNS() << "unreliable PCI chipset found!! " << pci_id << endl;
|
||||
failed = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -569,6 +567,3 @@ void timeStructToFormattedString(struct tm * time, std::string format, std::stri
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
protected:
|
||||
U64 mLastClockCount;
|
||||
U64 mExpirationTicks;
|
||||
BOOL mStarted;
|
||||
bool mStarted;
|
||||
|
||||
public:
|
||||
LLTimer();
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
F32 getElapsedTimeF32() const; // Returns elapsed time in seconds
|
||||
F64 getElapsedTimeF64() const; // Returns elapsed time in seconds
|
||||
|
||||
BOOL getStarted() const { return mStarted; }
|
||||
bool getStarted() const { return mStarted; }
|
||||
|
||||
|
||||
static U64 getCurrentClockCount(); // Returns the raw clockticks
|
||||
|
||||
@@ -716,7 +716,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
|
||||
getSystemTime(&time_last);
|
||||
uuids_this_tick = uuids_per_tick;
|
||||
init = TRUE;
|
||||
mMutex = new LLMutex;
|
||||
mMutex = new LLMutex();
|
||||
}
|
||||
|
||||
uuid_time_t time_now = {0,0};
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
@@ -116,6 +118,19 @@ public:
|
||||
U16 getCRC16() const;
|
||||
U32 getCRC32() const;
|
||||
|
||||
inline size_t hash() const
|
||||
{
|
||||
size_t seed = 0;
|
||||
for (U8 i = 0; i < 4; ++i)
|
||||
{
|
||||
seed ^= static_cast<size_t>(mData[i * 4]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
seed ^= static_cast<size_t>(mData[i * 4 + 1]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
seed ^= static_cast<size_t>(mData[i * 4 + 2]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
seed ^= static_cast<size_t>(mData[i * 4 + 3]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
|
||||
|
||||
static const LLUUID null;
|
||||
@@ -129,8 +144,6 @@ public:
|
||||
U8 mData[UUID_BYTES];
|
||||
};
|
||||
|
||||
typedef std::vector<LLUUID> uuid_vec_t;
|
||||
|
||||
// Construct
|
||||
inline LLUUID::LLUUID()
|
||||
{
|
||||
@@ -141,38 +154,20 @@ inline LLUUID::LLUUID()
|
||||
// Faster than copying from memory
|
||||
inline void LLUUID::setNull()
|
||||
{
|
||||
U32 *word = (U32 *)mData;
|
||||
word[0] = 0;
|
||||
word[1] = 0;
|
||||
word[2] = 0;
|
||||
word[3] = 0;
|
||||
memset(mData, 0, sizeof(mData)); // <alchemy/>
|
||||
}
|
||||
|
||||
|
||||
// Compare
|
||||
inline bool LLUUID::operator==(const LLUUID& rhs) const
|
||||
{
|
||||
U32 *tmp = (U32 *)mData;
|
||||
U32 *rhstmp = (U32 *)rhs.mData;
|
||||
// Note: binary & to avoid branching
|
||||
return
|
||||
(tmp[0] == rhstmp[0]) &
|
||||
(tmp[1] == rhstmp[1]) &
|
||||
(tmp[2] == rhstmp[2]) &
|
||||
(tmp[3] == rhstmp[3]);
|
||||
return !memcmp(mData, rhs.mData, sizeof(mData)); // <alchemy/>
|
||||
}
|
||||
|
||||
|
||||
inline bool LLUUID::operator!=(const LLUUID& rhs) const
|
||||
{
|
||||
U32 *tmp = (U32 *)mData;
|
||||
U32 *rhstmp = (U32 *)rhs.mData;
|
||||
// Note: binary | to avoid branching
|
||||
return
|
||||
(tmp[0] != rhstmp[0]) |
|
||||
(tmp[1] != rhstmp[1]) |
|
||||
(tmp[2] != rhstmp[2]) |
|
||||
(tmp[3] != rhstmp[3]);
|
||||
return !!memcmp(mData, rhs.mData, sizeof(mData)); // <alchemy/>
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -187,28 +182,20 @@ inline LLUUID::operator bool() const
|
||||
|
||||
inline BOOL LLUUID::notNull() const
|
||||
{
|
||||
U32 *word = (U32 *)mData;
|
||||
return (word[0] | word[1] | word[2] | word[3]) > 0;
|
||||
return !!memcmp(mData, null.mData, sizeof(mData)); // <alchemy/>
|
||||
}
|
||||
|
||||
// Faster than == LLUUID::null because doesn't require
|
||||
// as much memory access.
|
||||
inline BOOL LLUUID::isNull() const
|
||||
{
|
||||
U32 *word = (U32 *)mData;
|
||||
// If all bits are zero, return !0 == TRUE
|
||||
return !(word[0] | word[1] | word[2] | word[3]);
|
||||
return !memcmp(mData, null.mData, sizeof(mData)); // <alchemy/>
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
inline LLUUID::LLUUID(const LLUUID& rhs)
|
||||
{
|
||||
U32 *tmp = (U32 *)mData;
|
||||
U32 *rhstmp = (U32 *)rhs.mData;
|
||||
tmp[0] = rhstmp[0];
|
||||
tmp[1] = rhstmp[1];
|
||||
tmp[2] = rhstmp[2];
|
||||
tmp[3] = rhstmp[3];
|
||||
memcpy(mData, rhs.mData, sizeof(mData)); // <alchemy/>
|
||||
}
|
||||
|
||||
inline LLUUID::~LLUUID()
|
||||
@@ -218,14 +205,7 @@ inline LLUUID::~LLUUID()
|
||||
// Assignment
|
||||
inline LLUUID& LLUUID::operator=(const LLUUID& rhs)
|
||||
{
|
||||
// No need to check the case where this==&rhs. The branch is slower than the write.
|
||||
U32 *tmp = (U32 *)mData;
|
||||
U32 *rhstmp = (U32 *)rhs.mData;
|
||||
tmp[0] = rhstmp[0];
|
||||
tmp[1] = rhstmp[1];
|
||||
tmp[2] = rhstmp[2];
|
||||
tmp[3] = rhstmp[3];
|
||||
|
||||
memcpy(mData, rhs.mData, sizeof(mData)); // <alchemy/>
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -298,13 +278,25 @@ inline U16 LLUUID::getCRC16() const
|
||||
|
||||
inline U32 LLUUID::getCRC32() const
|
||||
{
|
||||
U32 *tmp = (U32*)mData;
|
||||
return tmp[0] + tmp[1] + tmp[2] + tmp[3];
|
||||
// <alchemy/>
|
||||
U32 ret = 0;
|
||||
for(U32 i = 0;i < 4;++i)
|
||||
{
|
||||
ret += (mData[i*4]) | (mData[i*4+1]) << 8 | (mData[i*4+2]) << 16 | (mData[i*4+3]) << 24;
|
||||
}
|
||||
return ret;
|
||||
// </alchemy>
|
||||
}
|
||||
|
||||
typedef std::vector<LLUUID> uuid_vec_t;
|
||||
typedef std::set<LLUUID> uuid_set_t;
|
||||
|
||||
// Helper structure for ordering lluuids in stl containers.
|
||||
// eg: std::map<LLUUID, LLWidget*, lluuid_less> widget_map;
|
||||
// Helper structure for ordering lluuids in stl containers. eg:
|
||||
// std::map<LLUUID, LLWidget*, lluuid_less> widget_map;
|
||||
//
|
||||
// (isn't this the default behavior anyway? I think we could
|
||||
// everywhere replace these with uuid_set_t, but someone should
|
||||
// verify.)
|
||||
struct lluuid_less
|
||||
{
|
||||
bool operator()(const LLUUID& lhs, const LLUUID& rhs) const
|
||||
@@ -315,6 +307,31 @@ struct lluuid_less
|
||||
|
||||
typedef std::set<LLUUID, lluuid_less> uuid_list_t;
|
||||
|
||||
|
||||
#ifdef LL_CPP11
|
||||
namespace std {
|
||||
template <> struct hash<LLUUID>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const LLUUID & id) const
|
||||
{
|
||||
return id.hash();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template<> class hash<LLUUID>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const LLUUID& id) const
|
||||
{
|
||||
return id.hash();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Sub-classes for keeping transaction IDs and asset IDs
|
||||
* straight.
|
||||
@@ -331,3 +348,5 @@ public:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/* Copyright (C) 2013 Siana Gearz
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA */
|
||||
|
||||
#ifndef SGUUIDHASH_H
|
||||
#define SGUUIDHASH_H
|
||||
|
||||
#include "lluuid.h"
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<> class hash<LLUUID> {
|
||||
public:
|
||||
size_t operator()(const LLUUID& id ) const
|
||||
{
|
||||
return *reinterpret_cast<const size_t*>(id.mData);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user