Conflicts:
	indra/llrender/llpostprocess.cpp
This commit is contained in:
Shyotl
2015-05-16 02:53:19 -05:00
283 changed files with 4359 additions and 2112 deletions

View File

@@ -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

View File

@@ -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';

View File

@@ -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; };

View File

@@ -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$
*/

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View 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
};
}

View 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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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?

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);
}
/*

View File

@@ -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))
{
}

View File

@@ -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);
}

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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};

View File

@@ -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

View File

@@ -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