Merge branch 'curlthreading2' into curlthreading3
Conflicts: indra/CMakeLists.txt indra/llcommon/llstring.h indra/llmessage/CMakeLists.txt indra/llmessage/llhttpclient.cpp indra/llmessage/llhttpclient.h indra/llmessage/llurlrequest.cpp indra/llmessage/llurlrequest.h indra/newview/hipporestrequest.cpp indra/newview/llappviewer.cpp
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
<key>OpenCircuit</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>template</string>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>false</boolean>
|
||||
</map>
|
||||
@@ -370,6 +370,14 @@
|
||||
</map>
|
||||
|
||||
<!-- Server to client -->
|
||||
<key>DisplayNameUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>ParcelVoiceInfo</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
@@ -419,6 +427,22 @@
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SetDisplayNameReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SimConsoleResponse</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>DirLandReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
@@ -515,8 +539,24 @@
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<!-- UDPDeprecated Messages -->
|
||||
|
||||
<key>NavMeshStatusUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>AgentStateUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<!-- UDPDeprecated Messages -->
|
||||
<key>ScriptRunningReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
@@ -569,26 +609,9 @@
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<!-- Server to client -->
|
||||
<key>DisplayNameUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SetDisplayNameReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
</map>
|
||||
<key>capBans</key>
|
||||
|
||||
@@ -47,7 +47,6 @@ add_custom_target(prepare DEPENDS ${prepare_depends})
|
||||
|
||||
add_subdirectory(cmake)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}cwdebug)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
|
||||
@@ -78,7 +77,6 @@ if (VIEWER)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
|
||||
|
||||
# viewer plugins directory
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
|
||||
|
||||
@@ -18,6 +18,7 @@ include_directories(
|
||||
)
|
||||
|
||||
set(aistatemachine_SOURCE_FILES
|
||||
debug_libcurl.cpp
|
||||
aistatemachine.cpp
|
||||
aitimer.cpp
|
||||
aicurl.cpp
|
||||
@@ -28,6 +29,7 @@ set(aistatemachine_SOURCE_FILES
|
||||
set(aistatemachine_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
debug_libcurl.h
|
||||
aistatemachine.h
|
||||
aitimer.h
|
||||
aicurlprivate.h
|
||||
|
||||
@@ -123,21 +123,14 @@ void ssl_locking_function(int mode, int n, char const* file, int line)
|
||||
}
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
static unsigned long __cdecl apr_os_thread_current_wrapper()
|
||||
{
|
||||
return (unsigned long)apr_os_thread_current();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_CRYPTO_THREADID
|
||||
// OpenSSL uniq id function.
|
||||
void ssl_id_function(CRYPTO_THREADID* thread_id)
|
||||
{
|
||||
#if 1 // apr_os_thread_current() returns an unsigned long.
|
||||
CRYPTO_THREADID_set_numeric(thread_id, apr_os_thread_current());
|
||||
#else // if it would return a pointer.
|
||||
#if LL_WINDOWS // apr_os_thread_current() returns a pointer,
|
||||
CRYPTO_THREADID_set_pointer(thread_id, apr_os_thread_current());
|
||||
#else // else it returns an unsigned long.
|
||||
CRYPTO_THREADID_set_numeric(thread_id, apr_os_thread_current());
|
||||
#endif
|
||||
}
|
||||
#endif // HAVE_CRYPTO_THREADID
|
||||
@@ -193,6 +186,13 @@ ssl_dyn_create_function_type old_ssl_dyn_create_function;
|
||||
ssl_dyn_destroy_function_type old_ssl_dyn_destroy_function;
|
||||
ssl_dyn_lock_function_type old_ssl_dyn_lock_function;
|
||||
|
||||
#if LL_WINDOWS
|
||||
static unsigned long __cdecl apr_os_thread_current_wrapper()
|
||||
{
|
||||
return (unsigned long)apr_os_thread_current();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set for openssl-1.0.1...1.0.1c.
|
||||
static bool need_renegotiation_hack = false;
|
||||
|
||||
@@ -200,15 +200,15 @@ static bool need_renegotiation_hack = false;
|
||||
void ssl_init(void)
|
||||
{
|
||||
// The version identifier format is: MMNNFFPPS: major minor fix patch status.
|
||||
int const compiled_openSLL_major = (OPENSSL_VERSION_NUMBER >> 28) & 0xff;
|
||||
int const compiled_openSLL_minor = (OPENSSL_VERSION_NUMBER >> 20) & 0xff;
|
||||
int const compiled_openSSL_major = (OPENSSL_VERSION_NUMBER >> 28) & 0xff;
|
||||
int const compiled_openSSL_minor = (OPENSSL_VERSION_NUMBER >> 20) & 0xff;
|
||||
unsigned long const ssleay = SSLeay();
|
||||
int const linked_openSLL_major = (ssleay >> 28) & 0xff;
|
||||
int const linked_openSLL_minor = (ssleay >> 20) & 0xff;
|
||||
int const linked_openSSL_major = (ssleay >> 28) & 0xff;
|
||||
int const linked_openSSL_minor = (ssleay >> 20) & 0xff;
|
||||
// Check if dynamically loaded version is compatible with the one we compiled against.
|
||||
// As off version 1.0.0 also minor versions are compatible.
|
||||
if (linked_openSLL_major != compiled_openSLL_major ||
|
||||
(compiled_openSLL_major == 0 && linked_openSLL_minor != compiled_openSLL_minor))
|
||||
if (linked_openSSL_major != compiled_openSSL_major ||
|
||||
(linked_openSSL_major == 0 && linked_openSSL_minor != compiled_openSSL_minor))
|
||||
{
|
||||
llerrs << "The viewer was compiled against " << OPENSSL_VERSION_TEXT <<
|
||||
" but linked against " << SSLeay_version(SSLEAY_VERSION) <<
|
||||
@@ -312,10 +312,19 @@ void initCurl(void (*flush_hook)())
|
||||
{
|
||||
llwarns << "libcurl was not compiled with support for asynchronous name lookups!" << llendl;
|
||||
}
|
||||
if (!version_info->ssl_version)
|
||||
{
|
||||
llerrs << "This libcurl has no SSL support!" << llendl;
|
||||
}
|
||||
|
||||
llinfos << "Successful initialization of libcurl " <<
|
||||
version_info->version << " (0x" << std::hex << version_info->version_num << "), (" <<
|
||||
version_info->ssl_version << ", libz/" << version_info->libz_version << ")." << llendl;
|
||||
version_info->ssl_version;
|
||||
if (version_info->libz_version)
|
||||
{
|
||||
llcont << ", libz/" << version_info->libz_version;
|
||||
}
|
||||
llcont << ")." << llendl;
|
||||
|
||||
// Detect SSL library used.
|
||||
gSSLlib = ssl_unknown;
|
||||
@@ -538,12 +547,12 @@ LLAtomicU32 Stats::multi_errors;
|
||||
//static
|
||||
void Stats::print(void)
|
||||
{
|
||||
llinfos << "============ CURL STATS ============" << llendl;
|
||||
llinfos << " Curl multi errors/calls : " << std::dec << multi_errors << "/" << multi_calls << llendl;
|
||||
llinfos << " Curl easy errors/calls : " << std::dec << easy_errors << "/" << easy_calls << llendl;
|
||||
llinfos << " curl_easy_init() errors/calls : " << std::dec << easy_init_errors << "/" << easy_init_calls << llendl;
|
||||
llinfos << " Current number of curl easy handles: " << std::dec << (easy_init_calls - easy_init_errors - easy_cleanup_calls) << llendl;
|
||||
llinfos << "========= END OF CURL STATS =========" << llendl;
|
||||
llinfos_nf << "============ CURL STATS ============" << llendl;
|
||||
llinfos_nf << " Curl multi errors/calls : " << std::dec << multi_errors << "/" << multi_calls << llendl;
|
||||
llinfos_nf << " Curl easy errors/calls : " << std::dec << easy_errors << "/" << easy_calls << llendl;
|
||||
llinfos_nf << " curl_easy_init() errors/calls : " << std::dec << easy_init_errors << "/" << easy_init_calls << llendl;
|
||||
llinfos_nf << " Current number of curl easy handles: " << std::dec << (easy_init_calls - easy_init_errors - easy_cleanup_calls) << llendl;
|
||||
llinfos_nf << "========= END OF CURL STATS =========" << llendl;
|
||||
}
|
||||
|
||||
// THREAD-SAFE
|
||||
@@ -648,7 +657,7 @@ void CurlEasyHandle::setErrorBuffer(void)
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode CurlEasyHandle::getinfo(CURLINFO info, void* data)
|
||||
CURLcode CurlEasyHandle::getinfo_priv(CURLINFO info, void* data)
|
||||
{
|
||||
setErrorBuffer();
|
||||
return check_easy_code(curl_easy_getinfo(mEasyHandle, info, data));
|
||||
@@ -692,6 +701,7 @@ CURLMcode CurlEasyHandle::remove_handle_from_multi(AICurlEasyRequest_wat& curl_e
|
||||
mActiveMultiHandle = NULL;
|
||||
CURLMcode res = check_multi_code(curl_multi_remove_handle(multi, mEasyHandle));
|
||||
removed_from_multi_handle(curl_easy_request_w);
|
||||
mPostField = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -708,8 +718,78 @@ void intrusive_ptr_release(ThreadSafeCurlEasyRequest* threadsafe_curl_easy_reque
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, long parameter)
|
||||
{
|
||||
llassert((CURLOPTTYPE_LONG <= option && option < CURLOPTTYPE_LONG + 1000) ||
|
||||
(sizeof(curl_off_t) == sizeof(long) &&
|
||||
CURLOPTTYPE_OFF_T <= option && option < CURLOPTTYPE_OFF_T + 1000));
|
||||
llassert(!mActiveMultiHandle);
|
||||
setErrorBuffer();
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||
}
|
||||
|
||||
// The standard requires that sizeof(long) < sizeof(long long), so it's safe to overload like this.
|
||||
// We assume that one of them is 64 bit, the size of curl_off_t.
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, long long parameter)
|
||||
{
|
||||
llassert(sizeof(curl_off_t) == sizeof(long long) &&
|
||||
CURLOPTTYPE_OFF_T <= option && option < CURLOPTTYPE_OFF_T + 1000);
|
||||
llassert(!mActiveMultiHandle);
|
||||
setErrorBuffer();
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||
}
|
||||
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, void const* parameter)
|
||||
{
|
||||
llassert(CURLOPTTYPE_OBJECTPOINT <= option && option < CURLOPTTYPE_OBJECTPOINT + 1000);
|
||||
setErrorBuffer();
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||
}
|
||||
|
||||
#define DEFINE_FUNCTION_SETOPT1(function_type, opt1) \
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, function_type parameter) \
|
||||
{ \
|
||||
llassert(option == opt1); \
|
||||
setErrorBuffer(); \
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter)); \
|
||||
}
|
||||
|
||||
#define DEFINE_FUNCTION_SETOPT3(function_type, opt1, opt2, opt3) \
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, function_type parameter) \
|
||||
{ \
|
||||
llassert(option == opt1 || option == opt2 || option == opt3); \
|
||||
setErrorBuffer(); \
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter)); \
|
||||
}
|
||||
|
||||
#define DEFINE_FUNCTION_SETOPT4(function_type, opt1, opt2, opt3, opt4) \
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, function_type parameter) \
|
||||
{ \
|
||||
llassert(option == opt1 || option == opt2 || option == opt3 || option == opt4); \
|
||||
setErrorBuffer(); \
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter)); \
|
||||
}
|
||||
|
||||
DEFINE_FUNCTION_SETOPT1(curl_debug_callback, CURLOPT_DEBUGFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT4(curl_write_callback, CURLOPT_HEADERFUNCTION, CURLOPT_WRITEFUNCTION, CURLOPT_INTERLEAVEFUNCTION, CURLOPT_READFUNCTION)
|
||||
//DEFINE_FUNCTION_SETOPT1(curl_read_callback, CURLOPT_READFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_ssl_ctx_callback, CURLOPT_SSL_CTX_FUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT3(curl_conv_callback, CURLOPT_CONV_FROM_NETWORK_FUNCTION, CURLOPT_CONV_TO_NETWORK_FUNCTION, CURLOPT_CONV_FROM_UTF8_FUNCTION)
|
||||
#if 0 // Not used by the viewer.
|
||||
DEFINE_FUNCTION_SETOPT1(curl_progress_callback, CURLOPT_PROGRESSFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_seek_callback, CURLOPT_SEEKFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_ioctl_callback, CURLOPT_IOCTLFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_sockopt_callback, CURLOPT_SOCKOPTFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_opensocket_callback, CURLOPT_OPENSOCKETFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_closesocket_callback, CURLOPT_CLOSESOCKETFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_sshkeycallback, CURLOPT_SSH_KEYFUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_chunk_bgn_callback, CURLOPT_CHUNK_BGN_FUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_chunk_end_callback, CURLOPT_CHUNK_END_FUNCTION)
|
||||
DEFINE_FUNCTION_SETOPT1(curl_fnmatch_callback, CURLOPT_FNMATCH_FUNCTION)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CurlEasyReqest
|
||||
// CurlEasyRequest
|
||||
|
||||
void CurlEasyRequest::setoptString(CURLoption option, std::string const& value)
|
||||
{
|
||||
@@ -717,11 +797,33 @@ void CurlEasyRequest::setoptString(CURLoption option, std::string const& value)
|
||||
setopt(option, value.c_str());
|
||||
}
|
||||
|
||||
void CurlEasyRequest::setPost(char const* postdata, S32 size)
|
||||
void CurlEasyRequest::setPost(AIPostFieldPtr const& postdata, S32 size)
|
||||
{
|
||||
setopt(CURLOPT_POST, 1L);
|
||||
setopt(CURLOPT_POSTFIELDS, static_cast<void*>(const_cast<char*>(postdata)));
|
||||
llassert_always(postdata->data());
|
||||
|
||||
Dout(dc::curl, "POST size is " << size << " bytes: \"" << libcwd::buf2str(postdata->data(), size) << "\".");
|
||||
setPostField(postdata); // Make sure the data stays around until we don't need it anymore.
|
||||
|
||||
setPost_raw(size, postdata->data());
|
||||
}
|
||||
|
||||
void CurlEasyRequest::setPost_raw(S32 size, char const* data)
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
// data == NULL when we're going to read the data using CURLOPT_READFUNCTION.
|
||||
Dout(dc::curl, "POST size is " << size << " bytes.");
|
||||
}
|
||||
|
||||
// The server never replies with 100-continue, so suppress the "Expect: 100-continue" header that libcurl adds by default.
|
||||
addHeader("Expect:");
|
||||
if (size > 0)
|
||||
{
|
||||
addHeader("Connection: keep-alive");
|
||||
addHeader("Keep-alive: 300");
|
||||
}
|
||||
setopt(CURLOPT_POSTFIELDSIZE, size);
|
||||
setopt(CURLOPT_POSTFIELDS, data);
|
||||
}
|
||||
|
||||
ThreadSafeCurlEasyRequest* CurlEasyRequest::get_lockobj(void)
|
||||
@@ -797,7 +899,7 @@ void CurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* us
|
||||
setopt(CURLOPT_SSL_CTX_DATA, userdata ? this : NULL);
|
||||
}
|
||||
|
||||
#define llmaybewarns lllog(LLApp::isExiting() ? LLError::LEVEL_INFO : LLError::LEVEL_WARN, NULL, NULL, false)
|
||||
#define llmaybewarns lllog(LLApp::isExiting() ? LLError::LEVEL_INFO : LLError::LEVEL_WARN, NULL, NULL, false, true)
|
||||
|
||||
static size_t noHeaderCallback(char* ptr, size_t size, size_t nmemb, void* userdata)
|
||||
{
|
||||
@@ -877,9 +979,11 @@ void CurlEasyRequest::addHeader(char const* header)
|
||||
mHeaders = curl_slist_append(mHeaders, header);
|
||||
}
|
||||
|
||||
#ifdef CWDEBUG
|
||||
static int curl_debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr)
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
|
||||
static int curl_debug_cb(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr)
|
||||
{
|
||||
#ifdef CWDEBUG
|
||||
using namespace ::libcwd;
|
||||
|
||||
CurlEasyRequest* request = (CurlEasyRequest*)user_ptr;
|
||||
@@ -890,6 +994,14 @@ static int curl_debug_callback(CURL*, curl_infotype infotype, char* buf, size_t
|
||||
if (!debug::channels::dc::curlio.is_on())
|
||||
debug::channels::dc::curlio.on();
|
||||
LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcw_do, dc::curlio|cond_nonewline_cf(infotype == CURLINFO_TEXT))
|
||||
#else
|
||||
if (infotype == CURLINFO_TEXT)
|
||||
{
|
||||
while (size > 0 && (buf[size - 1] == '\r' || buf[size - 1] == '\n'))
|
||||
--size;
|
||||
}
|
||||
LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcw_do, dc::curlio)
|
||||
#endif
|
||||
switch (infotype)
|
||||
{
|
||||
case CURLINFO_TEXT:
|
||||
@@ -924,7 +1036,7 @@ static int curl_debug_callback(CURL*, curl_infotype infotype, char* buf, size_t
|
||||
{
|
||||
LibcwDoutStream << size << " bytes";
|
||||
bool finished = false;
|
||||
int i = 0;
|
||||
size_t i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
char c = buf[i];
|
||||
@@ -967,7 +1079,9 @@ static int curl_debug_callback(CURL*, curl_infotype infotype, char* buf, size_t
|
||||
else
|
||||
LibcwDoutStream << size << " bytes";
|
||||
LibcwDoutScopeEnd;
|
||||
#ifdef CWDEBUG
|
||||
libcw_do.pop_marker();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1032,7 +1146,7 @@ void CurlEasyRequest::applyDefaultOptions(void)
|
||||
if (dc::curlio.is_on())
|
||||
{
|
||||
setopt(CURLOPT_VERBOSE, 1);
|
||||
setopt(CURLOPT_DEBUGFUNCTION, &curl_debug_callback);
|
||||
setopt(CURLOPT_DEBUGFUNCTION, &curl_debug_cb);
|
||||
setopt(CURLOPT_DEBUGDATA, this);
|
||||
}
|
||||
);
|
||||
@@ -1042,8 +1156,23 @@ void CurlEasyRequest::finalizeRequest(std::string const& url)
|
||||
{
|
||||
llassert(!mRequestFinalized);
|
||||
mResult = CURLE_FAILED_INIT; // General error code, the final code is written here in MultiHandle::check_run_count when msg is CURLMSG_DONE.
|
||||
mRequestFinalized = true;
|
||||
lldebugs << url << llendl;
|
||||
#ifdef SHOW_ASSERT
|
||||
// Do a sanity check on the headers.
|
||||
int content_type_count = 0;
|
||||
for (curl_slist* list = mHeaders; list; list = list->next)
|
||||
{
|
||||
if (strncmp(list->data, "Content-Type:", 13) == 0)
|
||||
{
|
||||
++content_type_count;
|
||||
}
|
||||
}
|
||||
if (content_type_count > 1)
|
||||
{
|
||||
llwarns << content_type_count << " Content-Type: headers!" << llendl;
|
||||
}
|
||||
#endif
|
||||
mRequestFinalized = true;
|
||||
setopt(CURLOPT_HTTPHEADER, mHeaders);
|
||||
setoptString(CURLOPT_URL, url);
|
||||
// The following line is a bit tricky: we store a pointer to the object without increasing its reference count.
|
||||
@@ -1124,7 +1253,7 @@ CurlResponderBuffer::CurlResponderBuffer() : mRequestTransferedBytes(0), mRespon
|
||||
curl_easy_request_w->send_events_to(this);
|
||||
}
|
||||
|
||||
#define llmaybeerrs lllog(LLApp::isRunning() ? LLError::LEVEL_ERROR : LLError::LEVEL_WARN, NULL, NULL, false)
|
||||
#define llmaybeerrs lllog(LLApp::isRunning() ? LLError::LEVEL_ERROR : LLError::LEVEL_WARN, NULL, NULL, false, true)
|
||||
|
||||
// The callbacks need to be revoked when the CurlResponderBuffer is destructed (because that is what the callbacks use).
|
||||
// The AIThreadSafeSimple<CurlResponderBuffer> is destructed first (right to left), so when we get here then the
|
||||
@@ -1182,7 +1311,8 @@ void CurlResponderBuffer::prepRequest(AICurlEasyRequest_wat& curl_easy_request_w
|
||||
{
|
||||
if (post)
|
||||
{
|
||||
curl_easy_request_w->setoptString(CURLOPT_ENCODING, "");
|
||||
// Accept everything (send an Accept-Encoding header containing all encodings we support (zlib and gzip)).
|
||||
curl_easy_request_w->setoptString(CURLOPT_ENCODING, ""); // CURLOPT_ACCEPT_ENCODING
|
||||
}
|
||||
|
||||
mInput.reset(new LLBufferArray);
|
||||
@@ -1215,9 +1345,7 @@ void CurlResponderBuffer::prepRequest(AICurlEasyRequest_wat& curl_easy_request_w
|
||||
|
||||
if (!post)
|
||||
{
|
||||
curl_easy_request_w->addHeader("Connection: keep-alive");
|
||||
curl_easy_request_w->addHeader("Keep-alive: 300");
|
||||
// Add other headers.
|
||||
// Add extra headers.
|
||||
for (std::vector<std::string>::const_iterator iter = headers.begin(); iter != headers.end(); ++iter)
|
||||
{
|
||||
curl_easy_request_w->addHeader((*iter).c_str());
|
||||
|
||||
@@ -37,10 +37,16 @@
|
||||
#include <stdexcept>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <curl/curl.h> // CURL, CURLM, CURLMcode, CURLoption, curl_*_callback
|
||||
|
||||
#include "llpreprocessor.h"
|
||||
#include <curl/curl.h> // Needed for files that include this header (also for aicurlprivate.h).
|
||||
#ifdef DEBUG_CURLIO
|
||||
#include "debug_libcurl.h"
|
||||
#endif
|
||||
|
||||
// Make sure we don't use this option: it is not thread-safe.
|
||||
#undef CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
#define CURLOPT_DNS_USE_GLOBAL_CACHE do_not_use_CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
|
||||
#include "stdtypes.h" // U32
|
||||
#include "lliopipe.h" // LLIOPipe::buffer_ptr_t
|
||||
@@ -242,6 +248,21 @@ struct AICurlEasyHandleEvents {
|
||||
virtual ~AICurlEasyHandleEvents() { }
|
||||
};
|
||||
|
||||
// Pointer to data we're going to POST.
|
||||
class AIPostField : public LLThreadSafeRefCount {
|
||||
protected:
|
||||
char const* mData;
|
||||
|
||||
public:
|
||||
AIPostField(char const* data) : mData(data) { }
|
||||
char const* data(void) const { return mData; }
|
||||
};
|
||||
|
||||
// The pointer to the data that we have to POST is passed around as AIPostFieldPtr,
|
||||
// which causes it to automatically clean up when there are no pointers left
|
||||
// pointing to it.
|
||||
typedef LLPointer<AIPostField> AIPostFieldPtr;
|
||||
|
||||
#include "aicurlprivate.h"
|
||||
|
||||
// AICurlPrivate::CurlEasyRequestPtr, a boost::intrusive_ptr, is no more threadsafe than a
|
||||
|
||||
@@ -59,6 +59,9 @@ void stopCurlThread(void);
|
||||
class ThreadSafeCurlEasyRequest;
|
||||
class ThreadSafeBufferedCurlEasyRequest;
|
||||
|
||||
#define DECLARE_SETOPT(param_type) \
|
||||
CURLcode setopt(CURLoption option, param_type parameter)
|
||||
|
||||
// This class wraps CURL*'s.
|
||||
// It guarantees that a pointer is cleaned up when no longer needed, as required by libcurl.
|
||||
class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEvents {
|
||||
@@ -75,8 +78,30 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
||||
void reset(void) { llassert(!mActiveMultiHandle); curl_easy_reset(mEasyHandle); }
|
||||
|
||||
// Set options for a curl easy handle.
|
||||
template<typename BUILTIN>
|
||||
CURLcode setopt(CURLoption option, BUILTIN parameter);
|
||||
DECLARE_SETOPT(long);
|
||||
DECLARE_SETOPT(long long);
|
||||
DECLARE_SETOPT(void const*);
|
||||
DECLARE_SETOPT(curl_debug_callback);
|
||||
DECLARE_SETOPT(curl_write_callback);
|
||||
//DECLARE_SETOPT(curl_read_callback); Same type as curl_write_callback
|
||||
DECLARE_SETOPT(curl_ssl_ctx_callback);
|
||||
DECLARE_SETOPT(curl_conv_callback);
|
||||
#if 0 // Not used by the viewer.
|
||||
DECLARE_SETOPT(curl_progress_callback);
|
||||
DECLARE_SETOPT(curl_seek_callback);
|
||||
DECLARE_SETOPT(curl_ioctl_callback);
|
||||
DECLARE_SETOPT(curl_sockopt_callback);
|
||||
DECLARE_SETOPT(curl_opensocket_callback);
|
||||
DECLARE_SETOPT(curl_closesocket_callback);
|
||||
DECLARE_SETOPT(curl_sshkeycallback);
|
||||
DECLARE_SETOPT(curl_chunk_bgn_callback);
|
||||
DECLARE_SETOPT(curl_chunk_end_callback);
|
||||
DECLARE_SETOPT(curl_fnmatch_callback);
|
||||
#endif
|
||||
// Automatically cast int types to a long. Note that U32/S32 are int and
|
||||
// that you can overload int and long even if they have the same size.
|
||||
CURLcode setopt(CURLoption option, U32 parameter) { return setopt(option, (long)parameter); }
|
||||
CURLcode setopt(CURLoption option, S32 parameter) { return setopt(option, (long)parameter); }
|
||||
|
||||
// Clone a libcurl session handle using all the options previously set.
|
||||
//CurlEasyHandle(CurlEasyHandle const& orig);
|
||||
@@ -86,11 +111,21 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
||||
char* unescape(char* url, int inlength , int* outlength);
|
||||
|
||||
// Extract information from a curl handle.
|
||||
CURLcode getinfo(CURLINFO info, void* data);
|
||||
#if _WIN64 || __x86_64__ || __ppc64__
|
||||
private:
|
||||
CURLcode getinfo_priv(CURLINFO info, void* data);
|
||||
public:
|
||||
// The rest are inlines to provide some type-safety.
|
||||
CURLcode getinfo(CURLINFO info, char** data) { return getinfo_priv(info, data); }
|
||||
CURLcode getinfo(CURLINFO info, curl_slist** data) { return getinfo_priv(info, data); }
|
||||
CURLcode getinfo(CURLINFO info, double* data) { return getinfo_priv(info, data); }
|
||||
CURLcode getinfo(CURLINFO info, long* data) { return getinfo_priv(info, data); }
|
||||
#ifdef __LP64__ // sizeof(long) > sizeof(int) ?
|
||||
// Overload for integer types that are too small (libcurl demands a long).
|
||||
CURLcode getinfo(CURLINFO info, S32* data) { long ldata; CURLcode res = getinfo(info, &ldata); *data = static_cast<S32>(ldata); return res; }
|
||||
CURLcode getinfo(CURLINFO info, U32* data) { long ldata; CURLcode res = getinfo(info, &ldata); *data = static_cast<U32>(ldata); return res; }
|
||||
CURLcode getinfo(CURLINFO info, S32* data) { long ldata; CURLcode res = getinfo_priv(info, &ldata); *data = static_cast<S32>(ldata); return res; }
|
||||
CURLcode getinfo(CURLINFO info, U32* data) { long ldata; CURLcode res = getinfo_priv(info, &ldata); *data = static_cast<U32>(ldata); return res; }
|
||||
#else
|
||||
CURLcode getinfo(CURLINFO info, S32* data) { return getinfo_priv(info, static_cast<long*>(data)); }
|
||||
CURLcode getinfo(CURLINFO info, U32* data) { return getinfo_priv(info, static_cast<long*>(data)); }
|
||||
#endif
|
||||
|
||||
// Perform a file transfer (blocking).
|
||||
@@ -108,6 +143,7 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
||||
CURL* mEasyHandle;
|
||||
CURLM* mActiveMultiHandle;
|
||||
char* mErrorBuffer;
|
||||
AIPostFieldPtr mPostField; // This keeps the POSTFIELD data alive for as long as the easy handle exists.
|
||||
bool mQueuedForRemoval; // Set if the easy handle is (probably) added to the multi handle, but is queued for removal.
|
||||
#ifdef SHOW_ASSERT
|
||||
public:
|
||||
@@ -155,19 +191,14 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
||||
// Return the underlying curl easy handle.
|
||||
CURL* getEasyHandle(void) const { return mEasyHandle; }
|
||||
|
||||
// Keep POSTFIELD data alive.
|
||||
void setPostField(AIPostFieldPtr const& post_field_ptr) { mPostField = post_field_ptr; }
|
||||
|
||||
private:
|
||||
// Return, and possibly create, the curl (easy) error buffer used by the current thread.
|
||||
static char* getTLErrorBuffer(void);
|
||||
};
|
||||
|
||||
template<typename BUILTIN>
|
||||
CURLcode CurlEasyHandle::setopt(CURLoption option, BUILTIN parameter)
|
||||
{
|
||||
llassert(!mActiveMultiHandle);
|
||||
setErrorBuffer();
|
||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||
}
|
||||
|
||||
// CurlEasyRequest adds a slightly more powerful interface that can be used
|
||||
// to set the options on a curl easy handle.
|
||||
//
|
||||
@@ -181,9 +212,13 @@ CURLcode CurlEasyHandle::setopt(CURLoption option, BUILTIN parameter)
|
||||
// AICurlEasyRequest is deleted, then also the ThreadSafeCurlEasyRequest is deleted
|
||||
// and the CurlEasyRequest destructed.
|
||||
class CurlEasyRequest : public CurlEasyHandle {
|
||||
private:
|
||||
void setPost_raw(S32 size, char const* data);
|
||||
public:
|
||||
void setPost(S32 size) { setPost_raw(size, NULL); }
|
||||
void setPost(AIPostFieldPtr const& postdata, S32 size);
|
||||
void setPost(char const* data, S32 size) { setPost(new AIPostField(data), size); }
|
||||
void setoptString(CURLoption option, std::string const& value);
|
||||
void setPost(char const* postdata, S32 size);
|
||||
void addHeader(char const* str);
|
||||
|
||||
private:
|
||||
@@ -408,16 +443,41 @@ class CurlMultiHandle : public boost::noncopyable {
|
||||
|
||||
public:
|
||||
// Set options for a curl multi handle.
|
||||
template<typename BUILTIN>
|
||||
CURLMcode setopt(CURLMoption option, BUILTIN parameter);
|
||||
CURLMcode setopt(CURLMoption option, long parameter);
|
||||
CURLMcode setopt(CURLMoption option, curl_socket_callback parameter);
|
||||
CURLMcode setopt(CURLMoption option, curl_multi_timer_callback parameter);
|
||||
CURLMcode setopt(CURLMoption option, void* parameter);
|
||||
|
||||
// Returns total number of existing CURLM* handles (excluding ones created outside this class).
|
||||
static U32 getTotalMultiHandles(void) { return sTotalMultiHandles; }
|
||||
};
|
||||
|
||||
template<typename BUILTIN>
|
||||
CURLMcode CurlMultiHandle::setopt(CURLMoption option, BUILTIN parameter)
|
||||
// Overload the setopt methods in order to enforce the correct types (ie, convert an int to a long).
|
||||
|
||||
// curl_multi_setopt may only be passed a long,
|
||||
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, long parameter)
|
||||
{
|
||||
llassert(option == CURLMOPT_MAXCONNECTS || option == CURLMOPT_PIPELINING);
|
||||
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||
}
|
||||
|
||||
// ... or a function pointer,
|
||||
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, curl_socket_callback parameter)
|
||||
{
|
||||
llassert(option == CURLMOPT_SOCKETFUNCTION);
|
||||
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||
}
|
||||
|
||||
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, curl_multi_timer_callback parameter)
|
||||
{
|
||||
llassert(option == CURLMOPT_TIMERFUNCTION);
|
||||
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||
}
|
||||
|
||||
// ... or an object pointer.
|
||||
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, void* parameter)
|
||||
{
|
||||
llassert(option == CURLMOPT_SOCKETDATA || option == CURLMOPT_TIMERDATA);
|
||||
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||
}
|
||||
|
||||
|
||||
@@ -147,8 +147,53 @@ static void FD_CLR(curl_socket_t s, windows_fd_set* fsp)
|
||||
#define fd_set windows_fd_set
|
||||
#define select windows_select
|
||||
|
||||
int WSAGetLastError(void)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
typedef char* LPTSTR;
|
||||
|
||||
bool FormatMessage(int, void*, int e, int, LPTSTR error_str_ptr, int, void*)
|
||||
{
|
||||
char* error_str = *(LPTSTR*)error_str_ptr;
|
||||
error_str = strerror(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LocalFree(LPTSTR)
|
||||
{
|
||||
}
|
||||
|
||||
int const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0;
|
||||
int const FORMAT_MESSAGE_FROM_SYSTEM = 0;
|
||||
int const FORMAT_MESSAGE_IGNORE_INSERTS = 0;
|
||||
int const INVALID_SOCKET = -1;
|
||||
int const SOCKET_ERROR = -1;
|
||||
int const WSAEWOULDBLOCK = EWOULDBLOCK;
|
||||
|
||||
int closesocket(curl_socket_t fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
int const FIONBIO = 0;
|
||||
|
||||
int ioctlsocket(int fd, int, unsigned long* nonblocking_enable)
|
||||
{
|
||||
int res = fcntl(fd, F_GETFL, 0);
|
||||
llassert_always(res != -1);
|
||||
if (*nonblocking_enable)
|
||||
res |= O_NONBLOCK;
|
||||
else
|
||||
res &= ~O_NONBLOCK;
|
||||
return fcntl(fd, F_SETFD, res);
|
||||
}
|
||||
|
||||
#endif // DEBUG_WINDOWS_CODE_ON_LINUX
|
||||
|
||||
#define WINDOWS_CODE (LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
|
||||
#undef AICurlPrivate
|
||||
|
||||
namespace AICurlPrivate {
|
||||
@@ -252,7 +297,7 @@ class PollSet
|
||||
// Return a pointer to the underlaying fd_set.
|
||||
fd_set* access(void) { return &mFdSet; }
|
||||
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
// Return the largest fd set in mFdSet by refresh.
|
||||
curl_socket_t get_max_fd(void) const { return mMaxFdSet; }
|
||||
#endif
|
||||
@@ -279,7 +324,7 @@ class PollSet
|
||||
|
||||
fd_set mFdSet; // Output variable for select(). (Re)initialized by calling refresh().
|
||||
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
curl_socket_t mMaxFd; // The largest filedescriptor in the array, or CURL_SOCKET_BAD when it is empty.
|
||||
curl_socket_t mMaxFdSet; // The largest filedescriptor set in mFdSet by refresh(), or CURL_SOCKET_BAD when it was empty.
|
||||
std::vector<curl_socket_t> mCopiedFileDescriptors; // Filedescriptors copied by refresh to mFdSet.
|
||||
@@ -311,7 +356,7 @@ static size_t const MAXSIZE = llmax(1024, FD_SETSIZE);
|
||||
// Create an empty PollSet.
|
||||
PollSet::PollSet(void) : mFileDescriptors(new curl_socket_t [MAXSIZE]),
|
||||
mNrFds(0), mNext(0)
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
, mMaxFd(-1), mMaxFdSet(-1)
|
||||
#endif
|
||||
{
|
||||
@@ -323,7 +368,7 @@ void PollSet::add(curl_socket_t s)
|
||||
{
|
||||
llassert_always(mNrFds < (int)MAXSIZE);
|
||||
mFileDescriptors[mNrFds++] = s;
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
mMaxFd = llmax(mMaxFd, s);
|
||||
#endif
|
||||
}
|
||||
@@ -360,7 +405,7 @@ void PollSet::remove(curl_socket_t s)
|
||||
// index: 0 1 2 3 4 5
|
||||
// a b c s d e
|
||||
curl_socket_t cur = mFileDescriptors[i]; // cur = 'e'
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
curl_socket_t max = -1;
|
||||
#endif
|
||||
while (cur != s)
|
||||
@@ -368,7 +413,7 @@ void PollSet::remove(curl_socket_t s)
|
||||
llassert(i > 0);
|
||||
curl_socket_t next = mFileDescriptors[--i]; // next = 'd'
|
||||
mFileDescriptors[i] = cur; // Overwrite 'd' with 'e'.
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
max = llmax(max, cur); // max is the maximum value in 'i' or higher.
|
||||
#endif
|
||||
cur = next; // cur = 'd'
|
||||
@@ -395,7 +440,7 @@ void PollSet::remove(curl_socket_t s)
|
||||
if (mNext > i) // i is where s was.
|
||||
--mNext;
|
||||
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
// If s was the largest file descriptor, we have to update mMaxFd.
|
||||
if (s == mMaxFd)
|
||||
{
|
||||
@@ -412,7 +457,7 @@ void PollSet::remove(curl_socket_t s)
|
||||
|
||||
// ALSO make sure that s is no longer set in mFdSet, or we might confuse libcurl by
|
||||
// calling curl_multi_socket_action for a socket that it told us to remove.
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
clr(s);
|
||||
#else
|
||||
// We have to use a custom implementation here, because we don't want to invalidate mIter.
|
||||
@@ -461,13 +506,13 @@ inline void PollSet::clr(curl_socket_t fd)
|
||||
refresh_t PollSet::refresh(void)
|
||||
{
|
||||
FD_ZERO(&mFdSet);
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
mCopiedFileDescriptors.clear();
|
||||
#endif
|
||||
|
||||
if (mNrFds == 0)
|
||||
{
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
mMaxFdSet = -1;
|
||||
#endif
|
||||
return empty_and_complete;
|
||||
@@ -482,7 +527,7 @@ refresh_t PollSet::refresh(void)
|
||||
if (mNrFds >= FD_SETSIZE)
|
||||
{
|
||||
llwarns << "PollSet::reset: More than FD_SETSIZE (" << FD_SETSIZE << ") file descriptors active!" << llendl;
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
// Calculate mMaxFdSet.
|
||||
// Run over FD_SETSIZE - 1 elements, starting at mNext, wrapping to 0 when we reach the end.
|
||||
int max = -1, i = mNext, count = 0;
|
||||
@@ -493,7 +538,7 @@ refresh_t PollSet::refresh(void)
|
||||
else
|
||||
{
|
||||
mNext = 0; // Start at the beginning if we copy everything anyway.
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
mMaxFdSet = mMaxFd;
|
||||
#endif
|
||||
}
|
||||
@@ -507,7 +552,7 @@ refresh_t PollSet::refresh(void)
|
||||
return not_complete_not_empty;
|
||||
}
|
||||
FD_SET(mFileDescriptors[i], &mFdSet);
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
mCopiedFileDescriptors.push_back(mFileDescriptors[i]);
|
||||
#endif
|
||||
if (++i == mNrFds)
|
||||
@@ -545,7 +590,7 @@ refresh_t PollSet::refresh(void)
|
||||
|
||||
void PollSet::reset(void)
|
||||
{
|
||||
#if LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX
|
||||
#if WINDOWS_CODE
|
||||
mIter = 0;
|
||||
#else
|
||||
if (mCopiedFileDescriptors.empty())
|
||||
@@ -561,7 +606,7 @@ void PollSet::reset(void)
|
||||
|
||||
inline curl_socket_t PollSet::get(void) const
|
||||
{
|
||||
#if LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX
|
||||
#if WINDOWS_CODE
|
||||
return (mIter >= mFdSet.fd_count) ? CURL_SOCKET_BAD : mFdSet.fd_array[mIter];
|
||||
#else
|
||||
return (mIter == mCopiedFileDescriptors.end()) ? CURL_SOCKET_BAD : *mIter;
|
||||
@@ -570,7 +615,7 @@ inline curl_socket_t PollSet::get(void) const
|
||||
|
||||
void PollSet::next(void)
|
||||
{
|
||||
#if LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX
|
||||
#if WINDOWS_CODE
|
||||
llassert(mIter < mFdSet.fd_count);
|
||||
++mIter;
|
||||
#else
|
||||
@@ -744,7 +789,8 @@ AICurlThread* AICurlThread::sInstance = NULL;
|
||||
|
||||
// MAIN-THREAD
|
||||
AICurlThread::AICurlThread(void) : LLThread("AICurlThread"),
|
||||
mWakeUpFd_in(CURL_SOCKET_BAD), mWakeUpFd(CURL_SOCKET_BAD),
|
||||
mWakeUpFd_in(CURL_SOCKET_BAD),
|
||||
mWakeUpFd(CURL_SOCKET_BAD),
|
||||
mZeroTimeOut(0), mRunning(true), mWakeUpFlag(false)
|
||||
{
|
||||
create_wakeup_fds();
|
||||
@@ -758,19 +804,149 @@ AICurlThread::~AICurlThread()
|
||||
cleanup_wakeup_fds();
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
static std::string formatWSAError()
|
||||
{
|
||||
std::ostringstream r;
|
||||
int e = WSAGetLastError();
|
||||
LPTSTR error_str = 0;
|
||||
r << e;
|
||||
if(FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, e, 0, (LPTSTR)&error_str, 0, NULL))
|
||||
{
|
||||
r << " " << utf16str_to_utf8str(error_str);
|
||||
LocalFree(error_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
r << " Unknown WinSock error";
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
#elif WINDOWS_CODE
|
||||
static std::string formatWSAError()
|
||||
{
|
||||
return strerror(errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
/* Copyright 2007, 2010 by Nathan C. Myers <ncm@cantrip.org>
|
||||
* This code is Free Software. It may be copied freely, in original or
|
||||
* modified form, subject only to the restrictions that (1) the author is
|
||||
* relieved from all responsibilities for any use for any purpose, and (2)
|
||||
* this copyright notice must be retained, unchanged, in its entirety. If
|
||||
* for any reason the author might be held responsible for any consequences
|
||||
* of copying or use, license is withheld.
|
||||
*/
|
||||
static int dumb_socketpair(SOCKET socks[2], bool make_overlapped)
|
||||
{
|
||||
union {
|
||||
struct sockaddr_in inaddr;
|
||||
struct sockaddr addr;
|
||||
} a;
|
||||
SOCKET listener;
|
||||
int e;
|
||||
socklen_t addrlen = sizeof(a.inaddr);
|
||||
DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
|
||||
int reuse = 1;
|
||||
|
||||
if (socks == 0) {
|
||||
WSASetLastError(WSAEINVAL);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (listener == INVALID_SOCKET)
|
||||
return SOCKET_ERROR;
|
||||
|
||||
memset(&a, 0, sizeof(a));
|
||||
a.inaddr.sin_family = AF_INET;
|
||||
a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
a.inaddr.sin_port = 0;
|
||||
|
||||
socks[0] = socks[1] = INVALID_SOCKET;
|
||||
do {
|
||||
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char*) &reuse, (socklen_t) sizeof(reuse)) == -1)
|
||||
break;
|
||||
if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
|
||||
break;
|
||||
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
|
||||
break;
|
||||
// win32 getsockname may only set the port number, p=0.0005.
|
||||
// ( http://msdn.microsoft.com/library/ms738543.aspx ):
|
||||
a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
a.inaddr.sin_family = AF_INET;
|
||||
|
||||
if (listen(listener, 1) == SOCKET_ERROR)
|
||||
break;
|
||||
|
||||
socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags);
|
||||
if (socks[0] == INVALID_SOCKET)
|
||||
break;
|
||||
if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
|
||||
break;
|
||||
|
||||
socks[1] = accept(listener, NULL, NULL);
|
||||
if (socks[1] == INVALID_SOCKET)
|
||||
break;
|
||||
|
||||
closesocket(listener);
|
||||
return 0;
|
||||
|
||||
} while (0);
|
||||
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
closesocket(socks[0]);
|
||||
closesocket(socks[1]);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
#elif WINDOWS_CODE
|
||||
int dumb_socketpair(int socks[2], int dummy)
|
||||
{
|
||||
(void) dummy;
|
||||
return socketpair(AF_LOCAL, SOCK_STREAM, 0, socks);
|
||||
}
|
||||
#endif
|
||||
|
||||
// MAIN-THREAD
|
||||
void AICurlThread::create_wakeup_fds(void)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Probably need to use sockets here, cause Windows select doesn't work for a pipe.
|
||||
#error Missing implementation
|
||||
#if WINDOWS_CODE
|
||||
//SGTODO
|
||||
curl_socket_t socks[2];
|
||||
if (dumb_socketpair(socks, false) == SOCKET_ERROR)
|
||||
{
|
||||
llerrs << "Failed to generate wake-up socket pair" << formatWSAError() << llendl;
|
||||
return;
|
||||
}
|
||||
u_long nonblocking_enable = TRUE;
|
||||
int error = ioctlsocket(socks[0], FIONBIO, &nonblocking_enable);
|
||||
if(error)
|
||||
{
|
||||
llerrs << "Failed to set wake-up socket nonblocking: " << formatWSAError() << llendl;
|
||||
}
|
||||
llassert(nonblocking_enable);
|
||||
error = ioctlsocket(socks[1], FIONBIO, &nonblocking_enable);
|
||||
if(error)
|
||||
{
|
||||
llerrs << "Failed to set wake-up input socket nonblocking: " << formatWSAError() << llendl;
|
||||
}
|
||||
mWakeUpFd = socks[0];
|
||||
mWakeUpFd_in = socks[1];
|
||||
#else
|
||||
int pipefd[2];
|
||||
if (pipe(pipefd))
|
||||
{
|
||||
llerrs << "Failed to create wakeup pipe: " << strerror(errno) << llendl;
|
||||
}
|
||||
long flags = O_NONBLOCK;
|
||||
int const flags = O_NONBLOCK;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (fcntl(pipefd[i], F_SETFL, flags))
|
||||
@@ -786,8 +962,24 @@ void AICurlThread::create_wakeup_fds(void)
|
||||
// MAIN-THREAD
|
||||
void AICurlThread::cleanup_wakeup_fds(void)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
#error Missing implementation
|
||||
#if WINDOWS_CODE
|
||||
//SGTODO
|
||||
if (mWakeUpFd != CURL_SOCKET_BAD)
|
||||
{
|
||||
int error = closesocket(mWakeUpFd);
|
||||
if (error)
|
||||
{
|
||||
llwarns << "Error closing wake-up socket" << formatWSAError() << llendl;
|
||||
}
|
||||
}
|
||||
if (mWakeUpFd_in != CURL_SOCKET_BAD)
|
||||
{
|
||||
int error = closesocket(mWakeUpFd_in);
|
||||
if (error)
|
||||
{
|
||||
llwarns << "Error closing wake-up input socket" << formatWSAError() << llendl;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (mWakeUpFd_in != CURL_SOCKET_BAD)
|
||||
close(mWakeUpFd_in);
|
||||
@@ -810,8 +1002,15 @@ void AICurlThread::wakeup_thread(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
#error Missing implementation
|
||||
#if WINDOWS_CODE
|
||||
//SGTODO
|
||||
int len = send(mWakeUpFd_in, "!", 1, 0);
|
||||
if (len == SOCKET_ERROR)
|
||||
{
|
||||
llerrs << "Send to wake-up socket failed: " << formatWSAError() << llendl;
|
||||
}
|
||||
llassert_always(len == 1);
|
||||
//SGTODO: handle EAGAIN if needed
|
||||
#else
|
||||
// If write() is interrupted by a signal before it writes any data, it shall return -1 with errno set to [EINTR].
|
||||
// If write() is interrupted by a signal after it successfully writes some data, it shall return the number of bytes written.
|
||||
@@ -840,8 +1039,50 @@ void AICurlThread::wakeup(AICurlMultiHandle_wat const& multi_handle_w)
|
||||
{
|
||||
DoutEntering(dc::curl, "AICurlThread::wakeup");
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
#error Missing implementation
|
||||
#if WINDOWS_CODE
|
||||
//SGTODO
|
||||
char buf[256];
|
||||
bool got_data = false;
|
||||
for(;;)
|
||||
{
|
||||
int len = recv(mWakeUpFd, buf, sizeof(buf), 0);
|
||||
if (len > 0)
|
||||
{
|
||||
// Data was read from the pipe.
|
||||
got_data = true;
|
||||
if (len < sizeof(buf))
|
||||
break;
|
||||
}
|
||||
else if (len == SOCKET_ERROR)
|
||||
{
|
||||
// An error occurred.
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
if (got_data)
|
||||
break;
|
||||
// There was no data, even though select() said so. If this ever happens at all(?), lets just return and enter select() again.
|
||||
return;
|
||||
}
|
||||
else if (errno == EINTR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "read(3) from mWakeUpFd: " << formatWSAError() << llendl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pipe(2) returned 0.
|
||||
llwarns << "read(3) from mWakeUpFd returned 0, indicating that the pipe on the other end was closed! Shutting down curl thread." << llendl;
|
||||
closesocket(mWakeUpFd);
|
||||
mWakeUpFd = CURL_SOCKET_BAD;
|
||||
mRunning = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// If a read() is interrupted by a signal before it reads any data, it shall return -1 with errno set to [EINTR].
|
||||
// If a read() is interrupted by a signal after it has successfully read some data, it shall return the number of bytes read.
|
||||
@@ -958,7 +1199,7 @@ void AICurlThread::run(void)
|
||||
FD_SET(mWakeUpFd, read_fd_set);
|
||||
fd_set* write_fd_set = ((wres & empty)) ? NULL : multi_handle_w->mWritePollSet->access();
|
||||
// Calculate nfds (ignored on windows).
|
||||
#if !(LL_WINDOWS || DEBUG_WINDOWS_CODE_ON_LINUX)
|
||||
#if !WINDOWS_CODE
|
||||
curl_socket_t const max_rfd = llmax(multi_handle_w->mReadPollSet->get_max_fd(), mWakeUpFd);
|
||||
curl_socket_t const max_wfd = multi_handle_w->mWritePollSet->get_max_fd();
|
||||
int nfds = llmax(max_rfd, max_wfd) + 1;
|
||||
@@ -1121,7 +1362,7 @@ MultiHandle::~MultiHandle()
|
||||
delete mReadPollSet;
|
||||
}
|
||||
|
||||
#ifdef CWDEBUG
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
#undef AI_CASE_RETURN
|
||||
#define AI_CASE_RETURN(x) do { case x: return #x; } while(0)
|
||||
char const* action_str(int action)
|
||||
|
||||
@@ -193,7 +193,7 @@ void AIStateMachine::locked_cont(void)
|
||||
// Atomic test mActive and change mIdle.
|
||||
mIdleActive.lock();
|
||||
#ifdef SHOW_ASSERT
|
||||
mContThread = apr_os_thread_current();
|
||||
mContThread.reset();
|
||||
#endif
|
||||
mIdle = false;
|
||||
bool not_active = mActive == as_idle;
|
||||
@@ -239,7 +239,7 @@ void AIStateMachine::set_state(state_type state)
|
||||
mSetStateLock.lock();
|
||||
|
||||
// Do not call set_state() unless running.
|
||||
llassert(mState == bs_run || !LLThread::is_main_thread());
|
||||
llassert(mState == bs_run || !is_main_thread());
|
||||
|
||||
// If this function is called from another thread than the main thread, then we have to ignore
|
||||
// it if we're not idle and the state is less than the current state. The main thread must
|
||||
@@ -265,12 +265,12 @@ void AIStateMachine::set_state(state_type state)
|
||||
// state is less than the current state, ignore it.
|
||||
// Also, if abort() or finish() was called, then we should just ignore it.
|
||||
if (mState != bs_run ||
|
||||
(!mIdle && state <= mRunState && !LLThread::is_main_thread()))
|
||||
(!mIdle && state <= mRunState && !AIThreadID::in_main_thread()))
|
||||
{
|
||||
#ifdef SHOW_ASSERT
|
||||
// It's a bit weird if the same thread does two calls on a row where the second call
|
||||
// has a smaller value: warn about that.
|
||||
if (mState == bs_run && mContThread == apr_os_thread_current())
|
||||
if (mState == bs_run && mContThread.equals_current_thread())
|
||||
{
|
||||
llwarns << "Ignoring call to set_state(" << state_str(state) <<
|
||||
") by non-main thread before main-thread could react on previous call, "
|
||||
@@ -282,7 +282,7 @@ void AIStateMachine::set_state(state_type state)
|
||||
}
|
||||
|
||||
// Do not call idle() when set_state is called from another thread; use idle(state_type) instead.
|
||||
llassert(!mCalledThreadUnsafeIdle || LLThread::is_main_thread());
|
||||
llassert(!mCalledThreadUnsafeIdle || is_main_thread());
|
||||
|
||||
// Change mRunState to the requested value.
|
||||
if (mRunState != state)
|
||||
|
||||
@@ -217,7 +217,7 @@ class AIStateMachine {
|
||||
S64 mSleep; //!< Non-zero while the state machine is sleeping.
|
||||
LLMutex mIdleActive; //!< Used for atomic operations on the pair mIdle / mActive.
|
||||
#ifdef SHOW_ASSERT
|
||||
apr_os_thread_t mContThread; //!< Thread that last called locked_cont().
|
||||
AIThreadID mContThread; //!< Thread that last called locked_cont().
|
||||
bool mCalledThreadUnsafeIdle; //!< Set to true when idle() is called.
|
||||
#endif
|
||||
|
||||
@@ -252,7 +252,7 @@ class AIStateMachine {
|
||||
//! Create a non-running state machine.
|
||||
AIStateMachine(void) : mState(bs_initialize), mIdle(true), mAborted(true), mActive(as_idle), mSleep(0), mParent(NULL), mCallback(NULL)
|
||||
#ifdef SHOW_ASSERT
|
||||
, mContThread(0), mCalledThreadUnsafeIdle(false)
|
||||
, mContThread(AIThreadID::none), mCalledThreadUnsafeIdle(false)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
@@ -279,7 +279,7 @@ class AIStateMachine {
|
||||
mSetStateLock.lock();
|
||||
// Ignore calls to cont() if the statemachine isn't idle. See comments in set_state().
|
||||
// Calling cont() twice or after calling set_state(), without first calling idle(), is an error.
|
||||
if (mState != bs_run || !mIdle) { llassert(mState != bs_run || mContThread != apr_os_thread_current()); mSetStateLock.unlock(); return; }
|
||||
if (mState != bs_run || !mIdle) { llassert(mState != bs_run || !mContThread.equals_current_thread()); mSetStateLock.unlock(); return; }
|
||||
locked_cont();
|
||||
}
|
||||
private:
|
||||
|
||||
942
indra/aistatemachine/debug_libcurl.cpp
Normal file
942
indra/aistatemachine/debug_libcurl.cpp
Normal file
@@ -0,0 +1,942 @@
|
||||
#ifdef DEBUG_CURLIO
|
||||
|
||||
#include "sys.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
#include <stdarg.h>
|
||||
#include <cstring>
|
||||
#include "llpreprocessor.h"
|
||||
#include <curl/curl.h>
|
||||
#define COMPILING_DEBUG_LIBCURL_CC
|
||||
#include "debug_libcurl.h"
|
||||
#include "debug.h"
|
||||
#include "llerror.h"
|
||||
#ifdef CWDEBUG
|
||||
#include <libcwd/buf2str.h>
|
||||
#endif
|
||||
|
||||
#define CURL_VERSION(major, minor, patch) \
|
||||
(LIBCURL_VERSION_MAJOR > major || \
|
||||
(LIBCURL_VERSION_MAJOR == major && \
|
||||
LIBCURL_VERSION_MINOR > minor || \
|
||||
(LIBCURL_VERSION_MINOR == minor && \
|
||||
LIBCURL_VERSION_PATCH >= patch)))
|
||||
|
||||
static struct curl_slist unchanged_slist;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, struct curl_slist const& slist)
|
||||
{
|
||||
struct curl_slist const* ptr = &slist;
|
||||
if (ptr == &unchanged_slist)
|
||||
os << " <unchanged> ";
|
||||
else
|
||||
{
|
||||
os << "(curl_slist)@0x" << std::hex << (size_t)ptr << std::dec << "{";
|
||||
do
|
||||
{
|
||||
os << '"' << ptr->data << '"';
|
||||
ptr = ptr->next;
|
||||
if (ptr)
|
||||
os << ", ";
|
||||
}
|
||||
while(ptr);
|
||||
os << "}";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
#define CASEPRINT(x) case x: os << #x; break
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CURLINFO info)
|
||||
{
|
||||
switch (info)
|
||||
{
|
||||
CASEPRINT(CURLINFO_EFFECTIVE_URL);
|
||||
CASEPRINT(CURLINFO_RESPONSE_CODE);
|
||||
CASEPRINT(CURLINFO_TOTAL_TIME);
|
||||
CASEPRINT(CURLINFO_NAMELOOKUP_TIME);
|
||||
CASEPRINT(CURLINFO_CONNECT_TIME);
|
||||
CASEPRINT(CURLINFO_PRETRANSFER_TIME);
|
||||
CASEPRINT(CURLINFO_SIZE_UPLOAD);
|
||||
CASEPRINT(CURLINFO_SIZE_DOWNLOAD);
|
||||
CASEPRINT(CURLINFO_SPEED_DOWNLOAD);
|
||||
CASEPRINT(CURLINFO_SPEED_UPLOAD);
|
||||
CASEPRINT(CURLINFO_HEADER_SIZE);
|
||||
CASEPRINT(CURLINFO_REQUEST_SIZE);
|
||||
CASEPRINT(CURLINFO_SSL_VERIFYRESULT);
|
||||
CASEPRINT(CURLINFO_FILETIME);
|
||||
CASEPRINT(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
|
||||
CASEPRINT(CURLINFO_CONTENT_LENGTH_UPLOAD);
|
||||
CASEPRINT(CURLINFO_STARTTRANSFER_TIME);
|
||||
CASEPRINT(CURLINFO_CONTENT_TYPE);
|
||||
CASEPRINT(CURLINFO_REDIRECT_TIME);
|
||||
CASEPRINT(CURLINFO_REDIRECT_COUNT);
|
||||
CASEPRINT(CURLINFO_PRIVATE);
|
||||
CASEPRINT(CURLINFO_HTTP_CONNECTCODE);
|
||||
CASEPRINT(CURLINFO_HTTPAUTH_AVAIL);
|
||||
CASEPRINT(CURLINFO_PROXYAUTH_AVAIL);
|
||||
CASEPRINT(CURLINFO_OS_ERRNO);
|
||||
CASEPRINT(CURLINFO_NUM_CONNECTS);
|
||||
CASEPRINT(CURLINFO_SSL_ENGINES);
|
||||
CASEPRINT(CURLINFO_COOKIELIST);
|
||||
CASEPRINT(CURLINFO_LASTSOCKET);
|
||||
CASEPRINT(CURLINFO_FTP_ENTRY_PATH);
|
||||
CASEPRINT(CURLINFO_REDIRECT_URL);
|
||||
CASEPRINT(CURLINFO_PRIMARY_IP);
|
||||
CASEPRINT(CURLINFO_APPCONNECT_TIME);
|
||||
CASEPRINT(CURLINFO_CERTINFO);
|
||||
CASEPRINT(CURLINFO_CONDITION_UNMET);
|
||||
CASEPRINT(CURLINFO_RTSP_SESSION_ID);
|
||||
CASEPRINT(CURLINFO_RTSP_CLIENT_CSEQ);
|
||||
CASEPRINT(CURLINFO_RTSP_SERVER_CSEQ);
|
||||
CASEPRINT(CURLINFO_RTSP_CSEQ_RECV);
|
||||
CASEPRINT(CURLINFO_PRIMARY_PORT);
|
||||
CASEPRINT(CURLINFO_LOCAL_IP);
|
||||
CASEPRINT(CURLINFO_LOCAL_PORT);
|
||||
default:
|
||||
os << "<unknown" << " CURLINFO value (" << (int)info << ")>";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CURLcode code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
CASEPRINT(CURLE_OK);
|
||||
CASEPRINT(CURLE_UNSUPPORTED_PROTOCOL);
|
||||
CASEPRINT(CURLE_FAILED_INIT);
|
||||
CASEPRINT(CURLE_URL_MALFORMAT);
|
||||
#if CURL_VERSION(7, 21, 5)
|
||||
CASEPRINT(CURLE_NOT_BUILT_IN);
|
||||
#endif
|
||||
CASEPRINT(CURLE_COULDNT_RESOLVE_PROXY);
|
||||
CASEPRINT(CURLE_COULDNT_RESOLVE_HOST);
|
||||
CASEPRINT(CURLE_COULDNT_CONNECT);
|
||||
CASEPRINT(CURLE_FTP_WEIRD_SERVER_REPLY);
|
||||
CASEPRINT(CURLE_REMOTE_ACCESS_DENIED);
|
||||
#if 0
|
||||
CASEPRINT(CURLE_FTP_ACCEPT_FAILED);
|
||||
#endif
|
||||
CASEPRINT(CURLE_FTP_WEIRD_PASS_REPLY);
|
||||
#if 0
|
||||
CASEPRINT(CURLE_FTP_ACCEPT_TIMEOUT);
|
||||
#endif
|
||||
CASEPRINT(CURLE_FTP_WEIRD_PASV_REPLY);
|
||||
CASEPRINT(CURLE_FTP_WEIRD_227_FORMAT);
|
||||
CASEPRINT(CURLE_FTP_CANT_GET_HOST);
|
||||
CASEPRINT(CURLE_OBSOLETE16);
|
||||
CASEPRINT(CURLE_FTP_COULDNT_SET_TYPE);
|
||||
CASEPRINT(CURLE_PARTIAL_FILE);
|
||||
CASEPRINT(CURLE_FTP_COULDNT_RETR_FILE);
|
||||
CASEPRINT(CURLE_OBSOLETE20);
|
||||
CASEPRINT(CURLE_QUOTE_ERROR);
|
||||
CASEPRINT(CURLE_HTTP_RETURNED_ERROR);
|
||||
CASEPRINT(CURLE_WRITE_ERROR);
|
||||
CASEPRINT(CURLE_OBSOLETE24);
|
||||
CASEPRINT(CURLE_UPLOAD_FAILED);
|
||||
CASEPRINT(CURLE_READ_ERROR);
|
||||
CASEPRINT(CURLE_OUT_OF_MEMORY);
|
||||
CASEPRINT(CURLE_OPERATION_TIMEDOUT);
|
||||
CASEPRINT(CURLE_OBSOLETE29);
|
||||
CASEPRINT(CURLE_FTP_PORT_FAILED);
|
||||
CASEPRINT(CURLE_FTP_COULDNT_USE_REST);
|
||||
CASEPRINT(CURLE_OBSOLETE32);
|
||||
CASEPRINT(CURLE_RANGE_ERROR);
|
||||
CASEPRINT(CURLE_HTTP_POST_ERROR);
|
||||
CASEPRINT(CURLE_SSL_CONNECT_ERROR);
|
||||
CASEPRINT(CURLE_BAD_DOWNLOAD_RESUME);
|
||||
CASEPRINT(CURLE_FILE_COULDNT_READ_FILE);
|
||||
CASEPRINT(CURLE_LDAP_CANNOT_BIND);
|
||||
CASEPRINT(CURLE_LDAP_SEARCH_FAILED);
|
||||
CASEPRINT(CURLE_OBSOLETE40);
|
||||
CASEPRINT(CURLE_FUNCTION_NOT_FOUND);
|
||||
CASEPRINT(CURLE_ABORTED_BY_CALLBACK);
|
||||
CASEPRINT(CURLE_BAD_FUNCTION_ARGUMENT);
|
||||
CASEPRINT(CURLE_OBSOLETE44);
|
||||
CASEPRINT(CURLE_INTERFACE_FAILED);
|
||||
CASEPRINT(CURLE_OBSOLETE46);
|
||||
CASEPRINT(CURLE_TOO_MANY_REDIRECTS );
|
||||
#if CURL_VERSION(7, 21, 5)
|
||||
CASEPRINT(CURLE_UNKNOWN_OPTION);
|
||||
#else
|
||||
CASEPRINT(CURLE_UNKNOWN_TELNET_OPTION);
|
||||
#endif
|
||||
CASEPRINT(CURLE_TELNET_OPTION_SYNTAX );
|
||||
CASEPRINT(CURLE_OBSOLETE50);
|
||||
CASEPRINT(CURLE_PEER_FAILED_VERIFICATION);
|
||||
CASEPRINT(CURLE_GOT_NOTHING);
|
||||
CASEPRINT(CURLE_SSL_ENGINE_NOTFOUND);
|
||||
CASEPRINT(CURLE_SSL_ENGINE_SETFAILED);
|
||||
CASEPRINT(CURLE_SEND_ERROR);
|
||||
CASEPRINT(CURLE_RECV_ERROR);
|
||||
CASEPRINT(CURLE_OBSOLETE57);
|
||||
CASEPRINT(CURLE_SSL_CERTPROBLEM);
|
||||
CASEPRINT(CURLE_SSL_CIPHER);
|
||||
CASEPRINT(CURLE_SSL_CACERT);
|
||||
CASEPRINT(CURLE_BAD_CONTENT_ENCODING);
|
||||
CASEPRINT(CURLE_LDAP_INVALID_URL);
|
||||
CASEPRINT(CURLE_FILESIZE_EXCEEDED);
|
||||
CASEPRINT(CURLE_USE_SSL_FAILED);
|
||||
CASEPRINT(CURLE_SEND_FAIL_REWIND);
|
||||
CASEPRINT(CURLE_SSL_ENGINE_INITFAILED);
|
||||
CASEPRINT(CURLE_LOGIN_DENIED);
|
||||
CASEPRINT(CURLE_TFTP_NOTFOUND);
|
||||
CASEPRINT(CURLE_TFTP_PERM);
|
||||
CASEPRINT(CURLE_REMOTE_DISK_FULL);
|
||||
CASEPRINT(CURLE_TFTP_ILLEGAL);
|
||||
CASEPRINT(CURLE_TFTP_UNKNOWNID);
|
||||
CASEPRINT(CURLE_REMOTE_FILE_EXISTS);
|
||||
CASEPRINT(CURLE_TFTP_NOSUCHUSER);
|
||||
CASEPRINT(CURLE_CONV_FAILED);
|
||||
CASEPRINT(CURLE_CONV_REQD);
|
||||
CASEPRINT(CURLE_SSL_CACERT_BADFILE);
|
||||
CASEPRINT(CURLE_REMOTE_FILE_NOT_FOUND);
|
||||
CASEPRINT(CURLE_SSH);
|
||||
CASEPRINT(CURLE_SSL_SHUTDOWN_FAILED);
|
||||
CASEPRINT(CURLE_AGAIN);
|
||||
CASEPRINT(CURLE_SSL_CRL_BADFILE);
|
||||
CASEPRINT(CURLE_SSL_ISSUER_ERROR);
|
||||
CASEPRINT(CURLE_FTP_PRET_FAILED);
|
||||
CASEPRINT(CURLE_RTSP_CSEQ_ERROR);
|
||||
CASEPRINT(CURLE_RTSP_SESSION_ERROR);
|
||||
CASEPRINT(CURLE_FTP_BAD_FILE_LIST);
|
||||
CASEPRINT(CURLE_CHUNK_FAILED);
|
||||
default:
|
||||
os << (code == CURL_LAST ? "<illegal" : "<unknown") << " CURLcode value (" << (int)code << ")>";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
struct AICURL;
|
||||
struct AICURLM;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, AICURL* curl)
|
||||
{
|
||||
os << "(CURL*)0x" << std::hex << (size_t)curl << std::dec;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, AICURLM* curl)
|
||||
{
|
||||
os << "(CURLM*)0x" << std::hex << (size_t)curl << std::dec;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CURLoption option)
|
||||
{
|
||||
switch(option)
|
||||
{
|
||||
CASEPRINT(CURLOPT_WRITEDATA);
|
||||
CASEPRINT(CURLOPT_URL);
|
||||
CASEPRINT(CURLOPT_PORT);
|
||||
CASEPRINT(CURLOPT_PROXY);
|
||||
CASEPRINT(CURLOPT_USERPWD);
|
||||
CASEPRINT(CURLOPT_PROXYUSERPWD);
|
||||
CASEPRINT(CURLOPT_RANGE);
|
||||
CASEPRINT(CURLOPT_READDATA);
|
||||
CASEPRINT(CURLOPT_ERRORBUFFER);
|
||||
CASEPRINT(CURLOPT_WRITEFUNCTION);
|
||||
CASEPRINT(CURLOPT_READFUNCTION);
|
||||
CASEPRINT(CURLOPT_TIMEOUT);
|
||||
CASEPRINT(CURLOPT_INFILESIZE);
|
||||
CASEPRINT(CURLOPT_POSTFIELDS);
|
||||
CASEPRINT(CURLOPT_REFERER);
|
||||
CASEPRINT(CURLOPT_FTPPORT);
|
||||
CASEPRINT(CURLOPT_USERAGENT);
|
||||
CASEPRINT(CURLOPT_LOW_SPEED_LIMIT);
|
||||
CASEPRINT(CURLOPT_LOW_SPEED_TIME);
|
||||
CASEPRINT(CURLOPT_RESUME_FROM);
|
||||
CASEPRINT(CURLOPT_COOKIE);
|
||||
CASEPRINT(CURLOPT_RTSPHEADER);
|
||||
CASEPRINT(CURLOPT_HTTPPOST);
|
||||
CASEPRINT(CURLOPT_SSLCERT);
|
||||
CASEPRINT(CURLOPT_KEYPASSWD);
|
||||
CASEPRINT(CURLOPT_CRLF);
|
||||
CASEPRINT(CURLOPT_QUOTE);
|
||||
CASEPRINT(CURLOPT_HEADERDATA);
|
||||
CASEPRINT(CURLOPT_COOKIEFILE);
|
||||
CASEPRINT(CURLOPT_SSLVERSION);
|
||||
CASEPRINT(CURLOPT_TIMECONDITION);
|
||||
CASEPRINT(CURLOPT_TIMEVALUE);
|
||||
CASEPRINT(CURLOPT_CUSTOMREQUEST);
|
||||
CASEPRINT(CURLOPT_STDERR);
|
||||
CASEPRINT(CURLOPT_POSTQUOTE);
|
||||
CASEPRINT(CURLOPT_WRITEINFO);
|
||||
CASEPRINT(CURLOPT_VERBOSE);
|
||||
CASEPRINT(CURLOPT_HEADER);
|
||||
CASEPRINT(CURLOPT_NOPROGRESS);
|
||||
CASEPRINT(CURLOPT_NOBODY);
|
||||
CASEPRINT(CURLOPT_FAILONERROR);
|
||||
CASEPRINT(CURLOPT_UPLOAD);
|
||||
CASEPRINT(CURLOPT_POST);
|
||||
CASEPRINT(CURLOPT_DIRLISTONLY);
|
||||
CASEPRINT(CURLOPT_APPEND);
|
||||
CASEPRINT(CURLOPT_NETRC);
|
||||
CASEPRINT(CURLOPT_FOLLOWLOCATION);
|
||||
CASEPRINT(CURLOPT_TRANSFERTEXT);
|
||||
CASEPRINT(CURLOPT_PUT);
|
||||
CASEPRINT(CURLOPT_PROGRESSFUNCTION);
|
||||
CASEPRINT(CURLOPT_PROGRESSDATA);
|
||||
CASEPRINT(CURLOPT_AUTOREFERER);
|
||||
CASEPRINT(CURLOPT_PROXYPORT);
|
||||
CASEPRINT(CURLOPT_POSTFIELDSIZE);
|
||||
CASEPRINT(CURLOPT_HTTPPROXYTUNNEL);
|
||||
CASEPRINT(CURLOPT_INTERFACE);
|
||||
CASEPRINT(CURLOPT_KRBLEVEL);
|
||||
CASEPRINT(CURLOPT_SSL_VERIFYPEER);
|
||||
CASEPRINT(CURLOPT_CAINFO);
|
||||
CASEPRINT(CURLOPT_MAXREDIRS);
|
||||
CASEPRINT(CURLOPT_FILETIME);
|
||||
CASEPRINT(CURLOPT_TELNETOPTIONS);
|
||||
CASEPRINT(CURLOPT_MAXCONNECTS);
|
||||
CASEPRINT(CURLOPT_CLOSEPOLICY);
|
||||
CASEPRINT(CURLOPT_FRESH_CONNECT);
|
||||
CASEPRINT(CURLOPT_FORBID_REUSE);
|
||||
CASEPRINT(CURLOPT_RANDOM_FILE);
|
||||
CASEPRINT(CURLOPT_EGDSOCKET);
|
||||
CASEPRINT(CURLOPT_CONNECTTIMEOUT);
|
||||
CASEPRINT(CURLOPT_HEADERFUNCTION);
|
||||
CASEPRINT(CURLOPT_HTTPGET);
|
||||
CASEPRINT(CURLOPT_SSL_VERIFYHOST);
|
||||
CASEPRINT(CURLOPT_COOKIEJAR);
|
||||
CASEPRINT(CURLOPT_SSL_CIPHER_LIST);
|
||||
CASEPRINT(CURLOPT_HTTP_VERSION);
|
||||
CASEPRINT(CURLOPT_FTP_USE_EPSV);
|
||||
CASEPRINT(CURLOPT_SSLCERTTYPE);
|
||||
CASEPRINT(CURLOPT_SSLKEY);
|
||||
CASEPRINT(CURLOPT_SSLKEYTYPE);
|
||||
CASEPRINT(CURLOPT_SSLENGINE);
|
||||
CASEPRINT(CURLOPT_SSLENGINE_DEFAULT);
|
||||
CASEPRINT(CURLOPT_DNS_USE_GLOBAL_CACHE);
|
||||
CASEPRINT(CURLOPT_DNS_CACHE_TIMEOUT);
|
||||
CASEPRINT(CURLOPT_PREQUOTE);
|
||||
CASEPRINT(CURLOPT_DEBUGFUNCTION);
|
||||
CASEPRINT(CURLOPT_DEBUGDATA);
|
||||
CASEPRINT(CURLOPT_COOKIESESSION);
|
||||
CASEPRINT(CURLOPT_CAPATH);
|
||||
CASEPRINT(CURLOPT_BUFFERSIZE);
|
||||
CASEPRINT(CURLOPT_NOSIGNAL);
|
||||
CASEPRINT(CURLOPT_SHARE);
|
||||
CASEPRINT(CURLOPT_PROXYTYPE);
|
||||
#if CURL_VERSION(7, 21, 6)
|
||||
CASEPRINT(CURLOPT_ACCEPT_ENCODING);
|
||||
#else
|
||||
CASEPRINT(CURLOPT_ENCODING);
|
||||
#endif
|
||||
CASEPRINT(CURLOPT_PRIVATE);
|
||||
CASEPRINT(CURLOPT_HTTP200ALIASES);
|
||||
CASEPRINT(CURLOPT_UNRESTRICTED_AUTH);
|
||||
CASEPRINT(CURLOPT_FTP_USE_EPRT);
|
||||
CASEPRINT(CURLOPT_HTTPAUTH);
|
||||
CASEPRINT(CURLOPT_SSL_CTX_FUNCTION);
|
||||
CASEPRINT(CURLOPT_SSL_CTX_DATA);
|
||||
CASEPRINT(CURLOPT_FTP_CREATE_MISSING_DIRS);
|
||||
CASEPRINT(CURLOPT_PROXYAUTH);
|
||||
CASEPRINT(CURLOPT_FTP_RESPONSE_TIMEOUT);
|
||||
CASEPRINT(CURLOPT_IPRESOLVE);
|
||||
CASEPRINT(CURLOPT_MAXFILESIZE);
|
||||
CASEPRINT(CURLOPT_INFILESIZE_LARGE);
|
||||
CASEPRINT(CURLOPT_RESUME_FROM_LARGE);
|
||||
CASEPRINT(CURLOPT_MAXFILESIZE_LARGE);
|
||||
CASEPRINT(CURLOPT_NETRC_FILE);
|
||||
CASEPRINT(CURLOPT_USE_SSL);
|
||||
CASEPRINT(CURLOPT_POSTFIELDSIZE_LARGE);
|
||||
CASEPRINT(CURLOPT_TCP_NODELAY);
|
||||
CASEPRINT(CURLOPT_FTPSSLAUTH);
|
||||
CASEPRINT(CURLOPT_IOCTLFUNCTION);
|
||||
CASEPRINT(CURLOPT_IOCTLDATA);
|
||||
CASEPRINT(CURLOPT_FTP_ACCOUNT);
|
||||
CASEPRINT(CURLOPT_COOKIELIST);
|
||||
CASEPRINT(CURLOPT_IGNORE_CONTENT_LENGTH);
|
||||
CASEPRINT(CURLOPT_FTP_SKIP_PASV_IP);
|
||||
CASEPRINT(CURLOPT_FTP_FILEMETHOD);
|
||||
CASEPRINT(CURLOPT_LOCALPORT);
|
||||
CASEPRINT(CURLOPT_LOCALPORTRANGE);
|
||||
CASEPRINT(CURLOPT_CONNECT_ONLY);
|
||||
CASEPRINT(CURLOPT_CONV_FROM_NETWORK_FUNCTION);
|
||||
CASEPRINT(CURLOPT_CONV_TO_NETWORK_FUNCTION);
|
||||
CASEPRINT(CURLOPT_CONV_FROM_UTF8_FUNCTION);
|
||||
CASEPRINT(CURLOPT_MAX_SEND_SPEED_LARGE);
|
||||
CASEPRINT(CURLOPT_MAX_RECV_SPEED_LARGE);
|
||||
CASEPRINT(CURLOPT_FTP_ALTERNATIVE_TO_USER);
|
||||
CASEPRINT(CURLOPT_SOCKOPTFUNCTION);
|
||||
CASEPRINT(CURLOPT_SOCKOPTDATA);
|
||||
CASEPRINT(CURLOPT_SSL_SESSIONID_CACHE);
|
||||
CASEPRINT(CURLOPT_SSH_AUTH_TYPES);
|
||||
CASEPRINT(CURLOPT_SSH_PUBLIC_KEYFILE);
|
||||
CASEPRINT(CURLOPT_SSH_PRIVATE_KEYFILE);
|
||||
CASEPRINT(CURLOPT_FTP_SSL_CCC);
|
||||
CASEPRINT(CURLOPT_TIMEOUT_MS);
|
||||
CASEPRINT(CURLOPT_CONNECTTIMEOUT_MS);
|
||||
CASEPRINT(CURLOPT_HTTP_TRANSFER_DECODING);
|
||||
CASEPRINT(CURLOPT_HTTP_CONTENT_DECODING);
|
||||
CASEPRINT(CURLOPT_NEW_FILE_PERMS);
|
||||
CASEPRINT(CURLOPT_NEW_DIRECTORY_PERMS);
|
||||
CASEPRINT(CURLOPT_POSTREDIR);
|
||||
CASEPRINT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5);
|
||||
CASEPRINT(CURLOPT_OPENSOCKETFUNCTION);
|
||||
CASEPRINT(CURLOPT_OPENSOCKETDATA);
|
||||
CASEPRINT(CURLOPT_COPYPOSTFIELDS);
|
||||
CASEPRINT(CURLOPT_PROXY_TRANSFER_MODE);
|
||||
CASEPRINT(CURLOPT_SEEKFUNCTION);
|
||||
CASEPRINT(CURLOPT_SEEKDATA);
|
||||
CASEPRINT(CURLOPT_CRLFILE);
|
||||
CASEPRINT(CURLOPT_ISSUERCERT);
|
||||
CASEPRINT(CURLOPT_ADDRESS_SCOPE);
|
||||
CASEPRINT(CURLOPT_CERTINFO);
|
||||
CASEPRINT(CURLOPT_USERNAME);
|
||||
CASEPRINT(CURLOPT_PASSWORD);
|
||||
CASEPRINT(CURLOPT_PROXYUSERNAME);
|
||||
CASEPRINT(CURLOPT_PROXYPASSWORD);
|
||||
CASEPRINT(CURLOPT_NOPROXY);
|
||||
CASEPRINT(CURLOPT_TFTP_BLKSIZE);
|
||||
CASEPRINT(CURLOPT_SOCKS5_GSSAPI_SERVICE);
|
||||
CASEPRINT(CURLOPT_SOCKS5_GSSAPI_NEC);
|
||||
CASEPRINT(CURLOPT_PROTOCOLS);
|
||||
CASEPRINT(CURLOPT_REDIR_PROTOCOLS);
|
||||
CASEPRINT(CURLOPT_SSH_KNOWNHOSTS);
|
||||
CASEPRINT(CURLOPT_SSH_KEYFUNCTION);
|
||||
CASEPRINT(CURLOPT_SSH_KEYDATA);
|
||||
CASEPRINT(CURLOPT_MAIL_FROM);
|
||||
CASEPRINT(CURLOPT_MAIL_RCPT);
|
||||
CASEPRINT(CURLOPT_FTP_USE_PRET);
|
||||
CASEPRINT(CURLOPT_RTSP_REQUEST);
|
||||
CASEPRINT(CURLOPT_RTSP_SESSION_ID);
|
||||
CASEPRINT(CURLOPT_RTSP_STREAM_URI);
|
||||
CASEPRINT(CURLOPT_RTSP_TRANSPORT);
|
||||
CASEPRINT(CURLOPT_RTSP_CLIENT_CSEQ);
|
||||
CASEPRINT(CURLOPT_RTSP_SERVER_CSEQ);
|
||||
CASEPRINT(CURLOPT_INTERLEAVEDATA);
|
||||
CASEPRINT(CURLOPT_INTERLEAVEFUNCTION);
|
||||
CASEPRINT(CURLOPT_WILDCARDMATCH);
|
||||
CASEPRINT(CURLOPT_CHUNK_BGN_FUNCTION);
|
||||
CASEPRINT(CURLOPT_CHUNK_END_FUNCTION);
|
||||
CASEPRINT(CURLOPT_FNMATCH_FUNCTION);
|
||||
CASEPRINT(CURLOPT_CHUNK_DATA);
|
||||
CASEPRINT(CURLOPT_FNMATCH_DATA);
|
||||
#if CURL_VERSION(7, 21, 3)
|
||||
CASEPRINT(CURLOPT_RESOLVE);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 21, 4)
|
||||
CASEPRINT(CURLOPT_TLSAUTH_USERNAME);
|
||||
CASEPRINT(CURLOPT_TLSAUTH_PASSWORD);
|
||||
CASEPRINT(CURLOPT_TLSAUTH_TYPE);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 21, 6)
|
||||
CASEPRINT(CURLOPT_TRANSFER_ENCODING);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 21, 7)
|
||||
CASEPRINT(CURLOPT_CLOSESOCKETFUNCTION);
|
||||
CASEPRINT(CURLOPT_CLOSESOCKETDATA);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 22, 0)
|
||||
CASEPRINT(CURLOPT_GSSAPI_DELEGATION);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 24, 0)
|
||||
CASEPRINT(CURLOPT_DNS_SERVERS);
|
||||
CASEPRINT(CURLOPT_ACCEPTTIMEOUT_MS);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 25, 0)
|
||||
CASEPRINT(CURLOPT_TCP_KEEPALIVE);
|
||||
CASEPRINT(CURLOPT_TCP_KEEPIDLE);
|
||||
CASEPRINT(CURLOPT_TCP_KEEPINTVL);
|
||||
#endif
|
||||
#if CURL_VERSION(7, 25, 0)
|
||||
CASEPRINT(CURLOPT_SSL_OPTIONS);
|
||||
CASEPRINT(CURLOPT_MAIL_AUTH);
|
||||
#endif
|
||||
default:
|
||||
os << "<unknown CURLoption value (" << (int)option << ")>";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CURLMoption option)
|
||||
{
|
||||
switch(option)
|
||||
{
|
||||
CASEPRINT(CURLMOPT_SOCKETFUNCTION);
|
||||
CASEPRINT(CURLMOPT_SOCKETDATA);
|
||||
CASEPRINT(CURLMOPT_PIPELINING);
|
||||
CASEPRINT(CURLMOPT_TIMERFUNCTION);
|
||||
CASEPRINT(CURLMOPT_TIMERDATA);
|
||||
CASEPRINT(CURLMOPT_MAXCONNECTS);
|
||||
default:
|
||||
os << "<unknown CURLMoption value (" << (int)option << ")>";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CURLMsg* msg)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
os << "(CURLMsg*){";
|
||||
if (msg->msg == CURLMSG_DONE)
|
||||
os << "CURLMSG_DONE";
|
||||
else
|
||||
os << msg->msg;
|
||||
os << ", " << (AICURL*)msg->easy_handle << ", 0x" << std::hex << (size_t)msg->data.whatever << std::dec << '}';
|
||||
}
|
||||
else
|
||||
os << "(CURLMsg*)NULL";
|
||||
return os;
|
||||
}
|
||||
|
||||
struct Socket {
|
||||
curl_socket_t mSocket;
|
||||
Socket(curl_socket_t sockfd) : mSocket(sockfd) { }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Socket const& sock)
|
||||
{
|
||||
if (sock.mSocket == CURL_SOCKET_TIMEOUT)
|
||||
os << "CURL_SOCKET_TIMEOUT";
|
||||
else
|
||||
os << sock.mSocket;
|
||||
return os;
|
||||
}
|
||||
|
||||
struct EvBitmask {
|
||||
int mBitmask;
|
||||
EvBitmask(int mask) : mBitmask(mask) { }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, EvBitmask const& bitmask)
|
||||
{
|
||||
int m = bitmask.mBitmask;
|
||||
if (m == 0)
|
||||
os << '0';
|
||||
if ((m & CURL_CSELECT_IN))
|
||||
{
|
||||
os << "CURL_CSELECT_IN";
|
||||
if ((m & (CURL_CSELECT_OUT|CURL_CSELECT_ERR)))
|
||||
os << '|';
|
||||
}
|
||||
if ((m & CURL_CSELECT_OUT))
|
||||
{
|
||||
os << "CURL_CSELECT_OUT";
|
||||
if ((m & CURL_CSELECT_ERR))
|
||||
os << '|';
|
||||
}
|
||||
if ((m & CURL_CSELECT_ERR))
|
||||
{
|
||||
os << "CURL_CSELECT_ERR";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void debug_curl_easy_cleanup(CURL* handle)
|
||||
{
|
||||
curl_easy_cleanup(handle);
|
||||
Dout(dc::curl, "curl_easy_cleanup(" << (AICURL*)handle << ")");
|
||||
}
|
||||
|
||||
CURL* debug_curl_easy_duphandle(CURL* handle)
|
||||
{
|
||||
CURL* ret;
|
||||
ret = curl_easy_duphandle(handle);
|
||||
Dout(dc::curl, "curl_easy_duphandle(" << (AICURL*)handle << ") = " << (AICURL*)ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* debug_curl_easy_escape(CURL* curl, char* url, int length)
|
||||
{
|
||||
char* ret;
|
||||
ret = curl_easy_escape(curl, url, length);
|
||||
Dout(dc::curl, "curl_easy_escape(" << curl << ", \"" << url << "\", " << length << ") = \"" << ret << '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLcode debug_curl_easy_getinfo(CURL* curl, CURLINFO info, ...)
|
||||
{
|
||||
CURLcode ret;
|
||||
va_list ap;
|
||||
union param_type {
|
||||
void* some_ptr;
|
||||
long* long_ptr;
|
||||
char** char_ptr;
|
||||
curl_slist** curl_slist_ptr;
|
||||
double* double_ptr;
|
||||
} param;
|
||||
va_start(ap, info);
|
||||
param.some_ptr = va_arg(ap, void*);
|
||||
va_end(ap);
|
||||
ret = curl_easy_getinfo(curl, info, param.some_ptr);
|
||||
if (info == CURLINFO_PRIVATE)
|
||||
{
|
||||
Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", 0x" << std::hex << (size_t)param.some_ptr << std::dec << ") = " << ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch((info & CURLINFO_TYPEMASK))
|
||||
{
|
||||
case CURLINFO_STRING:
|
||||
Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (char**){ \"" << (ret == CURLE_OK ? *param.char_ptr : " <unchanged> ") << "\" }) = " << ret);
|
||||
break;
|
||||
case CURLINFO_LONG:
|
||||
Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (long*){ " << (ret == CURLE_OK ? *param.long_ptr : 0L) << "L }) = " << ret);
|
||||
break;
|
||||
case CURLINFO_DOUBLE:
|
||||
Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (double*){" << (ret == CURLE_OK ? *param.double_ptr : 0.) << "}) = " << ret);
|
||||
break;
|
||||
case CURLINFO_SLIST:
|
||||
Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (curl_slist**){ " << (ret == CURLE_OK ? **param.curl_slist_ptr : unchanged_slist) << " }) = " << ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURL* debug_curl_easy_init(void)
|
||||
{
|
||||
CURL* ret;
|
||||
ret = curl_easy_init();
|
||||
Dout(dc::curl, "curl_easy_init() = " << (AICURL*)ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLcode debug_curl_easy_pause(CURL* handle, int bitmask)
|
||||
{
|
||||
CURLcode ret;
|
||||
ret = curl_easy_pause(handle, bitmask);
|
||||
Dout(dc::curl, "curl_easy_pause(" << (AICURL*)handle << ", 0x" << std::hex << bitmask << std::dec << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLcode debug_curl_easy_perform(CURL* handle)
|
||||
{
|
||||
CURLcode ret;
|
||||
ret = curl_easy_perform(handle);
|
||||
Dout(dc::curl, "curl_easy_perform(" << (AICURL*)handle << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void debug_curl_easy_reset(CURL* handle)
|
||||
{
|
||||
curl_easy_reset(handle);
|
||||
Dout(dc::curl, "curl_easy_reset(" << (AICURL*)handle << ")");
|
||||
}
|
||||
|
||||
CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...)
|
||||
{
|
||||
CURLcode ret;
|
||||
va_list ap;
|
||||
union param_type {
|
||||
long along;
|
||||
void* ptr;
|
||||
curl_off_t offset;
|
||||
} param;
|
||||
unsigned int param_type = (option / 10000) * 10000;
|
||||
va_start(ap, option);
|
||||
switch (param_type)
|
||||
{
|
||||
case CURLOPTTYPE_LONG:
|
||||
param.along = va_arg(ap, long);
|
||||
break;
|
||||
case CURLOPTTYPE_OBJECTPOINT:
|
||||
case CURLOPTTYPE_FUNCTIONPOINT:
|
||||
param.ptr = va_arg(ap, void*);
|
||||
break;
|
||||
case CURLOPTTYPE_OFF_T:
|
||||
param.offset = va_arg(ap, curl_off_t);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Extracting param_type failed; option = " << option << "; param_type = " << param_type << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
va_end(ap);
|
||||
static long postfieldsize; // Cache. Assumes only one thread sets CURLOPT_POSTFIELDSIZE.
|
||||
switch (param_type)
|
||||
{
|
||||
case CURLOPTTYPE_LONG:
|
||||
{
|
||||
ret = curl_easy_setopt(handle, option, param.along);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", " << param.along << "L) = " << ret);
|
||||
if (option == CURLOPT_POSTFIELDSIZE)
|
||||
{
|
||||
postfieldsize = param.along;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CURLOPTTYPE_OBJECTPOINT:
|
||||
{
|
||||
ret = curl_easy_setopt(handle, option, param.ptr);
|
||||
LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcwd::libcw_do, dc::curl)
|
||||
LibcwDoutStream << "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", ";
|
||||
// For a subset of all options that take a char*, print the string passed.
|
||||
if (option == CURLOPT_PROXY || // Set HTTP proxy to use. The parameter should be a char* to a zero terminated string holding the host name or dotted IP address.
|
||||
option == CURLOPT_PROXYUSERPWD || // Pass a char* as parameter, which should be [user name]:[password] to use for the connection to the HTTP proxy.
|
||||
option == CURLOPT_CAINFO || // Pass a char * to a zero terminated string naming a file holding one or more certificates to verify the peer with.
|
||||
option == CURLOPT_URL || // Pass in a pointer to the actual URL to deal with. The parameter should be a char * to a zero terminated string [...]
|
||||
option == CURLOPT_COOKIEFILE || // Pass a pointer to a zero terminated string as parameter. It should contain the name of your file holding cookie data to read.
|
||||
option == CURLOPT_CUSTOMREQUEST || // Pass a pointer to a zero terminated string as parameter. It can be used to specify the request instead of GET or HEAD when performing HTTP based requests
|
||||
option == CURLOPT_ENCODING || // Sets the contents of the Accept-Encoding: header sent in a HTTP request, and enables decoding of a response when a Content-Encoding: header is received.
|
||||
option == CURLOPT_POSTFIELDS ||
|
||||
option == CURLOPT_COPYPOSTFIELDS) // Full data to post in a HTTP POST operation.
|
||||
{
|
||||
bool const is_postfield = option == CURLOPT_POSTFIELDS || option == CURLOPT_COPYPOSTFIELDS;
|
||||
char* str = (char*)param.ptr;
|
||||
long size;
|
||||
LibcwDoutStream << "(char*)0x" << std::hex << (size_t)param.ptr << std::dec << ")";
|
||||
if (is_postfield)
|
||||
{
|
||||
size = postfieldsize < 32 ? postfieldsize : 32; // Only print first 32 characters (this was already written to debug output before).
|
||||
}
|
||||
else
|
||||
{
|
||||
size = strlen(str);
|
||||
}
|
||||
LibcwDoutStream << "[";
|
||||
if (str)
|
||||
{
|
||||
LibcwDoutStream << libcwd::buf2str(str, size);
|
||||
if (is_postfield && postfieldsize > 32)
|
||||
LibcwDoutStream << "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
LibcwDoutStream << "NULL";
|
||||
}
|
||||
LibcwDoutStream << "](" << (is_postfield ? postfieldsize : size) << " bytes))";
|
||||
}
|
||||
else
|
||||
{
|
||||
LibcwDoutStream << "(object*)0x" << std::hex << (size_t)param.ptr << std::dec << ")";
|
||||
}
|
||||
LibcwDoutStream << " = " << ret;
|
||||
LibcwDoutScopeEnd;
|
||||
if (option == CURLOPT_HTTPHEADER && param.ptr)
|
||||
{
|
||||
debug::Indent indent(2);
|
||||
Dout(dc::curl, "HTTP Headers:");
|
||||
struct curl_slist* list = (struct curl_slist*)param.ptr;
|
||||
while (list)
|
||||
{
|
||||
Dout(dc::curl, '"' << list->data << '"');
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CURLOPTTYPE_FUNCTIONPOINT:
|
||||
ret = curl_easy_setopt(handle, option, param.ptr);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret);
|
||||
break;
|
||||
case CURLOPTTYPE_OFF_T:
|
||||
{
|
||||
ret = curl_easy_setopt(handle, option, param.offset);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret);
|
||||
if (option == CURLOPT_POSTFIELDSIZE_LARGE)
|
||||
{
|
||||
postfieldsize = (long)param.offset;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char const* debug_curl_easy_strerror(CURLcode errornum)
|
||||
{
|
||||
char const* ret;
|
||||
ret = curl_easy_strerror(errornum);
|
||||
Dout(dc::curl, "curl_easy_strerror(" << errornum << ") = \"" << ret << '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* debug_curl_easy_unescape(CURL* curl, char* url, int inlength, int* outlength)
|
||||
{
|
||||
char* ret;
|
||||
ret = curl_easy_unescape(curl, url, inlength, outlength);
|
||||
Dout(dc::curl, "curl_easy_unescape(" << curl << ", \"" << url << "\", " << inlength << ", " << ((ret && outlength) ? *outlength : 1) << ") = \"" << ret << '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
void debug_curl_free(char* ptr)
|
||||
{
|
||||
curl_free(ptr);
|
||||
Dout(dc::curl, "curl_free(0x" << std::hex << (size_t)ptr << std::dec << ")");
|
||||
}
|
||||
|
||||
time_t debug_curl_getdate(char const* datestring, time_t* now)
|
||||
{
|
||||
time_t ret;
|
||||
ret = curl_getdate(datestring, now);
|
||||
Dout(dc::curl, "curl_getdate(\"" << datestring << "\", " << (now == NULL ? "NULL" : "<erroneous non-NULL value for 'now'>") << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void debug_curl_global_cleanup(void)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
Dout(dc::curl, "curl_global_cleanup()");
|
||||
}
|
||||
|
||||
CURLcode debug_curl_global_init(long flags)
|
||||
{
|
||||
CURLcode ret;
|
||||
ret = curl_global_init(flags);
|
||||
Dout(dc::curl, "curl_global_init(0x" << std::hex << flags << std::dec << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMcode debug_curl_multi_add_handle(CURLM* multi_handle, CURL* easy_handle)
|
||||
{
|
||||
CURLMcode ret;
|
||||
ret = curl_multi_add_handle(multi_handle, easy_handle);
|
||||
Dout(dc::curl, "curl_multi_add_handle(" << (AICURLM*)multi_handle << ", " << (AICURL*)easy_handle << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMcode debug_curl_multi_assign(CURLM* multi_handle, curl_socket_t sockfd, void* sockptr)
|
||||
{
|
||||
CURLMcode ret;
|
||||
ret = curl_multi_assign(multi_handle, sockfd, sockptr);
|
||||
Dout(dc::curl, "curl_multi_assign(" << (AICURLM*)multi_handle << ", " << Socket(sockfd) << ", " << sockptr << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMcode debug_curl_multi_cleanup(CURLM* multi_handle)
|
||||
{
|
||||
CURLMcode ret;
|
||||
ret = curl_multi_cleanup(multi_handle);
|
||||
Dout(dc::curl, "curl_multi_cleanup(" << (AICURLM*)multi_handle << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMsg* debug_curl_multi_info_read(CURLM* multi_handle, int* msgs_in_queue)
|
||||
{
|
||||
CURLMsg* ret;
|
||||
ret = curl_multi_info_read(multi_handle, msgs_in_queue);
|
||||
Dout(dc::curl, "curl_multi_info_read(" << (AICURLM*)multi_handle << ", {" << *msgs_in_queue << "}) = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLM* debug_curl_multi_init(void)
|
||||
{
|
||||
CURLM* ret;
|
||||
ret = curl_multi_init();
|
||||
Dout(dc::curl, "curl_multi_init() = " << (AICURLM*)ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMcode debug_curl_multi_remove_handle(CURLM* multi_handle, CURL* easy_handle)
|
||||
{
|
||||
CURLMcode ret;
|
||||
ret = curl_multi_remove_handle(multi_handle, easy_handle);
|
||||
Dout(dc::curl, "curl_multi_remove_handle(" << (AICURLM*)multi_handle << ", " << (AICURL*)easy_handle << ") = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...)
|
||||
{
|
||||
CURLMcode ret;
|
||||
va_list ap;
|
||||
union param_type {
|
||||
long along;
|
||||
void* ptr;
|
||||
curl_off_t offset;
|
||||
} param;
|
||||
unsigned int param_type = (option / 10000) * 10000;
|
||||
va_start(ap, option);
|
||||
switch (param_type)
|
||||
{
|
||||
case CURLOPTTYPE_LONG:
|
||||
param.along = va_arg(ap, long);
|
||||
break;
|
||||
case CURLOPTTYPE_OBJECTPOINT:
|
||||
case CURLOPTTYPE_FUNCTIONPOINT:
|
||||
param.ptr = va_arg(ap, void*);
|
||||
break;
|
||||
case CURLOPTTYPE_OFF_T:
|
||||
param.offset = va_arg(ap, curl_off_t);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Extracting param_type failed; option = " << option << "; param_type = " << param_type << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
va_end(ap);
|
||||
switch (param_type)
|
||||
{
|
||||
case CURLOPTTYPE_LONG:
|
||||
ret = curl_multi_setopt(multi_handle, option, param.along);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", " << param.along << "L) = " << ret);
|
||||
break;
|
||||
case CURLOPTTYPE_OBJECTPOINT:
|
||||
ret = curl_multi_setopt(multi_handle, option, param.ptr);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (object*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret);
|
||||
break;
|
||||
case CURLOPTTYPE_FUNCTIONPOINT:
|
||||
ret = curl_multi_setopt(multi_handle, option, param.ptr);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret);
|
||||
break;
|
||||
case CURLOPTTYPE_OFF_T:
|
||||
ret = curl_multi_setopt(multi_handle, option, param.offset);
|
||||
Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret);
|
||||
break;
|
||||
default: // Stop compiler complaining about no default.
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CURLMcode debug_curl_multi_socket_action(CURLM* multi_handle, curl_socket_t sockfd, int ev_bitmask, int* running_handles)
|
||||
{
|
||||
CURLMcode ret;
|
||||
ret = curl_multi_socket_action(multi_handle, sockfd, ev_bitmask, running_handles);
|
||||
Dout(dc::curl, "curl_multi_socket_action(" << (AICURLM*)multi_handle << ", " << Socket(sockfd) <<
|
||||
", " << EvBitmask(ev_bitmask) << ", {" << (ret == CURLM_OK ? *running_handles : 0) << "}) = " << ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char const* debug_curl_multi_strerror(CURLMcode errornum)
|
||||
{
|
||||
char const* ret;
|
||||
ret = curl_multi_strerror(errornum);
|
||||
Dout(dc::curl, "curl_multi_strerror(" << errornum << ") = \"" << ret << '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct curl_slist* debug_curl_slist_append(struct curl_slist* list, char const* string)
|
||||
{
|
||||
struct curl_slist* ret;
|
||||
ret = curl_slist_append(list, string);
|
||||
Dout(dc::curl, "curl_slist_append((curl_slist)@0x" << std::hex << (size_t)list << std::dec << ", \"" << string << "\") = " << *ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void debug_curl_slist_free_all(struct curl_slist* list)
|
||||
{
|
||||
curl_slist_free_all(list);
|
||||
Dout(dc::curl, "curl_slist_free_all((curl_slist)@0x" << std::hex << (size_t)list << std::dec << ")");
|
||||
}
|
||||
|
||||
char* debug_curl_unescape(char const* url, int length)
|
||||
{
|
||||
char* ret;
|
||||
ret = curl_unescape(url, length);
|
||||
Dout(dc::curl, "curl_unescape(\"" << url << "\", " << length << ") = \"" << ret << '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* debug_curl_version(void)
|
||||
{
|
||||
char* ret;
|
||||
ret = curl_version();
|
||||
Dout(dc::curl, "curl_version() = \"" << ret << '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else // DEBUG_CURLIO
|
||||
int debug_libcurl_dummy; // I thought some OS didn't like empty source files.
|
||||
#endif // DEBUG_CURLIO
|
||||
|
||||
89
indra/aistatemachine/debug_libcurl.h
Normal file
89
indra/aistatemachine/debug_libcurl.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef DEBUG_LIBCURL
|
||||
#define DEBUG_LIBCURL
|
||||
|
||||
#ifndef DEBUG_CURLIO
|
||||
#error "Don't include debug_libcurl.h unless DEBUG_CURLIO is defined."
|
||||
#endif
|
||||
|
||||
#ifndef CURLINFO_TYPEMASK
|
||||
#error "<curl/curl.h> must be included before including debug_libcurl.h!"
|
||||
#endif
|
||||
|
||||
#ifndef LLPREPROCESSOR_H
|
||||
// CURL_STATICLIB is needed on windows namely, which is defined in llpreprocessor.h (but only on windows).
|
||||
#error "llpreprocessor.h must be included before <curl/curl.h>."
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern void debug_curl_easy_cleanup(CURL* handle);
|
||||
extern CURL* debug_curl_easy_duphandle(CURL* handle);
|
||||
extern char* debug_curl_easy_escape(CURL* curl, char* url, int length);
|
||||
extern CURLcode debug_curl_easy_getinfo(CURL* curl, CURLINFO info, ...);
|
||||
extern CURL* debug_curl_easy_init(void);
|
||||
extern CURLcode debug_curl_easy_pause(CURL* handle, int bitmask);
|
||||
extern CURLcode debug_curl_easy_perform(CURL* handle);
|
||||
extern void debug_curl_easy_reset(CURL* handle);
|
||||
extern CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...);
|
||||
extern char const* debug_curl_easy_strerror(CURLcode errornum);
|
||||
extern char* debug_curl_easy_unescape(CURL* curl, char* url, int inlength, int* outlength);
|
||||
extern void debug_curl_free(char* ptr);
|
||||
extern time_t debug_curl_getdate(char const* datestring, time_t* now);
|
||||
extern void debug_curl_global_cleanup(void);
|
||||
extern CURLcode debug_curl_global_init(long flags);
|
||||
extern CURLMcode debug_curl_multi_add_handle(CURLM* multi_handle, CURL* easy_handle);
|
||||
extern CURLMcode debug_curl_multi_assign(CURLM* multi_handle, curl_socket_t sockfd, void* sockptr);
|
||||
extern CURLMcode debug_curl_multi_cleanup(CURLM* multi_handle);
|
||||
extern CURLMsg* debug_curl_multi_info_read(CURLM* multi_handle, int* msgs_in_queue);
|
||||
extern CURLM* debug_curl_multi_init(void);
|
||||
extern CURLMcode debug_curl_multi_remove_handle(CURLM* multi_handle, CURL* easy_handle);
|
||||
extern CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...);
|
||||
extern CURLMcode debug_curl_multi_socket_action(CURLM* multi_handle, curl_socket_t sockfd, int ev_bitmask, int* running_handles);
|
||||
extern char const* debug_curl_multi_strerror(CURLMcode errornum);
|
||||
extern struct curl_slist* debug_curl_slist_append(struct curl_slist* list, char const* string);
|
||||
extern void debug_curl_slist_free_all(struct curl_slist* list);
|
||||
extern char* debug_curl_unescape(char const* url, int length);
|
||||
extern char* debug_curl_version(void);
|
||||
|
||||
}
|
||||
|
||||
#ifndef COMPILING_DEBUG_LIBCURL_CC
|
||||
|
||||
#ifdef curl_easy_setopt
|
||||
#undef curl_easy_setopt
|
||||
#undef curl_easy_getinfo
|
||||
#undef curl_multi_setopt
|
||||
#endif
|
||||
|
||||
#define curl_easy_cleanup(handle) debug_curl_easy_cleanup(handle)
|
||||
#define curl_easy_duphandle(handle) debug_curl_easy_duphandle(handle)
|
||||
#define curl_easy_escape(curl, url, length) debug_curl_easy_escape(curl, url, length)
|
||||
#define curl_easy_getinfo(curl, info, param) debug_curl_easy_getinfo(curl, info, param)
|
||||
#define curl_easy_init() debug_curl_easy_init()
|
||||
#define curl_easy_pause(handle, bitmask) debug_curl_easy_pause(handle, bitmask)
|
||||
#define curl_easy_perform(handle) debug_curl_easy_perform(handle)
|
||||
#define curl_easy_reset(handle) debug_curl_easy_reset(handle)
|
||||
#define curl_easy_setopt(handle, option, param) debug_curl_easy_setopt(handle, option, param)
|
||||
#define curl_easy_strerror(errornum) debug_curl_easy_strerror(errornum)
|
||||
#define curl_easy_unescape(curl, url, inlength, outlength) debug_curl_easy_unescape(curl, url, inlength, outlength)
|
||||
#define curl_free(ptr) debug_curl_free(ptr)
|
||||
#define curl_getdate(datestring, now) debug_curl_getdate(datestring, now)
|
||||
#define curl_global_cleanup() debug_curl_global_cleanup()
|
||||
#define curl_global_init(flags) debug_curl_global_init(flags)
|
||||
#define curl_multi_add_handle(multi_handle, easy_handle) debug_curl_multi_add_handle(multi_handle, easy_handle)
|
||||
#define curl_multi_assign(multi_handle, sockfd, sockptr) debug_curl_multi_assign(multi_handle, sockfd, sockptr)
|
||||
#define curl_multi_cleanup(multi_handle) debug_curl_multi_cleanup(multi_handle)
|
||||
#define curl_multi_info_read(multi_handle, msgs_in_queue) debug_curl_multi_info_read(multi_handle, msgs_in_queue)
|
||||
#define curl_multi_init() debug_curl_multi_init()
|
||||
#define curl_multi_remove_handle(multi_handle, easy_handle) debug_curl_multi_remove_handle(multi_handle, easy_handle)
|
||||
#define curl_multi_setopt(multi_handle, option, param) debug_curl_multi_setopt(multi_handle, option, param)
|
||||
#define curl_multi_socket_action(multi_handle, sockfd, ev_bitmask, running_handles) debug_curl_multi_socket_action(multi_handle, sockfd, ev_bitmask, running_handles)
|
||||
#define curl_multi_strerror(errornum) debug_curl_multi_strerror(errornum)
|
||||
#define curl_slist_append(list, string) debug_curl_slist_append(list, string)
|
||||
#define curl_slist_free_all(list) debug_curl_slist_free_all(list)
|
||||
#define curl_unescape(url, length) debug_curl_unescape(url, length)
|
||||
#define curl_version() debug_curl_version()
|
||||
|
||||
#endif // !COMPILING_DEBUG_LIBCURL_CC
|
||||
|
||||
#endif // DEBUG_LIBCURL
|
||||
@@ -190,10 +190,10 @@ if (LINUX)
|
||||
endif (NOT STANDALONE)
|
||||
if (${ARCH} STREQUAL "x86_64")
|
||||
add_definitions(-DLINUX64=1 -pipe)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -funroll-loops")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -funroll-loops")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ffast-math")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ffast-math")
|
||||
else (${ARCH} STREQUAL "x86_64")
|
||||
if (NOT STANDALONE)
|
||||
set(MARCH_FLAG " -march=pentium4")
|
||||
@@ -269,14 +269,23 @@ if (DARWIN)
|
||||
add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch")
|
||||
# NOTE: it's critical that the optimization flag is put in front.
|
||||
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
if(${CMAKE_C_COMPILER} MATCHES "gcc*")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch")
|
||||
# NOTE: it's critical that the optimization flag is put in front.
|
||||
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||
elseif(${CMAKE_C_COMPILER} MATCHES "clang*")
|
||||
# NOTE: it's critical that the optimization flag is put in front.
|
||||
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3")
|
||||
endif()
|
||||
endif (DARWIN)
|
||||
|
||||
|
||||
@@ -318,7 +327,7 @@ else (STANDALONE)
|
||||
glib-2.0
|
||||
gstreamer-0.10
|
||||
gtk-2.0
|
||||
llfreetype2
|
||||
freetype2
|
||||
pango-1.0
|
||||
)
|
||||
endif (STANDALONE)
|
||||
|
||||
@@ -33,8 +33,8 @@ else (STANDALONE)
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.dylib
|
||||
)
|
||||
set(APRUTIL_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.0.dylib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.0.dylib
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.dylib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.dylib
|
||||
)
|
||||
set(APRICONV_LIBRARIES iconv)
|
||||
else (WINDOWS)
|
||||
|
||||
@@ -40,10 +40,10 @@ else (STANDALONE)
|
||||
debug libboost_regex-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION})
|
||||
|
||||
elseif (DARWIN)
|
||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
||||
set(BOOST_SYSTEM_LIBRARY boost_system-mt)
|
||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex)
|
||||
set(BOOST_SYSTEM_LIBRARY boost_system)
|
||||
elseif (LINUX)
|
||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||
|
||||
@@ -14,6 +14,9 @@ else (STANDALONE)
|
||||
optimized libcurl)
|
||||
else (WINDOWS)
|
||||
set(CURL_LIBRARIES curl)
|
||||
if(LINUX AND WORD_SIZE EQUAL 64)
|
||||
list(APPEND CURL_LIBRARIES idn)
|
||||
endif(LINUX AND WORD_SIZE EQUAL 64)
|
||||
endif (WINDOWS)
|
||||
set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
||||
@@ -1 +1,18 @@
|
||||
set(CWDEBUG_LIBRARIES cwdebug)
|
||||
include_directories (${CMAKE_SOURCE_DIR}/cwdebug)
|
||||
|
||||
set(cwdebug_SOURCE_FILES
|
||||
${CMAKE_SOURCE_DIR}/cwdebug/debug.cc
|
||||
)
|
||||
|
||||
set(cwdebug_HEADER_FILES
|
||||
${CMAKE_SOURCE_DIR}/cwdebug/cwdebug.h
|
||||
${CMAKE_SOURCE_DIR}/cwdebug/sys.h
|
||||
${CMAKE_SOURCE_DIR}/cwdebug/debug.h
|
||||
${CMAKE_SOURCE_DIR}/cwdebug/debug_ostream_operators.h
|
||||
)
|
||||
|
||||
set_source_files_properties(${cwdebug_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES})
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ if (NOT FMODEX_LIBRARY)
|
||||
set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
|
||||
if (FMODEX_SDK_DIR)
|
||||
find_library(FMODEX_LIBRARY
|
||||
fmodex fmodex_vc fmodexL_vc
|
||||
fmodex_vc fmodexL_vc fmodex fmodexL fmodex64 fmodexL64
|
||||
PATHS
|
||||
${FMODEX_SDK_DIR}/api/lib
|
||||
${FMODEX_SDK_DIR}/api
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
if(WORD_SIZE EQUAL 64)
|
||||
set(DISABLE_TCMALLOC TRUE)
|
||||
endif(WORD_SIZE EQUAL 64)
|
||||
|
||||
if (STANDALONE)
|
||||
include(FindGooglePerfTools)
|
||||
else (STANDALONE)
|
||||
if (LINUX OR WINDOWS)
|
||||
if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||
use_prebuilt_binary(gperftools)
|
||||
endif (LINUX OR WINDOWS)
|
||||
endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||
if (WINDOWS)
|
||||
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
|
||||
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
|
||||
|
||||
@@ -6,7 +6,7 @@ if (STANDALONE)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(hunspell)
|
||||
|
||||
set(HUNSPELL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/hunspell)
|
||||
set(HUNSPELL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/hunspell)
|
||||
|
||||
if (LINUX OR DARWIN)
|
||||
set(HUNSPELL_LIBRARY hunspell-1.3)
|
||||
|
||||
@@ -13,8 +13,8 @@ else (STANDALONE)
|
||||
set(JPEG_LIBRARIES jpeg)
|
||||
elseif (DARWIN)
|
||||
set(JPEG_LIBRARIES
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/liblljpeg.a
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/liblljpeg.a
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libjpeg.a
|
||||
)
|
||||
elseif (WINDOWS)
|
||||
set(JPEG_LIBRARIES jpeglib)
|
||||
|
||||
@@ -14,7 +14,7 @@ else (STANDALONE)
|
||||
debug json_vc${MSVC_SUFFIX}d
|
||||
optimized json_vc${MSVC_SUFFIX})
|
||||
elseif (DARWIN)
|
||||
set(JSONCPP_LIBRARIES json_mac-universal-gcc_libmt)
|
||||
set(JSONCPP_LIBRARIES json_linux-gcc-4.0.1_libmt)
|
||||
elseif (LINUX)
|
||||
set(JSONCPP_LIBRARIES jsoncpp)
|
||||
endif (WINDOWS)
|
||||
|
||||
@@ -18,7 +18,11 @@ else (STANDALONE)
|
||||
use_prebuilt_binary(SDL)
|
||||
set (SDL_FOUND TRUE)
|
||||
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR})
|
||||
set (SDL_LIBRARY SDL directfb fusion direct)
|
||||
if(WORD_SIZE EQUAL 64)
|
||||
set (SDL_LIBRARY SDL)
|
||||
else(WORD_SIZE EQUAL 64)
|
||||
set (SDL_LIBRARY SDL directfb fusion direct)
|
||||
endif(WORD_SIZE EQUAL 64)
|
||||
endif (LINUX)
|
||||
endif (STANDALONE)
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
set(LLXUIXML_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llxuixml
|
||||
)
|
||||
|
||||
set(LLXUIXML_LIBRARIES llxuixml)
|
||||
@@ -10,9 +10,9 @@ if (NOT STANDALONE)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${ARCH_PREBUILT_DIRS})
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS})
|
||||
elseif (DARWIN)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib_release)
|
||||
set(ARCH_PREBUILT_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS_RELEASE})
|
||||
set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib)
|
||||
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release)
|
||||
set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug)
|
||||
endif (WINDOWS)
|
||||
endif (NOT STANDALONE)
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ else (STANDALONE)
|
||||
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
||||
if (LINUX)
|
||||
if (LINUX OR DARWIN)
|
||||
set(CRYPTO_LIBRARIES crypto)
|
||||
elseif (DARWIN)
|
||||
set(CRYPTO_LIBRARIES llcrypto)
|
||||
endif (LINUX)
|
||||
endif (LINUX OR DARWIN)
|
||||
|
||||
@@ -15,5 +15,5 @@ else (STANDALONE)
|
||||
else(LINUX)
|
||||
set(PNG_LIBRARIES png15)
|
||||
endif()
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libpng15)
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/)
|
||||
endif (STANDALONE)
|
||||
|
||||
@@ -76,37 +76,36 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(DARWIN 1)
|
||||
|
||||
#SDK Compiler and Deployment targets for XCode
|
||||
if (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
|
||||
set(CMAKE_XCODE_ATTIBUTE_GCC_VERSION "4.2")
|
||||
else (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||
if(${CMAKE_GENERATOR} MATCHES Xcode)
|
||||
#SDK Compiler and Deployment targets for XCode
|
||||
if (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||
set(CMAKE_XCODE_ATTIBUTE_GCC_VERSION "4.2")
|
||||
else (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
||||
endif (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||
else()
|
||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
||||
endif (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||
endif(${CMAKE_GENERATOR} MATCHES Xcode)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||
## We currently support only 32-bit i386 builds, so use these:
|
||||
set(CMAKE_OSX_ARCHITECTURES i386)
|
||||
set(ARCH i386)
|
||||
set(WORD_SIZE 32)
|
||||
|
||||
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
|
||||
# -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc'
|
||||
# Build only for i386 by default, system default on MacOSX 10.6 is x86_64
|
||||
if (NOT CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES i386)
|
||||
endif (NOT CMAKE_OSX_ARCHITECTURES)
|
||||
|
||||
if (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
||||
set(ARCH universal)
|
||||
else (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
||||
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc")
|
||||
set(ARCH ppc)
|
||||
else (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc")
|
||||
set(ARCH i386)
|
||||
endif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc")
|
||||
endif (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
||||
## But if you want to compile for mixed 32/64 bit, try these:
|
||||
# set(CMAKE_OSX_ARCHITECTURES i386;x86_64)
|
||||
# set(ARCH universal)
|
||||
# set(WORD_SIZE 64)
|
||||
|
||||
## Finally, set up the build output directories
|
||||
set(LL_ARCH ${ARCH}_darwin)
|
||||
set(LL_ARCH_DIR universal-darwin)
|
||||
set(WORD_SIZE 32)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
project(cwdebug)
|
||||
|
||||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLVFS)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(cwdebug_SOURCE_FILES
|
||||
debug.cc
|
||||
)
|
||||
|
||||
set(cwdebug_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
cwdebug.h
|
||||
sys.h
|
||||
debug.h
|
||||
debug_ostream_operators.h
|
||||
)
|
||||
|
||||
set_source_files_properties(${cwdebug_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
if(NOT WORD_SIZE EQUAL 32)
|
||||
if(WINDOWS)
|
||||
add_definitions(/FIXED:NO)
|
||||
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
|
||||
add_definitions(-fPIC)
|
||||
endif(WINDOWS)
|
||||
endif (NOT WORD_SIZE EQUAL 32)
|
||||
|
||||
list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES})
|
||||
|
||||
add_library (cwdebug ${cwdebug_SOURCE_FILES})
|
||||
@@ -413,4 +413,98 @@ void cwdebug_backtrace(int n)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CWDEBUG
|
||||
#elif defined(DEBUG_CURLIO)
|
||||
|
||||
#include "debug.h"
|
||||
#include "aithreadid.h"
|
||||
|
||||
namespace debug
|
||||
{
|
||||
|
||||
namespace libcwd { libcwd_do_type const libcw_do; }
|
||||
|
||||
ll_thread_local int Indent::S_indentation;
|
||||
|
||||
Indent::Indent(int indent) : M_indent(indent)
|
||||
{
|
||||
S_indentation += M_indent;
|
||||
}
|
||||
|
||||
Indent::~Indent()
|
||||
{
|
||||
S_indentation -= M_indent;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Indent::print_nt)
|
||||
{
|
||||
if (Indent::S_indentation)
|
||||
os << std::string(Indent::S_indentation, ' ');
|
||||
return os;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CURLIO
|
||||
std::ostream& operator<<(std::ostream& os, print_thread_id_t)
|
||||
{
|
||||
if (!AIThreadID::in_main_thread_inline())
|
||||
{
|
||||
#ifdef LL_DARWIN
|
||||
os << std::hex << (size_t)apr_os_thread_current() << std::dec << ' ';
|
||||
#else
|
||||
os << std::hex << (size_t)AIThreadID::getCurrentThread_inline() << std::dec << ' ';
|
||||
#endif
|
||||
}
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s)
|
||||
{
|
||||
static char const c2s_tab[7] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' };
|
||||
size_t size = b2s.mSize;
|
||||
for (char const* p1 = b2s.mBuf; size > 0; --size, ++p1)
|
||||
{
|
||||
char c =*p1;
|
||||
if ((c > 31 && c != 92 && c != 127) || (unsigned char)c > 159)
|
||||
os.put(c);
|
||||
else
|
||||
{
|
||||
os.put('\\');
|
||||
if (c > 6 && c < 14)
|
||||
{
|
||||
os.put(c2s_tab[c - 7]);
|
||||
return os;
|
||||
}
|
||||
else if (c == 27)
|
||||
{
|
||||
os.put('e');
|
||||
return os;
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
os.put('\\');
|
||||
return os;
|
||||
}
|
||||
std::ostream::char_type old_fill = os.fill('0');
|
||||
std::ios_base::fmtflags old_flgs = os.flags();
|
||||
os.width(3);
|
||||
os << std::oct << (int)((unsigned char)c);
|
||||
os.setf(old_flgs);
|
||||
os.fill(old_fill);
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
namespace dc
|
||||
{
|
||||
|
||||
fake_channel const warning(1, "WARNING ");
|
||||
fake_channel const curl(1, "CURL ");
|
||||
fake_channel const curlio(1, "CURLIO ");
|
||||
fake_channel const statemachine(1, "STATEMACHINE");
|
||||
fake_channel const notice(1, "NOTICE ");
|
||||
|
||||
} // namespace dc
|
||||
} // namespace debug
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,94 @@
|
||||
|
||||
#ifndef CWDEBUG
|
||||
|
||||
#ifdef DEBUG_CURLIO
|
||||
|
||||
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
|
||||
// some of the cwd macro's with something that generates viewer
|
||||
// specific debug output. Note that this generates a LOT of
|
||||
// output and should not normally be defined.
|
||||
|
||||
#include <string>
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
namespace debug {
|
||||
namespace libcwd {
|
||||
|
||||
struct buf2str {
|
||||
buf2str(char const* buf, int size) : mBuf(buf), mSize(size) { }
|
||||
char const* mBuf;
|
||||
int mSize;
|
||||
};
|
||||
|
||||
struct libcwd_do_type {
|
||||
void on() const { }
|
||||
};
|
||||
extern LL_COMMON_API libcwd_do_type const libcw_do;
|
||||
|
||||
} // namespace libcwd
|
||||
|
||||
enum print_thread_id_t { print_thread_id };
|
||||
inline void init() { }
|
||||
struct Indent {
|
||||
int M_indent;
|
||||
static ll_thread_local int S_indentation;
|
||||
enum LL_COMMON_API print_nt { print };
|
||||
LL_COMMON_API Indent(int indent);
|
||||
LL_COMMON_API ~Indent();
|
||||
};
|
||||
|
||||
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s);
|
||||
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, Indent::print_nt);
|
||||
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
|
||||
|
||||
namespace dc {
|
||||
|
||||
struct fake_channel {
|
||||
int mOn;
|
||||
char const* mLabel;
|
||||
fake_channel(int on, char const* label) : mOn(on), mLabel(label) { }
|
||||
fake_channel(void) : mOn(0) { }
|
||||
bool is_on() const { return !!mOn; }
|
||||
bool is_off() const { return !mOn; }
|
||||
void on() const { }
|
||||
void off() const { }
|
||||
};
|
||||
extern LL_COMMON_API fake_channel const warning;
|
||||
extern LL_COMMON_API fake_channel const curl;
|
||||
extern LL_COMMON_API fake_channel const curlio;
|
||||
extern LL_COMMON_API fake_channel const statemachine;
|
||||
extern LL_COMMON_API fake_channel const notice;
|
||||
|
||||
} // namespace dc
|
||||
} // namespace debug
|
||||
|
||||
#define LIBCWD_DEBUG_CHANNELS debug
|
||||
#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; using namespace debug::libcwd; llinfos_nf << print_thread_id << (c).mLabel << ": " << Indent::print;
|
||||
#define LibcwDoutStream llcont
|
||||
#define LibcwDoutScopeEnd llcont << llendl; } while(0)
|
||||
|
||||
#define Debug(x) do { using namespace debug; using namespace debug::libcwd; x; } while(0)
|
||||
#define Dout(a, b) do { using namespace debug; using namespace debug::libcwd; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
|
||||
#define DoutEntering(a, b) \
|
||||
int __slviewer_debug_indentation = 2; \
|
||||
{ \
|
||||
using namespace debug; \
|
||||
using namespace debug::libcwd; \
|
||||
if ((a).mOn) \
|
||||
llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
|
||||
else \
|
||||
__slviewer_debug_indentation = 0; \
|
||||
} \
|
||||
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
|
||||
|
||||
#else // !DEBUG_CURLIO
|
||||
|
||||
#define Debug(x)
|
||||
#define Dout(a, b)
|
||||
#define DoutEntering(a, b)
|
||||
|
||||
#endif // !DEBUG_CURLIO
|
||||
|
||||
#ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
|
||||
|
||||
#include <iostream>
|
||||
@@ -36,9 +124,6 @@
|
||||
#define AllocTag2(p, desc)
|
||||
#define AllocTag_dynamic_description(p, x)
|
||||
#define AllocTag(p, x)
|
||||
#define Debug(x)
|
||||
#define Dout(a, b)
|
||||
#define DoutEntering(a, b)
|
||||
#define DoutFatal(a, b) LibcwDoutFatal(::std, , a, b)
|
||||
#define ForAllDebugChannels(STATEMENT)
|
||||
#define ForAllDebugObjects(STATEMENT)
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "lldir.h"
|
||||
#include "llendianswizzle.h"
|
||||
#include "llassetstorage.h"
|
||||
#include "llrefcount.h"
|
||||
|
||||
#include "vorbis/codec.h"
|
||||
#include "vorbis/vorbisfile.h"
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
#include "lluuid.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llassettype.h"
|
||||
#include "llextendedstatus.h"
|
||||
|
||||
#include "lllistener.h"
|
||||
|
||||
const F32 LL_WIND_UPDATE_INTERVAL = 0.1f;
|
||||
const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water
|
||||
const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
|
||||
|
||||
const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
|
||||
|
||||
@@ -72,6 +72,8 @@ bool attemptDelayLoad()
|
||||
|
||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
|
||||
|
||||
FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
|
||||
|
||||
LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler)
|
||||
{
|
||||
mInited = false;
|
||||
@@ -95,6 +97,28 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
|
||||
return true;
|
||||
}
|
||||
|
||||
void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
|
||||
{
|
||||
if(type & FMOD_MEMORY_STREAM_DECODE)
|
||||
{
|
||||
llinfos << "Decode buffer size: " << size << llendl;
|
||||
}
|
||||
else if(type & FMOD_MEMORY_STREAM_FILE)
|
||||
{
|
||||
llinfos << "Strean buffer size: " << size << llendl;
|
||||
}
|
||||
return new char[size];
|
||||
}
|
||||
void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
|
||||
{
|
||||
memset(ptr,0,size);
|
||||
return ptr;
|
||||
}
|
||||
void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr)
|
||||
{
|
||||
delete[] (char*)ptr;
|
||||
}
|
||||
|
||||
bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
|
||||
{
|
||||
|
||||
@@ -108,6 +132,10 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
|
||||
|
||||
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
|
||||
|
||||
//result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE);
|
||||
//if(Check_FMOD_Error(result, "FMOD::Memory_Initialize"))
|
||||
// return false;
|
||||
|
||||
result = FMOD::System_Create(&mSystem);
|
||||
if(Check_FMOD_Error(result, "FMOD::System_Create"))
|
||||
return false;
|
||||
@@ -124,54 +152,8 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
|
||||
<< ")! You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
int numdrivers;
|
||||
FMOD_SPEAKERMODE speakermode;
|
||||
FMOD_CAPS caps;
|
||||
char name[256];
|
||||
|
||||
//Is this block applicable to linux?
|
||||
{
|
||||
result = mSystem->getNumDrivers(&numdrivers);
|
||||
Check_FMOD_Error(result, "FMOD::System::getNumDrivers");
|
||||
if (numdrivers == 0)
|
||||
{
|
||||
result = mSystem->setOutput(FMOD_OUTPUTTYPE_NOSOUND);
|
||||
Check_FMOD_Error(result, "FMOD::System::setOutput");
|
||||
}
|
||||
else
|
||||
{
|
||||
result = mSystem->getDriverCaps(0, &caps, 0, &speakermode);
|
||||
Check_FMOD_Error(result,"FMOD::System::getDriverCaps");
|
||||
/*
|
||||
Set the user selected speaker mode.
|
||||
*/
|
||||
result = mSystem->setSpeakerMode(speakermode);
|
||||
Check_FMOD_Error(result, "FMOD::System::setSpeakerMode");
|
||||
if (caps & FMOD_CAPS_HARDWARE_EMULATED)
|
||||
{
|
||||
/*
|
||||
The user has the 'Acceleration' slider set to off! This is really bad
|
||||
for latency! You might want to warn the user about this.
|
||||
*/
|
||||
result = mSystem->setDSPBufferSize(1024, 10);
|
||||
Check_FMOD_Error(result, "FMOD::System::setDSPBufferSize");
|
||||
}
|
||||
result = mSystem->getDriverInfo(0, name, 256, 0);
|
||||
Check_FMOD_Error(result, "FMOD::System::getDriverInfo");
|
||||
|
||||
if (strstr(name, "SigmaTel"))
|
||||
{
|
||||
/*
|
||||
Sigmatel sound devices crackle for some reason if the format is PCM 16bit.
|
||||
PCM floating point output seems to solve it.
|
||||
*/
|
||||
result = mSystem->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0,0, FMOD_DSP_RESAMPLER_LINEAR);
|
||||
Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //LL_WINDOWS
|
||||
result = mSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
|
||||
Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat");
|
||||
|
||||
// In this case, all sounds, PLUS wind and stream will be software.
|
||||
result = mSystem->setSoftwareChannels(num_channels + 2);
|
||||
@@ -179,7 +161,13 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
|
||||
|
||||
U32 fmod_flags = FMOD_INIT_NORMAL;
|
||||
if(mEnableProfiler)
|
||||
{
|
||||
fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
|
||||
mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
|
||||
mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
|
||||
mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
|
||||
mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
|
||||
}
|
||||
|
||||
#if LL_LINUX
|
||||
bool audio_ok = false;
|
||||
@@ -297,6 +285,19 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
|
||||
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL;
|
||||
|
||||
int r_numbuffers, r_samplerate, r_channels, r_bits;
|
||||
unsigned int r_bufferlength;
|
||||
char r_name[256];
|
||||
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
|
||||
mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
|
||||
mSystem->getDriverInfo(0, r_name, 255, 0);
|
||||
r_name[255] = '\0';
|
||||
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
|
||||
|
||||
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
|
||||
<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
|
||||
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
|
||||
|
||||
mInited = true;
|
||||
|
||||
return true;
|
||||
@@ -611,6 +612,9 @@ void LLAudioChannelFMODEX::play()
|
||||
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
|
||||
|
||||
getSource()->setPlayedOnce(true);
|
||||
|
||||
if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()])
|
||||
mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace FMOD
|
||||
{
|
||||
class System;
|
||||
class Channel;
|
||||
class ChannelGroup;
|
||||
class Sound;
|
||||
class DSP;
|
||||
}
|
||||
@@ -83,6 +84,9 @@ protected:
|
||||
FMOD::DSP *mWindDSP;
|
||||
FMOD::System *mSystem;
|
||||
bool mEnableProfiler;
|
||||
|
||||
public:
|
||||
static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -106,6 +106,15 @@ void LLListener_FMODEX::commitDeferredChanges()
|
||||
|
||||
void LLListener_FMODEX::setRolloffFactor(F32 factor)
|
||||
{
|
||||
//An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment.
|
||||
//Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
|
||||
//In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call.
|
||||
if(mRolloffFactor != factor)
|
||||
{
|
||||
LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f);
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL);
|
||||
}
|
||||
mRolloffFactor = factor;
|
||||
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ class LLStreamingAudioInterface
|
||||
virtual const LLSD *getMetaData() = 0;
|
||||
virtual bool supportsWaveData() = 0;
|
||||
virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) = 0;
|
||||
|
||||
virtual bool supportsAdjustableBufferSizes(){return false;}
|
||||
virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){};
|
||||
};
|
||||
|
||||
#endif // LL_STREAMINGAUDIO_H
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
|
||||
const std::string& getURL() { return mInternetStreamURL; }
|
||||
|
||||
FMOD_OPENSTATE getOpenState();
|
||||
FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
|
||||
protected:
|
||||
FMOD::System* mSystem;
|
||||
FMOD::Channel* mStreamChannel;
|
||||
@@ -74,7 +74,7 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
|
||||
{
|
||||
// Number of milliseconds of audio to buffer for the audio card.
|
||||
// Must be larger than the usual Second Life frame stutter time.
|
||||
const U32 buffer_seconds = 5; //sec
|
||||
const U32 buffer_seconds = 10; //sec
|
||||
const U32 estimated_bitrate = 128; //kbit/sec
|
||||
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
|
||||
|
||||
@@ -145,7 +145,10 @@ void LLStreamingAudio_FMODEX::update()
|
||||
return;
|
||||
}
|
||||
|
||||
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState();
|
||||
unsigned int progress;
|
||||
bool starving;
|
||||
bool diskbusy;
|
||||
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
|
||||
|
||||
if (open_state == FMOD_OPENSTATE_READY)
|
||||
{
|
||||
@@ -158,6 +161,7 @@ void LLStreamingAudio_FMODEX::update()
|
||||
// Reset volume to previously set volume
|
||||
setGain(getGain());
|
||||
mFMODInternetStreamChannelp->setPaused(false);
|
||||
mLastStarved.stop();
|
||||
}
|
||||
}
|
||||
else if(open_state == FMOD_OPENSTATE_ERROR)
|
||||
@@ -237,12 +241,29 @@ void LLStreamingAudio_FMODEX::update()
|
||||
}
|
||||
}
|
||||
}
|
||||
if(starving)
|
||||
{
|
||||
if(!mLastStarved.getStarted())
|
||||
{
|
||||
llinfos << "Stream starvation detected! Muting stream audio until it clears." << llendl;
|
||||
llinfos << " (diskbusy="<<diskbusy<<")" << llendl;
|
||||
llinfos << " (progress="<<progress<<")" << llendl;
|
||||
mFMODInternetStreamChannelp->setMute(true);
|
||||
}
|
||||
mLastStarved.start();
|
||||
}
|
||||
else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 1.f)
|
||||
{
|
||||
mLastStarved.stop();
|
||||
mFMODInternetStreamChannelp->setMute(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODEX::stop()
|
||||
{
|
||||
mLastStarved.stop();
|
||||
if(mMetaData)
|
||||
{
|
||||
delete mMetaData;
|
||||
@@ -341,6 +362,11 @@ void LLStreamingAudio_FMODEX::setGain(F32 vol)
|
||||
if(!mFMODInternetStreamChannelp || !mCurrentInternetStreamp)
|
||||
return false;
|
||||
|
||||
bool muted=false;
|
||||
mFMODInternetStreamChannelp->getMute(&muted);
|
||||
if(muted)
|
||||
return false;
|
||||
|
||||
static std::vector<float> local_array(count); //Have to have an extra buffer to mix channels. Bleh.
|
||||
if(count > (S32)local_array.size()) //Expand the array if needed. Try to minimize allocation calls, so don't ever shrink.
|
||||
local_array.resize(count);
|
||||
@@ -369,12 +395,12 @@ LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, con
|
||||
{
|
||||
mInternetStreamURL = url;
|
||||
|
||||
FMOD_CREATESOUNDEXINFO exinfo;
|
||||
/*FMOD_CREATESOUNDEXINFO exinfo;
|
||||
memset(&exinfo,0,sizeof(exinfo));
|
||||
exinfo.cbsize = sizeof(exinfo);
|
||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_MPEG; //Hint to speed up loading.
|
||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS; //Hint to speed up loading.*/
|
||||
|
||||
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, &exinfo, &mInternetStream);
|
||||
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
|
||||
|
||||
if (result!= FMOD_OK)
|
||||
{
|
||||
@@ -442,9 +468,19 @@ bool LLAudioStreamManagerFMODEX::stopStream()
|
||||
}
|
||||
}
|
||||
|
||||
FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState()
|
||||
FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
|
||||
{
|
||||
FMOD_OPENSTATE state;
|
||||
mInternetStream->getOpenState(&state,NULL,NULL,NULL);
|
||||
mInternetStream->getOpenState(&state,percentbuffered,starving,diskbusy);
|
||||
return state;
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
|
||||
{
|
||||
mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES);
|
||||
FMOD_ADVANCEDSETTINGS settings;
|
||||
memset(&settings,0,sizeof(settings));
|
||||
settings.cbsize=sizeof(settings);
|
||||
settings.defaultDecodeBufferSize = decodebuffertime;//ms
|
||||
mSystem->setAdvancedSettings(&settings);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "stdtypes.h" // from llcommon
|
||||
|
||||
#include "llstreamingaudio.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
//Stubs
|
||||
class LLAudioStreamManagerFMODEX;
|
||||
@@ -66,6 +67,8 @@ class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
|
||||
/*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not playing.
|
||||
/*virtual*/ bool supportsWaveData(){return true;}
|
||||
/*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1);
|
||||
/*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
|
||||
/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
|
||||
private:
|
||||
FMOD::System *mSystem;
|
||||
|
||||
@@ -76,6 +79,8 @@ private:
|
||||
std::string mURL;
|
||||
F32 mGain;
|
||||
|
||||
LLTimer mLastStarved;
|
||||
|
||||
LLSD *mMetaData;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
#include "llcharacter.h"
|
||||
#include "llstring.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#define SKEL_HEADER "Linden Skeleton 1.0"
|
||||
|
||||
@@ -194,19 +193,14 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateMotions()
|
||||
//-----------------------------------------------------------------------------
|
||||
static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation");
|
||||
static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim");
|
||||
|
||||
void LLCharacter::updateMotions(e_update_t update_type)
|
||||
{
|
||||
if (update_type == HIDDEN_UPDATE)
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION);
|
||||
mMotionController.updateMotionsMinimal();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_ANIMATION);
|
||||
// unpause if the number of outstanding pause requests has dropped to the initial one
|
||||
if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1)
|
||||
{
|
||||
|
||||
@@ -250,9 +250,9 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)
|
||||
head_rot_local = nlerp(head_slerp_amt, mLastHeadRot, head_rot_local);
|
||||
mLastHeadRot = head_rot_local;
|
||||
|
||||
if(mNeckState->getJoint() && mNeckState->getJoint()->getParent()) //Guess this has crashed? Taken from snowglobe -Shyotl
|
||||
// Set the head rotation.
|
||||
if(mNeckState->getJoint() && mNeckState->getJoint()->getParent())
|
||||
{
|
||||
// Set the head rotation.
|
||||
LLQuaternion torsoRotLocal = mNeckState->getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld;
|
||||
head_rot_local = head_rot_local * ~torsoRotLocal;
|
||||
mNeckState->setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) );
|
||||
|
||||
@@ -637,9 +637,9 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
|
||||
motionp->fadeIn();
|
||||
}
|
||||
|
||||
// **********************
|
||||
//**********************
|
||||
// MOTION INACTIVE
|
||||
// **********************
|
||||
//**********************
|
||||
if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration())
|
||||
{
|
||||
// this motion has gone on too long, deactivate it
|
||||
@@ -659,9 +659,9 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
|
||||
}
|
||||
}
|
||||
|
||||
// **********************
|
||||
//**********************
|
||||
// MOTION EASE OUT
|
||||
// **********************
|
||||
//**********************
|
||||
else if (motionp->isStopped() && mAnimTime > motionp->getStopTime())
|
||||
{
|
||||
// is this the first iteration in the ease out phase?
|
||||
@@ -684,9 +684,9 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
|
||||
update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
|
||||
}
|
||||
|
||||
// **********************
|
||||
//**********************
|
||||
// MOTION ACTIVE
|
||||
// **********************
|
||||
//**********************
|
||||
else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration())
|
||||
{
|
||||
posep->setWeight(motionp->getFadeWeight());
|
||||
@@ -707,9 +707,9 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
|
||||
update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
|
||||
}
|
||||
|
||||
// **********************
|
||||
//**********************
|
||||
// MOTION EASE IN
|
||||
// **********************
|
||||
//**********************
|
||||
else if (mAnimTime >= motionp->mActivationTimestamp)
|
||||
{
|
||||
if (mLastTime < motionp->mActivationTimestamp)
|
||||
@@ -837,6 +837,7 @@ void LLMotionController::updateMotions(bool force_update)
|
||||
}
|
||||
|
||||
updateLoadingMotions();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ class LLVisualParam
|
||||
{
|
||||
public:
|
||||
typedef boost::function<LLVisualParam*(S32)> visual_param_mapper;
|
||||
|
||||
LLVisualParam();
|
||||
virtual ~LLVisualParam();
|
||||
|
||||
|
||||
@@ -15,8 +15,9 @@ include_directories(
|
||||
)
|
||||
|
||||
set(llcommon_SOURCE_FILES
|
||||
aiframetimer.cpp
|
||||
imageids.cpp
|
||||
aiframetimer.cpp
|
||||
aithreadid.cpp
|
||||
imageids.cpp
|
||||
indra_constants.cpp
|
||||
llallocator.cpp
|
||||
llallocator_heap_profile.cpp
|
||||
@@ -24,7 +25,7 @@ set(llcommon_SOURCE_FILES
|
||||
llapr.cpp
|
||||
llaprpool.cpp
|
||||
llassettype.cpp
|
||||
llavatarname.cpp
|
||||
llavatarname.cpp
|
||||
llbase32.cpp
|
||||
llbase64.cpp
|
||||
llcommon.cpp
|
||||
@@ -53,6 +54,7 @@ set(llcommon_SOURCE_FILES
|
||||
llformat.cpp
|
||||
llframetimer.cpp
|
||||
llheartbeat.cpp
|
||||
llinitparam.cpp
|
||||
llinstancetracker.cpp
|
||||
llindraconfigfile.cpp
|
||||
llliveappconfig.cpp
|
||||
@@ -103,6 +105,7 @@ set(llcommon_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
aiframetimer.h
|
||||
aithreadid.h
|
||||
aithreadsafe.h
|
||||
bitpack.h
|
||||
ctype_workaround.h
|
||||
@@ -171,6 +174,7 @@ set(llcommon_HEADER_FILES
|
||||
llheartbeat.h
|
||||
llhttpstatuscodes.h
|
||||
llindexedqueue.h
|
||||
llinitparam.h
|
||||
llinstancetracker.h
|
||||
llindraconfigfile.h
|
||||
llkeythrottle.h
|
||||
@@ -212,6 +216,7 @@ set(llcommon_HEADER_FILES
|
||||
llsingleton.h
|
||||
llskiplist.h
|
||||
llskipmap.h
|
||||
llsortedvector.h
|
||||
llstack.h
|
||||
llstacktrace.h
|
||||
llstat.h
|
||||
@@ -226,6 +231,7 @@ set(llcommon_HEADER_FILES
|
||||
llthreadsafequeue.h
|
||||
lltimer.h
|
||||
lltreeiterators.h
|
||||
lltypeinfolookup.h
|
||||
lluri.h
|
||||
lluuid.h
|
||||
lluuidhashmap.h
|
||||
@@ -250,6 +256,7 @@ set(llcommon_HEADER_FILES
|
||||
set_source_files_properties(${llcommon_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
list(APPEND llcommon_SOURCE_FILES ${cwdebug_SOURCE_FILES})
|
||||
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
|
||||
|
||||
add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
|
||||
@@ -262,15 +269,9 @@ target_link_libraries(
|
||||
${ZLIB_LIBRARIES}
|
||||
${WINDOWS_LIBRARIES}
|
||||
${BOOST_REGEX_LIBRARY}
|
||||
${CWDEBUG_LIBRARIES}
|
||||
${CORESERVICES_LIBRARY}
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
# When linking with llcommon later, we do not want to link with cwdebug.a again.
|
||||
set_property(TARGET llcommon PROPERTY LINK_INTERFACE_LIBRARIES "-lapr-1 -laprutil-1 -lz")
|
||||
endif (LINUX)
|
||||
|
||||
if (DARWIN)
|
||||
# Don't embed a full path in the library's install name
|
||||
set_target_properties(
|
||||
|
||||
76
indra/llcommon/aithreadid.cpp
Normal file
76
indra/llcommon/aithreadid.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file aithreadid.cpp
|
||||
*
|
||||
* Copyright (c) 2012, Aleric Inglewood.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 08/08/2012
|
||||
* - Initial version, written by Aleric Inglewood @ SL
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "aithreadid.h"
|
||||
|
||||
AIThreadID const AIThreadID::sNone(AIThreadID::none);
|
||||
apr_os_thread_t AIThreadID::sMainThreadID;
|
||||
apr_os_thread_t const AIThreadID::undefinedID = (apr_os_thread_t)-1;
|
||||
#ifndef LL_DARWIN
|
||||
apr_os_thread_t ll_thread_local AIThreadID::lCurrentThread;
|
||||
#endif
|
||||
|
||||
void AIThreadID::set_main_thread_id(void)
|
||||
{
|
||||
sMainThreadID = apr_os_thread_current();
|
||||
}
|
||||
|
||||
void AIThreadID::set_current_thread_id(void)
|
||||
{
|
||||
#ifndef LL_DARWIN
|
||||
lCurrentThread = apr_os_thread_current();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AIThreadID::reset(void)
|
||||
{
|
||||
mID = lCurrentThread;
|
||||
}
|
||||
|
||||
bool AIThreadID::equals_current_thread(void) const
|
||||
{
|
||||
return apr_os_thread_equal(mID, lCurrentThread);
|
||||
}
|
||||
|
||||
bool AIThreadID::in_main_thread(void)
|
||||
{
|
||||
return apr_os_thread_equal(lCurrentThread, sMainThreadID);
|
||||
}
|
||||
|
||||
apr_os_thread_t AIThreadID::getCurrentThread(void)
|
||||
{
|
||||
return lCurrentThread;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, AIThreadID const& id)
|
||||
{
|
||||
return os << id.mID;
|
||||
}
|
||||
88
indra/llcommon/aithreadid.h
Normal file
88
indra/llcommon/aithreadid.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @file aithreadid.h
|
||||
* @brief Declaration of AIThreadID.
|
||||
*
|
||||
* Copyright (c) 2012, Aleric Inglewood.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 08/08/2012
|
||||
* Initial version, written by Aleric Inglewood @ SL
|
||||
*/
|
||||
|
||||
#ifndef AI_THREAD_ID
|
||||
#define AI_THREAD_ID
|
||||
|
||||
#include <apr_portable.h> // apr_os_thread_t, apr_os_thread_current(), apr_os_thread_equal().
|
||||
#include <iosfwd> // std::ostream.
|
||||
#include "llpreprocessor.h" // LL_COMMON_API, LL_COMMON_API_TLS
|
||||
|
||||
// Lightweight wrapper around apr_os_thread_t.
|
||||
// This class introduces no extra assembly code after optimization; it's only intend is to provide type-safety.
|
||||
class AIThreadID
|
||||
{
|
||||
private:
|
||||
apr_os_thread_t mID;
|
||||
static LL_COMMON_API apr_os_thread_t sMainThreadID;
|
||||
static LL_COMMON_API apr_os_thread_t const undefinedID;
|
||||
#ifndef LL_DARWIN
|
||||
static ll_thread_local apr_os_thread_t lCurrentThread;
|
||||
#endif
|
||||
public:
|
||||
static LL_COMMON_API AIThreadID const sNone;
|
||||
enum undefined_thread_t { none };
|
||||
|
||||
public:
|
||||
AIThreadID(void) : mID(apr_os_thread_current()) { }
|
||||
explicit AIThreadID(undefined_thread_t) : mID(undefinedID) { } // Used for sNone.
|
||||
AIThreadID(AIThreadID const& id) : mID(id.mID) { }
|
||||
AIThreadID& operator=(AIThreadID const& id) { mID = id.mID; return *this; }
|
||||
bool is_main_thread(void) const { return apr_os_thread_equal(mID, sMainThreadID); }
|
||||
bool is_no_thread(void) const { return apr_os_thread_equal(mID, sNone.mID); }
|
||||
friend LL_COMMON_API bool operator==(AIThreadID const& id1, AIThreadID const& id2) { return apr_os_thread_equal(id1.mID, id2.mID); }
|
||||
friend LL_COMMON_API bool operator!=(AIThreadID const& id1, AIThreadID const& id2) { return !apr_os_thread_equal(id1.mID, id2.mID); }
|
||||
friend LL_COMMON_API std::ostream& operator<<(std::ostream& os, AIThreadID const& id);
|
||||
static void set_main_thread_id(void); // Called once to set sMainThreadID.
|
||||
static void set_current_thread_id(void); // Called once for every thread to set lCurrentThread.
|
||||
#ifdef LL_DARWIN
|
||||
void reset(void) { mID = apr_os_thread_current(); }
|
||||
bool equals_current_thread(void) const { return apr_os_thread_equal(mID, apr_os_thread_current()); }
|
||||
static bool in_main_thread(void) { return apr_os_thread_equal(apr_os_thread_current(), sMainThreadID); }
|
||||
#else
|
||||
LL_COMMON_API void reset(void);
|
||||
LL_COMMON_API bool equals_current_thread(void) const;
|
||||
LL_COMMON_API static bool in_main_thread(void);
|
||||
LL_COMMON_API static apr_os_thread_t getCurrentThread(void);
|
||||
// The *_inline variants cannot be exported because they access a thread-local member.
|
||||
void reset_inline(void) { mID = lCurrentThread; }
|
||||
bool equals_current_thread_inline(void) const { return apr_os_thread_equal(mID, lCurrentThread); }
|
||||
static bool in_main_thread_inline(void) { return apr_os_thread_equal(lCurrentThread, sMainThreadID); }
|
||||
static apr_os_thread_t getCurrentThread_inline(void) { return lCurrentThread; }
|
||||
#endif
|
||||
};
|
||||
|
||||
// Legacy function.
|
||||
inline bool is_main_thread(void)
|
||||
{
|
||||
return AIThreadID::in_main_thread();
|
||||
}
|
||||
|
||||
#endif // AI_THREAD_ID
|
||||
@@ -673,18 +673,18 @@ protected:
|
||||
|
||||
#ifdef LL_DEBUG
|
||||
mutable bool mAccessed;
|
||||
mutable apr_os_thread_t mTheadID;
|
||||
mutable AIThreadID mTheadID;
|
||||
|
||||
void accessed(void) const
|
||||
{
|
||||
if (!mAccessed)
|
||||
{
|
||||
mAccessed = true;
|
||||
mTheadID = apr_os_thread_current();
|
||||
mTheadID.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(apr_os_thread_equal(mTheadID, apr_os_thread_current()));
|
||||
llassert_always(mTheadID.equals_current_thread());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
#ifndef LL_LINDEN_COMMON_H
|
||||
#define LL_LINDEN_COMMON_H
|
||||
|
||||
// *NOTE: Please keep includes here to a minimum!
|
||||
//
|
||||
// Files included here are included in every library .cpp file and
|
||||
// are not precompiled.
|
||||
|
||||
#include "cwdebug.h"
|
||||
|
||||
#if defined(LL_WINDOWS) && defined(_DEBUG)
|
||||
@@ -55,34 +60,11 @@
|
||||
#include <ctime>
|
||||
#include <iosfwd>
|
||||
|
||||
// Work around Microsoft compiler warnings in STL headers
|
||||
#ifdef LL_WINDOWS
|
||||
#pragma warning (disable : 4702) // unreachable code
|
||||
#pragma warning (disable : 4244) // conversion from time_t to S32
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
// *TODO: Eliminate these, most library .cpp files don't need them.
|
||||
// Add them to llviewerprecompiledheaders.h if necessary.
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
// Reenable warnings we disabled above
|
||||
#pragma warning (3 : 4702) // unreachable code, we like level 3, not 4
|
||||
// moved msvc warnings to llpreprocessor.h *TODO - delete this comment after merge conflicts are unlikely -brad
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
// Linden only libs in alpha-order other than stdtypes.h
|
||||
// *NOTE: Please keep includes here to a minimum, see above.
|
||||
#include "stdtypes.h"
|
||||
#include "lldefs.h"
|
||||
#include "llerror.h"
|
||||
#include "llextendedstatus.h"
|
||||
// Don't do this, adds 15K lines of header code to every library file.
|
||||
//#include "llfasttimer.h"
|
||||
#include "llfile.h"
|
||||
#include "llformat.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,10 +43,14 @@ template <typename Type> class LLAtomic32;
|
||||
typedef LLAtomic32<U32> LLAtomicU32;
|
||||
class LLErrorThread;
|
||||
class LLLiveFile;
|
||||
|
||||
|
||||
#if LL_LINUX
|
||||
typedef struct siginfo siginfo_t;
|
||||
#include <signal.h>
|
||||
//typedef struct siginfo siginfo_t; //Removed as per changes in glibc 2.16 - Drake Arconis
|
||||
#endif
|
||||
|
||||
|
||||
typedef void (*LLAppErrorHandler)();
|
||||
typedef void (*LLAppChildCallback)(int pid, bool exited, int status);
|
||||
|
||||
|
||||
@@ -60,10 +60,10 @@ void LLAPRPool::create(LLAPRPool& parent)
|
||||
//
|
||||
// In other words, it's safe for any thread to create a (sub)pool, independent of who
|
||||
// owns the parent pool.
|
||||
mOwner = apr_os_thread_current();
|
||||
mOwner.reset_inline();
|
||||
#else
|
||||
mOwner = mParent->mOwner;
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
llassert(mOwner.equals_current_thread_inline());
|
||||
#endif
|
||||
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
|
||||
llassert_always(apr_pool_create_status == APR_SUCCESS);
|
||||
@@ -83,7 +83,7 @@ void LLAPRPool::destroy(void)
|
||||
// of course. Otherwise, if we are a subpool, only the thread that owns
|
||||
// the parent may destruct us, since that is the pool that is still alive,
|
||||
// possibly being used by others and being altered here.
|
||||
llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current()));
|
||||
llassert(!mParent || mParent->mOwner.equals_current_thread_inline());
|
||||
#endif
|
||||
apr_pool_t* pool = mPool;
|
||||
mPool = NULL; // Mark that we are BEING destructed.
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "apr_portable.h"
|
||||
#include "apr_pools.h"
|
||||
#include "llerror.h"
|
||||
#include "aithreadid.h"
|
||||
|
||||
extern void ll_init_apr();
|
||||
|
||||
@@ -62,22 +63,22 @@ class LL_COMMON_API LLAPRPool
|
||||
protected:
|
||||
apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized.
|
||||
LLAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero.
|
||||
apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero.
|
||||
AIThreadID mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero.
|
||||
|
||||
public:
|
||||
//! Construct an uninitialized (destructed) pool.
|
||||
LLAPRPool(void) : mPool(NULL) { }
|
||||
LLAPRPool(void) : mPool(NULL), mOwner(AIThreadID::none) { }
|
||||
|
||||
//! Construct a subpool from an existing pool.
|
||||
// This is not a copy-constructor, this class doesn't have one!
|
||||
LLAPRPool(LLAPRPool& parent) : mPool(NULL) { create(parent); }
|
||||
LLAPRPool(LLAPRPool& parent) : mPool(NULL), mOwner(AIThreadID::none) { create(parent); }
|
||||
|
||||
//! Destruct the memory pool (free all of it's subpools and allocated memory).
|
||||
~LLAPRPool() { destroy(); }
|
||||
|
||||
protected:
|
||||
// Create a pool that is allocated from the Operating System. Only used by LLAPRRootPool.
|
||||
LLAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current())
|
||||
LLAPRPool(int) : mPool(NULL), mParent(NULL)
|
||||
{
|
||||
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL);
|
||||
llassert_always(apr_pool_create_status == APR_SUCCESS);
|
||||
@@ -104,7 +105,7 @@ public:
|
||||
apr_pool_t* operator()(void) const
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
llassert(mOwner.equals_current_thread());
|
||||
return mPool;
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ public:
|
||||
void clear(void)
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
llassert(mOwner.equals_current_thread());
|
||||
apr_pool_clear(mPool);
|
||||
}
|
||||
|
||||
@@ -124,13 +125,13 @@ public:
|
||||
void* palloc(size_t size)
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
llassert(mOwner.equals_current_thread());
|
||||
return apr_palloc(mPool, size);
|
||||
}
|
||||
void* pcalloc(size_t size)
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
llassert(mOwner.equals_current_thread());
|
||||
return apr_pcalloc(mPool, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -148,7 +148,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type)
|
||||
}
|
||||
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::lookup( const char* name )
|
||||
LLAssetType::EType LLAssetType::lookup(const char* name)
|
||||
{
|
||||
return lookup(ll_safe_string(name));
|
||||
}
|
||||
@@ -186,7 +186,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
|
||||
}
|
||||
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name )
|
||||
LLAssetType::EType LLAssetType::lookupHumanReadable(const char* name)
|
||||
{
|
||||
return lookupHumanReadable(ll_safe_string(name));
|
||||
}
|
||||
@@ -208,12 +208,9 @@ LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string& readable_
|
||||
return AT_NONE;
|
||||
}
|
||||
|
||||
//NOTE: LLAssetType::lookupDragAndDropType & LLAssetType::generateDescriptionFor moved to newview/llviewerassettype.h
|
||||
|
||||
// static
|
||||
bool LLAssetType::lookupCanLink(EType asset_type)
|
||||
{
|
||||
//Check that enabling all these other types as linkable doesn't break things.
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
@@ -221,9 +218,6 @@ bool LLAssetType::lookupCanLink(EType asset_type)
|
||||
return entry->mCanLink;
|
||||
}
|
||||
return false;
|
||||
|
||||
/*return (asset_type == AT_CLOTHING || asset_type == AT_OBJECT || asset_type == AT_CATEGORY ||
|
||||
asset_type == AT_BODYPART || asset_type == AT_GESTURE);*/
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -268,4 +262,3 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -963,10 +963,14 @@ namespace LLError
|
||||
settings_w->shouldLogCallCounter += 1;
|
||||
|
||||
std::string class_name = className(site.mClassInfo);
|
||||
std::string function_name = functionName(site.mFunction);
|
||||
if (site.mClassInfo != typeid(NoClassInfo))
|
||||
std::string function_name;
|
||||
if (site.mFunction)
|
||||
{
|
||||
function_name = class_name + "::" + function_name;
|
||||
function_name = functionName(site.mFunction);
|
||||
if (site.mClassInfo != typeid(NoClassInfo))
|
||||
{
|
||||
function_name = class_name + "::" + function_name;
|
||||
}
|
||||
}
|
||||
|
||||
ELevel compareLevel = settings_w->defaultLevel;
|
||||
@@ -976,7 +980,7 @@ namespace LLError
|
||||
// So, in increasing order of importance:
|
||||
// Default < Broad Tag < File < Class < Function < Narrow Tag
|
||||
((site.mNarrowTag != NULL) ? checkLevelMap(settings_w->tagLevelMap, site.mNarrowTag, compareLevel) : false)
|
||||
|| checkLevelMap(settings_w->functionLevelMap, function_name, compareLevel)
|
||||
|| (site.mFunction && checkLevelMap(settings_w->functionLevelMap, function_name, compareLevel))
|
||||
|| checkLevelMap(settings_w->classLevelMap, class_name, compareLevel)
|
||||
|| checkLevelMap(settings_w->fileLevelMap, abbreviateFile(site.mFile), compareLevel)
|
||||
|| ((site.mBroadTag != NULL) ? checkLevelMap(settings_w->tagLevelMap, site.mBroadTag, compareLevel) : false);
|
||||
@@ -1083,8 +1087,8 @@ namespace LLError
|
||||
default: prefix << "XXX"; break;
|
||||
};
|
||||
|
||||
bool need_function = true;
|
||||
if (site.mBroadTag && *site.mBroadTag != '\0')
|
||||
bool need_function = site.mFunction;
|
||||
if (need_function && site.mBroadTag && *site.mBroadTag != '\0')
|
||||
{
|
||||
prefix << "(\"" << site.mBroadTag << "\")";
|
||||
#if LL_DEBUG
|
||||
@@ -1112,7 +1116,7 @@ namespace LLError
|
||||
#if LL_WINDOWS
|
||||
// DevStudio: __FUNCTION__ already includes the full class name
|
||||
#else
|
||||
if (need_function && site.mClassInfo != typeid(NoClassInfo))
|
||||
if (site.mClassInfo != typeid(NoClassInfo))
|
||||
{
|
||||
prefix << className(site.mClassInfo) << "::";
|
||||
}
|
||||
|
||||
@@ -238,10 +238,10 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
||||
See top of file for common usage.
|
||||
*/
|
||||
|
||||
#define lllog(level, broadTag, narrowTag, once) \
|
||||
#define lllog(level, broadTag, narrowTag, once, nofunction) \
|
||||
do { \
|
||||
static LLError::CallSite _site( \
|
||||
level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, broadTag, narrowTag, once);\
|
||||
level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), nofunction ? NULL : __FUNCTION__, broadTag, narrowTag, once);\
|
||||
if (LL_UNLIKELY(_site.shouldLog())) \
|
||||
{ \
|
||||
std::ostringstream* _out = LLError::Log::out(); \
|
||||
@@ -255,33 +255,39 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
||||
} while(0)
|
||||
|
||||
// DEPRECATED: Use the new macros that allow tags and *look* like macros.
|
||||
#define lldebugs lllog(LLError::LEVEL_DEBUG, NULL, NULL, false)
|
||||
#define llinfos lllog(LLError::LEVEL_INFO, NULL, NULL, false)
|
||||
#define llwarns lllog(LLError::LEVEL_WARN, NULL, NULL, false)
|
||||
#define llerrs lllog(LLError::LEVEL_ERROR, NULL, NULL, false)
|
||||
#define lldebugs lllog(LLError::LEVEL_DEBUG, NULL, NULL, false, false)
|
||||
#define llinfos lllog(LLError::LEVEL_INFO, NULL, NULL, false, false)
|
||||
#define llwarns lllog(LLError::LEVEL_WARN, NULL, NULL, false, false)
|
||||
#define llerrs lllog(LLError::LEVEL_ERROR, NULL, NULL, false, false)
|
||||
#define llcont (*_out)
|
||||
|
||||
// No function name
|
||||
#define lldebugs_nf lllog(LLError::LEVEL_DEBUG, NULL, NULL, false, true)
|
||||
#define llinfos_nf lllog(LLError::LEVEL_INFO, NULL, NULL, false, true)
|
||||
#define llwarns_nf lllog(LLError::LEVEL_WARN, NULL, NULL, false, true)
|
||||
#define llerrs_nf lllog(LLError::LEVEL_ERROR, NULL, NULL, false, true)
|
||||
|
||||
// NEW Macros for debugging, allow the passing of a string tag
|
||||
|
||||
// One Tag
|
||||
#define LL_DEBUGS(broadTag) lllog(LLError::LEVEL_DEBUG, broadTag, NULL, false)
|
||||
#define LL_INFOS(broadTag) lllog(LLError::LEVEL_INFO, broadTag, NULL, false)
|
||||
#define LL_WARNS(broadTag) lllog(LLError::LEVEL_WARN, broadTag, NULL, false)
|
||||
#define LL_ERRS(broadTag) lllog(LLError::LEVEL_ERROR, broadTag, NULL, false)
|
||||
#define LL_DEBUGS(broadTag) lllog(LLError::LEVEL_DEBUG, broadTag, NULL, false, false)
|
||||
#define LL_INFOS(broadTag) lllog(LLError::LEVEL_INFO, broadTag, NULL, false, false)
|
||||
#define LL_WARNS(broadTag) lllog(LLError::LEVEL_WARN, broadTag, NULL, false, false)
|
||||
#define LL_ERRS(broadTag) lllog(LLError::LEVEL_ERROR, broadTag, NULL, false, false)
|
||||
// Two Tags
|
||||
#define LL_DEBUGS2(broadTag, narrowTag) lllog(LLError::LEVEL_DEBUG, broadTag, narrowTag, false)
|
||||
#define LL_INFOS2(broadTag, narrowTag) lllog(LLError::LEVEL_INFO, broadTag, narrowTag, false)
|
||||
#define LL_WARNS2(broadTag, narrowTag) lllog(LLError::LEVEL_WARN, broadTag, narrowTag, false)
|
||||
#define LL_ERRS2(broadTag, narrowTag) lllog(LLError::LEVEL_ERROR, broadTag, narrowTag, false)
|
||||
#define LL_DEBUGS2(broadTag, narrowTag) lllog(LLError::LEVEL_DEBUG, broadTag, narrowTag, false, false)
|
||||
#define LL_INFOS2(broadTag, narrowTag) lllog(LLError::LEVEL_INFO, broadTag, narrowTag, false, false)
|
||||
#define LL_WARNS2(broadTag, narrowTag) lllog(LLError::LEVEL_WARN, broadTag, narrowTag, false, false)
|
||||
#define LL_ERRS2(broadTag, narrowTag) lllog(LLError::LEVEL_ERROR, broadTag, narrowTag, false, false)
|
||||
|
||||
// Only print the log message once (good for warnings or infos that would otherwise
|
||||
// spam the log file over and over, such as tighter loops).
|
||||
#define LL_DEBUGS_ONCE(broadTag) lllog(LLError::LEVEL_DEBUG, broadTag, NULL, true)
|
||||
#define LL_INFOS_ONCE(broadTag) lllog(LLError::LEVEL_INFO, broadTag, NULL, true)
|
||||
#define LL_WARNS_ONCE(broadTag) lllog(LLError::LEVEL_WARN, broadTag, NULL, true)
|
||||
#define LL_DEBUGS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_DEBUG, broadTag, narrowTag, true)
|
||||
#define LL_INFOS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_INFO, broadTag, narrowTag, true)
|
||||
#define LL_WARNS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_WARN, broadTag, narrowTag, true)
|
||||
#define LL_DEBUGS_ONCE(broadTag) lllog(LLError::LEVEL_DEBUG, broadTag, NULL, true, false)
|
||||
#define LL_INFOS_ONCE(broadTag) lllog(LLError::LEVEL_INFO, broadTag, NULL, true, false)
|
||||
#define LL_WARNS_ONCE(broadTag) lllog(LLError::LEVEL_WARN, broadTag, NULL, true, false)
|
||||
#define LL_DEBUGS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_DEBUG, broadTag, narrowTag, true, false)
|
||||
#define LL_INFOS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_INFO, broadTag, narrowTag, true, false)
|
||||
#define LL_WARNS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_WARN, broadTag, narrowTag, true, false)
|
||||
|
||||
#define LL_ENDL llendl
|
||||
#define LL_CONT (*_out)
|
||||
@@ -302,8 +308,4 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
||||
Such computation is done iff the message will be logged.
|
||||
*/
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
extern LL_COMMON_API bool is_main_thread();
|
||||
#endif
|
||||
|
||||
#endif // LL_LLERROR_H
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#include "lltimer.h"
|
||||
#include "timing.h"
|
||||
#include <apr_thread_mutex.h>
|
||||
#ifdef SHOW_ASSERT
|
||||
#include "aithreadid.h" // is_main_thread()
|
||||
#endif
|
||||
|
||||
class LL_COMMON_API LLFrameTimer
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llstl.h"
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
@@ -205,20 +206,12 @@ namespace LLInitParam
|
||||
mutable std::string mValueName;
|
||||
};
|
||||
|
||||
class Parser
|
||||
class LL_COMMON_API Parser
|
||||
{
|
||||
LOG_CLASS(Parser);
|
||||
|
||||
public:
|
||||
|
||||
struct CompareTypeID
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return lhs->before(*rhs);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<std::pair<std::string, bool> > name_stack_t;
|
||||
typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
|
||||
typedef std::vector<std::string> possible_values_t;
|
||||
@@ -227,9 +220,9 @@ namespace LLInitParam
|
||||
typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
|
||||
typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
|
||||
|
||||
typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
|
||||
|
||||
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
|
||||
: mParseSilently(false),
|
||||
@@ -301,7 +294,7 @@ namespace LLInitParam
|
||||
class Param;
|
||||
|
||||
// various callbacks and constraints associated with an individual param
|
||||
struct ParamDescriptor
|
||||
struct LL_COMMON_API ParamDescriptor
|
||||
{
|
||||
struct UserData
|
||||
{
|
||||
@@ -341,7 +334,7 @@ namespace LLInitParam
|
||||
typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
|
||||
|
||||
// each derived Block class keeps a static data structure maintaining offsets to various params
|
||||
class BlockDescriptor
|
||||
class LL_COMMON_API BlockDescriptor
|
||||
{
|
||||
public:
|
||||
BlockDescriptor();
|
||||
@@ -369,7 +362,7 @@ namespace LLInitParam
|
||||
class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
|
||||
};
|
||||
|
||||
class BaseBlock
|
||||
class LL_COMMON_API BaseBlock
|
||||
{
|
||||
public:
|
||||
//TODO: implement in terms of owned_ptr
|
||||
@@ -566,7 +559,7 @@ namespace LLInitParam
|
||||
static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
|
||||
};
|
||||
|
||||
class Param
|
||||
class LL_COMMON_API Param
|
||||
{
|
||||
public:
|
||||
void setProvided(bool is_provided = true)
|
||||
@@ -1253,15 +1246,16 @@ namespace LLInitParam
|
||||
return mValues.back();
|
||||
}
|
||||
|
||||
void add(const value_t& item)
|
||||
self_t& add(const value_t& item)
|
||||
{
|
||||
param_value_t param_value;
|
||||
param_value.setValue(item);
|
||||
mValues.push_back(param_value);
|
||||
setProvided();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void add(const typename name_value_lookup_t::name_t& name)
|
||||
self_t& add(const typename name_value_lookup_t::name_t& name)
|
||||
{
|
||||
value_t value;
|
||||
|
||||
@@ -1271,6 +1265,8 @@ namespace LLInitParam
|
||||
add(value);
|
||||
mValues.back().setValueName(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// implicit conversion
|
||||
@@ -1441,13 +1437,14 @@ namespace LLInitParam
|
||||
return mValues.back();
|
||||
}
|
||||
|
||||
void add(const value_t& item)
|
||||
self_t& add(const value_t& item)
|
||||
{
|
||||
mValues.push_back(item);
|
||||
setProvided();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void add(const typename name_value_lookup_t::name_t& name)
|
||||
self_t& add(const typename name_value_lookup_t::name_t& name)
|
||||
{
|
||||
value_t value;
|
||||
|
||||
@@ -1457,6 +1454,7 @@ namespace LLInitParam
|
||||
add(value);
|
||||
mValues.back().setValueName(name);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// implicit conversion
|
||||
@@ -2057,8 +2055,8 @@ namespace LLInitParam
|
||||
|
||||
|
||||
// block param interface
|
||||
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;
|
||||
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;
|
||||
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
|
||||
@@ -174,6 +174,7 @@ public:
|
||||
F64 averageCount = curr.count + prevCount * (1.0 - timeInCurrent);
|
||||
return averageCount;
|
||||
}
|
||||
|
||||
// call each time the key wants use
|
||||
State noteAction(const T& id, S32 weight = 1)
|
||||
{
|
||||
|
||||
@@ -73,6 +73,15 @@ const S32 LSL_PRIM_TEXGEN = 22;
|
||||
const S32 LSL_PRIM_POINT_LIGHT = 23;
|
||||
const S32 LSL_PRIM_CAST_SHADOWS = 24;
|
||||
const S32 LSL_PRIM_GLOW = 25;
|
||||
const S32 LSL_PRIM_TEXT = 26;
|
||||
const S32 LSL_PRIM_NAME = 27;
|
||||
const S32 LSL_PRIM_DESC = 28;
|
||||
const S32 LSL_PRIM_ROT_LOCAL = 29;
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_TYPE = 30;
|
||||
const S32 LSL_PRIM_OMEGA = 32;
|
||||
const S32 LSL_PRIM_POS_LOCAL = 33;
|
||||
const S32 LSL_PRIM_LINK_TARGET = 34;
|
||||
const S32 LSL_PRIM_SLICE = 35;
|
||||
|
||||
const S32 LSL_PRIM_TYPE_BOX = 0;
|
||||
const S32 LSL_PRIM_TYPE_CYLINDER= 1;
|
||||
@@ -132,6 +141,15 @@ const S32 LSL_PRIM_SCULPT_TYPE_MASK = 7;
|
||||
const S32 LSL_PRIM_SCULPT_FLAG_INVERT = 64;
|
||||
const S32 LSL_PRIM_SCULPT_FLAG_MIRROR = 128;
|
||||
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_PRIM = 0;
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_NONE = 1;
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_CONVEX = 2;
|
||||
|
||||
const S32 LSL_DENSITY = 1;
|
||||
const S32 LSL_FRICTION = 2;
|
||||
const S32 LSL_RESTITUTION = 4;
|
||||
const S32 LSL_GRAVITY_MULTIPLIER = 8;
|
||||
|
||||
const S32 LSL_ALL_SIDES = -1;
|
||||
const S32 LSL_LINK_ROOT = 1;
|
||||
const S32 LSL_LINK_FIRST_CHILD = 2;
|
||||
@@ -189,6 +207,13 @@ const S32 OBJECT_RUNNING_SCRIPT_COUNT = 9;
|
||||
const S32 OBJECT_TOTAL_SCRIPT_COUNT = 10;
|
||||
const S32 OBJECT_SCRIPT_MEMORY = 11;
|
||||
const S32 OBJECT_SCRIPT_TIME = 12;
|
||||
const S32 OBJECT_PRIM_EQUIVALENCE = 13;
|
||||
const S32 OBJECT_SERVER_COST = 14;
|
||||
const S32 OBJECT_STREAMING_COST = 15;
|
||||
const S32 OBJECT_PHYSICS_COST = 16;
|
||||
|
||||
// llTextBox() magic token string - yes it's a hack.
|
||||
char const* const TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!";
|
||||
|
||||
// changed() event flags
|
||||
const U32 CHANGED_NONE = 0x0;
|
||||
@@ -216,4 +241,156 @@ const U32 LSL_STATUS_INTERNAL_ERROR = 1999;
|
||||
|
||||
// Start per-function errors below, starting at 2000:
|
||||
const U32 LSL_STATUS_WHITELIST_FAILED = 2001;
|
||||
|
||||
// Memory profiling support
|
||||
const S32 LSL_PROFILE_SCRIPT_NONE = 0;
|
||||
const S32 LSL_PROFILE_SCRIPT_MEMORY = 1;
|
||||
|
||||
// HTTP responses contents type
|
||||
const S32 LSL_CONTENT_TYPE_TEXT = 0;
|
||||
const S32 LSL_CONTENT_TYPE_HTML = 1;
|
||||
|
||||
// Ray casting
|
||||
const S32 LSL_RCERR_UNKNOWN = -1;
|
||||
const S32 LSL_RCERR_SIM_PERF_LOW = -2;
|
||||
const S32 LSL_RCERR_CAST_TIME_EXCEEDED = -3;
|
||||
|
||||
const S32 LSL_RC_REJECT_TYPES = 0;
|
||||
const S32 LSL_RC_DETECT_PHANTOM = 1;
|
||||
const S32 LSL_RC_DATA_FLAGS = 2;
|
||||
const S32 LSL_RC_MAX_HITS = 3;
|
||||
|
||||
const S32 LSL_RC_REJECT_AGENTS = 1;
|
||||
const S32 LSL_RC_REJECT_PHYSICAL = 2;
|
||||
const S32 LSL_RC_REJECT_NONPHYSICAL = 4;
|
||||
const S32 LSL_RC_REJECT_LAND = 8;
|
||||
|
||||
const S32 LSL_RC_GET_NORMAL = 1;
|
||||
const S32 LSL_RC_GET_ROOT_KEY = 2;
|
||||
const S32 LSL_RC_GET_LINK_NUM = 4;
|
||||
|
||||
// Estate management
|
||||
const S32 LSL_ESTATE_ACCESS_ALLOWED_AGENT_ADD = 4;
|
||||
const S32 LSL_ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 8;
|
||||
const S32 LSL_ESTATE_ACCESS_ALLOWED_GROUP_ADD = 16;
|
||||
const S32 LSL_ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 32;
|
||||
const S32 LSL_ESTATE_ACCESS_BANNED_AGENT_ADD = 64;
|
||||
const S32 LSL_ESTATE_ACCESS_BANNED_AGENT_REMOVE = 128;
|
||||
|
||||
// Key Frame Motion:
|
||||
const S32 LSL_KFM_COMMAND = 0;
|
||||
const S32 LSL_KFM_MODE = 1;
|
||||
const S32 LSL_KFM_DATA = 2;
|
||||
const S32 LSL_KFM_FORWARD = 0;
|
||||
const S32 LSL_KFM_LOOP = 1;
|
||||
const S32 LSL_KFM_PING_PONG = 2;
|
||||
const S32 LSL_KFM_REVERSE = 3;
|
||||
const S32 LSL_KFM_ROTATION = 1;
|
||||
const S32 LSL_KFM_TRANSLATION = 2;
|
||||
const S32 LSL_KFM_CMD_PLAY = 0;
|
||||
const S32 LSL_KFM_CMD_STOP = 1;
|
||||
const S32 LSL_KFM_CMD_PAUSE = 2;
|
||||
|
||||
// Second Life Server/12 12.04.30.255166 constants for llGetAgentList
|
||||
const S32 AGENT_LIST_PARCEL = 1;
|
||||
const S32 AGENT_LIST_PARCEL_OWNER = 2;
|
||||
const S32 AGENT_LIST_REGION = 4;
|
||||
|
||||
|
||||
// --- SL Constants ABOVE this line ---
|
||||
// --- OpenSim / Aurora-Sim constants Below ---
|
||||
// OpenSim Constants (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\LSL_Constants.cs)
|
||||
// Constants for cmWindlight (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\CM_Constants.cs)
|
||||
const S32 CHANGED_ANIMATION = 16384;
|
||||
const S32 PARCEL_DETAILS_CLAIMDATE = 10; // used by OpenSim osSetParcelDetails
|
||||
const S32 STATS_TIME_DILATION = 0;
|
||||
const S32 STATS_SIM_FPS = 1;
|
||||
const S32 STATS_PHYSICS_FPS = 2;
|
||||
const S32 STATS_AGENT_UPDATES = 3;
|
||||
const S32 STATS_ROOT_AGENTS = 4;
|
||||
const S32 STATS_CHILD_AGENTS = 5;
|
||||
const S32 STATS_TOTAL_PRIMS = 6;
|
||||
const S32 STATS_ACTIVE_PRIMS = 7;
|
||||
const S32 STATS_FRAME_MS = 8;
|
||||
const S32 STATS_NET_MS = 9;
|
||||
const S32 STATS_PHYSICS_MS = 10;
|
||||
const S32 STATS_IMAGE_MS = 11;
|
||||
const S32 STATS_OTHER_MS = 12;
|
||||
const S32 STATS_IN_PACKETS_PER_SECOND = 13;
|
||||
const S32 STATS_OUT_PACKETS_PER_SECOND = 14;
|
||||
const S32 STATS_UNACKED_BYTES = 15;
|
||||
const S32 STATS_AGENT_MS = 16;
|
||||
const S32 STATS_PENDING_DOWNLOADS = 17;
|
||||
const S32 STATS_PENDING_UPLOADS = 18;
|
||||
const S32 STATS_ACTIVE_SCRIPTS = 19;
|
||||
const S32 STATS_SCRIPT_LPS = 20;
|
||||
// osNPC
|
||||
const S32 OS_NPC_FLY = 0;
|
||||
const S32 OS_NPC_NO_FLY = 1;
|
||||
const S32 OS_NPC_LAND_AT_TARGET = 2;
|
||||
const S32 OS_NPC_SIT_NOW = 0;
|
||||
const U32 OS_NPC_CREATOR_OWNED = 0x1;
|
||||
const U32 OS_NPC_NOT_OWNED = 0x2;
|
||||
const U32 OS_NPC_SENSE_AS_AGENT = 0x4;
|
||||
const U32 OS_NPC_RUNNING = 4;
|
||||
// Lightshare / Windlight
|
||||
const S32 WL_WATER_COLOR = 0;
|
||||
const S32 WL_WATER_FOG_DENSITY_EXPONENT = 1;
|
||||
const S32 WL_UNDERWATER_FOG_MODIFIER = 2;
|
||||
const S32 WL_REFLECTION_WAVELET_SCALE = 3;
|
||||
const S32 WL_FRESNEL_SCALE = 4;
|
||||
const S32 WL_FRESNEL_OFFSET = 5;
|
||||
const S32 WL_REFRACT_SCALE_ABOVE = 6;
|
||||
const S32 WL_REFRACT_SCALE_BELOW = 7;
|
||||
const S32 WL_BLUR_MULTIPLIER = 8;
|
||||
const S32 WL_BIG_WAVE_DIRECTION = 9;
|
||||
const S32 WL_LITTLE_WAVE_DIRECTION = 10;
|
||||
const S32 WL_NORMAL_MAP_TEXTURE = 11;
|
||||
const S32 WL_HORIZON = 12;
|
||||
const S32 WL_HAZE_HORIZON = 13;
|
||||
const S32 WL_BLUE_DENSITY = 14;
|
||||
const S32 WL_HAZE_DENSITY = 15;
|
||||
const S32 WL_DENSITY_MULTIPLIER = 16;
|
||||
const S32 WL_DISTANCE_MULTIPLIER = 17;
|
||||
const S32 WL_MAX_ALTITUDE = 18;
|
||||
const S32 WL_SUN_MOON_COLOR = 19;
|
||||
const S32 WL_AMBIENT = 20;
|
||||
const S32 WL_EAST_ANGLE = 21;
|
||||
const S32 WL_SUN_GLOW_FOCUS = 22;
|
||||
const S32 WL_SUN_GLOW_SIZE = 23;
|
||||
const S32 WL_SCENE_GAMMA = 24;
|
||||
const S32 WL_STAR_BRIGHTNESS = 25;
|
||||
const S32 WL_CLOUD_COLOR = 26;
|
||||
const S32 WL_CLOUD_XY_DENSITY = 27;
|
||||
const S32 WL_CLOUD_COVERAGE = 28;
|
||||
const S32 WL_CLOUD_SCALE = 29;
|
||||
const S32 WL_CLOUD_DETAIL_XY_DENSITY = 30;
|
||||
const S32 WL_CLOUD_SCROLL_X = 31;
|
||||
const S32 WL_CLOUD_SCROLL_Y = 32;
|
||||
const S32 WL_CLOUD_SCROLL_Y_LOCK = 33;
|
||||
const S32 WL_CLOUD_SCROLL_X_LOCK = 34;
|
||||
const S32 WL_DRAW_CLASSIC_CLOUDS = 35;
|
||||
const S32 WL_SUN_MOON_POSITION = 36;
|
||||
// Aurora-Sim Constants (\Aurora\AuroraDotNetEngine\APIs\AA_Constants.cs) -->
|
||||
const S32 BOT_FOLLOW_FLAG_NONE = 0;
|
||||
const S32 BOT_FOLLOW_FLAG_INDEFINITELY = 1;
|
||||
const S32 BOT_FOLLOW_WALK = 0;
|
||||
const S32 BOT_FOLLOW_RUN = 1;
|
||||
const S32 BOT_FOLLOW_FLY = 2;
|
||||
const S32 BOT_FOLLOW_TELEPORT = 3;
|
||||
const S32 BOT_FOLLOW_WAIT = 4;
|
||||
const S32 BOT_FOLLOW_TRIGGER_HERE_EVENT = 1;
|
||||
const S32 BOT_FOLLOW_FLAG_FORCEDIRECTPATH = 4;
|
||||
// string constants from Aurora-Sim
|
||||
char const* const ENABLE_GRAVITY = "enable_gravity";
|
||||
char const* const GRAVITY_FORCE_X = "gravity_force_x";
|
||||
char const* const GRAVITY_FORCE_Y = "gravity_force_y";
|
||||
char const* const GRAVITY_FORCE_Z = "gravity_force_z";
|
||||
char const* const ADD_GRAVITY_POINT = "add_gravity_point";
|
||||
char const* const ADD_GRAVITY_FORCE = "add_gravity_force";
|
||||
char const* const START_TIME_REVERSAL_SAVING = "start_time_reversal_saving";
|
||||
char const* const STOP_TIME_REVERSAL_SAVING = "stop_time_reversal_saving";
|
||||
char const* const START_TIME_REVERSAL = "start_time_reversal";
|
||||
char const* const STOP_TIME_REVERSAL = "stop_time_reversal";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -523,7 +523,6 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
|
||||
|
||||
//EVENTUALLY REMOVE THESE:
|
||||
#include "llpointer.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llsafehandle.h"
|
||||
|
||||
|
||||
@@ -195,4 +195,13 @@
|
||||
# define LL_COMMON_API
|
||||
#endif // LL_COMMON_LINK_SHARED
|
||||
|
||||
// Darwin does not support thread-local data.
|
||||
#ifndef LL_DARWIN
|
||||
#if LL_WINDOWS
|
||||
#define ll_thread_local __declspec(thread)
|
||||
#else // Linux
|
||||
#define ll_thread_local __thread
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // not LL_LINDEN_PREPROCESSOR_H
|
||||
|
||||
@@ -376,24 +376,24 @@ private:
|
||||
// uses the MSVC compiler intrinsics __cpuid() and __rdtsc().
|
||||
|
||||
// Delays for the specified amount of milliseconds
|
||||
static void _Delay(unsigned int ms)
|
||||
static void _Delay(unsigned int ms)
|
||||
{
|
||||
LARGE_INTEGER freq, c1, c2;
|
||||
__int64 x;
|
||||
LARGE_INTEGER freq, c1, c2;
|
||||
__int64 x;
|
||||
|
||||
// Get High-Res Timer frequency
|
||||
// Get High-Res Timer frequency
|
||||
if (!QueryPerformanceFrequency(&freq))
|
||||
return;
|
||||
|
||||
|
||||
// Convert ms to High-Res Timer value
|
||||
x = freq.QuadPart/1000*ms;
|
||||
|
||||
// Get first snapshot of High-Res Timer value
|
||||
// Get first snapshot of High-Res Timer value
|
||||
QueryPerformanceCounter(&c1);
|
||||
do
|
||||
{
|
||||
// Get second snapshot
|
||||
QueryPerformanceCounter(&c2);
|
||||
// Get second snapshot
|
||||
QueryPerformanceCounter(&c2);
|
||||
}while(c2.QuadPart-c1.QuadPart < x);
|
||||
// Loop while (second-first < x)
|
||||
}
|
||||
|
||||
@@ -52,5 +52,4 @@ private:
|
||||
LLProcessorInfoImpl* mImpl;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif // LLPROCESSOR_H
|
||||
|
||||
@@ -38,14 +38,6 @@ LLRefCount::LLRefCount(const LLRefCount& other)
|
||||
: mRef(0)
|
||||
{
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
if(gAPRPoolp)
|
||||
{
|
||||
mMutexp = new LLMutex(gAPRPoolp) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMutexp = NULL ;
|
||||
}
|
||||
mCrashAtUnlock = FALSE ;
|
||||
#endif
|
||||
}
|
||||
@@ -60,14 +52,6 @@ LLRefCount::LLRefCount() :
|
||||
mRef(0)
|
||||
{
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
if(gAPRPoolp)
|
||||
{
|
||||
mMutexp = new LLMutex(gAPRPoolp) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMutexp = NULL ;
|
||||
}
|
||||
mCrashAtUnlock = FALSE ;
|
||||
#endif
|
||||
}
|
||||
@@ -78,29 +62,20 @@ LLRefCount::~LLRefCount()
|
||||
{
|
||||
llerrs << "deleting non-zero reference" << llendl;
|
||||
}
|
||||
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
if(gAPRPoolp)
|
||||
{
|
||||
delete mMutexp ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
void LLRefCount::ref() const
|
||||
{
|
||||
if(mMutexp)
|
||||
{
|
||||
if(mMutexp->isLocked())
|
||||
if(mMutex.isLocked())
|
||||
{
|
||||
mCrashAtUnlock = TRUE ;
|
||||
llerrs << "the mutex is locked by the thread: " << mLockedThreadID
|
||||
<< " Current thread: " << LLThread::currentID() << llendl ;
|
||||
<< " Current thread: " << AIThreadID() << llendl ;
|
||||
}
|
||||
|
||||
mMutexp->lock() ;
|
||||
mLockedThreadID = LLThread::currentID() ;
|
||||
mMutex.lock() ;
|
||||
mLockedThreadID.reset_inline();
|
||||
|
||||
mRef++;
|
||||
|
||||
@@ -108,27 +83,20 @@ void LLRefCount::ref() const
|
||||
{
|
||||
while(1); //crash here.
|
||||
}
|
||||
mMutexp->unlock() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRef++;
|
||||
}
|
||||
mMutex.unlock() ;
|
||||
}
|
||||
|
||||
S32 LLRefCount::unref() const
|
||||
{
|
||||
if(mMutexp)
|
||||
{
|
||||
if(mMutexp->isLocked())
|
||||
if(mMutex.isLocked())
|
||||
{
|
||||
mCrashAtUnlock = TRUE ;
|
||||
llerrs << "the mutex is locked by the thread: " << mLockedThreadID
|
||||
<< " Current thread: " << LLThread::currentID() << llendl ;
|
||||
<< " Current thread: " << AIThreadID() << llendl ;
|
||||
}
|
||||
|
||||
mMutexp->lock() ;
|
||||
mLockedThreadID = LLThread::currentID() ;
|
||||
mMutex.lock() ;
|
||||
mLockedThreadID.reset_inline();
|
||||
|
||||
llassert(mRef >= 1);
|
||||
if (0 == --mRef)
|
||||
@@ -137,7 +105,7 @@ S32 LLRefCount::unref() const
|
||||
{
|
||||
while(1); //crash here.
|
||||
}
|
||||
mMutexp->unlock() ;
|
||||
mMutex.unlock() ;
|
||||
|
||||
delete this;
|
||||
return 0;
|
||||
@@ -147,18 +115,7 @@ S32 LLRefCount::unref() const
|
||||
{
|
||||
while(1); //crash here.
|
||||
}
|
||||
mMutexp->unlock() ;
|
||||
mMutex.unlock() ;
|
||||
return mRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(mRef >= 1);
|
||||
if (0 == --mRef)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRef;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#define LL_REF_COUNT_DEBUG 0
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
class LLMutex ;
|
||||
#include "llthread.h" // LLMutexRootPool
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -80,8 +80,8 @@ private:
|
||||
mutable S32 mRef;
|
||||
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
LLMutex* mMutexp ;
|
||||
mutable U32 mLockedThreadID ;
|
||||
mutable LLMutexRootPool mMutex ;
|
||||
mutable AIThreadID mLockedThreadID ;
|
||||
mutable BOOL mCrashAtUnlock ;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -60,6 +60,9 @@ static const char LEGACY_NON_HEADER[] = "<llsd>";
|
||||
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
|
||||
const std::string LLSD_XML_HEADER("LLSD/XML");
|
||||
|
||||
//used to deflate a gzipped asset (currently used for navmeshes)
|
||||
#define windowBits 15
|
||||
#define ENABLE_ZLIB_GZIP 32
|
||||
/**
|
||||
* LLSDSerialize
|
||||
*/
|
||||
@@ -2172,3 +2175,80 @@ 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.
|
||||
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
|
||||
{
|
||||
U8* result = NULL;
|
||||
U32 cur_size = 0;
|
||||
z_stream strm;
|
||||
|
||||
const U32 CHUNK = 0x4000;
|
||||
|
||||
U8 *in = new U8[size];
|
||||
is.read((char*) in, size);
|
||||
|
||||
U8 out[CHUNK];
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = size;
|
||||
strm.next_in = in;
|
||||
|
||||
|
||||
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
|
||||
do
|
||||
{
|
||||
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:
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
|
||||
result = (U8*) realloc(result, cur_size + have);
|
||||
memcpy(result+cur_size, out, have);
|
||||
cur_size += have;
|
||||
|
||||
} while (ret == Z_OK);
|
||||
|
||||
inflateEnd(&strm);
|
||||
delete [] in;
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
free(result);
|
||||
valid = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//result now points to the decompressed LLSD block
|
||||
{
|
||||
outsize= cur_size;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -755,6 +755,9 @@ public:
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
|
||||
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)
|
||||
{
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
|
||||
@@ -791,4 +794,5 @@ public:
|
||||
//dirty little zip functions -- yell at davep
|
||||
LL_COMMON_API std::string zip_llsd(LLSD& data);
|
||||
LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
|
||||
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
|
||||
#endif // LL_LLSDSERIALIZE_H
|
||||
|
||||
152
indra/llcommon/llsortedvector.h
Normal file
152
indra/llcommon/llsortedvector.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @file llsortedvector.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2012-04-08
|
||||
* @brief LLSortedVector class wraps a vector that we maintain in sorted
|
||||
* order so we can perform binary-search lookups.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Copyright (c) 2012, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLSORTEDVECTOR_H)
|
||||
#define LL_LLSORTEDVECTOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/**
|
||||
* LLSortedVector contains a std::vector<std::pair> that we keep sorted on the
|
||||
* first of the pair. This makes insertion somewhat more expensive than simple
|
||||
* std::vector::push_back(), but allows us to use binary search for lookups.
|
||||
* It's intended for small aggregates where lookup is far more performance-
|
||||
* critical than insertion; in such cases a binary search on a small, sorted
|
||||
* std::vector can be more performant than a std::map lookup.
|
||||
*/
|
||||
template <typename KEY, typename VALUE>
|
||||
class LLSortedVector
|
||||
{
|
||||
public:
|
||||
typedef LLSortedVector<KEY, VALUE> self;
|
||||
typedef KEY key_type;
|
||||
typedef VALUE mapped_type;
|
||||
typedef std::pair<key_type, mapped_type> value_type;
|
||||
typedef std::vector<value_type> PairVector;
|
||||
typedef typename PairVector::iterator iterator;
|
||||
typedef typename PairVector::const_iterator const_iterator;
|
||||
|
||||
/// Empty
|
||||
LLSortedVector() {}
|
||||
|
||||
/// Fixed initial size
|
||||
LLSortedVector(std::size_t size):
|
||||
mVector(size)
|
||||
{}
|
||||
|
||||
/// Bulk load
|
||||
template <typename ITER>
|
||||
LLSortedVector(ITER begin, ITER end):
|
||||
mVector(begin, end)
|
||||
{
|
||||
// Allow caller to dump in a bunch of (pairs convertible to)
|
||||
// value_type if desired, but make sure we sort afterwards.
|
||||
std::sort(mVector.begin(), mVector.end());
|
||||
}
|
||||
|
||||
/// insert(key, value)
|
||||
std::pair<iterator, bool> insert(const key_type& key, const mapped_type& value)
|
||||
{
|
||||
return insert(value_type(key, value));
|
||||
}
|
||||
|
||||
/// insert(value_type)
|
||||
std::pair<iterator, bool> insert(const value_type& pair)
|
||||
{
|
||||
typedef std::pair<iterator, bool> iterbool;
|
||||
iterator found = std::lower_bound(mVector.begin(), mVector.end(), pair,
|
||||
less<value_type>());
|
||||
// have to check for end() before it's even valid to dereference
|
||||
if (found == mVector.end())
|
||||
{
|
||||
std::size_t index(mVector.size());
|
||||
mVector.push_back(pair);
|
||||
// don't forget that push_back() invalidates 'found'
|
||||
return iterbool(mVector.begin() + index, true);
|
||||
}
|
||||
if (found->first == pair.first)
|
||||
{
|
||||
return iterbool(found, false);
|
||||
}
|
||||
// remember that insert() invalidates 'found' -- save index
|
||||
std::size_t index(found - mVector.begin());
|
||||
mVector.insert(found, pair);
|
||||
// okay, convert from index back to iterator
|
||||
return iterbool(mVector.begin() + index, true);
|
||||
}
|
||||
|
||||
iterator begin() { return mVector.begin(); }
|
||||
iterator end() { return mVector.end(); }
|
||||
const_iterator begin() const { return mVector.begin(); }
|
||||
const_iterator end() const { return mVector.end(); }
|
||||
|
||||
bool empty() const { return mVector.empty(); }
|
||||
std::size_t size() const { return mVector.size(); }
|
||||
|
||||
/// find
|
||||
iterator find(const key_type& key)
|
||||
{
|
||||
iterator found = std::lower_bound(mVector.begin(), mVector.end(),
|
||||
value_type(key, mapped_type()),
|
||||
less<value_type>());
|
||||
if (found == mVector.end() || found->first != key)
|
||||
return mVector.end();
|
||||
return found;
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& key) const
|
||||
{
|
||||
return const_cast<self*>(this)->find(key);
|
||||
}
|
||||
|
||||
private:
|
||||
// Define our own 'less' comparator so we can specialize without messing
|
||||
// with std::less.
|
||||
template <typename T>
|
||||
struct less: public std::less<T> {};
|
||||
|
||||
// Specialize 'less' for an LLSortedVector::value_type involving
|
||||
// std::type_info*. This is one of LLSortedVector's foremost use cases. We
|
||||
// specialize 'less' rather than just defining a specific comparator
|
||||
// because LLSortedVector should be usable for other key_types as well.
|
||||
template <typename T>
|
||||
struct less< std::pair<std::type_info*, T> >:
|
||||
public std::binary_function<std::pair<std::type_info*, T>,
|
||||
std::pair<std::type_info*, T>,
|
||||
bool>
|
||||
{
|
||||
bool operator()(const std::pair<std::type_info*, T>& lhs,
|
||||
const std::pair<std::type_info*, T>& rhs) const
|
||||
{
|
||||
return lhs.first->before(*rhs.first);
|
||||
}
|
||||
};
|
||||
|
||||
// Same as above, but with const std::type_info*.
|
||||
template <typename T>
|
||||
struct less< std::pair<const std::type_info*, T> >:
|
||||
public std::binary_function<std::pair<const std::type_info*, T>,
|
||||
std::pair<const std::type_info*, T>,
|
||||
bool>
|
||||
{
|
||||
bool operator()(const std::pair<const std::type_info*, T>& lhs,
|
||||
const std::pair<const std::type_info*, T>& rhs) const
|
||||
{
|
||||
return lhs.first->before(*rhs.first);
|
||||
}
|
||||
};
|
||||
|
||||
PairVector mVector;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLSORTEDVECTOR_H) */
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include "stdtypes.h" // llcommon/stdtypes.h, needed for S32 and U32.
|
||||
#include <typeinfo>
|
||||
|
||||
// Use to compare the first element only of a pair
|
||||
// e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
|
||||
@@ -477,4 +477,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
|
||||
return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare std::type_info* pointers a la std::less. We break this out as a
|
||||
* separate function for use in two different std::less specializations.
|
||||
*/
|
||||
inline
|
||||
bool before(const std::type_info* lhs, const std::type_info* rhs)
|
||||
{
|
||||
#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
||||
// If we're building on Linux with gcc, and it's either gcc 3.x or
|
||||
// 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on
|
||||
// Mac too, and some people build with gcc on Windows (cygwin or mingw).
|
||||
// On Linux, different load modules may produce different type_info*
|
||||
// pointers for the same type. Have to compare name strings to get good
|
||||
// results.
|
||||
return strcmp(lhs->name(), rhs->name()) < 0;
|
||||
#else // not Linux, or gcc 4.4+
|
||||
// Just use before(), as we normally would
|
||||
return lhs->before(*rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialize std::less<std::type_info*> to use std::type_info::before().
|
||||
* See MAINT-1175. It is NEVER a good idea to directly compare std::type_info*
|
||||
* because, on Linux, you might get different std::type_info* pointers for the
|
||||
* same type (from different load modules)!
|
||||
*/
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct less<const std::type_info*>:
|
||||
public std::binary_function<const std::type_info*, const std::type_info*, bool>
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return before(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct less<std::type_info*>:
|
||||
public std::binary_function<std::type_info*, std::type_info*, bool>
|
||||
{
|
||||
bool operator()(std::type_info* lhs, std::type_info* rhs) const
|
||||
{
|
||||
return before(lhs, rhs);
|
||||
}
|
||||
};
|
||||
} // std
|
||||
|
||||
#endif // LL_LLSTL_H
|
||||
|
||||
@@ -42,10 +42,10 @@ template <class Object> class LLStrider
|
||||
U8* mBytep;
|
||||
};
|
||||
U32 mSkip;
|
||||
//U32 mTypeSize;
|
||||
|
||||
public:
|
||||
|
||||
LLStrider() { mObjectp = NULL; /*mTypeSize = */mSkip = sizeof(Object); }
|
||||
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
|
||||
~LLStrider() { }
|
||||
|
||||
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
|
||||
@@ -60,9 +60,6 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
//void setTypeSize (S32 typeBytes){ mTypeSize = (typeBytes ? typeBytes : sizeof(Object)); }
|
||||
|
||||
//bool isStrided() const { return mTypeSize != mSkip; }
|
||||
void skip(const U32 index) { mBytep += mSkip*index;}
|
||||
U32 getSkip() const { return mSkip; }
|
||||
Object* get() { return mObjectp; }
|
||||
@@ -70,72 +67,9 @@ public:
|
||||
Object& operator *() { return *mObjectp; }
|
||||
Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
|
||||
Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
|
||||
|
||||
Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
|
||||
/*void assignArray(U8* __restrict source, const size_t elem_size, const size_t elem_count)
|
||||
{
|
||||
llassert_always(sizeof(Object) <= elem_size);
|
||||
|
||||
U8* __restrict dest = mBytep; //refer to dest instead of mBytep to benefit from __restrict hint
|
||||
const U32 bytes = elem_size * elem_count; //total bytes to copy from source to dest
|
||||
|
||||
//stride == sizeof(element) implies entire buffer is unstrided and thus memcpy-able, provided source buffer elements match in size.
|
||||
//Because LLStrider is often passed an LLVector3 even if the reprensentation is LLVector4 in the vertex buffer, mTypeSize is set to
|
||||
//the TRUE vbo datatype size via VertexBufferStrider::get
|
||||
if(!isStrided() && mTypeSize == elem_size)
|
||||
{
|
||||
if(bytes >= sizeof(LLVector4) * 4) //Should be able to pull at least 3 16byte blocks from this. Smaller isn't really beneficial.
|
||||
{
|
||||
U8* __restrict aligned_source = LL_NEXT_ALIGNED_ADDRESS(source);
|
||||
U8* __restrict aligned_dest = LL_NEXT_ALIGNED_ADDRESS(dest);
|
||||
const U32 source_offset = aligned_source - source; //Offset to first aligned location in source buffer.
|
||||
const U32 dest_offset = aligned_dest - dest; //Offset to first aligned location in dest buffer.
|
||||
llassert_always(source_offset < 16);
|
||||
llassert_always(dest_offset < 16);
|
||||
if(source_offset == dest_offset) //delta to aligned location matches between source and destination! _mm_*_ps should be viable.
|
||||
{
|
||||
const U32 end_offset = (bytes - source_offset) % sizeof(LLVector4); //buffers may not neatly end on a 16byte alignment boundary.
|
||||
const U32 aligned_bytes = bytes - source_offset - end_offset; //how many bytes to copy from aligned start to aligned end.
|
||||
|
||||
llassert_always(aligned_bytes > 0);
|
||||
|
||||
if(source_offset) //memcpy up to the aligned location if needed
|
||||
memcpy(dest,source,source_offset);
|
||||
LLVector4a::memcpyNonAliased16((F32*) aligned_dest, (F32*) aligned_source, aligned_bytes);
|
||||
if(end_offset) //memcpy to the very end if needed.
|
||||
memcpy(aligned_dest+aligned_bytes,aligned_source+aligned_bytes,end_offset);
|
||||
}
|
||||
else //buffers non-uniformly offset from aligned location. Using _mm_*u_ps.
|
||||
{
|
||||
U32 end = bytes/sizeof(LLVector4); //sizeof(LLVector4) = 16 bytes = 128 bits
|
||||
|
||||
llassert_always(end > 0);
|
||||
|
||||
__m128* dst = (__m128*) dest;
|
||||
__m128* src = (__m128*) source;
|
||||
|
||||
for (U32 i = 0; i < end; i++) //copy 128bit chunks
|
||||
{
|
||||
__m128 res = _mm_loadu_ps((F32*)&src[i]);
|
||||
_mm_storeu_ps((F32*)&dst[i], res);
|
||||
}
|
||||
end*=16;//Convert to real byte offset
|
||||
if(end < bytes) //just memcopy the rest
|
||||
memcpy(dest+end,source+end,bytes-end);
|
||||
}
|
||||
}
|
||||
else //Too small. just do a simple memcpy.
|
||||
memcpy(dest,source,bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(U32 i=0;i<elem_count;i++)
|
||||
{
|
||||
memcpy(dest,source,sizeof(Object));
|
||||
dest+=mSkip;
|
||||
source+=elem_size;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_LLSTRIDER_H
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#include "llstring.h"
|
||||
#include "llerror.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -604,16 +603,10 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
|
||||
}
|
||||
const char CR = 13;
|
||||
|
||||
S32 i = utf8str.find(CR);
|
||||
if(i == std::string::npos)
|
||||
return utf8str; //Save us from a reserve call.
|
||||
|
||||
std::string out;
|
||||
out.reserve(utf8str.length());
|
||||
const S32 len = (S32)utf8str.length();
|
||||
if(i)
|
||||
out.assign(utf8str,0,i); //Copy previous text to buffer
|
||||
for( ++i; i < len; i++ )
|
||||
for( S32 i = 0; i < len; i++ )
|
||||
{
|
||||
if( utf8str[i] != CR )
|
||||
{
|
||||
|
||||
@@ -35,11 +35,10 @@
|
||||
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <locale>
|
||||
#include <iomanip>
|
||||
#include "llsd.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
#include <wctype.h>
|
||||
@@ -47,6 +46,7 @@
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#if LL_SOLARIS
|
||||
// stricmp and strnicmp do not exist on Solaris:
|
||||
@@ -246,40 +246,77 @@ private:
|
||||
static std::string sLocale;
|
||||
|
||||
public:
|
||||
typedef typename std::basic_string<T>::size_type size_type;
|
||||
typedef std::basic_string<T> string_type;
|
||||
typedef typename string_type::size_type size_type;
|
||||
|
||||
public:
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Static Utility functions that operate on std::strings
|
||||
|
||||
static const std::basic_string<T> null;
|
||||
static const string_type null;
|
||||
|
||||
typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
|
||||
LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
|
||||
LL_COMMON_API static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
|
||||
LL_COMMON_API static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
|
||||
LL_COMMON_API static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
|
||||
LL_COMMON_API static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
|
||||
LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
|
||||
LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
|
||||
/// considers any sequence of delims as a single field separator
|
||||
LL_COMMON_API static void getTokens(const string_type& instr,
|
||||
std::vector<string_type >& tokens,
|
||||
const string_type& delims);
|
||||
/// like simple scan overload, but returns scanned vector
|
||||
static std::vector<string_type> getTokens(const string_type& instr,
|
||||
const string_type& delims);
|
||||
/// add support for keep_delims and quotes (either could be empty string)
|
||||
static void getTokens(const string_type& instr,
|
||||
std::vector<string_type>& tokens,
|
||||
const string_type& drop_delims,
|
||||
const string_type& keep_delims,
|
||||
const string_type& quotes=string_type());
|
||||
/// like keep_delims-and-quotes overload, but returns scanned vector
|
||||
static std::vector<string_type> getTokens(const string_type& instr,
|
||||
const string_type& drop_delims,
|
||||
const string_type& keep_delims,
|
||||
const string_type& quotes=string_type());
|
||||
/// add support for escapes (could be empty string)
|
||||
static void getTokens(const string_type& instr,
|
||||
std::vector<string_type>& tokens,
|
||||
const string_type& drop_delims,
|
||||
const string_type& keep_delims,
|
||||
const string_type& quotes,
|
||||
const string_type& escapes);
|
||||
/// like escapes overload, but returns scanned vector
|
||||
static std::vector<string_type> getTokens(const string_type& instr,
|
||||
const string_type& drop_delims,
|
||||
const string_type& keep_delims,
|
||||
const string_type& quotes,
|
||||
const string_type& escapes);
|
||||
|
||||
LL_COMMON_API static void formatNumber(string_type& numStr, string_type decimals);
|
||||
LL_COMMON_API static bool formatDatetime(string_type& replacement, string_type token, string_type param, S32 secFromEpoch);
|
||||
LL_COMMON_API static S32 format(string_type& s, const format_map_t& substitutions);
|
||||
LL_COMMON_API static S32 format(string_type& s, const LLSD& substitutions);
|
||||
LL_COMMON_API static bool simpleReplacement(string_type& replacement, string_type token, const format_map_t& substitutions);
|
||||
LL_COMMON_API static bool simpleReplacement(string_type& replacement, string_type token, const LLSD& substitutions);
|
||||
LL_COMMON_API static void setLocale (std::string inLocale);
|
||||
LL_COMMON_API static std::string getLocale (void);
|
||||
|
||||
static bool isValidIndex(const std::basic_string<T>& string, size_type i)
|
||||
static bool isValidIndex(const string_type& string, size_type i)
|
||||
{
|
||||
return !string.empty() && (0 <= i) && (i <= string.size());
|
||||
}
|
||||
|
||||
static void trimHead(std::basic_string<T>& string);
|
||||
static void trimTail(std::basic_string<T>& string);
|
||||
static void trim(std::basic_string<T>& string) { trimHead(string); trimTail(string); }
|
||||
static void truncate(std::basic_string<T>& string, size_type count);
|
||||
static bool contains(const string_type& string, T c, size_type i=0)
|
||||
{
|
||||
return string.find(c, i) != string_type::npos;
|
||||
}
|
||||
|
||||
static void toUpper(std::basic_string<T>& string);
|
||||
static void toLower(std::basic_string<T>& string);
|
||||
static void trimHead(string_type& string);
|
||||
static void trimTail(string_type& string);
|
||||
static void trim(string_type& string) { trimHead(string); trimTail(string); }
|
||||
static void truncate(string_type& string, size_type count);
|
||||
|
||||
static void toUpper(string_type& string);
|
||||
static void toLower(string_type& string);
|
||||
|
||||
// True if this is the head of s.
|
||||
static BOOL isHead( const std::basic_string<T>& string, const T* s );
|
||||
static BOOL isHead( const string_type& string, const T* s );
|
||||
|
||||
/**
|
||||
* @brief Returns true if string starts with substr
|
||||
@@ -287,8 +324,8 @@ public:
|
||||
* If etither string or substr are empty, this method returns false.
|
||||
*/
|
||||
static bool startsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr);
|
||||
const string_type& string,
|
||||
const string_type& substr);
|
||||
|
||||
/**
|
||||
* @brief Returns true if string ends in substr
|
||||
@@ -296,19 +333,32 @@ public:
|
||||
* If etither string or substr are empty, this method returns false.
|
||||
*/
|
||||
static bool endsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr);
|
||||
const string_type& string,
|
||||
const string_type& substr);
|
||||
|
||||
static void addCRLF(std::basic_string<T>& string);
|
||||
static void removeCRLF(std::basic_string<T>& string);
|
||||
static void addCRLF(string_type& string);
|
||||
static void removeCRLF(string_type& string);
|
||||
|
||||
static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab );
|
||||
static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement );
|
||||
static void replaceChar( std::basic_string<T>& string, T target, T replacement );
|
||||
static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement );
|
||||
static void replaceTabsWithSpaces( string_type& string, size_type spaces_per_tab );
|
||||
static void replaceNonstandardASCII( string_type& string, T replacement );
|
||||
static void replaceChar( string_type& string, T target, T replacement );
|
||||
static void replaceString( string_type& string, string_type target, string_type replacement );
|
||||
|
||||
static BOOL containsNonprintable(const std::basic_string<T>& string);
|
||||
static void stripNonprintable(std::basic_string<T>& string);
|
||||
static BOOL containsNonprintable(const string_type& string);
|
||||
static void stripNonprintable(string_type& string);
|
||||
|
||||
/**
|
||||
* Double-quote an argument string if needed, unless it's already
|
||||
* double-quoted. Decide whether it's needed based on the presence of any
|
||||
* character in @a triggers (default space or double-quote). If we quote
|
||||
* it, escape any embedded double-quote with the @a escape string (default
|
||||
* backslash).
|
||||
*
|
||||
* Passing triggers="" means always quote, unless it's already double-quoted.
|
||||
*/
|
||||
static string_type quote(const string_type& str,
|
||||
const string_type& triggers=" \"",
|
||||
const string_type& escape="\\");
|
||||
|
||||
/**
|
||||
* @brief Unsafe way to make ascii characters. You should probably
|
||||
@@ -317,19 +367,19 @@ public:
|
||||
* The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
|
||||
* should work.
|
||||
*/
|
||||
static void _makeASCII(std::basic_string<T>& string);
|
||||
static void _makeASCII(string_type& string);
|
||||
static bool _isASCII(std::basic_string<T> const& string);
|
||||
|
||||
// Conversion to other data types
|
||||
static BOOL convertToBOOL(const std::basic_string<T>& string, BOOL& value);
|
||||
static BOOL convertToU8(const std::basic_string<T>& string, U8& value);
|
||||
static BOOL convertToS8(const std::basic_string<T>& string, S8& value);
|
||||
static BOOL convertToS16(const std::basic_string<T>& string, S16& value);
|
||||
static BOOL convertToU16(const std::basic_string<T>& string, U16& value);
|
||||
static BOOL convertToU32(const std::basic_string<T>& string, U32& value);
|
||||
static BOOL convertToS32(const std::basic_string<T>& string, S32& value);
|
||||
static BOOL convertToF32(const std::basic_string<T>& string, F32& value);
|
||||
static BOOL convertToF64(const std::basic_string<T>& string, F64& value);
|
||||
static BOOL convertToBOOL(const string_type& string, BOOL& value);
|
||||
static BOOL convertToU8(const string_type& string, U8& value);
|
||||
static BOOL convertToS8(const string_type& string, S8& value);
|
||||
static BOOL convertToS16(const string_type& string, S16& value);
|
||||
static BOOL convertToU16(const string_type& string, U16& value);
|
||||
static BOOL convertToU32(const string_type& string, U32& value);
|
||||
static BOOL convertToS32(const string_type& string, S32& value);
|
||||
static BOOL convertToF32(const string_type& string, F32& value);
|
||||
static BOOL convertToF64(const string_type& string, F64& value);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Utility functions for working with char*'s and strings
|
||||
@@ -337,24 +387,24 @@ public:
|
||||
// Like strcmp but also handles empty strings. Uses
|
||||
// current locale.
|
||||
static S32 compareStrings(const T* lhs, const T* rhs);
|
||||
static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
|
||||
static S32 compareStrings(const string_type& lhs, const string_type& rhs);
|
||||
|
||||
// case insensitive version of above. Uses current locale on
|
||||
// Win32, and falls back to a non-locale aware comparison on
|
||||
// Linux.
|
||||
static S32 compareInsensitive(const T* lhs, const T* rhs);
|
||||
static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
|
||||
static S32 compareInsensitive(const string_type& lhs, const string_type& rhs);
|
||||
|
||||
// Case sensitive comparison with good handling of numbers. Does not use current locale.
|
||||
// a.k.a. strdictcmp()
|
||||
static S32 compareDict(const std::basic_string<T>& a, const std::basic_string<T>& b);
|
||||
static S32 compareDict(const string_type& a, const string_type& b);
|
||||
|
||||
// Case *in*sensitive comparison with good handling of numbers. Does not use current locale.
|
||||
// a.k.a. strdictcmp()
|
||||
static S32 compareDictInsensitive(const std::basic_string<T>& a, const std::basic_string<T>& b);
|
||||
static S32 compareDictInsensitive(const string_type& a, const string_type& b);
|
||||
|
||||
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
|
||||
static BOOL precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b );
|
||||
static BOOL precedesDict( const string_type& a, const string_type& b );
|
||||
|
||||
// A replacement for strncpy.
|
||||
// If the dst buffer is dst_size bytes long or more, ensures that dst is null terminated and holds
|
||||
@@ -362,7 +412,7 @@ public:
|
||||
static void copy(T* dst, const T* src, size_type dst_size);
|
||||
|
||||
// Copies src into dst at a given offset.
|
||||
static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
|
||||
static void copyInto(string_type& dst, const string_type& src, size_type offset);
|
||||
|
||||
static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
|
||||
|
||||
@@ -372,7 +422,7 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
|
||||
LL_COMMON_API static size_type getSubstitution(const string_type& instr, size_type& start, std::vector<string_type >& tokens);
|
||||
};
|
||||
|
||||
template<class T> const std::basic_string<T> LLStringUtilBase<T>::null;
|
||||
@@ -650,6 +700,321 @@ namespace LLStringFn
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
template <class T>
|
||||
std::vector<typename LLStringUtilBase<T>::string_type>
|
||||
LLStringUtilBase<T>::getTokens(const string_type& instr, const string_type& delims)
|
||||
{
|
||||
std::vector<string_type> tokens;
|
||||
getTokens(instr, tokens, delims);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// static
|
||||
template <class T>
|
||||
std::vector<typename LLStringUtilBase<T>::string_type>
|
||||
LLStringUtilBase<T>::getTokens(const string_type& instr,
|
||||
const string_type& drop_delims,
|
||||
const string_type& keep_delims,
|
||||
const string_type& quotes)
|
||||
{
|
||||
std::vector<string_type> tokens;
|
||||
getTokens(instr, tokens, drop_delims, keep_delims, quotes);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// static
|
||||
template <class T>
|
||||
std::vector<typename LLStringUtilBase<T>::string_type>
|
||||
LLStringUtilBase<T>::getTokens(const string_type& instr,
|
||||
const string_type& drop_delims,
|
||||
const string_type& keep_delims,
|
||||
const string_type& quotes,
|
||||
const string_type& escapes)
|
||||
{
|
||||
std::vector<string_type> tokens;
|
||||
getTokens(instr, tokens, drop_delims, keep_delims, quotes, escapes);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
namespace LLStringUtilBaseImpl
|
||||
{
|
||||
|
||||
/**
|
||||
* Input string scanner helper for getTokens(), or really any other
|
||||
* character-parsing routine that may have to deal with escape characters.
|
||||
* This implementation defines the concept (also an interface, should you
|
||||
* choose to implement the concept by subclassing) and provides trivial
|
||||
* implementations for a string @em without escape processing.
|
||||
*/
|
||||
template <class T>
|
||||
struct InString
|
||||
{
|
||||
typedef std::basic_string<T> string_type;
|
||||
typedef typename string_type::const_iterator const_iterator;
|
||||
|
||||
InString(const_iterator b, const_iterator e):
|
||||
mIter(b),
|
||||
mEnd(e)
|
||||
{}
|
||||
virtual ~InString() {}
|
||||
|
||||
bool done() const { return mIter == mEnd; }
|
||||
/// Is the current character (*mIter) escaped? This implementation can
|
||||
/// answer trivially because it doesn't support escapes.
|
||||
virtual bool escaped() const { return false; }
|
||||
/// Obtain the current character and advance @c mIter.
|
||||
virtual T next() { return *mIter++; }
|
||||
/// Does the current character match specified character?
|
||||
virtual bool is(T ch) const { return (! done()) && *mIter == ch; }
|
||||
/// Is the current character any one of the specified characters?
|
||||
virtual bool oneof(const string_type& delims) const
|
||||
{
|
||||
return (! done()) && LLStringUtilBase<T>::contains(delims, *mIter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan forward from @from until either @a delim or end. This is primarily
|
||||
* useful for processing quoted substrings.
|
||||
*
|
||||
* If we do see @a delim, append everything from @from until (excluding)
|
||||
* @a delim to @a into, advance @c mIter to skip @a delim, and return @c
|
||||
* true.
|
||||
*
|
||||
* If we do not see @a delim, do not alter @a into or @c mIter and return
|
||||
* @c false. Do not pass GO, do not collect $200.
|
||||
*
|
||||
* @note The @c false case described above implements normal getTokens()
|
||||
* treatment of an unmatched open quote: treat the quote character as if
|
||||
* escaped, that is, simply collect it as part of the current token. Other
|
||||
* plausible behaviors directly affect the way getTokens() deals with an
|
||||
* unmatched quote: e.g. throwing an exception to treat it as an error, or
|
||||
* assuming a close quote beyond end of string (in which case return @c
|
||||
* true).
|
||||
*/
|
||||
virtual bool collect_until(string_type& into, const_iterator from, T delim)
|
||||
{
|
||||
const_iterator found = std::find(from, mEnd, delim);
|
||||
// If we didn't find delim, change nothing, just tell caller.
|
||||
if (found == mEnd)
|
||||
return false;
|
||||
// Found delim! Append everything between from and found.
|
||||
into.append(from, found);
|
||||
// advance past delim in input
|
||||
mIter = found + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const_iterator mIter, mEnd;
|
||||
};
|
||||
|
||||
/// InString subclass that handles escape characters
|
||||
template <class T>
|
||||
class InEscString: public InString<T>
|
||||
{
|
||||
public:
|
||||
typedef InString<T> super;
|
||||
typedef typename super::string_type string_type;
|
||||
typedef typename super::const_iterator const_iterator;
|
||||
using super::done;
|
||||
using super::mIter;
|
||||
using super::mEnd;
|
||||
|
||||
InEscString(const_iterator b, const_iterator e, const string_type& escapes):
|
||||
super(b, e),
|
||||
mEscapes(escapes)
|
||||
{
|
||||
// Even though we've already initialized 'mIter' via our base-class
|
||||
// constructor, set it again to check for initial escape char.
|
||||
setiter(b);
|
||||
}
|
||||
|
||||
/// This implementation uses the answer cached by setiter().
|
||||
virtual bool escaped() const { return mIsEsc; }
|
||||
virtual T next()
|
||||
{
|
||||
// If we're looking at the escape character of an escape sequence,
|
||||
// skip that character. This is the one time we can modify 'mIter'
|
||||
// without using setiter: for this one case we DO NOT CARE if the
|
||||
// escaped character is itself an escape.
|
||||
if (mIsEsc)
|
||||
++mIter;
|
||||
// If we were looking at an escape character, this is the escaped
|
||||
// character; otherwise it's just the next character.
|
||||
T result(*mIter);
|
||||
// Advance mIter, checking for escape sequence.
|
||||
setiter(mIter + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual bool is(T ch) const
|
||||
{
|
||||
// Like base-class is(), except that an escaped character matches
|
||||
// nothing.
|
||||
return (! done()) && (! mIsEsc) && *mIter == ch;
|
||||
}
|
||||
|
||||
virtual bool oneof(const string_type& delims) const
|
||||
{
|
||||
// Like base-class oneof(), except that an escaped character matches
|
||||
// nothing.
|
||||
return (! done()) && (! mIsEsc) && LLStringUtilBase<T>::contains(delims, *mIter);
|
||||
}
|
||||
|
||||
virtual bool collect_until(string_type& into, const_iterator from, T delim)
|
||||
{
|
||||
// Deal with escapes in the characters we collect; that is, an escaped
|
||||
// character must become just that character without the preceding
|
||||
// escape. Collect characters in a separate string rather than
|
||||
// directly appending to 'into' in case we do not find delim, in which
|
||||
// case we're supposed to leave 'into' unmodified.
|
||||
string_type collected;
|
||||
// For scanning purposes, we're going to work directly with 'mIter'.
|
||||
// Save its current value in case we fail to see delim.
|
||||
const_iterator save_iter(mIter);
|
||||
// Okay, set 'mIter', checking for escape.
|
||||
setiter(from);
|
||||
while (! done())
|
||||
{
|
||||
// If we see an unescaped delim, stop and report success.
|
||||
if ((! mIsEsc) && *mIter == delim)
|
||||
{
|
||||
// Append collected chars to 'into'.
|
||||
into.append(collected);
|
||||
// Don't forget to advance 'mIter' past delim.
|
||||
setiter(mIter + 1);
|
||||
return true;
|
||||
}
|
||||
// We're not at end, and either we're not looking at delim or it's
|
||||
// escaped. Collect this character and keep going.
|
||||
collected.push_back(next());
|
||||
}
|
||||
// Here we hit 'mEnd' without ever seeing delim. Restore mIter and tell
|
||||
// caller.
|
||||
setiter(save_iter);
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void setiter(const_iterator i)
|
||||
{
|
||||
mIter = i;
|
||||
|
||||
// Every time we change 'mIter', set 'mIsEsc' to be able to repetitively
|
||||
// answer escaped() without having to rescan 'mEscapes'. mIsEsc caches
|
||||
// contains(mEscapes, *mIter).
|
||||
|
||||
// We're looking at an escaped char if we're not already at end (that
|
||||
// is, *mIter is even meaningful); if *mIter is in fact one of the
|
||||
// specified escape characters; and if there's one more character
|
||||
// following it. That is, if an escape character is the very last
|
||||
// character of the input string, it loses its special meaning.
|
||||
mIsEsc = (! done()) &&
|
||||
LLStringUtilBase<T>::contains(mEscapes, *mIter) &&
|
||||
(mIter+1) != mEnd;
|
||||
}
|
||||
|
||||
const string_type mEscapes;
|
||||
bool mIsEsc;
|
||||
};
|
||||
|
||||
/// getTokens() implementation based on InString concept
|
||||
template <typename INSTRING, typename string_type>
|
||||
void getTokens(INSTRING& instr, std::vector<string_type>& tokens,
|
||||
const string_type& drop_delims, const string_type& keep_delims,
|
||||
const string_type& quotes)
|
||||
{
|
||||
// There are times when we want to match either drop_delims or
|
||||
// keep_delims. Concatenate them up front to speed things up.
|
||||
string_type all_delims(drop_delims + keep_delims);
|
||||
// no tokens yet
|
||||
tokens.clear();
|
||||
|
||||
// try for another token
|
||||
while (! instr.done())
|
||||
{
|
||||
// scan past any drop_delims
|
||||
while (instr.oneof(drop_delims))
|
||||
{
|
||||
// skip this drop_delim
|
||||
instr.next();
|
||||
// but if that was the end of the string, done
|
||||
if (instr.done())
|
||||
return;
|
||||
}
|
||||
// found the start of another token: make a slot for it
|
||||
tokens.push_back(string_type());
|
||||
if (instr.oneof(keep_delims))
|
||||
{
|
||||
// *iter is a keep_delim, a token of exactly 1 character. Append
|
||||
// that character to the new token and proceed.
|
||||
tokens.back().push_back(instr.next());
|
||||
continue;
|
||||
}
|
||||
// Here we have a non-delimiter token, which might consist of a mix of
|
||||
// quoted and unquoted parts. Use bash rules for quoting: you can
|
||||
// embed a quoted substring in the midst of an unquoted token (e.g.
|
||||
// ~/"sub dir"/myfile.txt); you can ram two quoted substrings together
|
||||
// to make a single token (e.g. 'He said, "'"Don't."'"'). We diverge
|
||||
// from bash in that bash considers an unmatched quote an error. Our
|
||||
// param signature doesn't allow for errors, so just pretend it's not
|
||||
// a quote and embed it.
|
||||
// At this level, keep scanning until we hit the next delimiter of
|
||||
// either type (drop_delims or keep_delims).
|
||||
while (! instr.oneof(all_delims))
|
||||
{
|
||||
// If we're looking at an open quote, search forward for
|
||||
// a close quote, collecting characters along the way.
|
||||
if (instr.oneof(quotes) &&
|
||||
instr.collect_until(tokens.back(), instr.mIter+1, *instr.mIter))
|
||||
{
|
||||
// collect_until is cleverly designed to do exactly what we
|
||||
// need here. No further action needed if it returns true.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Either *iter isn't a quote, or there's no matching close
|
||||
// quote: in other words, just an ordinary char. Append it to
|
||||
// current token.
|
||||
tokens.back().push_back(instr.next());
|
||||
}
|
||||
// having scanned that segment of this token, if we've reached the
|
||||
// end of the string, we're done
|
||||
if (instr.done())
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LLStringUtilBaseImpl
|
||||
|
||||
// static
|
||||
template <class T>
|
||||
void LLStringUtilBase<T>::getTokens(const string_type& string, std::vector<string_type>& tokens,
|
||||
const string_type& drop_delims, const string_type& keep_delims,
|
||||
const string_type& quotes)
|
||||
{
|
||||
// Because this overload doesn't support escapes, use simple InString to
|
||||
// manage input range.
|
||||
LLStringUtilBaseImpl::InString<T> instring(string.begin(), string.end());
|
||||
LLStringUtilBaseImpl::getTokens(instring, tokens, drop_delims, keep_delims, quotes);
|
||||
}
|
||||
|
||||
// static
|
||||
template <class T>
|
||||
void LLStringUtilBase<T>::getTokens(const string_type& string, std::vector<string_type>& tokens,
|
||||
const string_type& drop_delims, const string_type& keep_delims,
|
||||
const string_type& quotes, const string_type& escapes)
|
||||
{
|
||||
// This overload must deal with escapes. Delegate that to InEscString
|
||||
// (unless there ARE no escapes).
|
||||
boost::scoped_ptr< LLStringUtilBaseImpl::InString<T> > instrp;
|
||||
if (escapes.empty())
|
||||
instrp.reset(new LLStringUtilBaseImpl::InString<T>(string.begin(), string.end()));
|
||||
else
|
||||
instrp.reset(new LLStringUtilBaseImpl::InEscString<T>(string.begin(), string.end(), escapes));
|
||||
LLStringUtilBaseImpl::getTokens(*instrp, tokens, drop_delims, keep_delims, quotes);
|
||||
}
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
@@ -679,7 +1044,7 @@ S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
|
||||
S32 LLStringUtilBase<T>::compareStrings(const string_type& lhs, const string_type& rhs)
|
||||
{
|
||||
return LLStringOps::collate(lhs.c_str(), rhs.c_str());
|
||||
}
|
||||
@@ -705,8 +1070,8 @@ S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
|
||||
}
|
||||
else
|
||||
{
|
||||
std::basic_string<T> lhs_string(lhs);
|
||||
std::basic_string<T> rhs_string(rhs);
|
||||
string_type lhs_string(lhs);
|
||||
string_type rhs_string(rhs);
|
||||
LLStringUtilBase<T>::toUpper(lhs_string);
|
||||
LLStringUtilBase<T>::toUpper(rhs_string);
|
||||
result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
|
||||
@@ -716,10 +1081,10 @@ S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
|
||||
S32 LLStringUtilBase<T>::compareInsensitive(const string_type& lhs, const string_type& rhs)
|
||||
{
|
||||
std::basic_string<T> lhs_string(lhs);
|
||||
std::basic_string<T> rhs_string(rhs);
|
||||
string_type lhs_string(lhs);
|
||||
string_type rhs_string(rhs);
|
||||
LLStringUtilBase<T>::toUpper(lhs_string);
|
||||
LLStringUtilBase<T>::toUpper(rhs_string);
|
||||
return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
|
||||
@@ -730,7 +1095,7 @@ S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, con
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
|
||||
S32 LLStringUtilBase<T>::compareDict(const string_type& astr, const string_type& bstr)
|
||||
{
|
||||
const T* a = astr.c_str();
|
||||
const T* b = bstr.c_str();
|
||||
@@ -771,7 +1136,7 @@ S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
|
||||
S32 LLStringUtilBase<T>::compareDictInsensitive(const string_type& astr, const string_type& bstr)
|
||||
{
|
||||
const T* a = astr.c_str();
|
||||
const T* b = bstr.c_str();
|
||||
@@ -806,7 +1171,7 @@ S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr
|
||||
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
|
||||
// static
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
|
||||
BOOL LLStringUtilBase<T>::precedesDict( const string_type& a, const string_type& b )
|
||||
{
|
||||
if( a.size() && b.size() )
|
||||
{
|
||||
@@ -820,7 +1185,7 @@ BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::toUpper(string_type& string)
|
||||
{
|
||||
if( !string.empty() )
|
||||
{
|
||||
@@ -834,7 +1199,7 @@ void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::toLower(string_type& string)
|
||||
{
|
||||
if( !string.empty() )
|
||||
{
|
||||
@@ -848,7 +1213,7 @@ void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::trimHead(string_type& string)
|
||||
{
|
||||
if( !string.empty() )
|
||||
{
|
||||
@@ -863,7 +1228,7 @@ void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::trimTail(string_type& string)
|
||||
{
|
||||
if( string.size() )
|
||||
{
|
||||
@@ -882,7 +1247,7 @@ void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
|
||||
// Replace line feeds with carriage return-line feed pairs.
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::addCRLF(string_type& string)
|
||||
{
|
||||
const T LF = 10;
|
||||
const T CR = 13;
|
||||
@@ -924,7 +1289,7 @@ void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
|
||||
// Remove all carriage returns
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::removeCRLF(string_type& string)
|
||||
{
|
||||
const T CR = 13;
|
||||
|
||||
@@ -945,10 +1310,10 @@ void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
|
||||
void LLStringUtilBase<T>::replaceChar( string_type& string, T target, T replacement )
|
||||
{
|
||||
size_type found_pos = 0;
|
||||
while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
|
||||
while( (found_pos = string.find(target, found_pos)) != string_type::npos )
|
||||
{
|
||||
string[found_pos] = replacement;
|
||||
found_pos++; // avoid infinite defeat if target == replacement
|
||||
@@ -957,10 +1322,10 @@ void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement )
|
||||
void LLStringUtilBase<T>::replaceString( string_type& string, string_type target, string_type replacement )
|
||||
{
|
||||
size_type found_pos = 0;
|
||||
while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
|
||||
while( (found_pos = string.find(target, found_pos)) != string_type::npos )
|
||||
{
|
||||
string.replace( found_pos, target.length(), replacement );
|
||||
found_pos += replacement.length(); // avoid infinite defeat if replacement contains target
|
||||
@@ -969,7 +1334,7 @@ void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basi
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
|
||||
void LLStringUtilBase<T>::replaceNonstandardASCII( string_type& string, T replacement )
|
||||
{
|
||||
const char LF = 10;
|
||||
const S8 MIN = 32;
|
||||
@@ -989,12 +1354,12 @@ void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string,
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
|
||||
void LLStringUtilBase<T>::replaceTabsWithSpaces( string_type& str, size_type spaces_per_tab )
|
||||
{
|
||||
const T TAB = '\t';
|
||||
const T SPACE = ' ';
|
||||
|
||||
std::basic_string<T> out_str;
|
||||
string_type out_str;
|
||||
// Replace tabs with spaces
|
||||
for (size_type i = 0; i < str.length(); i++)
|
||||
{
|
||||
@@ -1013,7 +1378,7 @@ void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
|
||||
BOOL LLStringUtilBase<T>::containsNonprintable(const string_type& string)
|
||||
{
|
||||
const char MIN = 32;
|
||||
BOOL rv = FALSE;
|
||||
@@ -1030,7 +1395,7 @@ BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& strin
|
||||
|
||||
//static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::stripNonprintable(string_type& string)
|
||||
{
|
||||
const char MIN = 32;
|
||||
size_type j = 0;
|
||||
@@ -1061,8 +1426,43 @@ void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
|
||||
delete []c_string;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str,
|
||||
const string_type& triggers,
|
||||
const string_type& escape)
|
||||
{
|
||||
size_type len(str.length());
|
||||
// If the string is already quoted, assume user knows what s/he's doing.
|
||||
if (len >= 2 && str[0] == '"' && str[len-1] == '"')
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
// Not already quoted: do we need to? triggers.empty() is a special case
|
||||
// meaning "always quote."
|
||||
if ((! triggers.empty()) && str.find_first_of(triggers) == string_type::npos)
|
||||
{
|
||||
// no trigger characters, don't bother quoting
|
||||
return str;
|
||||
}
|
||||
|
||||
// For whatever reason, we must quote this string.
|
||||
string_type result;
|
||||
result.push_back('"');
|
||||
for (typename string_type::const_iterator ci(str.begin()), cend(str.end()); ci != cend; ++ci)
|
||||
{
|
||||
if (*ci == '"')
|
||||
{
|
||||
result.append(escape);
|
||||
}
|
||||
result.push_back(*ci);
|
||||
}
|
||||
result.push_back('"');
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
|
||||
void LLStringUtilBase<T>::_makeASCII(string_type& string)
|
||||
{
|
||||
// Replace non-ASCII chars with LL_UNKNOWN_CHAR
|
||||
for (size_type i = 0; i < string.length(); i++)
|
||||
@@ -1105,7 +1505,7 @@ void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
|
||||
void LLStringUtilBase<T>::copyInto(string_type& dst, const string_type& src, size_type offset)
|
||||
{
|
||||
if ( offset == dst.length() )
|
||||
{
|
||||
@@ -1115,7 +1515,7 @@ void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_s
|
||||
}
|
||||
else
|
||||
{
|
||||
std::basic_string<T> tail = dst.substr(offset);
|
||||
string_type tail = dst.substr(offset);
|
||||
|
||||
dst = dst.substr(0, offset);
|
||||
dst += src;
|
||||
@@ -1126,7 +1526,7 @@ void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_s
|
||||
// True if this is the head of s.
|
||||
//static
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
|
||||
BOOL LLStringUtilBase<T>::isHead( const string_type& string, const T* s )
|
||||
{
|
||||
if( string.empty() )
|
||||
{
|
||||
@@ -1142,8 +1542,8 @@ BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s
|
||||
// static
|
||||
template<class T>
|
||||
bool LLStringUtilBase<T>::startsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr)
|
||||
const string_type& string,
|
||||
const string_type& substr)
|
||||
{
|
||||
if(string.empty() || (substr.empty())) return false;
|
||||
if(0 == string.find(substr)) return true;
|
||||
@@ -1153,8 +1553,8 @@ bool LLStringUtilBase<T>::startsWith(
|
||||
// static
|
||||
template<class T>
|
||||
bool LLStringUtilBase<T>::endsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr)
|
||||
const string_type& string,
|
||||
const string_type& substr)
|
||||
{
|
||||
if(string.empty() || (substr.empty())) return false;
|
||||
std::string::size_type idx = string.rfind(substr);
|
||||
@@ -1164,14 +1564,14 @@ bool LLStringUtilBase<T>::endsWith(
|
||||
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
|
||||
BOOL LLStringUtilBase<T>::convertToBOOL(const string_type& string, BOOL& value)
|
||||
{
|
||||
if( string.empty() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::basic_string<T> temp( string );
|
||||
string_type temp( string );
|
||||
trim(temp);
|
||||
if(
|
||||
(temp == "1") ||
|
||||
@@ -1201,7 +1601,7 @@ BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
|
||||
BOOL LLStringUtilBase<T>::convertToU8(const string_type& string, U8& value)
|
||||
{
|
||||
S32 value32 = 0;
|
||||
BOOL success = convertToS32(string, value32);
|
||||
@@ -1214,7 +1614,7 @@ BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& va
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
|
||||
BOOL LLStringUtilBase<T>::convertToS8(const string_type& string, S8& value)
|
||||
{
|
||||
S32 value32 = 0;
|
||||
BOOL success = convertToS32(string, value32);
|
||||
@@ -1227,7 +1627,7 @@ BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& va
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
|
||||
BOOL LLStringUtilBase<T>::convertToS16(const string_type& string, S16& value)
|
||||
{
|
||||
S32 value32 = 0;
|
||||
BOOL success = convertToS32(string, value32);
|
||||
@@ -1240,7 +1640,7 @@ BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16&
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
|
||||
BOOL LLStringUtilBase<T>::convertToU16(const string_type& string, U16& value)
|
||||
{
|
||||
S32 value32 = 0;
|
||||
BOOL success = convertToS32(string, value32);
|
||||
@@ -1253,17 +1653,17 @@ BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16&
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
|
||||
BOOL LLStringUtilBase<T>::convertToU32(const string_type& string, U32& value)
|
||||
{
|
||||
if( string.empty() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::basic_string<T> temp( string );
|
||||
string_type temp( string );
|
||||
trim(temp);
|
||||
U32 v;
|
||||
std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
|
||||
std::basic_istringstream<T> i_stream((string_type)temp);
|
||||
if(i_stream >> v)
|
||||
{
|
||||
value = v;
|
||||
@@ -1273,17 +1673,17 @@ BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32&
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
|
||||
BOOL LLStringUtilBase<T>::convertToS32(const string_type& string, S32& value)
|
||||
{
|
||||
if( string.empty() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::basic_string<T> temp( string );
|
||||
string_type temp( string );
|
||||
trim(temp);
|
||||
S32 v;
|
||||
std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
|
||||
std::basic_istringstream<T> i_stream((string_type)temp);
|
||||
if(i_stream >> v)
|
||||
{
|
||||
//TODO: figure out overflow and underflow reporting here
|
||||
@@ -1300,7 +1700,7 @@ BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32&
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
|
||||
BOOL LLStringUtilBase<T>::convertToF32(const string_type& string, F32& value)
|
||||
{
|
||||
F64 value64 = 0.0;
|
||||
BOOL success = convertToF64(string, value64);
|
||||
@@ -1313,17 +1713,17 @@ BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32&
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
|
||||
BOOL LLStringUtilBase<T>::convertToF64(const string_type& string, F64& value)
|
||||
{
|
||||
if( string.empty() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::basic_string<T> temp( string );
|
||||
string_type temp( string );
|
||||
trim(temp);
|
||||
F64 v;
|
||||
std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
|
||||
std::basic_istringstream<T> i_stream((string_type)temp);
|
||||
if(i_stream >> v)
|
||||
{
|
||||
//TODO: figure out overflow and underflow reporting here
|
||||
@@ -1340,7 +1740,7 @@ BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64&
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
|
||||
void LLStringUtilBase<T>::truncate(string_type& string, size_type count)
|
||||
{
|
||||
size_type cur_size = string.size();
|
||||
string.resize(count < cur_size ? count : cur_size);
|
||||
|
||||
@@ -67,18 +67,12 @@
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if !LL_DARWIN
|
||||
U32 ll_thread_local local_thread_ID = 0;
|
||||
#endif
|
||||
|
||||
U32 LLThread::sIDIter = 0;
|
||||
LLAtomicS32 LLThread::sCount = 0;
|
||||
LLAtomicS32 LLThread::sRunning = 0;
|
||||
|
||||
LL_COMMON_API void assert_main_thread()
|
||||
{
|
||||
static U32 s_thread_id = LLThread::currentID();
|
||||
if (LLThread::currentID() != s_thread_id)
|
||||
if (!AIThreadID::in_main_thread_inline())
|
||||
{
|
||||
llerrs << "Illegal execution outside main thread." << llendl;
|
||||
}
|
||||
@@ -95,9 +89,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
|
||||
|
||||
LLThread *threadp = (LLThread *)datap;
|
||||
|
||||
#if !LL_DARWIN
|
||||
local_thread_ID = threadp->mID;
|
||||
#endif
|
||||
// Initialize thread-local cache of current thread ID (if supported).
|
||||
AIThreadID::set_current_thread_id();
|
||||
|
||||
// Create a thread local data.
|
||||
LLThreadLocalData::create(threadp);
|
||||
@@ -137,7 +130,6 @@ LLThread::LLThread(std::string const& name) :
|
||||
mStatus(STOPPED),
|
||||
mThreadLocalData(NULL)
|
||||
{
|
||||
mID = ++sIDIter;
|
||||
sCount++;
|
||||
llassert(sCount <= 50);
|
||||
mRunCondition = new LLCondition;
|
||||
@@ -281,12 +273,6 @@ void LLThread::setQuitting()
|
||||
wake();
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLThread::currentID()
|
||||
{
|
||||
return (U32)apr_os_thread_current();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLThread::yield()
|
||||
{
|
||||
@@ -315,14 +301,6 @@ void LLThread::wakeLocked()
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
apr_os_thread_t LLThread::sMainThreadID;
|
||||
|
||||
void LLThread::set_main_thread_id(void)
|
||||
{
|
||||
sMainThreadID = apr_os_thread_current();
|
||||
}
|
||||
|
||||
// The thread private handle to access the LLThreadLocalData instance.
|
||||
apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey;
|
||||
|
||||
@@ -345,6 +323,10 @@ void LLThreadLocalData::init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// This function is called by the main thread (these values are also needed in the next line).
|
||||
AIThreadID::set_main_thread_id();
|
||||
AIThreadID::set_current_thread_id();
|
||||
|
||||
apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &LLThreadLocalData::destroy, LLAPRRootPool::get()());
|
||||
ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the
|
||||
// total number of keys per process {PTHREAD_KEYS_MAX}
|
||||
@@ -352,9 +334,6 @@ void LLThreadLocalData::init(void)
|
||||
|
||||
// Create the thread-local data for the main thread (this function is called by the main thread).
|
||||
LLThreadLocalData::create(NULL);
|
||||
|
||||
// This function is called by the main thread.
|
||||
LLThread::set_main_thread_id();
|
||||
}
|
||||
|
||||
// This is called once for every thread when the thread is destructed.
|
||||
@@ -421,27 +400,19 @@ void LLCondition::broadcast()
|
||||
|
||||
//============================================================================
|
||||
LLMutexBase::LLMutexBase() :
|
||||
mLockingThread(NO_THREAD),
|
||||
mLockingThread(AIThreadID::sNone),
|
||||
mCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool LLMutexBase::isSelfLocked() const
|
||||
{
|
||||
#if LL_DARWIN
|
||||
return mLockingThread == LLThread::currentID();
|
||||
#else
|
||||
return mLockingThread == local_thread_ID;
|
||||
#endif
|
||||
return mLockingThread.equals_current_thread_inline();
|
||||
}
|
||||
|
||||
void LLMutexBase::lock()
|
||||
{
|
||||
#if LL_DARWIN
|
||||
if (mLockingThread == LLThread::currentID())
|
||||
#else
|
||||
if (mLockingThread == local_thread_ID)
|
||||
#endif
|
||||
if (mLockingThread.equals_current_thread_inline())
|
||||
{ //redundant lock
|
||||
mCount++;
|
||||
return;
|
||||
@@ -449,11 +420,33 @@ void LLMutexBase::lock()
|
||||
|
||||
apr_thread_mutex_lock(mAPRMutexp);
|
||||
|
||||
#if LL_DARWIN
|
||||
mLockingThread = LLThread::currentID();
|
||||
#else
|
||||
mLockingThread = local_thread_ID;
|
||||
#endif
|
||||
mLockingThread.reset_inline();
|
||||
}
|
||||
|
||||
bool LLMutexBase::tryLock()
|
||||
{
|
||||
if (mLockingThread.equals_current_thread_inline())
|
||||
{ //redundant lock
|
||||
mCount++;
|
||||
return true;
|
||||
}
|
||||
bool success = !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp));
|
||||
if (success)
|
||||
{
|
||||
mLockingThread.reset_inline();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// non-blocking, but does do a lock/unlock so not free
|
||||
bool LLMutexBase::isLocked() const
|
||||
{
|
||||
if (mLockingThread.equals_current_thread_inline())
|
||||
return false; // A call to lock() won't block.
|
||||
if (APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)))
|
||||
return true;
|
||||
apr_thread_mutex_unlock(mAPRMutexp);
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLMutexBase::unlock()
|
||||
@@ -463,7 +456,7 @@ void LLMutexBase::unlock()
|
||||
mCount--;
|
||||
return;
|
||||
}
|
||||
mLockingThread = NO_THREAD;
|
||||
mLockingThread = AIThreadID::sNone;
|
||||
|
||||
apr_thread_mutex_unlock(mAPRMutexp);
|
||||
}
|
||||
|
||||
@@ -45,17 +45,12 @@
|
||||
#include "apr_thread_cond.h"
|
||||
#include "llaprpool.h"
|
||||
#include "llatomic.h"
|
||||
#include "aithreadid.h"
|
||||
|
||||
class LLThread;
|
||||
class LLMutex;
|
||||
class LLCondition;
|
||||
|
||||
#if LL_WINDOWS
|
||||
#define ll_thread_local __declspec(thread)
|
||||
#else
|
||||
#define ll_thread_local __thread
|
||||
#endif
|
||||
|
||||
class LL_COMMON_API LLThreadLocalDataMember
|
||||
{
|
||||
public:
|
||||
@@ -85,10 +80,12 @@ private:
|
||||
~LLThreadLocalData();
|
||||
};
|
||||
|
||||
// Print to llerrs if the current thread is not the main thread.
|
||||
LL_COMMON_API void assert_main_thread();
|
||||
|
||||
class LL_COMMON_API LLThread
|
||||
{
|
||||
private:
|
||||
static apr_os_thread_t sMainThreadID;
|
||||
static U32 sIDIter;
|
||||
static LLAtomicS32 sCount;
|
||||
static LLAtomicS32 sRunning;
|
||||
@@ -108,11 +105,9 @@ public:
|
||||
bool isQuitting() const { return (QUITTING == mStatus); }
|
||||
bool isStopped() const { return (STOPPED == mStatus); }
|
||||
|
||||
static U32 currentID(); // Return ID of current thread
|
||||
static S32 getCount() { return sCount; }
|
||||
static S32 getRunning() { return sRunning; }
|
||||
static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
|
||||
static bool is_main_thread(void) { return apr_os_thread_equal(LLThread::sMainThreadID, apr_os_thread_current()); }
|
||||
|
||||
public:
|
||||
// PAUSE / RESUME functionality. See source code for important usage notes.
|
||||
@@ -136,11 +131,6 @@ public:
|
||||
// Return thread-local data for the current thread.
|
||||
static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
|
||||
|
||||
// Called once, from LLThreadLocalData::init().
|
||||
static void set_main_thread_id(void);
|
||||
|
||||
U32 getID() const { return mID; }
|
||||
|
||||
private:
|
||||
bool mPaused;
|
||||
|
||||
@@ -153,7 +143,6 @@ protected:
|
||||
|
||||
apr_thread_t *mAPRThreadp;
|
||||
volatile EThreadStatus mStatus;
|
||||
U32 mID;
|
||||
|
||||
friend void LLThreadLocalData::create(LLThread* threadp);
|
||||
LLThreadLocalData* mThreadLocalData;
|
||||
@@ -183,8 +172,7 @@ protected:
|
||||
};
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
LL_COMMON_API inline bool is_main_thread(void) { return LLThread::is_main_thread(); }
|
||||
#define ASSERT_SINGLE_THREAD do { static apr_os_thread_t first_thread_id = apr_os_thread_current(); llassert(apr_os_thread_equal(first_thread_id, apr_os_thread_current())); } while(0)
|
||||
#define ASSERT_SINGLE_THREAD do { static AIThreadID first_thread_id; llassert(first_thread_id.equals_current_thread()); } while(0)
|
||||
#else
|
||||
#define ASSERT_SINGLE_THREAD do { } while(0)
|
||||
#endif
|
||||
@@ -204,32 +192,24 @@ LL_COMMON_API inline bool is_main_thread(void) { return LLThread::is_main_thread
|
||||
class LL_COMMON_API LLMutexBase
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
NO_THREAD = 0xFFFFFFFF
|
||||
} e_locking_thread;
|
||||
|
||||
LLMutexBase() ;
|
||||
|
||||
void lock(); // blocks
|
||||
void unlock();
|
||||
// Returns true if lock was obtained successfully.
|
||||
bool tryLock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); }
|
||||
bool tryLock();
|
||||
|
||||
// non-blocking, but does do a lock/unlock so not free
|
||||
bool isLocked() { bool is_not_locked = tryLock(); if (is_not_locked) unlock(); return !is_not_locked; }
|
||||
// Returns true if a call to lock() would block (returns false if self-locked()).
|
||||
bool isLocked() const;
|
||||
|
||||
// Returns true if locked by this thread.
|
||||
bool isSelfLocked() const;
|
||||
|
||||
// get ID of locking thread
|
||||
U32 lockingThread() const { return mLockingThread; }
|
||||
|
||||
protected:
|
||||
// mAPRMutexp is initialized and uninitialized in the derived class.
|
||||
apr_thread_mutex_t* mAPRMutexp;
|
||||
mutable U32 mCount;
|
||||
mutable U32 mLockingThread;
|
||||
mutable AIThreadID mLockingThread;
|
||||
|
||||
private:
|
||||
// Disallow copy construction and assignment.
|
||||
|
||||
117
indra/llcommon/lltypeinfolookup.h
Normal file
117
indra/llcommon/lltypeinfolookup.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file lltypeinfolookup.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2012-04-08
|
||||
* @brief Template data structure like std::map<std::type_info*, T>
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Copyright (c) 2012, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLTYPEINFOLOOKUP_H)
|
||||
#define LL_LLTYPEINFOLOOKUP_H
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <functional> // std::binary_function
|
||||
#include <typeinfo>
|
||||
|
||||
/**
|
||||
* The following helper classes are based on the Boost.Unordered documentation:
|
||||
* http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compute hash for a string passed as const char*
|
||||
*/
|
||||
struct const_char_star_hash: public std::unary_function<const char*, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const char* str) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
for ( ; *str; ++str)
|
||||
{
|
||||
boost::hash_combine(seed, *str);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute equality for strings passed as const char*
|
||||
*
|
||||
* I (nat) suspect that this is where the default behavior breaks for the
|
||||
* const char* values returned from std::type_info::name(). If you compare the
|
||||
* two const char* pointer values, as a naive, unspecialized implementation
|
||||
* will surely do, they'll compare unequal.
|
||||
*/
|
||||
struct const_char_star_equal: public std::binary_function<const char*, const char*, bool>
|
||||
{
|
||||
bool operator()(const char* lhs, const char* rhs) const
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LLTypeInfoLookup is specifically designed for use cases for which you might
|
||||
* consider std::map<std::type_info*, VALUE>. We have several such data
|
||||
* structures in the viewer. The trouble with them is that at least on Linux,
|
||||
* you can't rely on always getting the same std::type_info* for a given type:
|
||||
* different load modules will produce different std::type_info*.
|
||||
* LLTypeInfoLookup contains a workaround to address this issue.
|
||||
*
|
||||
* The API deliberately diverges from std::map in several respects:
|
||||
* * It avoids iterators, not only begin()/end() but also as return values
|
||||
* from insert() and find(). This bypasses transform_iterator overhead.
|
||||
* * Since we literally use compile-time types as keys, the essential insert()
|
||||
* and find() methods accept the key type as a @em template parameter,
|
||||
* accepting and returning value_type as a normal runtime value. This is to
|
||||
* permit future optimization (e.g. compile-time type hashing) without
|
||||
* changing the API.
|
||||
*/
|
||||
template <typename VALUE>
|
||||
class LLTypeInfoLookup
|
||||
{
|
||||
// Use this for our underlying implementation: lookup by
|
||||
// std::type_info::name() string. This is one of the rare cases in which I
|
||||
// dare use const char* directly, rather than std::string, because I'm
|
||||
// sure that every value returned by std::type_info::name() is static.
|
||||
// HOWEVER, specify our own hash + equality functors: naively comparing
|
||||
// distinct const char* values won't work.
|
||||
typedef boost::unordered_map<const char*, VALUE,
|
||||
const_char_star_hash, const_char_star_equal> impl_map_type;
|
||||
|
||||
public:
|
||||
typedef VALUE value_type;
|
||||
|
||||
LLTypeInfoLookup() {}
|
||||
|
||||
bool empty() const { return mMap.empty(); }
|
||||
std::size_t size() const { return mMap.size(); }
|
||||
|
||||
template <typename KEY>
|
||||
bool insert(const value_type& value)
|
||||
{
|
||||
// Obtain and store the std::type_info::name() string as the key.
|
||||
// Return just the bool from std::map::insert()'s return pair.
|
||||
return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second;
|
||||
}
|
||||
|
||||
template <typename KEY>
|
||||
boost::optional<value_type> find() const
|
||||
{
|
||||
// Use the std::type_info::name() string as the key.
|
||||
typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name());
|
||||
if (found == mMap.end())
|
||||
return boost::optional<value_type>();
|
||||
return found->second;
|
||||
}
|
||||
|
||||
private:
|
||||
impl_map_type mMap;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.
|
||||
#if LL_WINDOWS
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "lldefs.h"
|
||||
@@ -452,7 +452,8 @@ static void get_random_bytes(void *buf, int nbytes)
|
||||
return;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
#if LL_WINDOWS
|
||||
|
||||
typedef struct _ASTAT_
|
||||
{
|
||||
ADAPTER_STATUS adapt;
|
||||
@@ -460,58 +461,44 @@ typedef struct _ASTAT_
|
||||
}ASTAT, * PASTAT;
|
||||
|
||||
// static
|
||||
S32 LLUUID::getNodeID(unsigned char * node_id)
|
||||
S32 LLUUID::getNodeID(unsigned char *node_id)
|
||||
{
|
||||
ASTAT Adapter;
|
||||
NCB Ncb;
|
||||
UCHAR uRetCode;
|
||||
LANA_ENUM lenum;
|
||||
int i;
|
||||
int retval = 0;
|
||||
ASTAT Adapter;
|
||||
NCB Ncb;
|
||||
UCHAR uRetCode;
|
||||
LANA_ENUM lenum;
|
||||
int i;
|
||||
int retval = 0;
|
||||
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBENUM;
|
||||
Ncb.ncb_buffer = (UCHAR *)&lenum;
|
||||
Ncb.ncb_length = sizeof(lenum);
|
||||
uRetCode = Netbios( &Ncb );
|
||||
// printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBENUM;
|
||||
Ncb.ncb_buffer = (UCHAR *)&lenum;
|
||||
Ncb.ncb_length = sizeof(lenum);
|
||||
uRetCode = Netbios( &Ncb );
|
||||
|
||||
for(i=0; i < lenum.length ;i++)
|
||||
{
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBRESET;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
for(i=0; i < lenum.length ;i++)
|
||||
{
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBRESET;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
|
||||
uRetCode = Netbios( &Ncb );
|
||||
// printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
|
||||
// lenum.lana[i], uRetCode );
|
||||
uRetCode = Netbios( &Ncb );
|
||||
|
||||
memset( &Ncb, 0, sizeof (Ncb) );
|
||||
Ncb.ncb_command = NCBASTAT;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
memset( &Ncb, 0, sizeof (Ncb) );
|
||||
Ncb.ncb_command = NCBASTAT;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
|
||||
strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */
|
||||
Ncb.ncb_buffer = (unsigned char *)&Adapter;
|
||||
Ncb.ncb_length = sizeof(Adapter);
|
||||
strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */
|
||||
Ncb.ncb_buffer = (unsigned char *)&Adapter;
|
||||
Ncb.ncb_length = sizeof(Adapter);
|
||||
|
||||
uRetCode = Netbios( &Ncb );
|
||||
// printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
|
||||
// lenum.lana[i], uRetCode );
|
||||
if ( uRetCode == 0 )
|
||||
{
|
||||
// printf( "The Ethernet Number on LANA %d is: %02x%02x%02x%02x%02x%02x\n",
|
||||
// lenum.lana[i],
|
||||
// Adapter.adapt.adapter_address[0],
|
||||
// Adapter.adapt.adapter_address[1],
|
||||
// Adapter.adapt.adapter_address[2],
|
||||
// Adapter.adapt.adapter_address[3],
|
||||
// Adapter.adapt.adapter_address[4],
|
||||
// Adapter.adapt.adapter_address[5] );
|
||||
uRetCode = Netbios( &Ncb );
|
||||
if ( uRetCode == 0 )
|
||||
{
|
||||
memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */
|
||||
retval = 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
@@ -133,6 +132,7 @@ public:
|
||||
|
||||
U8 mData[UUID_BYTES];
|
||||
};
|
||||
|
||||
typedef std::vector<LLUUID> uuid_vec_t;
|
||||
|
||||
// Construct
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
#include "lluuid.h"
|
||||
#include "llstring.h"
|
||||
#include "llmemtype.h"
|
||||
#include "llthread.h"
|
||||
#include "llmemtype.h"
|
||||
#include "aithreadsafe.h"
|
||||
|
||||
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
|
||||
|
||||
@@ -32,7 +32,12 @@
|
||||
#ifndef LL_LLPNGWRAPPER_H
|
||||
#define LL_LLPNGWRAPPER_H
|
||||
|
||||
#include "png.h"
|
||||
#ifdef LL_STANDALONE
|
||||
#include <png.h>
|
||||
#else
|
||||
// Workaround for wrongly packaged prebuilt.
|
||||
#include "libpng15/png.h"
|
||||
#endif
|
||||
#include "llimage.h"
|
||||
|
||||
class LLPngWrapper
|
||||
|
||||
@@ -1700,6 +1700,6 @@ LLPointer<LLInventoryCategory> ll_create_category_from_sd(const LLSD& sd_cat)
|
||||
LLAssetType::lookup(sd_cat[INV_ASSET_TYPE_LABEL].asString()));
|
||||
rv->setPreferredType(
|
||||
LLFolderType::lookup(
|
||||
sd_cat[INV_PREFERRED_TYPE_LABEL].asString()));
|
||||
sd_cat[INV_PREFERRED_TYPE_LABEL].asString()));
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
|
||||
LLInventoryType::IT_NONE, // 46 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 47 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 48 AT_NONE
|
||||
LLInventoryType::IT_MESH // 49 AT_MESH
|
||||
LLInventoryType::IT_MESH // 49 AT_MESH
|
||||
};
|
||||
|
||||
// static
|
||||
|
||||
@@ -51,7 +51,7 @@ const S32 PARCEL_UNIT_AREA = 16;
|
||||
const F32 PARCEL_HEIGHT = 50.f;
|
||||
|
||||
//Height above ground which parcel boundries exist for explicitly banned avatars
|
||||
const F32 BAN_HEIGHT = 768.f;
|
||||
const F32 BAN_HEIGHT = 5000.f;
|
||||
|
||||
// Maximum number of entries in an access list
|
||||
const S32 PARCEL_MAX_ACCESS_LIST = 300;
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
void setMediaURLResetTimer(F32 time);
|
||||
virtual void setLocalID(S32 local_id);
|
||||
|
||||
// blow away all the extra crap lurking in parcels, including urls, access lists, etc
|
||||
// blow away all the extra stuff lurking in parcels, including urls, access lists, etc
|
||||
void clearParcel();
|
||||
|
||||
// This value is not persisted out to the parcel file, it is only
|
||||
@@ -686,6 +686,7 @@ public:
|
||||
std::map<LLUUID,LLAccessEntry> mBanList;
|
||||
std::map<LLUUID,LLAccessEntry> mTempBanList;
|
||||
std::map<LLUUID,LLAccessEntry> mTempAccessList;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
#ifndef LL_LLPERMISSIONSFLAGS_H
|
||||
#define LL_LLPERMISSIONSFLAGS_H
|
||||
|
||||
// llpermissionsflags.h
|
||||
// Copyright 2002, Linden Research, Inc.
|
||||
//
|
||||
// Flags for various permissions bits.
|
||||
// Shared between viewer and simulator.
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "lltransactiontypes.h"
|
||||
|
||||
#include "../newview/hippogridmanager.h"
|
||||
|
||||
|
||||
const U8 TRANSACTION_FLAGS_NONE = 0;
|
||||
const U8 TRANSACTION_FLAG_SOURCE_GROUP = 1;
|
||||
const U8 TRANSACTION_FLAG_DEST_GROUP = 2;
|
||||
|
||||
@@ -74,6 +74,7 @@ const S32 TRANS_CLASSIFIED_RENEW = 2005;
|
||||
// automatically end up in the list below :-(
|
||||
// So make sure you check the transaction_description table
|
||||
const S32 TRANS_RECURRING_GENERIC = 2100;
|
||||
|
||||
// Codes 3000-3999 reserved for inventory transactions
|
||||
const S32 TRANS_GIVE_INVENTORY = 3000;
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "v3math.h"
|
||||
#include "llvector4a.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
|
||||
#define OCT_ERRS LL_ERRS("OctreeErrors")
|
||||
@@ -89,11 +88,12 @@ public:
|
||||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef typename std::set<LLPointer<T> > element_list;
|
||||
typedef typename element_list::iterator element_iter;
|
||||
typedef typename element_list::const_iterator const_element_iter;
|
||||
typedef LLPointer<T>* element_list;
|
||||
typedef LLPointer<T>* element_iter;
|
||||
typedef const LLPointer<T>* const_element_iter;
|
||||
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
|
||||
typedef typename std::vector<LLOctreeNode<T>* > child_list;
|
||||
typedef LLOctreeNode<T>** child_list;
|
||||
typedef LLOctreeNode<T>** child_iter;
|
||||
typedef LLTreeNode<T> BaseType;
|
||||
typedef LLOctreeNode<T> oct_node;
|
||||
typedef LLOctreeListener<T> oct_listener;
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
: mParent((oct_node*)parent),
|
||||
mOctant(octant)
|
||||
{
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
|
||||
mCenter = center;
|
||||
mSize = size;
|
||||
|
||||
@@ -133,6 +136,16 @@ public:
|
||||
{
|
||||
BaseType::destroyListeners();
|
||||
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
{
|
||||
mData[i]->setBinIndex(-1);
|
||||
mData[i] = NULL;
|
||||
}
|
||||
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
delete getChild(i);
|
||||
@@ -229,12 +242,17 @@ public:
|
||||
}
|
||||
|
||||
void accept(oct_traveler* visitor) { visitor->visit(this); }
|
||||
virtual bool isLeaf() const { return mChild.empty(); }
|
||||
virtual bool isLeaf() const { return mChildCount == 0; }
|
||||
|
||||
U32 getElementCount() const { return mElementCount; }
|
||||
bool isEmpty() const { return mElementCount == 0; }
|
||||
element_list& getData() { return mData; }
|
||||
const element_list& getData() const { return mData; }
|
||||
|
||||
element_iter getDataBegin() { return mData; }
|
||||
element_iter getDataEnd() { return mDataEnd; }
|
||||
const_element_iter getDataBegin() const { return mData; }
|
||||
const_element_iter getDataEnd() const { return mDataEnd; }
|
||||
|
||||
U32 getChildCount() const { return mChildCount; }
|
||||
oct_node* getChild(U32 index) { return mChild[index]; }
|
||||
const oct_node* getChild(U32 index) const { return mChild[index]; }
|
||||
@@ -299,7 +317,7 @@ public:
|
||||
|
||||
virtual bool insert(T* data)
|
||||
{
|
||||
if (data == NULL)
|
||||
if (data == NULL || data->getBinIndex() != -1)
|
||||
{
|
||||
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
|
||||
return false;
|
||||
@@ -309,22 +327,19 @@ public:
|
||||
//is it here?
|
||||
if (isInside(data->getPositionGroup()))
|
||||
{
|
||||
if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) ||
|
||||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{ //it belongs here
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
//if this is a redundant insertion, error out (should never happen)
|
||||
if (mData.find(data) != mData.end())
|
||||
{
|
||||
llwarns << "Redundant octree insertion detected. " << data << llendl;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
mData.insert(data);
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
|
||||
mElementCount = mData.size();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -358,10 +373,16 @@ public:
|
||||
|
||||
if( lt == 0x7 )
|
||||
{
|
||||
mData.insert(data);
|
||||
BaseType::insert(data);
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
mElementCount = mData.size();
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -410,23 +431,59 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void _remove(T* data, S32 i)
|
||||
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
|
||||
|
||||
mElementCount--;
|
||||
data->setBinIndex(-1);
|
||||
|
||||
if (mElementCount > 0)
|
||||
{
|
||||
if (mElementCount != i)
|
||||
{
|
||||
mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
|
||||
mData[i]->setBinIndex(i);
|
||||
}
|
||||
|
||||
mData[mElementCount] = NULL; //needed for unref
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
mDataEnd = mData+mElementCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
mData[0] = NULL; //needed for unref
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
}
|
||||
|
||||
this->notifyRemoval(data);
|
||||
checkAlive();
|
||||
}
|
||||
|
||||
bool remove(T* data)
|
||||
{
|
||||
if (mData.find(data) != mData.end())
|
||||
{ //we have data
|
||||
mData.erase(data);
|
||||
mElementCount = mData.size();
|
||||
this->notifyRemoval(data);
|
||||
checkAlive();
|
||||
return true;
|
||||
S32 i = data->getBinIndex();
|
||||
|
||||
if (i >= 0 && i < (S32)mElementCount)
|
||||
{
|
||||
if (mData[i] == data)
|
||||
{ //found it
|
||||
_remove(data, i);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (isInside(data))
|
||||
|
||||
if (isInside(data))
|
||||
{
|
||||
oct_node* dest = getNodeAt(data);
|
||||
|
||||
if (dest != this)
|
||||
{
|
||||
return dest->remove(data);
|
||||
bool ret = dest->remove(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,19 +502,20 @@ public:
|
||||
//node is now root
|
||||
llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
|
||||
node->removeByAddress(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void removeByAddress(T* data)
|
||||
{
|
||||
if (mData.find(data) != mData.end())
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
{
|
||||
mData.erase(data);
|
||||
mElementCount = mData.size();
|
||||
this->notifyRemoval(data);
|
||||
llwarns << "FOUND!" << llendl;
|
||||
checkAlive();
|
||||
return;
|
||||
if (mData[i] == data)
|
||||
{ //we have data
|
||||
_remove(data, i);
|
||||
llwarns << "FOUND!" << llendl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
@@ -469,8 +527,8 @@ public:
|
||||
|
||||
void clearChildren()
|
||||
{
|
||||
mChild.clear();
|
||||
mChildCount = 0;
|
||||
|
||||
U32* foo = (U32*) mChildMap;
|
||||
foo[0] = foo[1] = 0xFFFFFFFF;
|
||||
}
|
||||
@@ -532,7 +590,7 @@ public:
|
||||
|
||||
mChildMap[child->getOctant()] = mChildCount;
|
||||
|
||||
mChild.push_back(child);
|
||||
mChild[mChildCount] = child;
|
||||
++mChildCount;
|
||||
child->setParent(this);
|
||||
|
||||
@@ -561,9 +619,12 @@ public:
|
||||
mChild[index]->destroy();
|
||||
delete mChild[index];
|
||||
}
|
||||
mChild.erase(mChild.begin() + index);
|
||||
|
||||
--mChildCount;
|
||||
|
||||
mChild[index] = mChild[mChildCount];
|
||||
|
||||
|
||||
//rebuild child map
|
||||
U32* foo = (U32*) mChildMap;
|
||||
foo[0] = foo[1] = 0xFFFFFFFF;
|
||||
@@ -619,11 +680,12 @@ protected:
|
||||
oct_node* mParent;
|
||||
U8 mOctant;
|
||||
|
||||
child_list mChild;
|
||||
LLOctreeNode<T>* mChild[8];
|
||||
U8 mChildMap[8];
|
||||
U32 mChildCount;
|
||||
|
||||
element_list mData;
|
||||
element_iter mDataEnd;
|
||||
U32 mElementCount;
|
||||
|
||||
};
|
||||
|
||||
@@ -324,16 +324,16 @@ public:
|
||||
LLVector4a& min = node->mExtents[0];
|
||||
LLVector4a& max = node->mExtents[1];
|
||||
|
||||
if (!branch->getData().empty())
|
||||
if (!branch->isEmpty())
|
||||
{ //node has data, find AABB that binds data set
|
||||
const LLVolumeTriangle* tri = *(branch->getData().begin());
|
||||
const LLVolumeTriangle* tri = *(branch->getDataBegin());
|
||||
|
||||
//initialize min/max to first available vertex
|
||||
min = *(tri->mV[0]);
|
||||
max = *(tri->mV[0]);
|
||||
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
|
||||
branch->getData().begin(); iter != branch->getData().end(); ++iter)
|
||||
branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
|
||||
{ //for each triangle in node
|
||||
|
||||
//stretch by triangles in node
|
||||
@@ -348,7 +348,7 @@ public:
|
||||
max.setMax(max, *tri->mV[2]);
|
||||
}
|
||||
}
|
||||
else if (!branch->getChildren().empty())
|
||||
else if (!branch->isLeaf())
|
||||
{ //no data, but child nodes exist
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
|
||||
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
|
||||
{
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
|
||||
node->getData().begin(); iter != node->getData().end(); ++iter)
|
||||
node->getDataBegin(); iter != node->getDataEnd(); ++iter)
|
||||
{
|
||||
const LLVolumeTriangle* tri = *iter;
|
||||
|
||||
@@ -236,8 +236,8 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
|
||||
}
|
||||
|
||||
//children fit, check data
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
|
||||
iter != branch->getData().end(); ++iter)
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
|
||||
iter != branch->getDataEnd(); ++iter)
|
||||
{
|
||||
const LLVolumeTriangle* tri = *iter;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class LLVolumeTriangle : public LLRefCount
|
||||
public:
|
||||
LLVolumeTriangle()
|
||||
{
|
||||
|
||||
mBinIndex = -1;
|
||||
}
|
||||
|
||||
LLVolumeTriangle(const LLVolumeTriangle& rhs)
|
||||
@@ -64,9 +64,14 @@ public:
|
||||
U16 mIndex[3];
|
||||
|
||||
F32 mRadius;
|
||||
mutable S32 mBinIndex;
|
||||
|
||||
|
||||
virtual const LLVector4a& getPositionGroup() const;
|
||||
virtual const F32& getBinRadius() const;
|
||||
|
||||
S32 getBinIndex() const { return mBinIndex; }
|
||||
void setBinIndex(S32 idx) const { mBinIndex = idx; }
|
||||
};
|
||||
|
||||
class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include "apr_poll.h"
|
||||
|
||||
#include "llapr.h"
|
||||
#include "llaprpool.h"
|
||||
#include "llareslistener.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
|
||||
@@ -468,6 +468,7 @@ bool LLAres::process(U64 timeout)
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
|
||||
apr_int32_t nsds = 0;
|
||||
apr_status_t status;
|
||||
int nactive = 0;
|
||||
int bitmask;
|
||||
|
||||
@@ -478,8 +479,6 @@ bool LLAres::process(U64 timeout)
|
||||
return nsds > 0;
|
||||
}
|
||||
|
||||
LLScopedVolatileAPRPool scoped_pool;
|
||||
|
||||
for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
|
||||
{
|
||||
if (ARES_GETSOCK_READABLE(bitmask, i))
|
||||
@@ -495,7 +494,7 @@ bool LLAres::process(U64 timeout)
|
||||
|
||||
apr_socket_t *aprSock = NULL;
|
||||
|
||||
apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
|
||||
status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], LLAPRRootPool::get()());
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(status);
|
||||
@@ -504,7 +503,7 @@ bool LLAres::process(U64 timeout)
|
||||
|
||||
aprFds[nactive].desc.s = aprSock;
|
||||
aprFds[nactive].desc_type = APR_POLL_SOCKET;
|
||||
aprFds[nactive].p = scoped_pool;
|
||||
aprFds[nactive].p = LLAPRRootPool::get()();
|
||||
aprFds[nactive].rtnevents = 0;
|
||||
aprFds[nactive].client_data = &socks[i];
|
||||
|
||||
@@ -513,7 +512,7 @@ bool LLAres::process(U64 timeout)
|
||||
|
||||
if (nactive > 0)
|
||||
{
|
||||
apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
|
||||
status = apr_poll(aprFds, nactive, &nsds, timeout);
|
||||
|
||||
if (status != APR_SUCCESS && status != APR_TIMEUP)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llbuffer.h"
|
||||
#include <iterator>
|
||||
|
||||
#include "llmath.h"
|
||||
#include "llmemtype.h"
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "llstl.h"
|
||||
#include "lltransfermanager.h"
|
||||
#include "llmodularmath.h"
|
||||
#include "llpacketring.h"
|
||||
|
||||
const S32 PING_START_BLOCK = 3; // How many pings behind we have to be to consider ourself blocked.
|
||||
const S32 PING_RELEASE_BLOCK = 2; // How many pings behind we have to be to consider ourself unblocked.
|
||||
@@ -346,7 +347,7 @@ S32 LLCircuitData::resendUnackedPackets(const F64 now)
|
||||
|
||||
packetp->mBuffer[0] |= LL_RESENT_FLAG; // tag packet id as being a resend
|
||||
|
||||
gMessageSystem->mPacketRing.sendPacket(packetp->mSocket,
|
||||
gMessageSystem->mPacketRing->sendPacket(packetp->mSocket,
|
||||
(char *)packetp->mBuffer, packetp->mBufferLength,
|
||||
packetp->mHost);
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ bool Request::post(std::string const& url, headers_t const& headers, std::string
|
||||
llassert_always(success); // AIFIXME: Maybe throw an error.
|
||||
if (!success)
|
||||
return false;
|
||||
buffered_easy_request_w->setPost(NULL, bytes);
|
||||
buffered_easy_request_w->setPost(bytes);
|
||||
buffered_easy_request_w->addHeader("Content-Type: application/octet-stream");
|
||||
buffered_easy_request_w->finalizeRequest(url);
|
||||
|
||||
@@ -128,7 +128,7 @@ bool Request::post(std::string const& url, headers_t const& headers, LLSD const&
|
||||
LLBufferStream buffer_stream(buffer_w->sChannels, buffer_w->getInput().get());
|
||||
LLSDSerialize::toXML(data, buffer_stream);
|
||||
S32 bytes = buffer_w->getInput()->countAfter(buffer_w->sChannels.out(), NULL);
|
||||
buffered_easy_request_w->setPost(NULL, bytes);
|
||||
buffered_easy_request_w->setPost(bytes);
|
||||
buffered_easy_request_w->addHeader("Content-Type: application/llsd+xml");
|
||||
buffered_easy_request_w->finalizeRequest(url);
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "lldispatcher.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include "llstl.h"
|
||||
#include "message.h"
|
||||
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
|
||||
#include "llbuffer.h"
|
||||
#include "llbufferstream.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llmemorystream.h"
|
||||
#include "llsd.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include "llhttpclient.h"
|
||||
|
||||
#include "llassetstorage.h"
|
||||
@@ -36,16 +35,13 @@
|
||||
#include "llvfile.h"
|
||||
#include "llvfs.h"
|
||||
#include "lluri.h"
|
||||
#include "llpumpio.h" // LLPumpIO::chain_t
|
||||
|
||||
#include "message.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
|
||||
#ifdef AI_UNUSED
|
||||
LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
|
||||
#endif // AI_UNUSED
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Responder class moved to LLCurl
|
||||
@@ -128,7 +124,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {}
|
||||
virtual ~RawInjector() {delete mData;}
|
||||
virtual ~RawInjector() {delete [] mData;}
|
||||
|
||||
const char* contentType() { return "application/octet-stream"; }
|
||||
|
||||
@@ -193,11 +189,9 @@ namespace
|
||||
|
||||
LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ);
|
||||
S32 fileSize = vfile.getSize();
|
||||
U8* fileBuffer;
|
||||
fileBuffer = new U8 [fileSize];
|
||||
vfile.read(fileBuffer, fileSize);
|
||||
ostream.write((char*)fileBuffer, fileSize);
|
||||
delete [] fileBuffer;
|
||||
std::vector<U8> fileBuffer(fileSize);
|
||||
vfile.read(&fileBuffer[0], fileSize);
|
||||
ostream.write((char*)&fileBuffer[0], fileSize);
|
||||
eos = true;
|
||||
return STATUS_DONE;
|
||||
}
|
||||
@@ -206,25 +200,16 @@ namespace
|
||||
LLAssetType::EType mAssetType;
|
||||
};
|
||||
|
||||
|
||||
LLPumpIO* theClientPump = NULL;
|
||||
}
|
||||
|
||||
#ifdef AI_UNUSED
|
||||
void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback)
|
||||
{
|
||||
LLHTTPClient::mCertVerifyCallback = callback;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void request(
|
||||
const std::string& url,
|
||||
LLURLRequest::ERequestAction method,
|
||||
Injector* body_injector,
|
||||
LLCurl::ResponderPtr responder,
|
||||
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
|
||||
const LLSD& headers = LLSD()
|
||||
)
|
||||
const LLSD& headers = LLSD())
|
||||
{
|
||||
if (responder)
|
||||
{
|
||||
@@ -251,8 +236,7 @@ static void request(
|
||||
return ;
|
||||
}
|
||||
|
||||
//AIFIXME: getCertVerifyCallback() always return NULL, so we might as well not do this call:
|
||||
//req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
|
||||
req->checkRootCertificate(true);
|
||||
|
||||
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " " << headers << llendl;
|
||||
|
||||
@@ -460,10 +444,9 @@ static LLSD blocking_request(
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*easy_request);
|
||||
|
||||
LLHTTPBuffer http_buffer;
|
||||
std::string body_str;
|
||||
|
||||
// * Set curl handle options
|
||||
curlEasyRequest_w->setopt(CURLOPT_TIMEOUT, timeout); // seconds, see warning at top of function.
|
||||
curlEasyRequest_w->setopt(CURLOPT_TIMEOUT, (long)timeout); // seconds, see warning at top of function.
|
||||
curlEasyRequest_w->setWriteCallback(&LLHTTPBuffer::curl_write, &http_buffer);
|
||||
|
||||
// * Setup headers.
|
||||
@@ -480,6 +463,9 @@ static LLSD blocking_request(
|
||||
}
|
||||
}
|
||||
|
||||
// Needs to stay alive until after the call to perform().
|
||||
std::ostringstream ostr;
|
||||
|
||||
// * Setup specific method / "verb" for the URI (currently only GET and POST supported + poppy)
|
||||
if (method == LLURLRequest::HTTP_GET)
|
||||
{
|
||||
@@ -487,24 +473,13 @@ static LLSD blocking_request(
|
||||
}
|
||||
else if (method == LLURLRequest::HTTP_POST)
|
||||
{
|
||||
curlEasyRequest_w->setopt(CURLOPT_POST, 1);
|
||||
//serialize to ostr then copy to str - need to because ostr ptr is unstable :(
|
||||
std::ostringstream ostr;
|
||||
LLSDSerialize::toXML(body, ostr);
|
||||
body_str = ostr.str();
|
||||
curlEasyRequest_w->setopt(CURLOPT_POSTFIELDS, body_str.c_str());
|
||||
//copied from PHP libs, correct?
|
||||
curlEasyRequest_w->addHeader("Content-Type: application/llsd+xml");
|
||||
|
||||
// copied from llurlrequest.cpp
|
||||
// it appears that apache2.2.3 or django in etch is busted. If
|
||||
// we do not clear the expect header, we get a 500. May be
|
||||
// limited to django/mod_wsgi.
|
||||
curlEasyRequest_w->addHeader("Expect:");
|
||||
LLSDSerialize::toXML(body, ostr);
|
||||
curlEasyRequest_w->setPost(ostr.str().c_str(), ostr.str().length());
|
||||
}
|
||||
|
||||
// * Do the action using curl, handle results
|
||||
lldebugs << "HTTP body: " << body_str << llendl;
|
||||
curlEasyRequest_w->addHeader("Accept: application/llsd+xml");
|
||||
curlEasyRequest_w->finalizeRequest(url);
|
||||
|
||||
@@ -517,7 +492,7 @@ static LLSD blocking_request(
|
||||
llwarns << "CURL REQ URL: " << url << llendl;
|
||||
llwarns << "CURL REQ METHOD TYPE: " << LLURLRequest::actionAsVerb(method) << llendl;
|
||||
llwarns << "CURL REQ HEADERS: " << headers.asString() << llendl;
|
||||
llwarns << "CURL REQ BODY: " << body_str << llendl;
|
||||
llwarns << "CURL REQ BODY: " << ostr.str() << llendl;
|
||||
llwarns << "CURL HTTP_STATUS: " << http_status << llendl;
|
||||
llwarns << "CURL ERROR: " << curlEasyRequest_w->getErrorString() << llendl;
|
||||
llwarns << "CURL ERROR BODY: " << http_buffer.asString() << llendl;
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
//#include "llurlrequest.h"
|
||||
#include "llassettype.h"
|
||||
#include "llcurl.h"
|
||||
#include "lliopipe.h"
|
||||
@@ -155,13 +154,7 @@ public:
|
||||
///< for testing
|
||||
static LLPumpIO &getPump();
|
||||
///< Hippo special
|
||||
|
||||
#ifdef AI_UNUSED
|
||||
static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
|
||||
static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
|
||||
|
||||
protected:
|
||||
static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
|
||||
#endif // AI_UNUSED
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "llapr.h"
|
||||
#include "llbuffer.h"
|
||||
#include "llbufferstream.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llhttpnode.h"
|
||||
#include "lliopipe.h"
|
||||
#include "lliosocket.h"
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "llapr.h"
|
||||
|
||||
#include "llbuffer.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llhost.h"
|
||||
#include "llmemtype.h"
|
||||
#include "llpumpio.h"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
* OS poll indicates it will not block.
|
||||
*/
|
||||
|
||||
#include "llaprpool.h"
|
||||
#include "lliopipe.h"
|
||||
#include "apr_network_io.h"
|
||||
#include "llchainio.h"
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llioutil.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
/**
|
||||
* LLIOFlush
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user