summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt188
-rw-r--r--indra/llcommon/linden_common.h5
-rw-r--r--indra/llcommon/llapr.h10
-rw-r--r--indra/llcommon/llbase64.cpp2
-rw-r--r--indra/llcommon/llcrc.cpp224
-rw-r--r--indra/llcommon/llcrc.h73
-rw-r--r--indra/llcommon/lldarray.h1
-rw-r--r--indra/llcommon/lldate.cpp2
-rw-r--r--indra/llcommon/llerror.cpp2
-rw-r--r--indra/llcommon/llfile.cpp48
-rw-r--r--indra/llcommon/llfile.h13
-rw-r--r--indra/llcommon/llhash.h4
-rw-r--r--indra/llcommon/llheartbeat.cpp7
-rw-r--r--indra/llcommon/llmd5.cpp531
-rw-r--r--indra/llcommon/llmd5.h133
-rw-r--r--indra/llcommon/llpreprocessor.h7
-rw-r--r--indra/llcommon/llptrskiplist.h1
-rw-r--r--indra/llcommon/llrand.cpp176
-rw-r--r--indra/llcommon/llrand.h132
-rw-r--r--indra/llcommon/llsd.cpp23
-rw-r--r--indra/llcommon/llsd.h2
-rw-r--r--indra/llcommon/llsdserialize.cpp2
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp2
-rw-r--r--indra/llcommon/llsdutil.cpp118
-rw-r--r--indra/llcommon/llsdutil.h13
-rw-r--r--indra/llcommon/llstring.cpp2
-rw-r--r--indra/llcommon/llthread.cpp2
-rw-r--r--indra/llcommon/llthread.h2
-rw-r--r--indra/llcommon/lltimer.cpp17
-rw-r--r--indra/llcommon/lltimer.h33
-rw-r--r--indra/llcommon/lluri.cpp2
-rw-r--r--indra/llcommon/lluuid.cpp923
-rw-r--r--indra/llcommon/lluuid.h330
-rw-r--r--indra/llcommon/stdtypes.h2
34 files changed, 2861 insertions, 171 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
new file mode 100644
index 0000000000..72d267d794
--- /dev/null
+++ b/indra/llcommon/CMakeLists.txt
@@ -0,0 +1,188 @@
+# -*- cmake -*-
+
+project(llcommon)
+
+include(00-Common)
+include(LLCommon)
+
+include_directories(
+ ${EXPAT_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${ZLIB_INCLUDE_DIRS}
+ )
+
+set(llcommon_SOURCE_FILES
+ llapp.cpp
+ llapr.cpp
+ llassettype.cpp
+ llbase32.cpp
+ llbase64.cpp
+ llcommon.cpp
+ llcrc.cpp
+ llcriticaldamp.cpp
+ lldate.cpp
+ llerror.cpp
+ llerrorthread.cpp
+ llevent.cpp
+ llfasttimer.cpp
+ llfile.cpp
+ llfindlocale.cpp
+ llfixedbuffer.cpp
+ llformat.cpp
+ llframetimer.cpp
+ llheartbeat.cpp
+ llindraconfigfile.cpp
+ llliveappconfig.cpp
+ lllivefile.cpp
+ lllog.cpp
+ llmd5.cpp
+ llmemory.cpp
+ llmemorystream.cpp
+ llmetrics.cpp
+ llmortician.cpp
+ llprocessor.cpp
+ llqueuedthread.cpp
+ llrand.cpp
+ llrun.cpp
+ llsd.cpp
+ llsdserialize.cpp
+ llsdserialize_xml.cpp
+ llsdutil.cpp
+ llsecondlifeurls.cpp
+ llstat.cpp
+ llstreamtools.cpp
+ llstring.cpp
+ llstringtable.cpp
+ llsys.cpp
+ llthread.cpp
+ lltimer.cpp
+ lluri.cpp
+ lluuid.cpp
+ llworkerthread.cpp
+ metaclass.cpp
+ metaproperty.cpp
+ reflective.cpp
+ timing.cpp
+ u64.cpp
+ )
+
+set(llcommon_HEADER_FILES
+ CMakeLists.txt
+
+ bitpack.h
+ ctype_workaround.h
+ doublelinkedlist.h
+ imageids.h
+ indra_constants.h
+ linden_common.h
+ linked_lists.h
+ llagentconstants.h
+ llapp.h
+ llapr.h
+ llassettype.h
+ llassoclist.h
+ llavatarconstants.h
+ llbase32.h
+ llbase64.h
+ llboost.h
+ llchat.h
+ llclickaction.h
+ llcommon.h
+ llcrc.h
+ llcriticaldamp.h
+ lldarray.h
+ lldarrayptr.h
+ lldate.h
+ lldefs.h
+ lldepthstack.h
+ lldlinked.h
+ lldqueueptr.h
+ llendianswizzle.h
+ llenum.h
+ llerror.h
+ llerrorcontrol.h
+ llerrorlegacy.h
+ llerrorthread.h
+ llevent.h
+ lleventemitter.h
+ llextendedstatus.h
+ llfasttimer.h
+ llfile.h
+ llfindlocale.h
+ llfixedbuffer.h
+ llformat.h
+ llframetimer.h
+ llhash.h
+ llheartbeat.h
+ llindexedqueue.h
+ llindraconfigfile.h
+ llkeythrottle.h
+ lllinkedqueue.h
+ llliveappconfig.h
+ lllivefile.h
+ lllocalidhashmap.h
+ lllog.h
+ lllslconstants.h
+ llmap.h
+ llmd5.h
+ llmemory.h
+ llmemorystream.h
+ llmemtype.h
+ llmetrics.h
+ llmortician.h
+ llnametable.h
+ llpreprocessor.h
+ llpriqueuemap.h
+ llprocessor.h
+ llptrskiplist.h
+ llptrskipmap.h
+ llqueuedthread.h
+ llrand.h
+ llrun.h
+ llsd.h
+ llsdserialize.h
+ llsdserialize_xml.h
+ llsdutil.h
+ llsecondlifeurls.h
+ llsimplehash.h
+ llskiplist.h
+ llskipmap.h
+ llstack.h
+ llstat.h
+ llstatenums.h
+ llstl.h
+ llstreamtools.h
+ llstrider.h
+ llstring.h
+ llstringtable.h
+ llsys.h
+ llthread.h
+ lltimer.h
+ lluri.h
+ lluuid.h
+ lluuidhashmap.h
+ llversionserver.h
+ llversionviewer.h
+ llworkerthread.h
+ metaclass.h
+ metaclasst.h
+ metaproperty.h
+ metapropertyt.h
+ processor.h
+ reflective.h
+ reflectivet.h
+ roles_constants.h
+ stdenums.h
+ stdtypes.h
+ string_table.h
+ timer.h
+ timing.h
+ u64.h
+ )
+
+set_source_files_properties(${llcommon_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
+
+add_library (llcommon ${llcommon_SOURCE_FILES})
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index 9ee4d1159e..60ea21d642 100644
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
@@ -45,9 +45,10 @@
#include <iostream>
#include <fstream>
-// Work around stupid Microsoft STL warning
+// Work Microsoft compiler warnings
#ifdef LL_WINDOWS
-#pragma warning (disable : 4702) // warning C4702: unreachable code
+#pragma warning (disable : 4702) // unreachable code
+#pragma warning (disable : 4244) // conversion from time_t to S32
#endif // LL_WINDOWS
#include <algorithm>
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index b6c363886c..3927d5f014 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -40,11 +40,11 @@
#include <boost/noncopyable.hpp>
-#include "apr-1/apr_thread_proc.h"
-#include "apr-1/apr_thread_mutex.h"
-#include "apr-1/apr_getopt.h"
-#include "apr-1/apr_signal.h"
-#include "apr-1/apr_atomic.h"
+#include "apr_thread_proc.h"
+#include "apr_thread_mutex.h"
+#include "apr_getopt.h"
+#include "apr_signal.h"
+#include "apr_atomic.h"
#include "llstring.h"
extern apr_thread_mutex_t* gLogMutexp;
diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp
index 207b367f6d..ce10e07a0a 100644
--- a/indra/llcommon/llbase64.cpp
+++ b/indra/llcommon/llbase64.cpp
@@ -36,7 +36,7 @@
#include <string>
-#include "apr-1/apr_base64.h"
+#include "apr_base64.h"
// static
diff --git a/indra/llcommon/llcrc.cpp b/indra/llcommon/llcrc.cpp
new file mode 100644
index 0000000000..0836ccb66b
--- /dev/null
+++ b/indra/llcommon/llcrc.cpp
@@ -0,0 +1,224 @@
+/**
+ * @file llcrc.cpp
+ * @brief implementation of the crc class.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llcrc.h"
+#include "llerror.h"
+
+/* Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ code or tables extracted from it, as desired without restriction.*/
+
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* 1. The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
+/* be they sixteen or thirty-two bits wide. You simply choose the */
+/* appropriate table. Alternatively, because the table can be */
+/* generated at runtime, you can start by generating the table for */
+/* the polynomial in question and use exactly the same "updcrc", */
+/* if your application needn't simultaneously handle two CRC */
+/* polynomials. (Note, however, that XMODEM is strange.) */
+/* */
+/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
+/* of course, 32-bit entries work OK if the high 16 bits are zero. */
+/* */
+/* 4. The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+#define UPDC32(octet,crc) (crc_32_tab[((crc) \
+ ^ ((U8)octet)) & 0xff] ^ ((crc) >> 8))
+
+
+static U32 crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
+0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+
+///----------------------------------------------------------------------------
+/// Class llcrc
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLCRC::LLCRC() : mCurrent(0xffffffff)
+{
+}
+
+
+U32 LLCRC::getCRC() const
+{
+ return ~mCurrent;
+}
+
+void LLCRC::update(U8 next_byte)
+{
+ mCurrent = UPDC32(next_byte, mCurrent);
+}
+
+void LLCRC::update(const U8* buffer, size_t buffer_size)
+{
+ for (size_t i = 0; i < buffer_size; i++)
+ {
+ mCurrent = UPDC32(buffer[i], mCurrent);
+ }
+}
+
+void LLCRC::update(const char* filename)
+{
+ if (!filename)
+ {
+ llerrs << "No filename specified" << llendl;
+ return;
+ }
+
+ FILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
+
+ if (fp)
+ {
+ fseek(fp, 0, SEEK_END);
+ long size = ftell(fp);
+
+ fseek(fp, 0, SEEK_SET);
+
+ if (size > 0)
+ {
+ U8* data = new U8[size];
+ size_t nread;
+
+ nread = fread(data, 1, size, fp);
+ fclose(fp);
+
+ if (nread < (size_t) size)
+ {
+ llwarns << "Short read on " << filename << llendl;
+ }
+
+ update(data, nread);
+ delete[] data;
+ }
+ }
+}
+
+
+#ifdef _DEBUG
+BOOL LLCRC::testHarness()
+{
+ const S32 TEST_BUFFER_SIZE = 16;
+ const char TEST_BUFFER[TEST_BUFFER_SIZE] = "hello &#$)$&Nd0"; /* Flawfinder: ignore */
+ LLCRC c1, c2;
+ c1.update((U8*)TEST_BUFFER, TEST_BUFFER_SIZE - 1);
+ char* rh = (char*)TEST_BUFFER;
+ while(*rh != '\0')
+ {
+ c2.update(*rh);
+ ++rh;
+ }
+ return(c1.getCRC() == c2.getCRC());
+}
+#endif
+
+
+
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
diff --git a/indra/llcommon/llcrc.h b/indra/llcommon/llcrc.h
new file mode 100644
index 0000000000..287c1fbc41
--- /dev/null
+++ b/indra/llcommon/llcrc.h
@@ -0,0 +1,73 @@
+/**
+ * @file llcrc.h
+ * @brief LLCRC class header file.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCRC_H
+#define LL_LLCRC_H
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class llcrc
+//
+// Simple 32 bit crc. To use, instantiate an LLCRC instance and feed
+// it the bytes you want to check. It will update the internal crc as
+// you go, and you can qery it at the end. As a horribly inefficient
+// example (don't try this at work kids):
+//
+// LLCRC crc;
+// FILE* fp = LLFile::fopen(filename,"rb");
+// while(!feof(fp)) {
+// crc.update(fgetc(fp));
+// }
+// fclose(fp);
+// llinfos << "File crc: " << crc.getCRC() << llendl;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLCRC
+{
+protected:
+ U32 mCurrent;
+
+public:
+ LLCRC();
+
+ U32 getCRC() const;
+ void update(U8 next_byte);
+ void update(const U8* buffer, size_t buffer_size);
+ void update(const char *filename);
+
+#ifdef _DEBUG
+ // This function runs tests to make sure the crc is
+ // working. Returns TRUE if it is.
+ static BOOL testHarness();
+#endif
+};
+
+
+#endif // LL_LLCRC_H
diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h
index c7268b8dab..8784bdfb02 100644
--- a/indra/llcommon/lldarray.h
+++ b/indra/llcommon/lldarray.h
@@ -32,7 +32,6 @@
#ifndef LL_LLDARRAY_H
#define LL_LLDARRAY_H
-#include "llmath.h"
#include "llerror.h"
#include <vector>
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 37b912df3d..3cc4cca706 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -34,7 +34,7 @@
#include "linden_common.h"
#include "lldate.h"
-#include "apr-1/apr_time.h"
+#include "apr_time.h"
#include <iomanip>
#include <sstream>
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 95038bea4c..fa3a01c191 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -168,7 +168,7 @@ namespace {
private:
bool mTimestamp;
- typedef enum ANSIState {ANSI_PROBE, ANSI_YES, ANSI_NO};
+ enum ANSIState {ANSI_PROBE, ANSI_YES, ANSI_NO};
ANSIState mUseANSI;
void colorANSI(const std::string color)
{
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 4e868eb5a1..6b8f8e68c5 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -32,6 +32,10 @@
* $/LicenseInfo$
*/
+#if LL_WINDOWS
+#include <windows.h>
+#endif
+
#include "linden_common.h"
#include "llfile.h"
#include "llstring.h"
@@ -128,6 +132,50 @@ int LLFile::stat(const char* filename, llstat* filestatus)
#endif
}
+bool LLFile::isdir(const char *filename)
+{
+ llstat st;
+
+ return stat(filename, &st) == 0 && S_ISDIR(st.st_mode);
+}
+
+bool LLFile::isfile(const char *filename)
+{
+ llstat st;
+
+ return stat(filename, &st) == 0 && S_ISREG(st.st_mode);
+}
+
+const char *LLFile::tmpdir()
+{
+ static std::string utf8path;
+
+ if (utf8path.empty())
+ {
+ char sep;
+#if LL_WINDOWS
+ sep = '\\';
+
+ DWORD len = GetTempPathW(0, L"");
+ llutf16string utf16path;
+ utf16path.resize(len + 1);
+ len = GetTempPathW(static_cast<DWORD>(utf16path.size()), &utf16path[0]);
+ utf8path = utf16str_to_utf8str(utf16path);
+#else
+ sep = '/';
+
+ char *env = getenv("TMPDIR");
+
+ utf8path = env ? env : "/tmp/";
+#endif
+ if (utf8path[utf8path.size() - 1] != sep)
+ {
+ utf8path += sep;
+ }
+ }
+ return utf8path.c_str();
+}
+
/***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index a8a6965c0d..bd51ac2aa9 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -50,15 +50,23 @@ typedef FILE LLFILE;
#define USE_LLFILESTREAMS 0
#endif
+#include <sys/stat.h>
#if LL_WINDOWS
// windows version of stat function and stat data structure are called _stat
typedef struct _stat llstat;
#else
-#include <sys/stat.h>
typedef struct stat llstat;
#endif
+#ifndef S_ISREG
+# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISDIR
+# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
+#endif
+
class LLFile
{
public:
@@ -74,7 +82,10 @@ public:
static int remove(const char* filename);
static int rename(const char* filename,const char* newname);
static int stat(const char* filename,llstat* file_status);
+ static bool isdir(const char* filename);
+ static bool isfile(const char* filename);
static LLFILE * _Fiopen(const char *filename, std::ios::openmode mode,int); // protection currently unused
+ static const char * tmpdir();
};
diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h
index f4b05869a4..08299f5ddc 100644
--- a/indra/llcommon/llhash.h
+++ b/indra/llcommon/llhash.h
@@ -38,7 +38,9 @@
#include <hash_map>
#include <algorithm>
#elif LL_DARWIN || LL_LINUX
-# if GCC_VERSION >= 30400 // gcc 3.4 and up
+# if GCC_VERSION >= 40300 // gcc 4.3 and up
+# include <backward/hashtable.h>
+# elif GCC_VERSION >= 30400 // gcc 3.4 and up
# include <ext/hashtable.h>
# elif __GNUC__ >= 3
# include <ext/stl_hashtable.h>
diff --git a/indra/llcommon/llheartbeat.cpp b/indra/llcommon/llheartbeat.cpp
index 782a4f7ff6..b08e72137a 100644
--- a/indra/llcommon/llheartbeat.cpp
+++ b/indra/llcommon/llheartbeat.cpp
@@ -72,8 +72,13 @@ LLHeartbeat::rawSend()
if (mSuppressed)
return 0; // Pretend we succeeded.
+ int result;
+#ifndef LL_DARWIN
union sigval dummy;
- int result = sigqueue(getppid(), LL_HEARTBEAT_SIGNAL, dummy);
+ result = sigqueue(getppid(), LL_HEARTBEAT_SIGNAL, dummy);
+#else
+ result = kill(getppid(), LL_HEARTBEAT_SIGNAL);
+#endif
if (result == 0)
return 0; // success
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
new file mode 100644
index 0000000000..033eb2f44d
--- /dev/null
+++ b/indra/llcommon/llmd5.cpp
@@ -0,0 +1,531 @@
+/**
+ * @file llmd5.cpp
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// llMD5.CC - source code for the C++/object oriented translation and
+// modification of MD5.
+//
+// Adapted to Linden Lab by Frank Filipanits, 6/25/2002
+// Fixed potential memory leak, James Cook, 6/27/2002
+
+// Translation and modification (c) 1995 by Mordechai T. Abzug
+
+// This translation/ modification is provided "as is," without express or
+// implied warranty of any kind.
+
+// The translator/ modifier does not claim (1) that MD5 will do what you think
+// it does; (2) that this translation/ modification is accurate; or (3) that
+// this software is "merchantible." (Language for this disclaimer partially
+// copied from the disclaimer below).
+
+/* based on:
+
+ MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ MDDRIVER.C - test driver for MD2, MD4 and MD5
+
+
+ Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+
+ */
+
+
+
+
+
+#include "linden_common.h"
+
+#include "llmd5.h"
+
+#include <cassert>
+
+// how many bytes to grab at a time when checking files
+const int LLMD5::BLOCK_LEN = 4096;
+
+
+// LLMD5 simple initialization method
+
+LLMD5::LLMD5()
+{
+ init();
+}
+
+
+
+
+// MD5 block update operation. Continues an MD5 message-digest
+// operation, processing another message block, and updating the
+// context.
+
+void LLMD5::update (const uint1 *input, const uint4 input_length) {
+
+ uint4 input_index, buffer_index;
+ uint4 buffer_space; // how much space is left in buffer
+
+ if (finalized){ // so we can't update!
+ std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl;
+ return;
+ }
+
+ // Compute number of bytes mod 64
+ buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
+
+ // Update number of bits
+ if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
+ count[1]++;
+
+ count[1] += ((uint4)input_length >> 29);
+
+
+ buffer_space = 64 - buffer_index; // how much space is left in buffer
+
+ // Transform as many times as possible.
+ if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
+ // fill the rest of the buffer and transform
+ memcpy( /* Flawfinder: ignore */
+ buffer + buffer_index,
+ input,
+ buffer_space);
+ transform (buffer);
+
+ // now, transform each 64-byte piece of the input, bypassing the buffer
+ if (input == NULL || input_length == 0){
+ std::cerr << "LLMD5::update: Invalid input!" << std::endl;
+ return;
+ }
+
+ for (input_index = buffer_space; input_index + 63 < input_length;
+ input_index += 64)
+ transform (input+input_index);
+
+ buffer_index = 0; // so we can buffer remaining
+ }
+ else
+ input_index=0; // so we can buffer the whole input
+
+
+ // and here we do the buffering:
+ memcpy(buffer+buffer_index, input+input_index, input_length-input_index); /* Flawfinder: ignore */
+}
+
+
+
+// MD5 update for files.
+// Like above, except that it works on files (and uses above as a primitive.)
+
+void LLMD5::update(FILE* file){
+
+ unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
+ int len;
+
+ while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) )
+ update(buffer, len);
+
+ fclose (file);
+
+}
+
+
+
+
+
+
+// MD5 update for istreams.
+// Like update for files; see above.
+
+void LLMD5::update(std::istream& stream){
+
+ unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
+ int len;
+
+ while (stream.good()){
+ stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable.
+ len=stream.gcount();
+ update(buffer, len);
+ }
+
+}
+
+
+
+
+
+// MD5 finalization. Ends an MD5 message-digest operation, writing the
+// the message digest and zeroizing the context.
+
+
+void LLMD5::finalize (){
+
+ unsigned char bits[8]; /* Flawfinder: ignore */
+ unsigned int index, padLen;
+ static uint1 PADDING[64]={
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ if (finalized){
+ std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl;
+ return;
+ }
+
+ // Save number of bits
+ encode (bits, count, 8);
+
+ // Pad out to 56 mod 64.
+ index = (uint4) ((count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ update (PADDING, padLen);
+
+ // Append length (before padding)
+ update (bits, 8);
+
+ // Store state in digest
+ encode (digest, state, 16);
+
+ // Zeroize sensitive information
+ memset (buffer, 0, sizeof(*buffer));
+
+ finalized=1;
+
+}
+
+
+
+
+LLMD5::LLMD5(FILE *file){
+
+ init(); // must be called be all constructors
+ update(file);
+ finalize ();
+}
+
+
+
+
+LLMD5::LLMD5(std::istream& stream){
+
+ init(); // must called by all constructors
+ update (stream);
+ finalize();
+}
+
+// Digest a string of the format ("%s:%i" % (s, number))
+LLMD5::LLMD5(const unsigned char *string, const unsigned int number)
+{
+ const char *colon = ":";
+ char tbuf[16]; /* Flawfinder: ignore */
+ init();
+ update(string, (U32)strlen((const char *) string)); /* Flawfinder: ignore */
+ update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */
+ snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */
+ update((const unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */
+ finalize();
+}
+
+// Digest a string
+LLMD5::LLMD5(const unsigned char *s)
+{
+ init();
+ update(s, (U32)strlen((const char *) s)); /* Flawfinder: ignore */
+ finalize();
+}
+
+void LLMD5::raw_digest(unsigned char *s)
+{
+ if (!finalized)
+ {
+ std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "<<
+ "finalized the digest!" << std::endl;
+ s[0] = '\0';
+ return;
+ }
+
+ memcpy(s, digest, 16); /* Flawfinder: ignore */
+ return;
+}
+
+
+
+void LLMD5::hex_digest(char *s)
+{
+ int i;
+
+ if (!finalized)
+ {
+ std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "<<
+ "finalized the digest!" <<std::endl;
+ s[0] = '\0';
+ return;
+ }
+
+ for (i=0; i<16; i++)
+ {
+ sprintf(s+i*2, "%02x", digest[i]); /* Flawfinder: ignore */
+ }
+
+ s[32]='\0';
+
+ return;
+}
+
+
+
+
+
+std::ostream& operator<<(std::ostream &stream, LLMD5 context)
+{
+ char s[33]; /* Flawfinder: ignore */
+ context.hex_digest(s);
+ stream << s;
+ return stream;
+}
+
+
+
+
+// PRIVATE METHODS:
+
+
+
+void LLMD5::init(){
+ finalized=0; // we just started!
+
+ // Nothing counted, so count=0
+ count[0] = 0;
+ count[1] = 0;
+
+ // Load magic initialization constants.
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+}
+
+
+
+// Constants for MD5Transform routine.
+// Although we could use C++ style constants, defines are actually better,
+// since they let us easily evade scope clashes.
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+// #defines are faster then inline, etc because the compiler is not required to inline.
+// Timing tests prove that this works ~40% faster on win with msvc++2k3 over using static inline.
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+
+
+// LLMD5 basic transformation. Transforms state based on block.
+void LLMD5::transform (const U8 block[64]){
+
+ uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ decode (x, block, 64);
+
+ assert(!finalized); // not just a user error, since the method is private
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ // Zeroize sensitive information.
+ memset ( (uint1 *) x, 0, sizeof(x));
+
+}
+
+
+
+// Encodes input (UINT4) into output (unsigned char). Assumes len is
+// a multiple of 4.
+void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) {
+
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (uint1) (input[i] & 0xff);
+ output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
+ output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
+ output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
+ }
+}
+
+
+
+
+// Decodes input (unsigned char) into output (UINT4). Assumes len is
+// a multiple of 4.
+void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){
+
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
+ (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
+}
diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h
new file mode 100644
index 0000000000..7dabbfeb0f
--- /dev/null
+++ b/indra/llcommon/llmd5.h
@@ -0,0 +1,133 @@
+/**
+ * @file llmd5.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMD5_H
+#define LL_LLMD5_H
+
+// LLMD5.CC - source code for the C++/object oriented translation and
+// modification of MD5.
+
+// Translation and modification (c) 1995 by Mordechai T. Abzug
+
+// This translation/ modification is provided "as is," without express or
+// implied warranty of any kind.
+
+// The translator/ modifier does not claim (1) that MD5 will do what you think
+// it does; (2) that this translation/ modification is accurate; or (3) that
+// this software is "merchantible." (Language for this disclaimer partially
+// copied from the disclaimer below).
+
+/* based on:
+
+ MD5.H - header file for MD5C.C
+ MDDRIVER.C - test driver for MD2, MD4 and MD5
+
+ Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+
+*/
+
+// use for the raw digest output
+const int MD5RAW_BYTES = 16;
+
+// use for outputting hex digests
+const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null
+const int MD5HEX_STR_BYTES = 32; // message system fixed size
+
+class LLMD5 {
+// first, some types:
+ typedef unsigned int uint4; // assumes integer is 4 words long
+ typedef unsigned short int uint2; // assumes short integer is 2 words long
+ typedef unsigned char uint1; // assumes char is 1 word long
+
+// how many bytes to grab at a time when checking files
+ static const int BLOCK_LEN;
+
+public:
+// methods for controlled operation:
+ LLMD5 (); // simple initializer
+ void update (const uint1 *input, const uint4 input_length);
+ void update (std::istream& stream);
+ void update (FILE *file);
+ void finalize ();
+
+// constructors for special circumstances. All these constructors finalize
+// the MD5 context.
+ LLMD5 (const unsigned char *string); // digest string, finalize
+ LLMD5 (std::istream& stream); // digest stream, finalize
+ LLMD5 (FILE *file); // digest file, close, finalize
+ LLMD5 (const unsigned char *string, const unsigned int number);
+
+// methods to acquire finalized result
+ void raw_digest(unsigned char *array); // provide 16-byte array for binary data
+ void hex_digest(char *string); // provide 33-byte array for ascii-hex string
+ friend std::ostream& operator<< (std::ostream&, LLMD5 context);
+
+
+
+private:
+
+
+// next, the private data:
+ uint4 state[4];
+ uint4 count[2]; // number of *bits*, mod 2^64
+ uint1 buffer[64]; // input buffer
+ uint1 digest[16];
+ uint1 finalized;
+
+// last, the private methods, mostly static:
+ void init (); // called by all constructors
+ void transform (const uint1 *buffer); // does the real update work. Note
+ // that length is implied to be 64.
+
+ static void encode (uint1 *dest, const uint4 *src, const uint4 length);
+ static void decode (uint4 *dest, const uint1 *src, const uint4 length);
+
+};
+
+#endif // LL_LLMD5_H
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 454a820ce5..dc4ac18c4d 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -64,6 +64,9 @@
#ifndef LL_MSVC
#define LL_MSVC 1
#endif
+ #if _MSC_VER < 1400
+ #define LL_MSVC7 //Visual C++ 2003 or earlier
+ #endif
#endif
// Deal with minor differences on Unixy OSes.
@@ -104,9 +107,7 @@ using snprintf_hack::snprintf;
#if defined(LL_WINDOWS)
#define BOOST_REGEX_NO_LIB 1
#define CURL_STATICLIB 1
-
-#define LL_LCD_COMPILE 1
-
+#define XML_STATIC
#endif // LL_WINDOWS
diff --git a/indra/llcommon/llptrskiplist.h b/indra/llcommon/llptrskiplist.h
index b03faf57f1..90bcec535d 100644
--- a/indra/llcommon/llptrskiplist.h
+++ b/indra/llcommon/llptrskiplist.h
@@ -33,6 +33,7 @@
#define LL_LLPTRSKIPLIST_H
#include "llerror.h"
+#include "llrand.h"
//#include "vmath.h"
#include "llrand.h"
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
new file mode 100644
index 0000000000..11ecd8efde
--- /dev/null
+++ b/indra/llcommon/llrand.cpp
@@ -0,0 +1,176 @@
+/**
+ * @file llrand.cpp
+ * @brief Global random generator.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llrand.h"
+#include "lluuid.h"
+
+/**
+ * Through analysis, we have decided that we want to take values which
+ * are close enough to 1.0 to map back to 0.0. We came to this
+ * conclusion from noting that:
+ *
+ * [0.0, 1.0)
+ *
+ * when scaled to the integer set:
+ *
+ * [0, 4)
+ *
+ * there is some value close enough to 1.0 that when multiplying by 4,
+ * gets truncated to 4. Therefore:
+ *
+ * [0,1-eps] => 0
+ * [1,2-eps] => 1
+ * [2,3-eps] => 2
+ * [3,4-eps] => 3
+ *
+ * So 0 gets uneven distribution if we simply clamp. The actual
+ * clamp utilized in this file is to map values out of range back
+ * to 0 to restore uniform distribution.
+ *
+ * Also, for clamping floats when asking for a distribution from
+ * [0.0,g) we have determined that for values of g < 0.5, then
+ * rand*g=g, which is not the desired result. As above, we clamp to 0
+ * to restore uniform distribution.
+ */
+
+// *NOTE: The system rand implementation is probably not correct.
+#define LL_USE_SYSTEM_RAND 0
+
+#if LL_USE_SYSTEM_RAND
+#include <cstdlib>
+#endif
+
+#if LL_USE_SYSTEM_RAND
+class LLSeedRand
+{
+public:
+ LLSeedRand()
+ {
+#if LL_WINDOWS
+ srand(LLUUID::getRandomSeed());
+#else
+ srand48(LLUUID::getRandomSeed());
+#endif
+ }
+};
+static LLSeedRand sRandomSeeder;
+inline F64 ll_internal_random_double()
+{
+#if LL_WINDOWS
+ return (F64)rand() / (F64)RAND_MAX;
+#else
+ return drand48();
+#endif
+}
+inline F32 ll_internal_random_float()
+{
+#if LL_WINDOWS
+ return (F32)rand() / (F32)RAND_MAX;
+#else
+ return (F32)drand48();
+#endif
+}
+#else
+static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
+inline F64 ll_internal_random_double()
+{
+ // *HACK: Through experimentation, we have found that dual core
+ // CPUs (or at least multi-threaded processes) seem to
+ // occasionally give an obviously incorrect random number -- like
+ // 5^15 or something. Sooooo, clamp it as described above.
+ F64 rv = gRandomGenerator();
+ if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0);
+ return rv;
+}
+
+inline F32 ll_internal_random_float()
+{
+ // The clamping rules are described above.
+ F32 rv = (F32)gRandomGenerator();
+ if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f);
+ return rv;
+}
+#endif
+
+S32 ll_rand()
+{
+ return ll_rand(RAND_MAX);
+}
+
+S32 ll_rand(S32 val)
+{
+ // The clamping rules are described above.
+ S32 rv = (S32)(ll_internal_random_double() * val);
+ if(rv == val) return 0;
+ return rv;
+}
+
+F32 ll_frand()
+{
+ return ll_internal_random_float();
+}
+
+F32 ll_frand(F32 val)
+{
+ // The clamping rules are described above.
+ F32 rv = ll_internal_random_float() * val;
+ if(val > 0)
+ {
+ if(rv >= val) return 0.0f;
+ }
+ else
+ {
+ if(rv <= val) return 0.0f;
+ }
+ return rv;
+}
+
+F64 ll_drand()
+{
+ return ll_internal_random_double();
+}
+
+F64 ll_drand(F64 val)
+{
+ // The clamping rules are described above.
+ F64 rv = ll_internal_random_double() * val;
+ if(val > 0)
+ {
+ if(rv >= val) return 0.0;
+ }
+ else
+ {
+ if(rv <= val) return 0.0;
+ }
+ return rv;
+}
diff --git a/indra/llcommon/llrand.h b/indra/llcommon/llrand.h
new file mode 100644
index 0000000000..5bd874ba83
--- /dev/null
+++ b/indra/llcommon/llrand.h
@@ -0,0 +1,132 @@
+/**
+ * @file llrand.h
+ * @brief Information, functions, and typedefs for randomness.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLRAND_H
+#define LL_LLRAND_H
+
+#include <boost/random/lagged_fibonacci.hpp>
+#include <boost/random/mersenne_twister.hpp>
+
+/**
+ * Use the boost random number generators if you want a stateful
+ * random numbers. If you want more random numbers, use the
+ * c-functions since they will generate faster/better randomness
+ * across the process.
+ *
+ * I tested some of the boost random engines, and picked a good double
+ * generator and a good integer generator. I also took some timings
+ * for them on linux using gcc 3.3.5. The harness also did some other
+ * fairly trivial operations to try to limit compiler optimizations,
+ * so these numbers are only good for relative comparisons.
+ *
+ * usec/inter algorithm
+ * 0.21 boost::minstd_rand0
+ * 0.039 boost:lagged_fibonacci19937
+ * 0.036 boost:lagged_fibonacci607
+ * 0.44 boost::hellekalek1995
+ * 0.44 boost::ecuyer1988
+ * 0.042 boost::rand48
+ * 0.043 boost::mt11213b
+ * 0.028 stdlib random()
+ * 0.05 stdlib lrand48()
+ * 0.034 stdlib rand()
+ * 0.020 the old & lame LLRand
+ */
+
+/**
+ *@brief Generate a float from [0, RAND_MAX).
+ */
+S32 ll_rand();
+
+/**
+ *@brief Generate a float from [0, val) or (val, 0].
+ */
+S32 ll_rand(S32 val);
+
+/**
+ *@brief Generate a float from [0, 1.0).
+ */
+F32 ll_frand();
+
+/**
+ *@brief Generate a float from [0, val) or (val, 0].
+ */
+F32 ll_frand(F32 val);
+
+/**
+ *@brief Generate a double from [0, 1.0).
+ */
+F64 ll_drand();
+
+/**
+ *@brief Generate a double from [0, val) or (val, 0].
+ */
+F64 ll_drand(F64 val);
+
+/**
+ * @brief typedefs for good boost lagged fibonacci.
+ * @see boost::lagged_fibonacci
+ *
+ * These generators will quickly generate doubles. Note the memory
+ * requirements, because they are somewhat high. I chose the smallest
+ * one, and one comparable in speed but higher periodicity without
+ * outrageous memory requirements.
+ * To use:
+ * LLRandLagFib607 foo((U32)time(NULL));
+ * double bar = foo();
+ */
+
+typedef boost::lagged_fibonacci607 LLRandLagFib607;
+/**<
+ * lengh of cycle: 2^32,000
+ * memory: 607*sizeof(double) (about 5K)
+ */
+
+typedef boost::lagged_fibonacci2281 LLRandLagFib2281;
+/**<
+ * lengh of cycle: 2^120,000
+ * memory: 2281*sizeof(double) (about 17K)
+ */
+
+/**
+ * @breif typedefs for a good boost mersenne twister implementation.
+ * @see boost::mersenne_twister
+ *
+ * This fairly quickly generates U32 values
+ * To use:
+ * LLRandMT19937 foo((U32)time(NULL));
+ * U32 bar = foo();
+ *
+ * lengh of cycle: 2^19,937-1
+ * memory: about 2496 bytes
+ */
+typedef boost::mt11213b LLRandMT19937;
+#endif
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 19030cd4fd..099f233f56 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -42,10 +42,11 @@
#endif
#ifdef NAME_UNNAMED_NAMESPACE
-namespace LLSDUnnamedNamespace {
+namespace LLSDUnnamedNamespace
#else
-namespace {
+namespace
#endif
+{
class ImplMap;
class ImplArray;
}
@@ -127,10 +128,10 @@ public:
virtual void erase(Integer) { }
virtual const LLSD& ref(Integer) const { return undef(); }
- virtual LLSD::map_const_iterator beginMap() const { return LLSD::map_const_iterator(); }
- virtual LLSD::map_const_iterator endMap() const { return LLSD::map_const_iterator(); }
- virtual LLSD::array_const_iterator beginArray() const { return LLSD::array_const_iterator(); }
- virtual LLSD::array_const_iterator endArray() const { return LLSD::array_const_iterator(); }
+ virtual LLSD::map_const_iterator beginMap() const { return endMap(); }
+ virtual LLSD::map_const_iterator endMap() const { static const std::map<String, LLSD> empty; return empty.end(); }
+ virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
+ virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
static const LLSD& undef();
@@ -139,10 +140,11 @@ public:
};
#ifdef NAME_UNNAMED_NAMESPACE
-namespace LLSDUnnamedNamespace {
+namespace LLSDUnnamedNamespace
#else
-namespace {
+namespace
#endif
+{
template<LLSD::Type T, class Data, class DataRef = Data>
class ImplBase : public LLSD::Impl
///< This class handles most of the work for a subclass of Impl
@@ -655,10 +657,11 @@ U32 LLSD::Impl::sOutstandingCount = 0;
#ifdef NAME_UNNAMED_NAMESPACE
-namespace LLSDUnnamedNamespace {
+namespace LLSDUnnamedNamespace
#else
-namespace {
+namespace
#endif
+{
inline LLSD::Impl& safe(LLSD::Impl* impl)
{ return LLSD::Impl::safe(impl); }
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 1ba57b1e95..307d73608c 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -40,7 +40,7 @@
#include "lldate.h"
#include "lluri.h"
-#include "../llmath/lluuid.h"
+#include "lluuid.h"
/**
LLSD provides a flexible data system similar to the data facilities of
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 6f4a49180d..2183792bb1 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -37,7 +37,7 @@
#include "llstreamtools.h" // for fullread
#include <iostream>
-#include "apr-1/apr_base64.h"
+#include "apr_base64.h"
#if !LL_WINDOWS
#include <netinet/in.h> // htonl & ntohl
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index b3596e8705..cddb243faf 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -35,7 +35,7 @@
#include <iostream>
#include <deque>
-#include "apr-1/apr_base64.h"
+#include "apr_base64.h"
extern "C"
{
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index 992c883a7e..6f26447695 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -46,124 +46,6 @@
#include "llsdserialize.h"
-// vector3
-LLSD ll_sd_from_vector3(const LLVector3& vec)
-{
- LLSD rv;
- rv.append((F64)vec.mV[VX]);
- rv.append((F64)vec.mV[VY]);
- rv.append((F64)vec.mV[VZ]);
- return rv;
-}
-
-LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index)
-{
- LLVector3 rv;
- rv.mV[VX] = (F32)sd[start_index].asReal();
- rv.mV[VY] = (F32)sd[++start_index].asReal();
- rv.mV[VZ] = (F32)sd[++start_index].asReal();
- return rv;
-}
-
-// vector4
-LLSD ll_sd_from_vector4(const LLVector4& vec)
-{
- LLSD rv;
- rv.append((F64)vec.mV[VX]);
- rv.append((F64)vec.mV[VY]);
- rv.append((F64)vec.mV[VZ]);
- rv.append((F64)vec.mV[VW]);
- return rv;
-}
-
-LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index)
-{
- LLVector4 rv;
- rv.mV[VX] = (F32)sd[start_index].asReal();
- rv.mV[VY] = (F32)sd[++start_index].asReal();
- rv.mV[VZ] = (F32)sd[++start_index].asReal();
- rv.mV[VW] = (F32)sd[++start_index].asReal();
- return rv;
-}
-
-// vector3d
-LLSD ll_sd_from_vector3d(const LLVector3d& vec)
-{
- LLSD rv;
- rv.append(vec.mdV[VX]);
- rv.append(vec.mdV[VY]);
- rv.append(vec.mdV[VZ]);
- return rv;
-}
-
-LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index)
-{
- LLVector3d rv;
- rv.mdV[VX] = sd[start_index].asReal();
- rv.mdV[VY] = sd[++start_index].asReal();
- rv.mdV[VZ] = sd[++start_index].asReal();
- return rv;
-}
-
-//vector2
-LLSD ll_sd_from_vector2(const LLVector2& vec)
-{
- LLSD rv;
- rv.append((F64)vec.mV[VX]);
- rv.append((F64)vec.mV[VY]);
- return rv;
-}
-
-LLVector2 ll_vector2_from_sd(const LLSD& sd)
-{
- LLVector2 rv;
- rv.mV[VX] = (F32)sd[0].asReal();
- rv.mV[VY] = (F32)sd[1].asReal();
- return rv;
-}
-
-// Quaternion
-LLSD ll_sd_from_quaternion(const LLQuaternion& quat)
-{
- LLSD rv;
- rv.append((F64)quat.mQ[VX]);
- rv.append((F64)quat.mQ[VY]);
- rv.append((F64)quat.mQ[VZ]);
- rv.append((F64)quat.mQ[VW]);
- return rv;
-}
-
-LLQuaternion ll_quaternion_from_sd(const LLSD& sd)
-{
- LLQuaternion quat;
- quat.mQ[VX] = (F32)sd[0].asReal();
- quat.mQ[VY] = (F32)sd[1].asReal();
- quat.mQ[VZ] = (F32)sd[2].asReal();
- quat.mQ[VW] = (F32)sd[3].asReal();
- return quat;
-}
-
-// color4
-LLSD ll_sd_from_color4(const LLColor4& c)
-{
- LLSD rv;
- rv.append(c.mV[0]);
- rv.append(c.mV[1]);
- rv.append(c.mV[2]);
- rv.append(c.mV[3]);
- return rv;
-}
-
-LLColor4 ll_color4_from_sd(const LLSD& sd)
-{
- LLColor4 c;
- c.mV[0] = (F32)sd[0].asReal();
- c.mV[1] = (F32)sd[1].asReal();
- c.mV[2] = (F32)sd[2].asReal();
- c.mV[3] = (F32)sd[3].asReal();
- return c;
-}
-
// U32
LLSD ll_sd_from_U32(const U32 val)
{
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 9f73222bc3..7098fa8252 100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
@@ -35,35 +35,34 @@
#define LL_LLSDUTIL_H
#include "llsd.h"
-#include "../llmath/v3math.h"
-#include "../llmath/v4math.h"
-#include "../llmath/v3dmath.h"
-#include "../llmath/v2math.h"
-#include "../llmath/llquaternion.h"
-#include "../llmath/v4color.h"
-#include "../llprimitive/lltextureanim.h"
// vector3
+class LLVector3;
LLSD ll_sd_from_vector3(const LLVector3& vec);
LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index = 0);
// vector4
+class LLVector4;
LLSD ll_sd_from_vector4(const LLVector4& vec);
LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index = 0);
// vector3d (double)
+class LLVector3d;
LLSD ll_sd_from_vector3d(const LLVector3d& vec);
LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index = 0);
// vector2
+class LLVector2;
LLSD ll_sd_from_vector2(const LLVector2& vec);
LLVector2 ll_vector2_from_sd(const LLSD& sd);
// Quaternion
+class LLQuaternion;
LLSD ll_sd_from_quaternion(const LLQuaternion& quat);
LLQuaternion ll_quaternion_from_sd(const LLSD& sd);
// color4
+class LLColor4;
LLSD ll_sd_from_color4(const LLColor4& c);
LLColor4 ll_color4_from_sd(const LLSD& sd);
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 59d71a8e8e..7a2d42dfaa 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -70,7 +70,7 @@ bool _read_file_into_string(std::string& str, const char* filename)
llifstream ifs(filename, llifstream::binary);
if (!ifs.is_open())
{
- llinfos << "Unable to open file" << filename << llendl;
+ llinfos << "Unable to open file " << filename << llendl;
return false;
}
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 02ed0dcfc6..dc0a7a83e4 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -31,7 +31,7 @@
#include "linden_common.h"
#include "llapr.h"
-#include "apr-1/apr_portable.h"
+#include "apr_portable.h"
#include "llthread.h"
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index a07c64b8fc..7864d93395 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -36,7 +36,7 @@
#include "llapp.h"
#include "llmemory.h"
-#include "apr-1/apr_thread_cond.h"
+#include "apr_thread_cond.h"
class LLThread;
class LLMutex;
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index af89a09d2f..3d05699cd6 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -429,10 +429,9 @@ BOOL LLTimer::knownBadTimer()
//
///////////////////////////////////////////////////////////////////////////////
-U32 time_corrected()
+time_t time_corrected()
{
- U32 corrected_time = (U32)time(NULL) + gUTCOffset;
- return corrected_time;
+ return time(NULL) + gUTCOffset;
}
@@ -452,27 +451,25 @@ BOOL is_daylight_savings()
}
-struct tm* utc_to_pacific_time(S32 utc_time, BOOL pacific_daylight_time)
+struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time)
{
- time_t unix_time = (time_t)utc_time;
-
S32 pacific_offset_hours;
if (pacific_daylight_time)
{
- pacific_offset_hours = -7;
+ pacific_offset_hours = 7;
}
else
{
- pacific_offset_hours = -8;
+ pacific_offset_hours = 8;
}
// We subtract off the PST/PDT offset _before_ getting
// "UTC" time, because this will handle wrapping around
// for 5 AM UTC -> 10 PM PDT of the previous day.
- unix_time += pacific_offset_hours * MIN_PER_HOUR * SEC_PER_MIN;
+ utc_time -= pacific_offset_hours * MIN_PER_HOUR * SEC_PER_MIN;
// Internal buffer to PST/PDT (see above)
- struct tm* internal_time = gmtime(&unix_time);
+ struct tm* internal_time = gmtime(&utc_time);
/*
// Don't do this, this won't correctly tell you if daylight savings is active in CA or not.
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 57f9e23e7a..41562f4a51 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -35,6 +35,7 @@
#if LL_LINUX || LL_DARWIN
#include <sys/time.h>
#endif
+#include <limits.h>
#include "stdtypes.h"
@@ -117,7 +118,35 @@ void ms_sleep(U32 ms);
// Returns the correct UTC time in seconds, like time(NULL).
// Useful on the viewer, which may have its local clock set wrong.
-U32 time_corrected();
+time_t time_corrected();
+
+static inline time_t time_min()
+{
+ if (sizeof(time_t) == 4)
+ {
+ return (time_t) INT_MIN;
+ } else {
+#ifdef LLONG_MIN
+ return (time_t) LLONG_MIN;
+#else
+ return (time_t) LONG_MIN;
+#endif
+ }
+}
+
+static inline time_t time_max()
+{
+ if (sizeof(time_t) == 4)
+ {
+ return (time_t) INT_MAX;
+ } else {
+#ifdef LLONG_MAX
+ return (time_t) LLONG_MAX;
+#else
+ return (time_t) LONG_MAX;
+#endif
+ }
+}
// Correction factor used by time_corrected() above.
extern S32 gUTCOffset;
@@ -131,7 +160,7 @@ BOOL is_daylight_savings();
// S32 utc_time;
// utc_time = time_corrected();
// struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight);
-struct tm* utc_to_pacific_time(S32 utc_time, BOOL pacific_daylight_time);
+struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time);
void microsecondsToTimecodeString(U64 current_time, char *tcstring);
void secondsToTimecodeString(F32 current_time, char *tcstring);
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 022742660d..57d55c7e71 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -38,7 +38,7 @@
#include "llsd.h"
#include <iomanip>
-#include "../llmath/lluuid.h"
+#include "lluuid.h"
// system includes
#include <boost/tokenizer.hpp>
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
new file mode 100644
index 0000000000..3f86681315
--- /dev/null
+++ b/indra/llcommon/lluuid.cpp
@@ -0,0 +1,923 @@
+/**
+ * @file lluuid.cpp
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+// 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>
+#endif
+
+#include "lldefs.h"
+#include "llerror.h"
+
+#include "lluuid.h"
+#include "llerror.h"
+#include "llrand.h"
+#include "llmd5.h"
+#include "llstring.h"
+#include "lltimer.h"
+
+const LLUUID LLUUID::null;
+const LLTransactionID LLTransactionID::tnull;
+
+/*
+
+NOT DONE YET!!!
+
+static char BASE85_TABLE[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*',
+ '+', '-', ';', '[', '=', '>', '?', '@', '^', '_',
+ '`', '{', '|', '}', '~', '\0'
+};
+
+
+void encode( char * fiveChars, unsigned int word ) throw( )
+{
+for( int ix = 0; ix < 5; ++ix ) {
+fiveChars[4-ix] = encodeTable[ word % 85];
+word /= 85;
+}
+}
+
+To decode:
+unsigned int decode( char const * fiveChars ) throw( bad_input_data )
+{
+unsigned int ret = 0;
+for( int ix = 0; ix < 5; ++ix ) {
+char * s = strchr( encodeTable, fiveChars[ ix ] );
+if( s == 0 ) throw bad_input_data();
+ret = ret * 85 + (s-encodeTable);
+}
+return ret;
+}
+
+void LLUUID::toBase85(char* out)
+{
+ U32* me = (U32*)&(mData[0]);
+ for(S32 i = 0; i < 4; ++i)
+ {
+ char* o = &out[i*i];
+ for(S32 j = 0; j < 5; ++j)
+ {
+ o[4-j] = BASE85_TABLE[ me[i] % 85];
+ word /= 85;
+ }
+ }
+}
+
+unsigned int decode( char const * fiveChars ) throw( bad_input_data )
+{
+ unsigned int ret = 0;
+ for( S32 ix = 0; ix < 5; ++ix )
+ {
+ char * s = strchr( encodeTable, fiveChars[ ix ] );
+ ret = ret * 85 + (s-encodeTable);
+ }
+ return ret;
+}
+*/
+
+#define LL_USE_JANKY_RANDOM_NUMBER_GENERATOR 0
+#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
+/**
+ * @brief a global for
+ */
+static U64 sJankyRandomSeed(LLUUID::getRandomSeed());
+
+/**
+ * @brief generate a random U32.
+ */
+U32 janky_fast_random_bytes()
+{
+ sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223);
+ return (U32)sJankyRandomSeed;
+}
+
+/**
+ * @brief generate a random U32 from [0, val)
+ */
+U32 janky_fast_random_byes_range(U32 val)
+{
+ sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223);
+ return (U32)(sJankyRandomSeed) % val;
+}
+
+/**
+ * @brief generate a random U32 from [0, val)
+ */
+U32 janky_fast_random_seeded_bytes(U32 seed, U32 val)
+{
+ seed = U64L(1664525) * (U64)(seed) + U64L(1013904223);
+ return (U32)(seed) % val;
+}
+#endif
+
+// Common to all UUID implementations
+void LLUUID::toString(char *out) const
+{
+ sprintf(out,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (U8)(mData[0]),
+ (U8)(mData[1]),
+ (U8)(mData[2]),
+ (U8)(mData[3]),
+ (U8)(mData[4]),
+ (U8)(mData[5]),
+ (U8)(mData[6]),
+ (U8)(mData[7]),
+ (U8)(mData[8]),
+ (U8)(mData[9]),
+ (U8)(mData[10]),
+ (U8)(mData[11]),
+ (U8)(mData[12]),
+ (U8)(mData[13]),
+ (U8)(mData[14]),
+ (U8)(mData[15]));
+}
+
+void LLUUID::toCompressedString(char *out) const
+{
+ memcpy(out, mData, UUID_BYTES); /* Flawfinder: ignore */
+ out[UUID_BYTES] = '\0';
+}
+
+std::string LLUUID::getString() const
+{
+ return asString();
+}
+
+std::string LLUUID::asString() const
+{
+ char str[UUID_STR_SIZE]; /* Flawfinder: ignore */
+ toString(str);
+ return std::string(str);
+}
+
+BOOL LLUUID::set(const std::string& in_string, BOOL emit)
+{
+ return set(in_string.c_str(), emit);
+}
+
+BOOL LLUUID::set(const char *in_string, BOOL emit)
+{
+ BOOL broken_format = FALSE;
+ if (!in_string)
+ {
+ llerrs << "No string pointer in LLUUID::set!" << llendl;
+ setNull();
+ return FALSE;
+ }
+
+ // empty strings should make NULL uuid
+ if (!in_string[0])
+ {
+ setNull();
+ return TRUE;
+ }
+
+ if (strlen(in_string) != (UUID_STR_LENGTH - 1)) /* Flawfinder: ignore */
+ {
+ // I'm a moron. First implementation didn't have the right UUID format.
+ // Shouldn't see any of these any more
+ if (strlen(in_string) == (UUID_STR_LENGTH - 2)) /* Flawfinder: ignore */
+ {
+ if(emit)
+ {
+ llinfos << "Warning! Using broken UUID string format" << llendl;
+ }
+ broken_format = TRUE;
+ }
+ else
+ {
+ // Bad UUID string. Spam as INFO, as most cases we don't care.
+ if(emit)
+ {
+ llinfos << "Bad UUID string: " << in_string << llendl;
+ }
+ setNull();
+ return FALSE;
+ }
+ }
+
+ U8 cur_pos = 0;
+ S32 i;
+ for (i = 0; i < UUID_BYTES; i++)
+ {
+ if ((i == 4) || (i == 6) || (i == 8) || (i == 10))
+ {
+ cur_pos++;
+ if (broken_format && (i==10))
+ {
+ // Missing - in the broken format
+ cur_pos--;
+ }
+ }
+
+ mData[i] = 0;
+
+ if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9'))
+ {
+ mData[i] += (U8)(*(in_string + cur_pos) - '0');
+ }
+ else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f'))
+ {
+ mData[i] += (U8)(10 + *(in_string + cur_pos) - 'a');
+ }
+ else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F'))
+ {
+ mData[i] += (U8)(10 + *(in_string + cur_pos) - 'A');
+ }
+ else
+ {
+ if(emit)
+ {
+ llwarns << "Invalid UUID string character" << llendl;
+ }
+ setNull();
+ return FALSE;
+ }
+
+ mData[i] = mData[i] << 4;
+ cur_pos++;
+
+ if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9'))
+ {
+ mData[i] += (U8)(*(in_string + cur_pos) - '0');
+ }
+ else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f'))
+ {
+ mData[i] += (U8)(10 + *(in_string + cur_pos) - 'a');
+ }
+ else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F'))
+ {
+ mData[i] += (U8)(10 + *(in_string + cur_pos) - 'A');
+ }
+ else
+ {
+ if(emit)
+ {
+ llwarns << "Invalid UUID string character" << llendl;
+ }
+ setNull();
+ return FALSE;
+ }
+ cur_pos++;
+ }
+
+ return TRUE;
+}
+
+BOOL LLUUID::validate(const std::string& in_string)
+{
+ return validate(in_string.c_str());
+}
+
+BOOL LLUUID::validate(const char *in_string)
+{
+ BOOL broken_format = FALSE;
+ if (!in_string)
+ {
+ return FALSE;
+ }
+ if (strlen(in_string) != (UUID_STR_LENGTH - 1)) /* Flawfinder: ignore */
+ {
+ // I'm a moron. First implementation didn't have the right UUID format.
+ if (strlen(in_string) == (UUID_STR_LENGTH - 2)) /* Flawfinder: ignore */
+ {
+ broken_format = TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ U8 cur_pos = 0;
+ U32 i;
+ for (i = 0; i < 16; i++)
+ {
+ if ((i == 4) || (i == 6) || (i == 8) || (i == 10))
+ {
+ cur_pos++;
+ if (broken_format && (i==10))
+ {
+ // Missing - in the broken format
+ cur_pos--;
+ }
+ }
+
+ if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9'))
+ {
+ }
+ else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f'))
+ {
+ }
+ else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F'))
+ {
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ cur_pos++;
+
+ if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9'))
+ {
+ }
+ else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f'))
+ {
+ }
+ else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F'))
+ {
+ }
+ else
+ {
+ return FALSE;
+ }
+ cur_pos++;
+ }
+ return TRUE;
+}
+
+const LLUUID& LLUUID::operator^=(const LLUUID& rhs)
+{
+ U32* me = (U32*)&(mData[0]);
+ const U32* other = (U32*)&(rhs.mData[0]);
+ for(S32 i = 0; i < 4; ++i)
+ {
+ me[i] = me[i] ^ other[i];
+ }
+ return *this;
+}
+
+LLUUID LLUUID::operator^(const LLUUID& rhs) const
+{
+ LLUUID id(*this);
+ id ^= rhs;
+ return id;
+}
+
+void LLUUID::combine(const LLUUID& other, LLUUID& result) const
+{
+ LLMD5 md5_uuid;
+ md5_uuid.update((unsigned char*)mData, 16);
+ md5_uuid.update((unsigned char*)other.mData, 16);
+ md5_uuid.finalize();
+ md5_uuid.raw_digest(result.mData);
+}
+
+LLUUID LLUUID::combine(const LLUUID &other) const
+{
+ LLUUID combination;
+ combine(other, combination);
+ return combination;
+}
+
+std::ostream& operator<<(std::ostream& s, const LLUUID &uuid)
+{
+ char uuid_str[UUID_STR_LENGTH];
+
+ uuid.toString(uuid_str);
+ s << uuid_str;
+ return s;
+}
+
+std::istream& operator>>(std::istream &s, LLUUID &uuid)
+{
+ U32 i;
+ char uuid_str[UUID_STR_LENGTH]; /* Flawfinder: ignore */
+ for (i = 0; i < UUID_STR_LENGTH-1; i++)
+ {
+ s >> uuid_str[i];
+ }
+ uuid_str[i] = '\0';
+ uuid.set(uuid_str);
+ return s;
+}
+
+static void get_random_bytes(void *buf, int nbytes)
+{
+ int i;
+ char *cp = (char *) buf;
+
+ // *NOTE: If we are not using the janky generator ll_rand()
+ // generates at least 3 good bytes of data since it is 0 to
+ // RAND_MAX. This could be made more efficient by copying all the
+ // bytes.
+ for (i=0; i < nbytes; i++)
+#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
+ *cp++ = janky_fast_random_bytes() & 0xFF;
+#else
+ *cp++ = ll_rand() & 0xFF;
+#endif
+ return;
+}
+
+#if LL_WINDOWS
+typedef struct _ASTAT_
+{
+ ADAPTER_STATUS adapt;
+ NAME_BUFFER NameBuff [30];
+}ASTAT, * PASTAT;
+
+// static
+S32 LLUUID::getNodeID(unsigned char * node_id)
+{
+ 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 );
+
+ 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 );
+
+ 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);
+
+ 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] );
+ memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */
+ retval = 1;
+
+ }
+ }
+ return retval;
+}
+
+#elif LL_DARWIN
+// Mac OS X version of the UUID generation code...
+/*
+ * Get an ethernet hardware address, if we can find it...
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <ifaddrs.h>
+
+// static
+S32 LLUUID::getNodeID(unsigned char *node_id)
+{
+ int i;
+ unsigned char *a = NULL;
+ struct ifaddrs *ifap, *ifa;
+ int rv;
+ S32 result = 0;
+
+ if ((rv=getifaddrs(&ifap))==-1)
+ {
+ return -1;
+ }
+ if (ifap == NULL)
+ {
+ return -1;
+ }
+
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
+ {
+// printf("Interface %s, address family %d, ", ifa->ifa_name, ifa->ifa_addr->sa_family);
+ for(i=0; i< ifa->ifa_addr->sa_len; i++)
+ {
+// printf("%02X ", (unsigned char)ifa->ifa_addr->sa_data[i]);
+ }
+// printf("\n");
+
+ if(ifa->ifa_addr->sa_family == AF_LINK)
+ {
+ // This is a link-level address
+ struct sockaddr_dl *lla = (struct sockaddr_dl *)ifa->ifa_addr;
+
+// printf("\tLink level address, type %02X\n", lla->sdl_type);
+
+ if(lla->sdl_type == IFT_ETHER)
+ {
+ // Use the first ethernet MAC in the list.
+ // For some reason, the macro LLADDR() defined in net/if_dl.h doesn't expand correctly. This is what it would do.
+ a = (unsigned char *)&((lla)->sdl_data);
+ a += (lla)->sdl_nlen;
+
+ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+ {
+ continue;
+ }
+
+ if (node_id)
+ {
+ memcpy(node_id, a, 6);
+ result = 1;
+ }
+
+ // We found one.
+ break;
+ }
+ }
+ }
+ freeifaddrs(ifap);
+
+ return result;
+}
+
+#else
+
+// Linux version of the UUID generation code...
+/*
+ * Get the ethernet hardware address, if we can find it...
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#define HAVE_NETINET_IN_H
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#if LL_SOLARIS
+#include <sys/sockio.h>
+#elif !LL_DARWIN
+#include <linux/sockios.h>
+#endif
+#endif
+
+// static
+S32 LLUUID::getNodeID(unsigned char *node_id)
+{
+ int sd;
+ struct ifreq ifr, *ifrp;
+ struct ifconf ifc;
+ char buf[1024];
+ int n, i;
+ unsigned char *a;
+
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+ sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sd < 0) {
+ return -1;
+ }
+ memset(buf, 0, sizeof(buf));
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+ if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
+ close(sd);
+ return -1;
+ }
+ n = ifc.ifc_len;
+ for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
+ ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
+ strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); /* Flawfinder: ignore */
+#ifdef SIOCGIFHWADDR
+ if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+ if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) ifr.ifr_enaddr;
+#else
+ /*
+ * XXX we don't have a way of getting the hardware
+ * address
+ */
+ close(sd);
+ return 0;
+#endif /* SIOCGENADDR */
+#endif /* SIOCGIFHWADDR */
+ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+ continue;
+ if (node_id) {
+ memcpy(node_id, a, 6); /* Flawfinder: ignore */
+ close(sd);
+ return 1;
+ }
+ }
+ close(sd);
+ return 0;
+}
+
+#endif
+
+S32 LLUUID::cmpTime(uuid_time_t *t1, uuid_time_t *t2)
+{
+ // Compare two time values.
+
+ if (t1->high < t2->high) return -1;
+ if (t1->high > t2->high) return 1;
+ if (t1->low < t2->low) return -1;
+ if (t1->low > t2->low) return 1;
+ return 0;
+}
+
+void LLUUID::getSystemTime(uuid_time_t *timestamp)
+{
+ // Get system time with 100ns precision. Time is since Oct 15, 1582.
+#if LL_WINDOWS
+ ULARGE_INTEGER time;
+ GetSystemTimeAsFileTime((FILETIME *)&time);
+ // NT keeps time in FILETIME format which is 100ns ticks since
+ // Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582.
+ // The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
+ // + 18 years and 5 leap days.
+ time.QuadPart +=
+ (unsigned __int64) (1000*1000*10) // seconds
+ * (unsigned __int64) (60 * 60 * 24) // days
+ * (unsigned __int64) (17+30+31+365*18+5); // # of days
+
+ timestamp->high = time.HighPart;
+ timestamp->low = time.LowPart;
+#else
+ struct timeval tp;
+ gettimeofday(&tp, 0);
+
+ // Offset between UUID formatted times and Unix formatted times.
+ // UUID UTC base time is October 15, 1582.
+ // Unix base time is January 1, 1970.
+ U64 uuid_time = ((U64)tp.tv_sec * 10000000) + (tp.tv_usec * 10) +
+ U64L(0x01B21DD213814000);
+ timestamp->high = (U32) (uuid_time >> 32);
+ timestamp->low = (U32) (uuid_time & 0xFFFFFFFF);
+#endif
+}
+
+void LLUUID::getCurrentTime(uuid_time_t *timestamp)
+{
+ // Get current time as 60 bit 100ns ticks since whenever.
+ // Compensate for the fact that real clock resolution is less
+ // than 100ns.
+
+ const U32 uuids_per_tick = 1024;
+
+ static uuid_time_t time_last;
+ static U32 uuids_this_tick;
+ static BOOL init = FALSE;
+
+ if (!init) {
+ getSystemTime(&time_last);
+ uuids_this_tick = uuids_per_tick;
+ init = TRUE;
+ }
+
+ uuid_time_t time_now = {0,0};
+
+ while (1) {
+ getSystemTime(&time_now);
+
+ // if clock reading changed since last UUID generated
+ if (cmpTime(&time_last, &time_now)) {
+ // reset count of uuid's generated with this clock reading
+ uuids_this_tick = 0;
+ break;
+ }
+ if (uuids_this_tick < uuids_per_tick) {
+ uuids_this_tick++;
+ break;
+ }
+ // going too fast for our clock; spin
+ }
+
+ time_last = time_now;
+
+ if (uuids_this_tick != 0) {
+ if (time_now.low & 0x80000000) {
+ time_now.low += uuids_this_tick;
+ if (!(time_now.low & 0x80000000))
+ time_now.high++;
+ } else
+ time_now.low += uuids_this_tick;
+ }
+
+ timestamp->high = time_now.high;
+ timestamp->low = time_now.low;
+}
+
+void LLUUID::generate()
+{
+ // Create a UUID.
+ uuid_time_t timestamp;
+
+ static unsigned char node_id[6]; /* Flawfinder: ignore */
+ static int has_init = 0;
+
+ // Create a UUID.
+ static uuid_time_t time_last = {0,0};
+ static U16 clock_seq = 0;
+#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
+ static U32 seed = 0L; // dummy seed. reset it below
+#endif
+ if (!has_init)
+ {
+ if (getNodeID(node_id) <= 0)
+ {
+ get_random_bytes(node_id, 6);
+ /*
+ * Set multicast bit, to prevent conflicts
+ * with IEEE 802 addresses obtained from
+ * network cards
+ */
+ node_id[0] |= 0x80;
+ }
+
+ getCurrentTime(&time_last);
+#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
+ seed = time_last.low;
+#endif
+
+#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
+ clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536);
+#else
+ clock_seq = (U16)ll_rand(65536);
+#endif
+ has_init = 1;
+ }
+
+ // get current time
+ getCurrentTime(&timestamp);
+
+ // if clock went backward change clockseq
+ if (cmpTime(&timestamp, &time_last) == -1) {
+ clock_seq = (clock_seq + 1) & 0x3FFF;
+ if (clock_seq == 0) clock_seq++;
+ }
+
+ memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */
+ U32 tmp;
+ tmp = timestamp.low;
+ mData[3] = (unsigned char) tmp;
+ tmp >>= 8;
+ mData[2] = (unsigned char) tmp;
+ tmp >>= 8;
+ mData[1] = (unsigned char) tmp;
+ tmp >>= 8;
+ mData[0] = (unsigned char) tmp;
+
+ tmp = (U16) timestamp.high;
+ mData[5] = (unsigned char) tmp;
+ tmp >>= 8;
+ mData[4] = (unsigned char) tmp;
+
+ tmp = (timestamp.high >> 16) | 0x1000;
+ mData[7] = (unsigned char) tmp;
+ tmp >>= 8;
+ mData[6] = (unsigned char) tmp;
+
+ tmp = clock_seq;
+ mData[9] = (unsigned char) tmp;
+ tmp >>= 8;
+ mData[8] = (unsigned char) tmp;
+
+ LLMD5 md5_uuid;
+
+ md5_uuid.update(mData,16);
+ md5_uuid.finalize();
+ md5_uuid.raw_digest(mData);
+
+ time_last = timestamp;
+}
+
+void LLUUID::generate(const std::string& hash_string)
+{
+ LLMD5 md5_uuid((U8*)hash_string.c_str());
+ md5_uuid.raw_digest(mData);
+}
+
+U32 LLUUID::getRandomSeed()
+{
+ static unsigned char seed[16]; /* Flawfinder: ignore */
+
+ getNodeID(&seed[0]);
+ seed[6]='\0';
+ seed[7]='\0';
+ getSystemTime((uuid_time_t *)(&seed[8]));
+
+ LLMD5 md5_seed;
+
+ md5_seed.update(seed,16);
+ md5_seed.finalize();
+ md5_seed.raw_digest(seed);
+
+ return(*(U32 *)seed);
+}
+
+BOOL LLUUID::parseUUID(const char* buf, LLUUID* value)
+{
+ if( buf == NULL || buf[0] == '\0' || value == NULL)
+ {
+ return FALSE;
+ }
+
+ LLString temp( buf );
+ LLString::trim(temp);
+ if( LLUUID::validate( temp ) )
+ {
+ value->set( temp );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const
+{
+ LLAssetID result;
+ if (isNull())
+ {
+ result.setNull();
+ }
+ else
+ {
+ combine(session, result);
+ }
+ return result;
+}
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
new file mode 100644
index 0000000000..2f82ec9a93
--- /dev/null
+++ b/indra/llcommon/lluuid.h
@@ -0,0 +1,330 @@
+/**
+ * @file lluuid.h
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLUUID_H
+#define LL_LLUUID_H
+
+#include <iostream>
+#include <set>
+#include "stdtypes.h"
+
+const S32 UUID_BYTES = 16;
+const S32 UUID_WORDS = 4;
+const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below
+const S32 UUID_STR_SIZE = 37;
+const S32 UUID_BASE85_LENGTH = 21; // including the trailing NULL.
+
+struct uuid_time_t {
+ U32 high;
+ U32 low;
+ };
+
+class LLUUID
+{
+public:
+ //
+ // CREATORS
+ //
+ LLUUID();
+ explicit LLUUID(const char *in_string); // Convert from string.
+ explicit LLUUID(const std::string& in_string); // Convert from string.
+ LLUUID(const LLUUID &in);
+ LLUUID &operator=(const LLUUID &rhs);
+
+ ~LLUUID();
+
+ //
+ // MANIPULATORS
+ //
+ void generate(); // Generate a new UUID
+ void generate(const std::string& stream); //Generate a new UUID based on hash of input stream
+ BOOL set(const char *in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings
+ BOOL set(const std::string& in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings
+ void setNull(); // Faster than setting to LLUUID::null.
+
+ S32 cmpTime(uuid_time_t *t1, uuid_time_t *t2);
+ static void getSystemTime(uuid_time_t *timestamp);
+ void getCurrentTime(uuid_time_t *timestamp);
+
+ //
+ // ACCESSORS
+ //
+ BOOL isNull() const; // Faster than comparing to LLUUID::null.
+ BOOL notNull() const; // Faster than comparing to LLUUID::null.
+ // JC: This is dangerous. It allows UUIDs to be cast automatically
+ // to integers, among other things. Use isNull() or notNull().
+ // operator bool() const;
+
+ // JC: These must return real bool's (not BOOLs) or else use of the STL
+ // will generate bool-to-int performance warnings.
+ bool operator==(const LLUUID &rhs) const;
+ bool operator!=(const LLUUID &rhs) const;
+ bool operator<(const LLUUID &rhs) const;
+ bool operator>(const LLUUID &rhs) const;
+
+ // xor functions. Useful since any two random uuids xored together
+ // will yield a determinate third random unique id that can be
+ // used as a key in a single uuid that represents 2.
+ const LLUUID& operator^=(const LLUUID& rhs);
+ LLUUID operator^(const LLUUID& rhs) const;
+
+ // similar to functions above, but not invertible
+ // yields a third random UUID that can be reproduced from the two inputs
+ // but which, given the result and one of the inputs can't be used to
+ // deduce the other input
+ LLUUID combine(const LLUUID& other) const;
+ void combine(const LLUUID& other, LLUUID& result) const;
+
+ friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid);
+ friend std::istream& operator>>(std::istream& s, LLUUID &uuid);
+
+ void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0)
+ void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0)
+
+ std::string asString() const;
+ std::string getString() const;
+
+ U16 getCRC16() const;
+ U32 getCRC32() const;
+
+ static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
+ static BOOL validate(const char *in_string); // Validate that the UUID string is legal.
+
+ static const LLUUID null;
+
+ static U32 getRandomSeed();
+ static S32 getNodeID(unsigned char * node_id);
+
+ static BOOL parseUUID(const char* buf, LLUUID* value);
+
+ U8 mData[UUID_BYTES];
+};
+
+
+// Construct
+inline LLUUID::LLUUID()
+{
+ setNull();
+}
+
+
+// Faster than copying from memory
+inline void LLUUID::setNull()
+{
+ U32 *word = (U32 *)mData;
+ word[0] = 0;
+ word[1] = 0;
+ word[2] = 0;
+ word[3] = 0;
+}
+
+
+// Compare
+inline bool LLUUID::operator==(const LLUUID& rhs) const
+{
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ // Note: binary & to avoid branching
+ return
+ (tmp[0] == rhstmp[0]) &
+ (tmp[1] == rhstmp[1]) &
+ (tmp[2] == rhstmp[2]) &
+ (tmp[3] == rhstmp[3]);
+}
+
+
+inline bool LLUUID::operator!=(const LLUUID& rhs) const
+{
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ // Note: binary | to avoid branching
+ return
+ (tmp[0] != rhstmp[0]) |
+ (tmp[1] != rhstmp[1]) |
+ (tmp[2] != rhstmp[2]) |
+ (tmp[3] != rhstmp[3]);
+}
+
+/*
+// JC: This is dangerous. It allows UUIDs to be cast automatically
+// to integers, among other things. Use isNull() or notNull().
+inline LLUUID::operator bool() const
+{
+ U32 *word = (U32 *)mData;
+ return (word[0] | word[1] | word[2] | word[3]) > 0;
+}
+*/
+
+inline BOOL LLUUID::notNull() const
+{
+ U32 *word = (U32 *)mData;
+ return (word[0] | word[1] | word[2] | word[3]) > 0;
+}
+
+// Faster than == LLUUID::null because doesn't require
+// as much memory access.
+inline BOOL LLUUID::isNull() const
+{
+ U32 *word = (U32 *)mData;
+ // If all bits are zero, return !0 == TRUE
+ return !(word[0] | word[1] | word[2] | word[3]);
+}
+
+// Copy constructor
+inline LLUUID::LLUUID(const LLUUID& rhs)
+{
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ tmp[0] = rhstmp[0];
+ tmp[1] = rhstmp[1];
+ tmp[2] = rhstmp[2];
+ tmp[3] = rhstmp[3];
+}
+
+inline LLUUID::~LLUUID()
+{
+}
+
+// Assignment
+inline LLUUID& LLUUID::operator=(const LLUUID& rhs)
+{
+ // No need to check the case where this==&rhs. The branch is slower than the write.
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ tmp[0] = rhstmp[0];
+ tmp[1] = rhstmp[1];
+ tmp[2] = rhstmp[2];
+ tmp[3] = rhstmp[3];
+
+ return *this;
+}
+
+
+inline LLUUID::LLUUID(const char *in_string)
+{
+ if (!in_string || in_string[0] == 0)
+ {
+ setNull();
+ return;
+ }
+
+ set(in_string);
+}
+
+inline LLUUID::LLUUID(const std::string& in_string)
+{
+ if (in_string.empty())
+ {
+ setNull();
+ return;
+ }
+
+ set(in_string);
+}
+
+// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order
+// IW: this will make me very sad
+inline bool LLUUID::operator<(const LLUUID &rhs) const
+{
+ U32 i;
+ for( i = 0; i < (UUID_BYTES - 1); i++ )
+ {
+ if( mData[i] != rhs.mData[i] )
+ {
+ return (mData[i] < rhs.mData[i]);
+ }
+ }
+ return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);
+}
+
+inline bool LLUUID::operator>(const LLUUID &rhs) const
+{
+ U32 i;
+ for( i = 0; i < (UUID_BYTES - 1); i++ )
+ {
+ if( mData[i] != rhs.mData[i] )
+ {
+ return (mData[i] > rhs.mData[i]);
+ }
+ }
+ return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);
+}
+
+inline U16 LLUUID::getCRC16() const
+{
+ // A UUID is 16 bytes, or 8 shorts.
+ U16 *short_data = (U16*)mData;
+ U16 out = 0;
+ out += short_data[0];
+ out += short_data[1];
+ out += short_data[2];
+ out += short_data[3];
+ out += short_data[4];
+ out += short_data[5];
+ out += short_data[6];
+ out += short_data[7];
+ return out;
+}
+
+inline U32 LLUUID::getCRC32() const
+{
+ U32 *tmp = (U32*)mData;
+ return tmp[0] + tmp[1] + tmp[2] + tmp[3];
+}
+
+
+// Helper structure for ordering lluuids in stl containers.
+// eg: std::map<LLUUID, LLWidget*, lluuid_less> widget_map;
+struct lluuid_less
+{
+ bool operator()(const LLUUID& lhs, const LLUUID& rhs) const
+ {
+ return (lhs < rhs) ? true : false;
+ }
+};
+
+typedef std::set<LLUUID, lluuid_less> uuid_list_t;
+
+/*
+ * Sub-classes for keeping transaction IDs and asset IDs
+ * straight.
+ */
+typedef LLUUID LLAssetID;
+
+class LLTransactionID : public LLUUID
+{
+public:
+ LLTransactionID() : LLUUID() { }
+
+ static const LLTransactionID tnull;
+ LLAssetID makeAssetID(const LLUUID& session) const;
+};
+
+#endif
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index f8982d79f8..ea89d724d8 100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
@@ -31,6 +31,8 @@
#ifndef LL_STDTYPES_H
#define LL_STDTYPES_H
+#include <cfloat>
+
typedef signed char S8;
typedef unsigned char U8;
typedef signed short S16;