diff options
author | Brad Linden <brad@lindenlab.com> | 2024-05-23 11:31:19 -0700 |
---|---|---|
committer | Brad Linden <brad@lindenlab.com> | 2024-05-23 11:31:19 -0700 |
commit | a1f49564d670a2c41bfa25c833bba2564b9b7f48 (patch) | |
tree | 1d205e51bc37621916a17d459ad83782fe41f975 /indra/llmessage | |
parent | 6af5db09faf5ea33a2d4c47b64e76f42edae178a (diff) | |
parent | 6377610f6587989c126b00f490dfc8d527a1c2ce (diff) |
Merge remote-tracking branch 'origin/DRTVWR-600-maint-A' into brad/merge-maint-a-to-dev
Diffstat (limited to 'indra/llmessage')
179 files changed, 32618 insertions, 32618 deletions
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index dd63724039..88fa572092 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -1,4 +1,4 @@ -/** +/** * @file llassetstorage.h * @brief definition of LLAssetStorage class which allows simple * up/downloads of uuid,type asets @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -60,9 +60,9 @@ const int LL_ERR_INSUFFICIENT_PERMISSIONS = -5; const int LL_ERR_PRICE_MISMATCH = -23018; // *TODO: these typedefs are passed into the cache via a legacy C function pointer -// future project would be to convert these to C++ callables (std::function<>) so that +// future project would be to convert these to C++ callables (std::function<>) so that // we can use bind and remove the userData parameter. -// +// typedef std::function<void(const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback; typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> LLStoreAssetCallback; @@ -70,32 +70,32 @@ typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, class LLAssetInfo { protected: - std::string mDescription; - std::string mName; + std::string mDescription; + std::string mName; public: - LLUUID mUuid; - LLTransactionID mTransactionID; - LLUUID mCreatorID; - LLAssetType::EType mType; - - LLAssetInfo( void ); - LLAssetInfo( const LLUUID& object_id, const LLUUID& creator_id, - LLAssetType::EType type, const char* name, const char* desc ); - LLAssetInfo( const LLNameValue& nv ); - - const std::string& getName( void ) const { return mName; } - const std::string& getDescription( void ) const { return mDescription; } - void setName( const std::string& name ); - void setDescription( const std::string& desc ); - - // Assets (aka potential inventory items) can be applied to an - // object in the world. We'll store that as a string name value - // pair where the name encodes part of asset info, and the value - // the rest. LLAssetInfo objects will be responsible for parsing - // the meaning out froman LLNameValue object. See the inventory - // design docs for details. - void setFromNameValue( const LLNameValue& nv ); + LLUUID mUuid; + LLTransactionID mTransactionID; + LLUUID mCreatorID; + LLAssetType::EType mType; + + LLAssetInfo( void ); + LLAssetInfo( const LLUUID& object_id, const LLUUID& creator_id, + LLAssetType::EType type, const char* name, const char* desc ); + LLAssetInfo( const LLNameValue& nv ); + + const std::string& getName( void ) const { return mName; } + const std::string& getDescription( void ) const { return mDescription; } + void setName( const std::string& name ); + void setDescription( const std::string& desc ); + + // Assets (aka potential inventory items) can be applied to an + // object in the world. We'll store that as a string name value + // pair where the name encodes part of asset info, and the value + // the rest. LLAssetInfo objects will be responsible for parsing + // the meaning out froman LLNameValue object. See the inventory + // design docs for details. + void setFromNameValue( const LLNameValue& nv ); }; @@ -105,8 +105,8 @@ public: LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType at); virtual ~LLBaseDownloadRequest(); - LLUUID getUUID() const { return mUUID; } - LLAssetType::EType getType() const { return mType; } + LLUUID getUUID() const { return mUUID; } + LLAssetType::EType getType() const { return mType; } void setUUID(const LLUUID& id) { mUUID = id; } void setType(LLAssetType::EType type) { mType = type; } @@ -114,19 +114,19 @@ public: virtual LLBaseDownloadRequest* getCopy(); protected: - LLUUID mUUID; + LLUUID mUUID; LLAssetType::EType mType; public: LLGetAssetCallback mDownCallback; - void *mUserData; + void *mUserData; LLHost mHost; - bool mIsTemp; - F64Seconds mTime; // Message system time + bool mIsTemp; + F64Seconds mTime; // Message system time bool mIsPriority; - bool mDataSentInFirstPacket; - bool mDataIsInCache; + bool mDataSentInFirstPacket; + bool mDataIsInCache; }; class LLAssetRequest : public LLBaseDownloadRequest @@ -140,27 +140,27 @@ public: virtual LLBaseDownloadRequest* getCopy(); LLStoreAssetCallback mUpCallback; -// void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat); - void (*mInfoCallback)(LLAssetInfo *, void *, S32); +// void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat); + void (*mInfoCallback)(LLAssetInfo *, void *, S32); - bool mIsLocal; - bool mIsUserWaiting; // We don't want to try forever if a user is waiting for a result. - F64Seconds mTimeout; // Amount of time before timing out. - LLUUID mRequestingAgentID; // Only valid for uploads from an agent - F64 mBytesFetched; + bool mIsLocal; + bool mIsUserWaiting; // We don't want to try forever if a user is waiting for a result. + F64Seconds mTimeout; // Amount of time before timing out. + LLUUID mRequestingAgentID; // Only valid for uploads from an agent + F64 mBytesFetched; - virtual LLSD getTerseDetails() const; - virtual LLSD getFullDetails() const; + virtual LLSD getTerseDetails() const; + virtual LLSD getFullDetails() const; }; template <class T> struct ll_asset_request_equal : public std::equal_to<T> { - bool operator()(const T& x, const T& y) const - { - return ( x->getType() == y->getType() - && x->getUUID() == y->getUUID() ); - } + bool operator()(const T& x, const T& y) const + { + return ( x->getType() == y->getType() + && x->getUUID() == y->getUUID() ); + } }; @@ -179,12 +179,12 @@ public: LLEstateAssetRequest(const LLUUID &uuid, const LLAssetType::EType at, EstateAssetType et); virtual ~LLEstateAssetRequest(); - LLAssetType::EType getAType() const { return mType; } + LLAssetType::EType getAType() const { return mType; } virtual LLBaseDownloadRequest* getCopy(); protected: - EstateAssetType mEstateAssetType; + EstateAssetType mEstateAssetType; }; @@ -199,125 +199,125 @@ public: typedef ::LLStoreAssetCallback LLStoreAssetCallback; typedef ::LLGetAssetCallback LLGetAssetCallback; - enum ERequestType - { - RT_INVALID = -1, - RT_DOWNLOAD = 0, - RT_UPLOAD = 1, - RT_LOCALUPLOAD = 2, - RT_COUNT = 3 - }; + enum ERequestType + { + RT_INVALID = -1, + RT_DOWNLOAD = 0, + RT_UPLOAD = 1, + RT_LOCALUPLOAD = 2, + RT_COUNT = 3 + }; protected: - bool mShutDown; - LLHost mUpstreamHost; - - LLMessageSystem *mMessageSys; - LLXferManager *mXferManager; + bool mShutDown; + LLHost mUpstreamHost; + + LLMessageSystem *mMessageSys; + LLXferManager *mXferManager; - typedef std::list<LLAssetRequest*> request_list_t; - request_list_t mPendingDownloads; - request_list_t mPendingUploads; - request_list_t mPendingLocalUploads; - - // Map of toxic assets - these caused problems when recently rezzed, so avoid them - toxic_asset_map_t mToxicAssetMap; // Objects in this list are known to cause problems and are not loaded + typedef std::list<LLAssetRequest*> request_list_t; + request_list_t mPendingDownloads; + request_list_t mPendingUploads; + request_list_t mPendingLocalUploads; + + // Map of toxic assets - these caused problems when recently rezzed, so avoid them + toxic_asset_map_t mToxicAssetMap; // Objects in this list are known to cause problems and are not loaded public: - LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, const LLHost &upstream_host); - - LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer); - virtual ~LLAssetStorage(); - - void setUpstream(const LLHost &upstream_host); - - bool hasLocalAsset(const LLUUID &uuid, LLAssetType::EType type); - - // public interface methods - // note that your callback may get called BEFORE the function returns - void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, bool is_priority = false); - - /* - * TransactionID version - * Viewer needs the store_local - */ - virtual void storeAssetData( - const LLTransactionID& tid, - LLAssetType::EType atype, - LLStoreAssetCallback callback, - void* user_data, - bool temp_file = false, - bool is_priority = false, - bool store_local = false, - bool user_waiting= false, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) = 0; + LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, const LLHost &upstream_host); + + LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer); + virtual ~LLAssetStorage(); + + void setUpstream(const LLHost &upstream_host); + + bool hasLocalAsset(const LLUUID &uuid, LLAssetType::EType type); + + // public interface methods + // note that your callback may get called BEFORE the function returns + void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, bool is_priority = false); + + /* + * TransactionID version + * Viewer needs the store_local + */ + virtual void storeAssetData( + const LLTransactionID& tid, + LLAssetType::EType atype, + LLStoreAssetCallback callback, + void* user_data, + bool temp_file = false, + bool is_priority = false, + bool store_local = false, + bool user_waiting= false, + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) = 0; virtual void logAssetStorageInfo() = 0; - - virtual void checkForTimeouts(); - void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, - const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, - LLGetAssetCallback callback, void *user_data, bool is_priority); + virtual void checkForTimeouts(); + + void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, + const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, + LLGetAssetCallback callback, void *user_data, bool is_priority); - void getInvItemAsset(const LLHost &object_sim, - const LLUUID &agent_id, const LLUUID &session_id, - const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id, - const LLUUID &asset_id, LLAssetType::EType atype, - LLGetAssetCallback cb, void *user_data, bool is_priority = false); // Get a particular inventory item. + void getInvItemAsset(const LLHost &object_sim, + const LLUUID &agent_id, const LLUUID &session_id, + const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id, + const LLUUID &asset_id, LLAssetType::EType atype, + LLGetAssetCallback cb, void *user_data, bool is_priority = false); // Get a particular inventory item. - // Check if an asset is in the toxic map. If it is, the entry is updated - bool isAssetToxic( const LLUUID& uuid ); + // Check if an asset is in the toxic map. If it is, the entry is updated + bool isAssetToxic( const LLUUID& uuid ); - // Clean the toxic asset list, remove old entries - void flushOldToxicAssets( bool force_it ); + // Clean the toxic asset list, remove old entries + void flushOldToxicAssets( bool force_it ); - // Add an item to the toxic asset map - void markAssetToxic( const LLUUID& uuid ); + // Add an item to the toxic asset map + void markAssetToxic( const LLUUID& uuid ); protected: - bool findInCacheAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type, - LLGetAssetCallback callback, void *user_data); + bool findInCacheAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type, + LLGetAssetCallback callback, void *user_data); - LLSD getPendingDetailsImpl(const request_list_t* requests, + LLSD getPendingDetailsImpl(const request_list_t* requests, LLAssetType::EType asset_type, const std::string& detail_prefix) const; - LLSD getPendingRequestImpl(const request_list_t* requests, + LLSD getPendingRequestImpl(const request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) const; - bool deletePendingRequestImpl(request_list_t* requests, + bool deletePendingRequestImpl(request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id); public: - static const LLAssetRequest* findRequest(const request_list_t* requests, - LLAssetType::EType asset_type, - const LLUUID& asset_id); - static LLAssetRequest* findRequest(request_list_t* requests, - LLAssetType::EType asset_type, - const LLUUID& asset_id); - - request_list_t* getRequestList(ERequestType rt); - const request_list_t* getRequestList(ERequestType rt) const; - static std::string getRequestName(ERequestType rt); - - S32 getNumPendingDownloads() const; - S32 getNumPendingUploads() const; - S32 getNumPendingLocalUploads(); - S32 getNumPending(ERequestType rt) const; - - LLSD getPendingDetails(ERequestType rt, + static const LLAssetRequest* findRequest(const request_list_t* requests, + LLAssetType::EType asset_type, + const LLUUID& asset_id); + static LLAssetRequest* findRequest(request_list_t* requests, + LLAssetType::EType asset_type, + const LLUUID& asset_id); + + request_list_t* getRequestList(ERequestType rt); + const request_list_t* getRequestList(ERequestType rt) const; + static std::string getRequestName(ERequestType rt); + + S32 getNumPendingDownloads() const; + S32 getNumPendingUploads() const; + S32 getNumPendingLocalUploads(); + S32 getNumPending(ERequestType rt) const; + + LLSD getPendingDetails(ERequestType rt, LLAssetType::EType asset_type, const std::string& detail_prefix) const; - LLSD getPendingRequest(ERequestType rt, + LLSD getPendingRequest(ERequestType rt, LLAssetType::EType asset_type, const LLUUID& asset_id) const; - bool deletePendingRequest(ERequestType rt, + bool deletePendingRequest(ERequestType rt, LLAssetType::EType asset_type, const LLUUID& asset_id); @@ -325,92 +325,92 @@ public: static void removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type, const LLUUID& callback_id, LLAssetType::EType callback_type, S32 result_code, LLExtStat ext_status); - - // download process callbacks - static void downloadCompleteCallback( - S32 result, - const LLUUID& file_id, - LLAssetType::EType file_type, - LLBaseDownloadRequest* user_data, LLExtStat ext_status); - static void downloadEstateAssetCompleteCallback( - S32 result, - const LLUUID& file_id, - LLAssetType::EType file_type, - LLBaseDownloadRequest* user_data, LLExtStat ext_status); - static void downloadInvItemCompleteCallback( - S32 result, - const LLUUID& file_id, - LLAssetType::EType file_type, - LLBaseDownloadRequest* user_data, LLExtStat ext_status); - - // upload process callbacks - static void uploadCompleteCallback(const LLUUID&, void *user_data, S32 result, LLExtStat ext_status); - static void processUploadComplete(LLMessageSystem *msg, void **this_handle); - - // debugging - static const char* getErrorString( S32 status ); - - // deprecated file-based methods + + // download process callbacks + static void downloadCompleteCallback( + S32 result, + const LLUUID& file_id, + LLAssetType::EType file_type, + LLBaseDownloadRequest* user_data, LLExtStat ext_status); + static void downloadEstateAssetCompleteCallback( + S32 result, + const LLUUID& file_id, + LLAssetType::EType file_type, + LLBaseDownloadRequest* user_data, LLExtStat ext_status); + static void downloadInvItemCompleteCallback( + S32 result, + const LLUUID& file_id, + LLAssetType::EType file_type, + LLBaseDownloadRequest* user_data, LLExtStat ext_status); + + // upload process callbacks + static void uploadCompleteCallback(const LLUUID&, void *user_data, S32 result, LLExtStat ext_status); + static void processUploadComplete(LLMessageSystem *msg, void **this_handle); + + // debugging + static const char* getErrorString( S32 status ); + + // deprecated file-based methods // Not overriden - void getAssetData(const LLUUID uuid, LLAssetType::EType type, void (*callback)(const char*, const LLUUID&, void *, S32, LLExtStat), void *user_data, bool is_priority = false); - - /* - * TransactionID version - */ - virtual void storeAssetData( - const std::string& filename, - const LLTransactionID &transaction_id, - LLAssetType::EType type, - LLStoreAssetCallback callback, - void *user_data, - bool temp_file = false, - bool is_priority = false, - bool user_waiting = false, - F64Seconds timeout = LL_ASSET_STORAGE_TIMEOUT) = 0; - - static void legacyGetDataCallback(const LLUUID &uuid, LLAssetType::EType, void *user_data, S32 status, LLExtStat ext_status); - static void legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status); - - // add extra methods to handle metadata + void getAssetData(const LLUUID uuid, LLAssetType::EType type, void (*callback)(const char*, const LLUUID&, void *, S32, LLExtStat), void *user_data, bool is_priority = false); + + /* + * TransactionID version + */ + virtual void storeAssetData( + const std::string& filename, + const LLTransactionID &transaction_id, + LLAssetType::EType type, + LLStoreAssetCallback callback, + void *user_data, + bool temp_file = false, + bool is_priority = false, + bool user_waiting = false, + F64Seconds timeout = LL_ASSET_STORAGE_TIMEOUT) = 0; + + static void legacyGetDataCallback(const LLUUID &uuid, LLAssetType::EType, void *user_data, S32 status, LLExtStat ext_status); + static void legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status); + + // add extra methods to handle metadata protected: - void _cleanupRequests(bool all, S32 error); - void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, bool success, LLExtStat ext_status); + void _cleanupRequests(bool all, S32 error); + void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, bool success, LLExtStat ext_status); - virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback, - void *user_data, bool duplicate, - bool is_priority) = 0; + virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback, + void *user_data, bool duplicate, + bool is_priority) = 0; private: - void _init(LLMessageSystem *msg, - LLXferManager *xfer, - const LLHost &upstream_host); + void _init(LLMessageSystem *msg, + LLXferManager *xfer, + const LLHost &upstream_host); protected: - enum EMetricResult - { - // Static valued enums for #dw readability - please copy this - // declaration to them on updates -- source in llassetstorage.h - MR_INVALID = -1, // Makes no sense - MR_OKAY = 0, // Success - no metric normally - MR_ZERO_SIZE = 1, // Zero size asset - MR_BAD_FUNCTION = 2, // Tried to use a virtual base (PROGRAMMER ERROR) - MR_FILE_NONEXIST = 3, // Old format store call - source file does not exist - MR_NO_FILENAME = 4, // Old format store call - source filename is NULL/0-length - MR_NO_UPSTREAM = 5, // Upstream provider is missing - MR_CACHE_CORRUPTION = 6 // cache is corrupt - too-large or mismatched stated/returned sizes - }; - - static class LLMetrics *metric_recipient; - - static void reportMetric( const LLUUID& asset_id, const LLAssetType::EType asset_type, const std::string& filename, - const LLUUID& agent_id, S32 asset_size, EMetricResult result, - const char* file, const S32 line, const std::string& message ); + enum EMetricResult + { + // Static valued enums for #dw readability - please copy this + // declaration to them on updates -- source in llassetstorage.h + MR_INVALID = -1, // Makes no sense + MR_OKAY = 0, // Success - no metric normally + MR_ZERO_SIZE = 1, // Zero size asset + MR_BAD_FUNCTION = 2, // Tried to use a virtual base (PROGRAMMER ERROR) + MR_FILE_NONEXIST = 3, // Old format store call - source file does not exist + MR_NO_FILENAME = 4, // Old format store call - source filename is NULL/0-length + MR_NO_UPSTREAM = 5, // Upstream provider is missing + MR_CACHE_CORRUPTION = 6 // cache is corrupt - too-large or mismatched stated/returned sizes + }; + + static class LLMetrics *metric_recipient; + + static void reportMetric( const LLUUID& asset_id, const LLAssetType::EType asset_type, const std::string& filename, + const LLUUID& agent_id, S32 asset_size, EMetricResult result, + const char* file, const S32 line, const std::string& message ); public: - static void setMetricRecipient( LLMetrics *recip ) - { - metric_recipient = recip; - } + static void setMetricRecipient( LLMetrics *recip ) + { + metric_recipient = recip; + } }; //////////////////////////////////////////////////////////////////////// @@ -420,12 +420,12 @@ public: class LLLegacyAssetRequest { public: - void (*mDownCallback)(const char *, const LLUUID&, void *, S32, LLExtStat); - LLStoreAssetCallback mUpCallback; + void (*mDownCallback)(const char *, const LLUUID&, void *, S32, LLExtStat); + LLStoreAssetCallback mUpCallback; - void *mUserData; + void *mUserData; }; extern LLAssetStorage *gAssetStorage; extern const LLUUID CATEGORIZE_LOST_AND_FOUND_ID; -#endif +#endif diff --git a/indra/llmessage/llavatarname.cpp b/indra/llmessage/llavatarname.cpp index 7e1246f885..650a76860a 100644 --- a/indra/llmessage/llavatarname.cpp +++ b/indra/llmessage/llavatarname.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llavatarname.cpp * @brief Represents name-related data for an avatar, such as the * username/SLID ("bobsmith123" or "james.linden") and the display @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,222 +48,222 @@ bool LLAvatarName::sUseUsernames = true; // Minimum time-to-live (in seconds) for a name entry. // Avatar name should always guarantee to expire reasonably soon by default -// so if the failure to get a valid expiration time was due to something temporary +// so if the failure to get a valid expiration time was due to something temporary // we will eventually request and get the right data. const F64 MIN_ENTRY_LIFETIME = 60.0; LLAvatarName::LLAvatarName() -: mUsername(), - mDisplayName(), - mLegacyFirstName(), - mLegacyLastName(), - mIsDisplayNameDefault(false), - mIsTemporaryName(false), - mExpires(F64_MAX), - mNextUpdate(0.0) +: mUsername(), + mDisplayName(), + mLegacyFirstName(), + mLegacyLastName(), + mIsDisplayNameDefault(false), + mIsTemporaryName(false), + mExpires(F64_MAX), + mNextUpdate(0.0) { } bool LLAvatarName::operator<(const LLAvatarName& rhs) const { - if (mUsername == rhs.mUsername) - return mDisplayName < rhs.mDisplayName; - else - return mUsername < rhs.mUsername; + if (mUsername == rhs.mUsername) + return mDisplayName < rhs.mDisplayName; + else + return mUsername < rhs.mUsername; } -//static +//static void LLAvatarName::setUseDisplayNames(bool use) { - sUseDisplayNames = use; + sUseDisplayNames = use; } -//static -bool LLAvatarName::useDisplayNames() -{ - return sUseDisplayNames; +//static +bool LLAvatarName::useDisplayNames() +{ + return sUseDisplayNames; } void LLAvatarName::setUseUsernames(bool use) { - sUseUsernames = use; + sUseUsernames = use; } bool LLAvatarName::useUsernames() { - return sUseUsernames; + return sUseUsernames; } LLSD LLAvatarName::asLLSD() const { - LLSD sd; - sd[USERNAME] = mUsername; - sd[DISPLAY_NAME] = mDisplayName; - sd[LEGACY_FIRST_NAME] = mLegacyFirstName; - sd[LEGACY_LAST_NAME] = mLegacyLastName; - sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault; - sd[DISPLAY_NAME_EXPIRES] = LLDate(mExpires); - sd[DISPLAY_NAME_NEXT_UPDATE] = LLDate(mNextUpdate); - return sd; + LLSD sd; + sd[USERNAME] = mUsername; + sd[DISPLAY_NAME] = mDisplayName; + sd[LEGACY_FIRST_NAME] = mLegacyFirstName; + sd[LEGACY_LAST_NAME] = mLegacyLastName; + sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault; + sd[DISPLAY_NAME_EXPIRES] = LLDate(mExpires); + sd[DISPLAY_NAME_NEXT_UPDATE] = LLDate(mNextUpdate); + return sd; } void LLAvatarName::fromLLSD(const LLSD& sd) { - mUsername = sd[USERNAME].asString(); - mDisplayName = sd[DISPLAY_NAME].asString(); - mLegacyFirstName = sd[LEGACY_FIRST_NAME].asString(); - mLegacyLastName = sd[LEGACY_LAST_NAME].asString(); - mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean(); - LLDate expires = sd[DISPLAY_NAME_EXPIRES]; - mExpires = expires.secondsSinceEpoch(); - LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE]; - mNextUpdate = next_update.secondsSinceEpoch(); - - // Some avatars don't have explicit display names set. Force a legible display name here. - if (mDisplayName.empty()) - { - mDisplayName = mUsername; - } + mUsername = sd[USERNAME].asString(); + mDisplayName = sd[DISPLAY_NAME].asString(); + mLegacyFirstName = sd[LEGACY_FIRST_NAME].asString(); + mLegacyLastName = sd[LEGACY_LAST_NAME].asString(); + mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean(); + LLDate expires = sd[DISPLAY_NAME_EXPIRES]; + mExpires = expires.secondsSinceEpoch(); + LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE]; + mNextUpdate = next_update.secondsSinceEpoch(); + + // Some avatars don't have explicit display names set. Force a legible display name here. + if (mDisplayName.empty()) + { + mDisplayName = mUsername; + } } // Transform a string (typically provided by the legacy service) into a decent // avatar name instance. void LLAvatarName::fromString(const std::string& full_name) { - mDisplayName = full_name; - std::string::size_type index = full_name.find(' '); - if (index != std::string::npos) - { - // The name is in 2 parts (first last) - mLegacyFirstName = full_name.substr(0, index); - mLegacyLastName = full_name.substr(index+1); - if (mLegacyLastName != "Resident") - { - mUsername = mLegacyFirstName + "." + mLegacyLastName; - mDisplayName = full_name; - LLStringUtil::toLower(mUsername); - } - else - { - // Very old names do have a dummy "Resident" last name - // that we choose to hide from users. - mUsername = mLegacyFirstName; - mDisplayName = mLegacyFirstName; - } - } - else - { - mLegacyFirstName = full_name; - mLegacyLastName = ""; - mUsername = full_name; - mDisplayName = full_name; - } - mIsDisplayNameDefault = true; - mIsTemporaryName = true; - setExpires(MIN_ENTRY_LIFETIME); + mDisplayName = full_name; + std::string::size_type index = full_name.find(' '); + if (index != std::string::npos) + { + // The name is in 2 parts (first last) + mLegacyFirstName = full_name.substr(0, index); + mLegacyLastName = full_name.substr(index+1); + if (mLegacyLastName != "Resident") + { + mUsername = mLegacyFirstName + "." + mLegacyLastName; + mDisplayName = full_name; + LLStringUtil::toLower(mUsername); + } + else + { + // Very old names do have a dummy "Resident" last name + // that we choose to hide from users. + mUsername = mLegacyFirstName; + mDisplayName = mLegacyFirstName; + } + } + else + { + mLegacyFirstName = full_name; + mLegacyLastName = ""; + mUsername = full_name; + mDisplayName = full_name; + } + mIsDisplayNameDefault = true; + mIsTemporaryName = true; + setExpires(MIN_ENTRY_LIFETIME); } void LLAvatarName::setExpires(F64 expires) { - mExpires = LLFrameTimer::getTotalSeconds() + expires; + mExpires = LLFrameTimer::getTotalSeconds() + expires; } std::string LLAvatarName::getCompleteName(bool use_parentheses, bool force_use_complete_name) const { - std::string name; - if (sUseDisplayNames || force_use_complete_name) - { - if (mUsername.empty() || mIsDisplayNameDefault) - { - // If this particular display name is defaulted (i.e. based on user name), - // then display only the easier to read instance of the person's name. - name = mDisplayName; - } - else - { - name = mDisplayName; - if(sUseUsernames || force_use_complete_name) - { - if(use_parentheses) - { - name += " (" + mUsername + ")"; - } - else - { - name += " [ " + mUsername + " ]"; - } - } - } - } - else - { - name = getUserName(); - } - return name; + std::string name; + if (sUseDisplayNames || force_use_complete_name) + { + if (mUsername.empty() || mIsDisplayNameDefault) + { + // If this particular display name is defaulted (i.e. based on user name), + // then display only the easier to read instance of the person's name. + name = mDisplayName; + } + else + { + name = mDisplayName; + if(sUseUsernames || force_use_complete_name) + { + if(use_parentheses) + { + name += " (" + mUsername + ")"; + } + else + { + name += " [ " + mUsername + " ]"; + } + } + } + } + else + { + name = getUserName(); + } + return name; } std::string LLAvatarName::getLegacyName() const { - if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled? - { - return mDisplayName; - } + if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled? + { + return mDisplayName; + } - std::string name; - name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() ); - name = mLegacyFirstName; - name += " "; - name += mLegacyLastName; - return name; + std::string name; + name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() ); + name = mLegacyFirstName; + name += " "; + name += mLegacyLastName; + return name; } std::string LLAvatarName::getDisplayName(bool force_use_display_name) const { - if (sUseDisplayNames || force_use_display_name) - { - return mDisplayName; - } - else - { - return getUserName(); - } + if (sUseDisplayNames || force_use_display_name) + { + return mDisplayName; + } + else + { + return getUserName(); + } } std::string LLAvatarName::getUserName(bool lowercase) const { - std::string name; - if (mLegacyLastName.empty() || (mLegacyLastName == "Resident")) - { - if (mLegacyFirstName.empty()) - { - // If we cannot create a user name from the legacy strings, use the display name - name = mDisplayName; - } - else - { - // The last name might be empty if it defaulted to "Resident" - name = mLegacyFirstName; - } - } - else - { - if(lowercase) - { - name = mLegacyFirstName + "." + mLegacyLastName; - LLStringUtil::toLower(name); - } - else - { - name = mLegacyFirstName + " " + mLegacyLastName; - } - } - return name; + std::string name; + if (mLegacyLastName.empty() || (mLegacyLastName == "Resident")) + { + if (mLegacyFirstName.empty()) + { + // If we cannot create a user name from the legacy strings, use the display name + name = mDisplayName; + } + else + { + // The last name might be empty if it defaulted to "Resident" + name = mLegacyFirstName; + } + } + else + { + if(lowercase) + { + name = mLegacyFirstName + "." + mLegacyLastName; + LLStringUtil::toLower(name); + } + else + { + name = mLegacyFirstName + " " + mLegacyLastName; + } + } + return name; } void LLAvatarName::dump() const { - LL_DEBUGS("AvNameCache") << "LLAvatarName: " - << "user '" << mUsername << "' " - << "display '" << mDisplayName << "' " - << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds" - << LL_ENDL; + LL_DEBUGS("AvNameCache") << "LLAvatarName: " + << "user '" << mUsername << "' " + << "display '" << mDisplayName << "' " + << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds" + << LL_ENDL; } diff --git a/indra/llmessage/llavatarname.h b/indra/llmessage/llavatarname.h index 20f7140797..eec966d51b 100644 --- a/indra/llmessage/llavatarname.h +++ b/indra/llmessage/llavatarname.h @@ -1,4 +1,4 @@ -/** +/** * @file llavatarname.h * @brief Represents name-related data for an avatar, such as the * username/SLID ("bobsmith123" or "james.linden") and the display @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,105 +35,105 @@ class LLSD; class LL_COMMON_API LLAvatarName { public: - LLAvatarName(); - - bool operator<(const LLAvatarName& rhs) const; - - // Conversion to and from LLSD (cache file or server response) - LLSD asLLSD() const; - void fromLLSD(const LLSD& sd); - - // Used only in legacy mode when the display name capability is not provided server side - // or to otherwise create a temporary valid item. - void fromString(const std::string& full_name); - - // Set the name object to become invalid in "expires" seconds from now - void setExpires(F64 expires); - - // Set and get the display name flag set by the user in preferences. - static void setUseDisplayNames(bool use); - static bool useDisplayNames(); - - static void setUseUsernames(bool use); - static bool useUsernames(); - - // A name object is valid if not temporary and not yet expired (default is expiration not checked) - bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); } - - // Return true if the name is made up from legacy or temporary data - bool isDisplayNameDefault() const { return mIsDisplayNameDefault; } - - // For normal names, returns "James Linden (james.linden)" - // When display names are disabled returns just "James Linden" - std::string getCompleteName(bool use_parentheses = true, bool force_use_complete_name = false) const; - - // Returns "James Linden" or "bobsmith123 Resident" for backwards - // compatibility with systems like voice and muting - // *TODO: Eliminate this in favor of username only - std::string getLegacyName() const; - - // "José Sanchez" or "James Linden", UTF-8 encoded Unicode - // Takes the display name preference into account. This is truly the name that should - // be used for all UI where an avatar name has to be used unless we truly want something else (rare) - std::string getDisplayName(bool force_use_display_name = false) const; - - // Returns "James Linden" or "bobsmith123 Resident" - // Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name - // Also used for backwards compatibility with systems like voice and muting - std::string getUserName(bool lowercase = false) const; - - // Returns "james.linden" or the legacy name for very old names - std::string getAccountName() const { return mUsername; } - - // Debug print of the object - void dump() const; - - // Names can change, so need to keep track of when name was - // last checked. - // Unix time-from-epoch seconds for efficiency - F64 mExpires; - - // You can only change your name every N hours, so record - // when the next update is allowed - // Unix time-from-epoch seconds - F64 mNextUpdate; - + LLAvatarName(); + + bool operator<(const LLAvatarName& rhs) const; + + // Conversion to and from LLSD (cache file or server response) + LLSD asLLSD() const; + void fromLLSD(const LLSD& sd); + + // Used only in legacy mode when the display name capability is not provided server side + // or to otherwise create a temporary valid item. + void fromString(const std::string& full_name); + + // Set the name object to become invalid in "expires" seconds from now + void setExpires(F64 expires); + + // Set and get the display name flag set by the user in preferences. + static void setUseDisplayNames(bool use); + static bool useDisplayNames(); + + static void setUseUsernames(bool use); + static bool useUsernames(); + + // A name object is valid if not temporary and not yet expired (default is expiration not checked) + bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); } + + // Return true if the name is made up from legacy or temporary data + bool isDisplayNameDefault() const { return mIsDisplayNameDefault; } + + // For normal names, returns "James Linden (james.linden)" + // When display names are disabled returns just "James Linden" + std::string getCompleteName(bool use_parentheses = true, bool force_use_complete_name = false) const; + + // Returns "James Linden" or "bobsmith123 Resident" for backwards + // compatibility with systems like voice and muting + // *TODO: Eliminate this in favor of username only + std::string getLegacyName() const; + + // "José Sanchez" or "James Linden", UTF-8 encoded Unicode + // Takes the display name preference into account. This is truly the name that should + // be used for all UI where an avatar name has to be used unless we truly want something else (rare) + std::string getDisplayName(bool force_use_display_name = false) const; + + // Returns "James Linden" or "bobsmith123 Resident" + // Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name + // Also used for backwards compatibility with systems like voice and muting + std::string getUserName(bool lowercase = false) const; + + // Returns "james.linden" or the legacy name for very old names + std::string getAccountName() const { return mUsername; } + + // Debug print of the object + void dump() const; + + // Names can change, so need to keep track of when name was + // last checked. + // Unix time-from-epoch seconds for efficiency + F64 mExpires; + + // You can only change your name every N hours, so record + // when the next update is allowed + // Unix time-from-epoch seconds + F64 mNextUpdate; + private: - // "bobsmith123" or "james.linden", US-ASCII only - std::string mUsername; - - // "José Sanchez" or "James Linden", UTF-8 encoded Unicode - // Contains data whether or not user has explicitly set - // a display name; may duplicate their username. - std::string mDisplayName; - - // For "James Linden", "James" - // For "bobsmith123", "bobsmith123" - // Used to communicate with legacy systems like voice and muting which - // rely on old-style names. - // *TODO: Eliminate this in favor of username only - std::string mLegacyFirstName; - - // For "James Linden", "Linden" - // For "bobsmith123", "Resident" - // see above for rationale - std::string mLegacyLastName; - - // If true, both display name and SLID were generated from - // a legacy first and last name, like "James Linden (james.linden)" - bool mIsDisplayNameDefault; - - // Under error conditions, we may insert "dummy" records with - // names like "???" into caches as placeholders. These can be - // shown in UI, but are not serialized. - bool mIsTemporaryName; - - // Global flag indicating if display name should be used or not - // This will affect the output of the high level "get" methods - static bool sUseDisplayNames; - - // Flag indicating if username should be shown after display name or not - static bool sUseUsernames; + // "bobsmith123" or "james.linden", US-ASCII only + std::string mUsername; + + // "José Sanchez" or "James Linden", UTF-8 encoded Unicode + // Contains data whether or not user has explicitly set + // a display name; may duplicate their username. + std::string mDisplayName; + + // For "James Linden", "James" + // For "bobsmith123", "bobsmith123" + // Used to communicate with legacy systems like voice and muting which + // rely on old-style names. + // *TODO: Eliminate this in favor of username only + std::string mLegacyFirstName; + + // For "James Linden", "Linden" + // For "bobsmith123", "Resident" + // see above for rationale + std::string mLegacyLastName; + + // If true, both display name and SLID were generated from + // a legacy first and last name, like "James Linden (james.linden)" + bool mIsDisplayNameDefault; + + // Under error conditions, we may insert "dummy" records with + // names like "???" into caches as placeholders. These can be + // shown in UI, but are not serialized. + bool mIsTemporaryName; + + // Global flag indicating if display name should be used or not + // This will affect the output of the high level "get" methods + static bool sUseDisplayNames; + + // Flag indicating if username should be shown after display name or not + static bool sUseUsernames; }; #endif diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 314e7f0217..9910e19499 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llavatarnamecache.cpp * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names * ("James Cook") from avatar UUIDs. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,7 +28,7 @@ #include "llavatarnamecache.h" -#include "llcachename.h" // we wrap this system +#include "llcachename.h" // we wrap this system #include "llframetimer.h" #include "llsd.h" #include "llsdserialize.h" @@ -61,10 +61,10 @@ const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; static LLFrameTimer sRequestTimer; // static to avoid unnessesary dependencies -LLCore::HttpRequest::ptr_t sHttpRequest; -LLCore::HttpHeaders::ptr_t sHttpHeaders; -LLCore::HttpOptions::ptr_t sHttpOptions; -LLCore::HttpRequest::policy_t sHttpPolicy; +LLCore::HttpRequest::ptr_t sHttpRequest; +LLCore::HttpHeaders::ptr_t sHttpHeaders; +LLCore::HttpOptions::ptr_t sHttpOptions; +LLCore::HttpRequest::policy_t sHttpPolicy; /* Sample response: <?xml version="1.0"?> @@ -105,7 +105,7 @@ LLCore::HttpRequest::policy_t sHttpPolicy; </llsd> */ -// Coroutine for sending and processing avatar name cache requests. +// Coroutine for sending and processing avatar name cache requests. // Do not call directly. See documentation in lleventcoro.h and llcoro.h for // further explanation. @@ -188,7 +188,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU workqueue->post([=]() { if (!success) - { // on any sort of failure add dummy records for any agent IDs + { // on any sort of failure add dummy records for any agent IDs // in this request that we do not have cached already for (const auto& agent_id : agentIds) { @@ -276,16 +276,16 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h // Provide some fallback for agents that return errors void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) { - std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id); - if (existing == mCache.end()) + std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id); + if (existing == mCache.end()) { // there is no existing cache entry, so make a temporary name from legacy LL_DEBUGS("AvNameCache") << "LLAvatarNameCache get legacy for agent " - << agent_id << LL_ENDL; + << agent_id << LL_ENDL; gCacheName->get(agent_id, false, // legacy compatibility boost::bind(&LLAvatarNameCache::legacyNameFetch, _1, _2, _3)); } - else + else { // we have a cached (but probably expired) entry - since that would have // been returned by the get method, there is no need to signal anyone @@ -295,19 +295,19 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) LLAvatarName& av_name = existing->second; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL; - av_name.dump(); + av_name.dump(); - // Reset expiry time so we don't constantly rerequest. - av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME); + // Reset expiry time so we don't constantly rerequest. + av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME); } } void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name) { - if (agent_id.isNull()) - { - return; - } + if (agent_id.isNull()) + { + return; + } bool updated_account = true; // assume obsolete value for new arrivals by default @@ -318,175 +318,175 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& updated_account = false; } - // Add to the cache - mCache[agent_id] = av_name; + // Add to the cache + mCache[agent_id] = av_name; - // Suppress request from the queue - mPendingQueue.erase(agent_id); + // Suppress request from the queue + mPendingQueue.erase(agent_id); - // notify mute list about changes + // notify mute list about changes if (updated_account && mAccountNameChangedCallback) { mAccountNameChangedCallback(agent_id, av_name); } - // Signal everyone waiting on this name - signal_map_t::iterator sig_it = mSignalMap.find(agent_id); - if (sig_it != mSignalMap.end()) - { - callback_signal_t* signal = sig_it->second; - (*signal)(agent_id, av_name); + // Signal everyone waiting on this name + signal_map_t::iterator sig_it = mSignalMap.find(agent_id); + if (sig_it != mSignalMap.end()) + { + callback_signal_t* signal = sig_it->second; + (*signal)(agent_id, av_name); - mSignalMap.erase(agent_id); + mSignalMap.erase(agent_id); - delete signal; - signal = NULL; - } + delete signal; + signal = NULL; + } } void LLAvatarNameCache::requestNamesViaCapability() { - F64 now = LLFrameTimer::getTotalSeconds(); - - // URL format is like: - // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0 - // - // Apache can handle URLs of 4096 chars, but let's be conservative - static const U32 NAME_URL_MAX = 4096; - static const U32 NAME_URL_SEND_THRESHOLD = 3500; - - std::string url; - url.reserve(NAME_URL_MAX); - - std::vector<LLUUID> agent_ids; - agent_ids.reserve(128); - - U32 ids = 0; - ask_queue_t::const_iterator it; - while(!mAskQueue.empty()) - { - it = mAskQueue.begin(); - LLUUID agent_id = *it; - mAskQueue.erase(it); - - if (url.empty()) - { - // ...starting new request - url += mNameLookupURL; - url += "?ids="; - ids = 1; - } - else - { - // ...continuing existing request - url += "&ids="; - ids++; - } - url += agent_id.asString(); - agent_ids.push_back(agent_id); - - // mark request as pending - mPendingQueue[agent_id] = now; - - if (url.size() > NAME_URL_SEND_THRESHOLD) - { - break; - } - } + F64 now = LLFrameTimer::getTotalSeconds(); + + // URL format is like: + // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0 + // + // Apache can handle URLs of 4096 chars, but let's be conservative + static const U32 NAME_URL_MAX = 4096; + static const U32 NAME_URL_SEND_THRESHOLD = 3500; + + std::string url; + url.reserve(NAME_URL_MAX); + + std::vector<LLUUID> agent_ids; + agent_ids.reserve(128); + + U32 ids = 0; + ask_queue_t::const_iterator it; + while(!mAskQueue.empty()) + { + it = mAskQueue.begin(); + LLUUID agent_id = *it; + mAskQueue.erase(it); + + if (url.empty()) + { + // ...starting new request + url += mNameLookupURL; + url += "?ids="; + ids = 1; + } + else + { + // ...continuing existing request + url += "&ids="; + ids++; + } + url += agent_id.asString(); + agent_ids.push_back(agent_id); + + // mark request as pending + mPendingQueue[agent_id] = now; + + if (url.size() > NAME_URL_SEND_THRESHOLD) + { + break; + } + } if (!url.empty()) { LL_DEBUGS("AvNameCache") << "requested " << ids << " ids" << LL_ENDL; - std::string coroname = + std::string coroname = LLCoros::instance().launch("LLAvatarNameCache::requestAvatarNameCache_", boost::bind(&LLAvatarNameCache::requestAvatarNameCache_, url, agent_ids)); LL_DEBUGS("AvNameCache") << coroname << " with url '" << url << "', agent_ids.size()=" << agent_ids.size() << LL_ENDL; - } + } } void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, - const std::string& full_name, - bool is_group) + const std::string& full_name, + bool is_group) { - // Put the received data in the cache - legacyNameFetch(agent_id, full_name, is_group); - - // Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy - // protocol, we do not get an expiration date for each name and there's no reason to ask the - // data again and again so we set the expiration time to the largest value admissible. - std::map<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id); - LLAvatarName& av_name = av_record->second; - av_name.setExpires(MAX_UNREFRESHED_TIME); + // Put the received data in the cache + legacyNameFetch(agent_id, full_name, is_group); + + // Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy + // protocol, we do not get an expiration date for each name and there's no reason to ask the + // data again and again so we set the expiration time to the largest value admissible. + std::map<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id); + LLAvatarName& av_name = av_record->second; + av_name.setExpires(MAX_UNREFRESHED_TIME); } void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id, - const std::string& full_name, - bool is_group) -{ - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache agent " << agent_id << " " - << "full name '" << full_name << "'" - << ( is_group ? " [group]" : "" ) - << LL_ENDL; - - // Construct an av_name record from this name. - LLAvatarName av_name; - av_name.fromString(full_name); - - // Add to cache: we're still using the new cache even if we're using the old (legacy) protocol. - LLAvatarNameCache::getInstance()->processName(agent_id, av_name); + const std::string& full_name, + bool is_group) +{ + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache agent " << agent_id << " " + << "full name '" << full_name << "'" + << ( is_group ? " [group]" : "" ) + << LL_ENDL; + + // Construct an av_name record from this name. + LLAvatarName av_name; + av_name.fromString(full_name); + + // Add to cache: we're still using the new cache even if we're using the old (legacy) protocol. + LLAvatarNameCache::getInstance()->processName(agent_id, av_name); } void LLAvatarNameCache::requestNamesViaLegacy() { - static const S32 MAX_REQUESTS = 100; - F64 now = LLFrameTimer::getTotalSeconds(); - std::string full_name; - ask_queue_t::const_iterator it; - for (S32 requests = 0; !mAskQueue.empty() && requests < MAX_REQUESTS; ++requests) - { - it = mAskQueue.begin(); - LLUUID agent_id = *it; - mAskQueue.erase(it); + static const S32 MAX_REQUESTS = 100; + F64 now = LLFrameTimer::getTotalSeconds(); + std::string full_name; + ask_queue_t::const_iterator it; + for (S32 requests = 0; !mAskQueue.empty() && requests < MAX_REQUESTS; ++requests) + { + it = mAskQueue.begin(); + LLUUID agent_id = *it; + mAskQueue.erase(it); - // Mark as pending first, just in case the callback is immediately - // invoked below. This should never happen in practice. - mPendingQueue[agent_id] = now; + // Mark as pending first, just in case the callback is immediately + // invoked below. This should never happen in practice. + mPendingQueue[agent_id] = now; - LL_DEBUGS("AvNameCache") << "agent " << agent_id << LL_ENDL; + LL_DEBUGS("AvNameCache") << "agent " << agent_id << LL_ENDL; - gCacheName->get(agent_id, false, // legacy compatibility - boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3)); - } + gCacheName->get(agent_id, false, // legacy compatibility + boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3)); + } } bool LLAvatarNameCache::importFile(std::istream& istr) { - LLSD data; - if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) - { + LLSD data; + if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) + { LL_WARNS("AvNameCache") << "avatar name cache data xml parse failed" << LL_ENDL; - return false; - } - - // by convention LLSD storage is a map - // we only store one entry in the map - LLSD agents = data["agents"]; - - LLUUID agent_id; - LLAvatarName av_name; - LLSD::map_const_iterator it = agents.beginMap(); - for ( ; it != agents.endMap(); ++it) - { - agent_id.set(it->first); - av_name.fromLLSD( it->second ); - mCache[agent_id] = av_name; - } + return false; + } + + // by convention LLSD storage is a map + // we only store one entry in the map + LLSD agents = data["agents"]; + + LLUUID agent_id; + LLAvatarName av_name; + LLSD::map_const_iterator it = agents.beginMap(); + for ( ; it != agents.endMap(); ++it) + { + agent_id.set(it->first); + av_name.fromLLSD( it->second ); + mCache[agent_id] = av_name; + } LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << mCache.size() << LL_ENDL; - // Some entries may have expired since the cache was stored, + // Some entries may have expired since the cache was stored, // but they will be flushed in the first call to eraseUnrefreshed // from LLAvatarNameResponder::idle @@ -495,35 +495,35 @@ bool LLAvatarNameCache::importFile(std::istream& istr) void LLAvatarNameCache::exportFile(std::ostream& ostr) { - LLSD agents; - F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME; + LLSD agents; + F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME; LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << mCache.size() << LL_ENDL; - cache_t::const_iterator it = mCache.begin(); - for ( ; it != mCache.end(); ++it) - { - const LLUUID& agent_id = it->first; - const LLAvatarName& av_name = it->second; - // Do not write temporary or expired entries to the stored cache - if (av_name.isValidName(max_unrefreshed)) - { - // key must be a string - agents[agent_id.asString()] = av_name.asLLSD(); - } - } + cache_t::const_iterator it = mCache.begin(); + for ( ; it != mCache.end(); ++it) + { + const LLUUID& agent_id = it->first; + const LLAvatarName& av_name = it->second; + // Do not write temporary or expired entries to the stored cache + if (av_name.isValidName(max_unrefreshed)) + { + // key must be a string + agents[agent_id.asString()] = av_name.asLLSD(); + } + } LL_INFOS("AvNameCache") << "LLAvatarNameCache returning " << agents.size() << LL_ENDL; - LLSD data; - data["agents"] = agents; - LLSDSerialize::toPrettyXML(data, ostr); + LLSD data; + data["agents"] = agents; + LLSDSerialize::toPrettyXML(data, ostr); } void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url) { - mNameLookupURL = name_lookup_url; + mNameLookupURL = name_lookup_url; } bool LLAvatarNameCache::hasNameLookupURL() { - return !mNameLookupURL.empty(); + return !mNameLookupURL.empty(); } void LLAvatarNameCache::setUsePeopleAPI(bool use_api) @@ -533,25 +533,25 @@ void LLAvatarNameCache::setUsePeopleAPI(bool use_api) bool LLAvatarNameCache::usePeopleAPI() { - return hasNameLookupURL() && mUsePeopleAPI; + return hasNameLookupURL() && mUsePeopleAPI; } void LLAvatarNameCache::idle() { - // By convention, start running at first idle() call - mRunning = true; + // By convention, start running at first idle() call + mRunning = true; - // *TODO: Possibly re-enabled this based on People API load measurements - // 100 ms is the threshold for "user speed" operations, so we can - // stall for about that long to batch up requests. - const F32 SECS_BETWEEN_REQUESTS = 0.1f; - if (!sRequestTimer.hasExpired()) - { - return; - } + // *TODO: Possibly re-enabled this based on People API load measurements + // 100 ms is the threshold for "user speed" operations, so we can + // stall for about that long to batch up requests. + const F32 SECS_BETWEEN_REQUESTS = 0.1f; + if (!sRequestTimer.hasExpired()) + { + return; + } - if (!mAskQueue.empty()) - { + if (!mAskQueue.empty()) + { if (usePeopleAPI()) { requestNamesViaCapability(); @@ -561,13 +561,13 @@ void LLAvatarNameCache::idle() LL_WARNS_ONCE("AvNameCache") << "LLAvatarNameCache still using legacy api" << LL_ENDL; requestNamesViaLegacy(); } - } + } - if (mAskQueue.empty()) - { - // cleared the list, reset the request timer. - sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS); - } + if (mAskQueue.empty()) + { + // cleared the list, reset the request timer. + sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS); + } // erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME eraseUnrefreshed(); @@ -575,23 +575,23 @@ void LLAvatarNameCache::idle() bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id) { - bool isPending = false; - const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; + bool isPending = false; + const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; - pending_queue_t::const_iterator it = mPendingQueue.find(agent_id); - if (it != mPendingQueue.end()) - { - // in the list of requests in flight, retry if too old - F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; - isPending = (it->second > expire_time); - } - return isPending; + pending_queue_t::const_iterator it = mPendingQueue.find(agent_id); + if (it != mPendingQueue.end()) + { + // in the list of requests in flight, retry if too old + F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; + isPending = (it->second > expire_time); + } + return isPending; } void LLAvatarNameCache::eraseUnrefreshed() { - F64 now = LLFrameTimer::getTotalSeconds(); - F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME; + F64 now = LLFrameTimer::getTotalSeconds(); + F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME; if (!mLastExpireCheck || mLastExpireCheck < max_unrefreshed) { @@ -602,21 +602,21 @@ void LLAvatarNameCache::eraseUnrefreshed() const LLAvatarName& av_name = it->second; if (av_name.mExpires < max_unrefreshed) { - LL_DEBUGS("AvNameCacheExpired") << "LLAvatarNameCache " << it->first + LL_DEBUGS("AvNameCacheExpired") << "LLAvatarNameCache " << it->first << " user '" << av_name.getAccountName() << "' " << "expired " << now - av_name.mExpires << " secs ago" << LL_ENDL; mCache.erase(it++); expired++; } - else - { - ++it; - } + else + { + ++it; + } } LL_INFOS("AvNameCache") << "LLAvatarNameCache expired " << expired << " cached avatar names, " << mCache.size() << " remaining" << LL_ENDL; - } + } } //static, wrapper @@ -628,45 +628,45 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) // returns bool specifying if av_name was filled, false otherwise bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name) { - if (mRunning) - { - // ...only do immediate lookups when cache is running - std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); - if (it != mCache.end()) - { - *av_name = it->second; - - // re-request name if entry is expired - if (av_name->mExpires < LLFrameTimer::getTotalSeconds()) - { - if (!isRequestPending(agent_id)) - { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache refresh agent " << agent_id - << LL_ENDL; - mAskQueue.insert(agent_id); - } - } - - return true; - } - } - - if (!isRequestPending(agent_id)) - { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache queue request for agent " << agent_id << LL_ENDL; - mAskQueue.insert(agent_id); - } - - return false; + if (mRunning) + { + // ...only do immediate lookups when cache is running + std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); + if (it != mCache.end()) + { + *av_name = it->second; + + // re-request name if entry is expired + if (av_name->mExpires < LLFrameTimer::getTotalSeconds()) + { + if (!isRequestPending(agent_id)) + { + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache refresh agent " << agent_id + << LL_ENDL; + mAskQueue.insert(agent_id); + } + } + + return true; + } + } + + if (!isRequestPending(agent_id)) + { + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache queue request for agent " << agent_id << LL_ENDL; + mAskQueue.insert(agent_id); + } + + return false; } void LLAvatarNameCache::fireSignal(const LLUUID& agent_id, - const callback_slot_t& slot, - const LLAvatarName& av_name) + const callback_slot_t& slot, + const LLAvatarName& av_name) { - callback_signal_t signal; - signal.connect(slot); - signal(agent_id, av_name); + callback_signal_t signal; + signal.connect(slot); + signal(agent_id, av_name); } // static, wrapper @@ -677,78 +677,78 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(const LLUUID& agent_id, callback_slot_t slot) { - callback_connection_t connection; - - if (mRunning) - { - // ...only do immediate lookups when cache is running - std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); - if (it != mCache.end()) - { - const LLAvatarName& av_name = it->second; - - if (av_name.mExpires > LLFrameTimer::getTotalSeconds()) - { - // ...name already exists in cache, fire callback now - fireSignal(agent_id, slot, av_name); - return connection; - } - } - } - - // schedule a request - if (!isRequestPending(agent_id)) - { - mAskQueue.insert(agent_id); - } - - // always store additional callback, even if request is pending - signal_map_t::iterator sig_it = mSignalMap.find(agent_id); - if (sig_it == mSignalMap.end()) - { - // ...new callback for this id - callback_signal_t* signal = new callback_signal_t(); - connection = signal->connect(slot); - mSignalMap[agent_id] = signal; - } - else - { - // ...existing callback, bind additional slot - callback_signal_t* signal = sig_it->second; - connection = signal->connect(slot); - } - - return connection; + callback_connection_t connection; + + if (mRunning) + { + // ...only do immediate lookups when cache is running + std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); + if (it != mCache.end()) + { + const LLAvatarName& av_name = it->second; + + if (av_name.mExpires > LLFrameTimer::getTotalSeconds()) + { + // ...name already exists in cache, fire callback now + fireSignal(agent_id, slot, av_name); + return connection; + } + } + } + + // schedule a request + if (!isRequestPending(agent_id)) + { + mAskQueue.insert(agent_id); + } + + // always store additional callback, even if request is pending + signal_map_t::iterator sig_it = mSignalMap.find(agent_id); + if (sig_it == mSignalMap.end()) + { + // ...new callback for this id + callback_signal_t* signal = new callback_signal_t(); + connection = signal->connect(slot); + mSignalMap[agent_id] = signal; + } + else + { + // ...existing callback, bind additional slot + callback_signal_t* signal = sig_it->second; + connection = signal->connect(slot); + } + + return connection; } void LLAvatarNameCache::setUseDisplayNames(bool use) { - if (use != LLAvatarName::useDisplayNames()) - { - LLAvatarName::setUseDisplayNames(use); - mUseDisplayNamesSignal(); - } + if (use != LLAvatarName::useDisplayNames()) + { + LLAvatarName::setUseDisplayNames(use); + mUseDisplayNamesSignal(); + } } void LLAvatarNameCache::setUseUsernames(bool use) { - if (use != LLAvatarName::useUsernames()) - { - LLAvatarName::setUseUsernames(use); - mUseDisplayNamesSignal(); - } + if (use != LLAvatarName::useUsernames()) + { + LLAvatarName::setUseUsernames(use); + mUseDisplayNamesSignal(); + } } void LLAvatarNameCache::erase(const LLUUID& agent_id) { - mCache.erase(agent_id); + mCache.erase(agent_id); } void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name) { - // *TODO: update timestamp if zero? - mCache[agent_id] = av_name; + // *TODO: update timestamp if zero? + mCache[agent_id] = av_name; } LLUUID LLAvatarNameCache::findIdByName(const std::string& name) @@ -797,7 +797,7 @@ bool LLAvatarNameCache::expirationFromCacheControl(LLCore::HttpHeaders *headers, // Allow the header to override the default const std::string *cache_control; - + cache_control = headers->find(HTTP_IN_HEADER_CACHE_CONTROL); if (cache_control && !cache_control->empty()) @@ -819,53 +819,53 @@ bool LLAvatarNameCache::expirationFromCacheControl(LLCore::HttpHeaders *headers, #else F64 LLAvatarNameCache::nameExpirationFromHeaders(const LLSD& headers) { - F64 expires = 0.0; - if (expirationFromCacheControl(headers, &expires)) - { - return expires; - } - else - { - // With no expiration info, default to an hour - const F64 DEFAULT_EXPIRES = 60.0 * 60.0; - F64 now = LLFrameTimer::getTotalSeconds(); - return now + DEFAULT_EXPIRES; - } + F64 expires = 0.0; + if (expirationFromCacheControl(headers, &expires)) + { + return expires; + } + else + { + // With no expiration info, default to an hour + const F64 DEFAULT_EXPIRES = 60.0 * 60.0; + F64 now = LLFrameTimer::getTotalSeconds(); + return now + DEFAULT_EXPIRES; + } } bool LLAvatarNameCache::expirationFromCacheControl(const LLSD& headers, F64 *expires) { - bool fromCacheControl = false; - F64 now = LLFrameTimer::getTotalSeconds(); - - // Allow the header to override the default - std::string cache_control; - if (headers.has(HTTP_IN_HEADER_CACHE_CONTROL)) - { - cache_control = headers[HTTP_IN_HEADER_CACHE_CONTROL].asString(); - } - - if (!cache_control.empty()) - { - S32 max_age = 0; - if (max_age_from_cache_control(cache_control, &max_age)) - { - *expires = now + (F64)max_age; - fromCacheControl = true; - } - } - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache " - << ( fromCacheControl ? "expires based on cache control " : "default expiration " ) - << "in " << *expires - now << " seconds" - << LL_ENDL; - - return fromCacheControl; + bool fromCacheControl = false; + F64 now = LLFrameTimer::getTotalSeconds(); + + // Allow the header to override the default + std::string cache_control; + if (headers.has(HTTP_IN_HEADER_CACHE_CONTROL)) + { + cache_control = headers[HTTP_IN_HEADER_CACHE_CONTROL].asString(); + } + + if (!cache_control.empty()) + { + S32 max_age = 0; + if (max_age_from_cache_control(cache_control, &max_age)) + { + *expires = now + (F64)max_age; + fromCacheControl = true; + } + } + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache " + << ( fromCacheControl ? "expires based on cache control " : "default expiration " ) + << "in " << *expires - now << " seconds" + << LL_ENDL; + + return fromCacheControl; } #endif -void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb) -{ - mUseDisplayNamesSignal.connect(cb); +void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb) +{ + mUseDisplayNamesSignal.connect(cb); } @@ -875,55 +875,55 @@ static const boost::char_separator<char> COMMA_SEPARATOR(","); bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age) { - // Split the string on "," to get a list of directives - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - tokenizer directives(cache_control, COMMA_SEPARATOR); - - tokenizer::iterator token_it = directives.begin(); - for ( ; token_it != directives.end(); ++token_it) - { - // Tokens may have leading or trailing whitespace - std::string token = *token_it; - LLStringUtil::trim(token); - - if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0) - { - // ...this token starts with max-age, so let's chop it up by "=" - tokenizer subtokens(token, EQUALS_SEPARATOR); - tokenizer::iterator subtoken_it = subtokens.begin(); - - // Must have a token - if (subtoken_it == subtokens.end()) return false; - std::string subtoken = *subtoken_it; - - // Must exactly equal "max-age" - LLStringUtil::trim(subtoken); - if (subtoken != MAX_AGE) return false; - - // Must have another token - ++subtoken_it; - if (subtoken_it == subtokens.end()) return false; - subtoken = *subtoken_it; - - // Must be a valid integer - // *NOTE: atoi() returns 0 for invalid values, so we have to - // check the string first. - // *TODO: Do servers ever send "0000" for zero? We don't handle it - LLStringUtil::trim(subtoken); - if (subtoken == "0") - { - *max_age = 0; - return true; - } - S32 val = atoi( subtoken.c_str() ); - if (val > 0 && val < S32_MAX) - { - *max_age = val; - return true; - } - return false; - } - } - return false; + // Split the string on "," to get a list of directives + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + tokenizer directives(cache_control, COMMA_SEPARATOR); + + tokenizer::iterator token_it = directives.begin(); + for ( ; token_it != directives.end(); ++token_it) + { + // Tokens may have leading or trailing whitespace + std::string token = *token_it; + LLStringUtil::trim(token); + + if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0) + { + // ...this token starts with max-age, so let's chop it up by "=" + tokenizer subtokens(token, EQUALS_SEPARATOR); + tokenizer::iterator subtoken_it = subtokens.begin(); + + // Must have a token + if (subtoken_it == subtokens.end()) return false; + std::string subtoken = *subtoken_it; + + // Must exactly equal "max-age" + LLStringUtil::trim(subtoken); + if (subtoken != MAX_AGE) return false; + + // Must have another token + ++subtoken_it; + if (subtoken_it == subtokens.end()) return false; + subtoken = *subtoken_it; + + // Must be a valid integer + // *NOTE: atoi() returns 0 for invalid values, so we have to + // check the string first. + // *TODO: Do servers ever send "0000" for zero? We don't handle it + LLStringUtil::trim(subtoken); + if (subtoken == "0") + { + *max_age = 0; + return true; + } + S32 val = atoi( subtoken.c_str() ); + if (val > 0 && val < S32_MAX) + { + *max_age = val; + return true; + } + return false; + } + } + return false; } diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 549d1703fa..fe51355207 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -1,4 +1,4 @@ -/** +/** * @file llavatarnamecache.h * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names * ("James Cook") from avatar UUIDs. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,7 +28,7 @@ #ifndef LLAVATARNAMECACHE_H #define LLAVATARNAMECACHE_H -#include "llavatarname.h" // for convenience +#include "llavatarname.h" // for convenience #include "llsingleton.h" #include <boost/signals2.hpp> #include <set> @@ -38,71 +38,71 @@ class LLUUID; class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache> { - LLSINGLETON(LLAvatarNameCache); - ~LLAvatarNameCache(); + LLSINGLETON(LLAvatarNameCache); + ~LLAvatarNameCache(); public: - typedef boost::signals2::signal<void (void)> use_display_name_signal_t; - typedef boost::function<void (const LLUUID id, const LLAvatarName& av_name)> account_name_changed_callback_t; - - // Import/export the name cache to file. - bool importFile(std::istream& istr); - void exportFile(std::ostream& ostr); - - // On the viewer, usually a simulator capabilities. - // If empty, name cache will fall back to using legacy name lookup system. - void setNameLookupURL(const std::string& name_lookup_url); - - // Do we have a valid lookup URL, i.e. are we trying to use the - // more recent display name lookup system? - bool hasNameLookupURL(); - void setUsePeopleAPI(bool use_api); - bool usePeopleAPI(); - - // Periodically makes a batch request for display names not already in - // cache. Called once per frame. - void idle(); - - // If name is in cache, returns true and fills in provided LLAvatarName - // otherwise returns false. - static bool get(const LLUUID& agent_id, LLAvatarName *av_name); - bool getName(const LLUUID& agent_id, LLAvatarName *av_name); - - // Callback types for get() below - typedef boost::signals2::signal< - void (const LLUUID& agent_id, const LLAvatarName& av_name)> - callback_signal_t; - typedef callback_signal_t::slot_type callback_slot_t; - typedef boost::signals2::connection callback_connection_t; - - // Fetches name information and calls callbacks. - // If name information is in cache, callbacks will be called immediately. - static callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); - callback_connection_t getNameCallback(const LLUUID& agent_id, callback_slot_t slot); - - // Set display name: flips the switch and triggers the callbacks. - void setUseDisplayNames(bool use); - - void setUseUsernames(bool use); - - void insert(const LLUUID& agent_id, const LLAvatarName& av_name); - void erase(const LLUUID& agent_id); - - // A way to find agent id by UUID, very slow, also unreliable - // since it doesn't request names, just serch exsisting ones - // that are likely not in cache. - // - // Todo: Find a way to remove this. - // Curently this method is used for chat history and in some cases notices. - LLUUID findIdByName(const std::string& name); - - /// Provide some fallback for agents that return errors. - void handleAgentError(const LLUUID& agent_id); - - // Compute name expiration time from HTTP Cache-Control header, - // or return default value, in seconds from epoch. + typedef boost::signals2::signal<void (void)> use_display_name_signal_t; + typedef boost::function<void (const LLUUID id, const LLAvatarName& av_name)> account_name_changed_callback_t; + + // Import/export the name cache to file. + bool importFile(std::istream& istr); + void exportFile(std::ostream& ostr); + + // On the viewer, usually a simulator capabilities. + // If empty, name cache will fall back to using legacy name lookup system. + void setNameLookupURL(const std::string& name_lookup_url); + + // Do we have a valid lookup URL, i.e. are we trying to use the + // more recent display name lookup system? + bool hasNameLookupURL(); + void setUsePeopleAPI(bool use_api); + bool usePeopleAPI(); + + // Periodically makes a batch request for display names not already in + // cache. Called once per frame. + void idle(); + + // If name is in cache, returns true and fills in provided LLAvatarName + // otherwise returns false. + static bool get(const LLUUID& agent_id, LLAvatarName *av_name); + bool getName(const LLUUID& agent_id, LLAvatarName *av_name); + + // Callback types for get() below + typedef boost::signals2::signal< + void (const LLUUID& agent_id, const LLAvatarName& av_name)> + callback_signal_t; + typedef callback_signal_t::slot_type callback_slot_t; + typedef boost::signals2::connection callback_connection_t; + + // Fetches name information and calls callbacks. + // If name information is in cache, callbacks will be called immediately. + static callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); + callback_connection_t getNameCallback(const LLUUID& agent_id, callback_slot_t slot); + + // Set display name: flips the switch and triggers the callbacks. + void setUseDisplayNames(bool use); + + void setUseUsernames(bool use); + + void insert(const LLUUID& agent_id, const LLAvatarName& av_name); + void erase(const LLUUID& agent_id); + + // A way to find agent id by UUID, very slow, also unreliable + // since it doesn't request names, just serch exsisting ones + // that are likely not in cache. + // + // Todo: Find a way to remove this. + // Curently this method is used for chat history and in some cases notices. + LLUUID findIdByName(const std::string& name); + + /// Provide some fallback for agents that return errors. + void handleAgentError(const LLUUID& agent_id); + + // Compute name expiration time from HTTP Cache-Control header, + // or return default value, in seconds from epoch. F64 nameExpirationFromHeaders(const LLSD& headers); - void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); + void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); void setAccountNameChangedCallback(const account_name_changed_callback_t& cb) { mAccountNameChangedCallback = cb; } diff --git a/indra/llmessage/llblowfishcipher.cpp b/indra/llmessage/llblowfishcipher.cpp index 949d4cc0c7..ed036e396d 100644 --- a/indra/llmessage/llblowfishcipher.cpp +++ b/indra/llmessage/llblowfishcipher.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llblowfishcipher.cpp * @brief Wrapper around OpenSSL Blowfish encryption algorithm. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,28 +30,28 @@ LLBlowfishCipher::LLBlowfishCipher(const U8* secret, size_t secret_size) -: LLCipher() +: LLCipher() { - llassert(secret); + llassert(secret); - mSecretSize = secret_size; - mSecret = new U8[mSecretSize]; - memcpy(mSecret, secret, mSecretSize); + mSecretSize = secret_size; + mSecret = new U8[mSecretSize]; + memcpy(mSecret, secret, mSecretSize); } LLBlowfishCipher::~LLBlowfishCipher() { - delete [] mSecret; - mSecret = NULL; + delete [] mSecret; + mSecret = NULL; } // virtual U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) { - if (!src || !src_len || !dst || !dst_len) return 0; - if (src_len > dst_len) return 0; + if (!src || !src_len || !dst || !dst_len) return 0; + if (src_len > dst_len) return 0; - // OpenSSL uses "cipher contexts" to hold encryption parameters. + // OpenSSL uses "cipher contexts" to hold encryption parameters. EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new(); if (!context) { @@ -59,71 +59,71 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) return 0; } - // We want a blowfish cyclic block chain cipher, but need to set - // the key length before we pass in a key, so call EncryptInit - // first with NULLs. - EVP_EncryptInit_ex(context, EVP_bf_cbc(), NULL, NULL, NULL); - EVP_CIPHER_CTX_set_key_length(context, (int)mSecretSize); - - // Complete initialization. Per EVP_EncryptInit man page, the - // cipher pointer must be NULL. Apparently initial_vector must - // be 8 bytes for blowfish, as this is the block size. + // We want a blowfish cyclic block chain cipher, but need to set + // the key length before we pass in a key, so call EncryptInit + // first with NULLs. + EVP_EncryptInit_ex(context, EVP_bf_cbc(), NULL, NULL, NULL); + EVP_CIPHER_CTX_set_key_length(context, (int)mSecretSize); + + // Complete initialization. Per EVP_EncryptInit man page, the + // cipher pointer must be NULL. Apparently initial_vector must + // be 8 bytes for blowfish, as this is the block size. unsigned char initial_vector[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - EVP_EncryptInit_ex(context, NULL, NULL, mSecret, initial_vector); + EVP_EncryptInit_ex(context, NULL, NULL, mSecret, initial_vector); int blocksize = EVP_CIPHER_CTX_block_size(context); int keylen = EVP_CIPHER_CTX_key_length(context); int iv_length = EVP_CIPHER_CTX_iv_length(context); LL_DEBUGS() << "LLBlowfishCipher blocksize " << blocksize - << " keylen " << keylen - << " iv_len " << iv_length - << LL_ENDL; - - int output_len = 0; - int temp_len = 0; - if (!EVP_EncryptUpdate(context, - dst, - &output_len, - src, - src_len)) - { - LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << LL_ENDL; - goto ERROR; - } - - // There may be some final data left to encrypt if the input is - // not an exact multiple of the block size. - if (!EVP_EncryptFinal_ex(context, (unsigned char*)(dst + output_len), &temp_len)) - { - LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << LL_ENDL; - goto ERROR; - } - output_len += temp_len; - - EVP_CIPHER_CTX_free(context); - return output_len; + << " keylen " << keylen + << " iv_len " << iv_length + << LL_ENDL; + + int output_len = 0; + int temp_len = 0; + if (!EVP_EncryptUpdate(context, + dst, + &output_len, + src, + src_len)) + { + LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << LL_ENDL; + goto ERROR; + } + + // There may be some final data left to encrypt if the input is + // not an exact multiple of the block size. + if (!EVP_EncryptFinal_ex(context, (unsigned char*)(dst + output_len), &temp_len)) + { + LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << LL_ENDL; + goto ERROR; + } + output_len += temp_len; + + EVP_CIPHER_CTX_free(context); + return output_len; ERROR: - EVP_CIPHER_CTX_free(context); - return 0; + EVP_CIPHER_CTX_free(context); + return 0; } // virtual U32 LLBlowfishCipher::decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) { - LL_ERRS() << "LLBlowfishCipher decrypt unsupported" << LL_ENDL; - return 0; + LL_ERRS() << "LLBlowfishCipher decrypt unsupported" << LL_ENDL; + return 0; } // virtual U32 LLBlowfishCipher::requiredEncryptionSpace(U32 len) const { - // *HACK: We know blowfish uses an 8 byte block size. - // Oddly, sometimes EVP_Encrypt produces an extra block - // if the input is an exact multiple of the block size. - // So round up. - const U32 BLOCK_SIZE = 8; - len += BLOCK_SIZE; - len -= (len % BLOCK_SIZE); - return len; + // *HACK: We know blowfish uses an 8 byte block size. + // Oddly, sometimes EVP_Encrypt produces an extra block + // if the input is an exact multiple of the block size. + // So round up. + const U32 BLOCK_SIZE = 8; + len += BLOCK_SIZE; + len -= (len % BLOCK_SIZE); + return len; } diff --git a/indra/llmessage/llblowfishcipher.h b/indra/llmessage/llblowfishcipher.h index 65228df11f..53dc94cce9 100644 --- a/indra/llmessage/llblowfishcipher.h +++ b/indra/llmessage/llblowfishcipher.h @@ -1,4 +1,4 @@ -/** +/** * @file llblowfishcipher.h * @brief A symmetric block cipher, designed in 1993 by Bruce Schneier. * We use it because it has an 8 byte block size, allowing encryption of @@ -8,21 +8,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,22 +36,22 @@ class LLBlowfishCipher : public LLCipher { public: - // Secret may be up to 56 bytes in length per Blowfish spec. - LLBlowfishCipher(const U8* secret, size_t secret_size); - virtual ~LLBlowfishCipher(); + // Secret may be up to 56 bytes in length per Blowfish spec. + LLBlowfishCipher(const U8* secret, size_t secret_size); + virtual ~LLBlowfishCipher(); - // See llcipher.h for documentation. - /*virtual*/ U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); - /*virtual*/ U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); - /*virtual*/ U32 requiredEncryptionSpace(U32 src_len) const; + // See llcipher.h for documentation. + /*virtual*/ U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); + /*virtual*/ U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); + /*virtual*/ U32 requiredEncryptionSpace(U32 src_len) const; #ifdef _DEBUG - static bool testHarness(); + static bool testHarness(); #endif private: - U8* mSecret; - size_t mSecretSize; + U8* mSecret; + size_t mSecretSize; }; #endif // LL_LLCRYPTO_H diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp index cfe38605ad..dc7115b167 100644 --- a/indra/llmessage/llbuffer.cpp +++ b/indra/llmessage/llbuffer.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llbuffer.cpp * @author Phoenix * @date 2005-09-20 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,20 +37,20 @@ #define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED() llassert(!mMutexp || mMutexp->isSelfLocked()) -/** +/** * LLSegment */ LLSegment::LLSegment() : - mChannel(0), - mData(NULL), - mSize(0) + mChannel(0), + mData(NULL), + mSize(0) { } LLSegment::LLSegment(S32 channel, U8* data, S32 data_len) : - mChannel(channel), - mData(data), - mSize(data_len) + mChannel(channel), + mData(data), + mSize(data_len) { } @@ -60,849 +60,849 @@ LLSegment::~LLSegment() bool LLSegment::isOnChannel(S32 channel) const { - return (mChannel == channel); + return (mChannel == channel); } S32 LLSegment::getChannel() const { - return mChannel; + return mChannel; } void LLSegment::setChannel(S32 channel) { - mChannel = channel; + mChannel = channel; } U8* LLSegment::data() const { - return mData; + return mData; } S32 LLSegment::size() const { - return mSize; + return mSize; } bool LLSegment::operator==(const LLSegment& rhs) const { - if((mData != rhs.mData)||(mSize != rhs.mSize)||(mChannel != rhs.mChannel)) - { - return false; - } - return true; + if((mData != rhs.mData)||(mSize != rhs.mSize)||(mChannel != rhs.mChannel)) + { + return false; + } + return true; } -/** +/** * LLHeapBuffer */ LLHeapBuffer::LLHeapBuffer() : - mBuffer(NULL), - mSize(0), - mNextFree(NULL), - mReclaimedBytes(0) + mBuffer(NULL), + mSize(0), + mNextFree(NULL), + mReclaimedBytes(0) { - const S32 DEFAULT_HEAP_BUFFER_SIZE = 16384; - allocate(DEFAULT_HEAP_BUFFER_SIZE); + const S32 DEFAULT_HEAP_BUFFER_SIZE = 16384; + allocate(DEFAULT_HEAP_BUFFER_SIZE); } LLHeapBuffer::LLHeapBuffer(S32 size) : - mBuffer(NULL), - mSize(0), - mNextFree(NULL), - mReclaimedBytes(0) + mBuffer(NULL), + mSize(0), + mNextFree(NULL), + mReclaimedBytes(0) { - allocate(size); + allocate(size); } LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) : - mBuffer(NULL), - mSize(0), - mNextFree(NULL), - mReclaimedBytes(0) + mBuffer(NULL), + mSize(0), + mNextFree(NULL), + mReclaimedBytes(0) { - if((len > 0) && src) - { - allocate(len); - if(mBuffer) - { - memcpy(mBuffer, src, len); /*Flawfinder: ignore*/ - } - } + if((len > 0) && src) + { + allocate(len); + if(mBuffer) + { + memcpy(mBuffer, src, len); /*Flawfinder: ignore*/ + } + } } // virtual LLHeapBuffer::~LLHeapBuffer() { - delete[] mBuffer; - mBuffer = NULL; - mSize = 0; - mNextFree = NULL; + delete[] mBuffer; + mBuffer = NULL; + mSize = 0; + mNextFree = NULL; } S32 LLHeapBuffer::bytesLeft() const { - return (mSize - (mNextFree - mBuffer)); + return (mSize - (mNextFree - mBuffer)); } // virtual bool LLHeapBuffer::createSegment( - S32 channel, - S32 size, - LLSegment& segment) + S32 channel, + S32 size, + LLSegment& segment) { - // get actual size of the segment. - S32 actual_size = llmin(size, (mSize - S32(mNextFree - mBuffer))); + // get actual size of the segment. + S32 actual_size = llmin(size, (mSize - S32(mNextFree - mBuffer))); - // bail if we cannot build a valid segment - if(actual_size <= 0) - { - return false; - } + // bail if we cannot build a valid segment + if(actual_size <= 0) + { + return false; + } - // Yay, we're done. - segment = LLSegment(channel, mNextFree, actual_size); - mNextFree += actual_size; - return true; + // Yay, we're done. + segment = LLSegment(channel, mNextFree, actual_size); + mNextFree += actual_size; + return true; } // virtual bool LLHeapBuffer::reclaimSegment(const LLSegment& segment) { - if(containsSegment(segment)) - { - mReclaimedBytes += segment.size(); - if(mReclaimedBytes == mSize) - { - // We have reclaimed all of the memory from this - // buffer. Therefore, we can reset the mNextFree to the - // start of the buffer, and reset the reclaimed bytes. - mReclaimedBytes = 0; - mNextFree = mBuffer; - } - else if(mReclaimedBytes > mSize) - { - LL_WARNS() << "LLHeapBuffer reclaimed more memory than allocated." - << " This is probably programmer error." << LL_ENDL; - } - return true; - } - return false; + if(containsSegment(segment)) + { + mReclaimedBytes += segment.size(); + if(mReclaimedBytes == mSize) + { + // We have reclaimed all of the memory from this + // buffer. Therefore, we can reset the mNextFree to the + // start of the buffer, and reset the reclaimed bytes. + mReclaimedBytes = 0; + mNextFree = mBuffer; + } + else if(mReclaimedBytes > mSize) + { + LL_WARNS() << "LLHeapBuffer reclaimed more memory than allocated." + << " This is probably programmer error." << LL_ENDL; + } + return true; + } + return false; } // virtual bool LLHeapBuffer::containsSegment(const LLSegment& segment) const { - // *NOTE: this check is fairly simple because heap buffers are - // simple contiguous chunks of heap memory. - if((mBuffer > segment.data()) - || ((mBuffer + mSize) < (segment.data() + segment.size()))) - { - return false; - } - return true; + // *NOTE: this check is fairly simple because heap buffers are + // simple contiguous chunks of heap memory. + if((mBuffer > segment.data()) + || ((mBuffer + mSize) < (segment.data() + segment.size()))) + { + return false; + } + return true; } void LLHeapBuffer::allocate(S32 size) { - mReclaimedBytes = 0; - mBuffer = new U8[size]; - if(mBuffer) - { - mSize = size; - mNextFree = mBuffer; - } + mReclaimedBytes = 0; + mBuffer = new U8[size]; + if(mBuffer) + { + mSize = size; + mNextFree = mBuffer; + } } -/** +/** * LLBufferArray */ LLBufferArray::LLBufferArray() : - mNextBaseChannel(0), - mMutexp(NULL) + mNextBaseChannel(0), + mMutexp(NULL) { } LLBufferArray::~LLBufferArray() { - std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer()); - mBuffers.clear(); - delete mMutexp; + std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer()); + mBuffers.clear(); + delete mMutexp; } // static LLChannelDescriptors LLBufferArray::makeChannelConsumer( - const LLChannelDescriptors& channels) + const LLChannelDescriptors& channels) { - LLChannelDescriptors rv(channels.out()); - return rv; + LLChannelDescriptors rv(channels.out()); + return rv; } void LLBufferArray::lock() { - if(mMutexp) - { - mMutexp->lock() ; - } + if(mMutexp) + { + mMutexp->lock() ; + } } void LLBufferArray::unlock() { - if(mMutexp) - { - mMutexp->unlock() ; - } + if(mMutexp) + { + mMutexp->unlock() ; + } } LLMutex* LLBufferArray::getMutex() { - return mMutexp ; + return mMutexp ; } void LLBufferArray::setThreaded(bool threaded) { - if(threaded) - { - if(!mMutexp) - { - mMutexp = new LLMutex(); - } - } - else - { - if(mMutexp) - { - delete mMutexp ; - mMutexp = NULL ; - } - } + if(threaded) + { + if(!mMutexp) + { + mMutexp = new LLMutex(); + } + } + else + { + if(mMutexp) + { + delete mMutexp ; + mMutexp = NULL ; + } + } } LLChannelDescriptors LLBufferArray::nextChannel() { - LLChannelDescriptors rv(mNextBaseChannel++); - return rv; + LLChannelDescriptors rv(mNextBaseChannel++); + return rv; } //mMutexp should be locked before calling this. S32 LLBufferArray::capacity() const { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - S32 total = 0; - const_buffer_iterator_t iter = mBuffers.begin(); - const_buffer_iterator_t end = mBuffers.end(); - for(; iter != end; ++iter) - { - total += (*iter)->capacity(); - } - return total; + S32 total = 0; + const_buffer_iterator_t iter = mBuffers.begin(); + const_buffer_iterator_t end = mBuffers.end(); + for(; iter != end; ++iter) + { + total += (*iter)->capacity(); + } + return total; } bool LLBufferArray::append(S32 channel, const U8* src, S32 len) { - LLMutexLock lock(mMutexp) ; + LLMutexLock lock(mMutexp) ; - std::vector<LLSegment> segments; - if(copyIntoBuffers(channel, src, len, segments)) - { - mSegments.insert(mSegments.end(), segments.begin(), segments.end()); - return true; - } - return false; + std::vector<LLSegment> segments; + if(copyIntoBuffers(channel, src, len, segments)) + { + mSegments.insert(mSegments.end(), segments.begin(), segments.end()); + return true; + } + return false; } //mMutexp should be locked before calling this. bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len) { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - std::vector<LLSegment> segments; - if(copyIntoBuffers(channel, src, len, segments)) - { - mSegments.insert(mSegments.begin(), segments.begin(), segments.end()); - return true; - } - return false; + std::vector<LLSegment> segments; + if(copyIntoBuffers(channel, src, len, segments)) + { + mSegments.insert(mSegments.begin(), segments.begin(), segments.end()); + return true; + } + return false; } bool LLBufferArray::insertAfter( - segment_iterator_t segment, - S32 channel, - const U8* src, - S32 len) -{ - std::vector<LLSegment> segments; - - LLMutexLock lock(mMutexp) ; - if(mSegments.end() != segment) - { - ++segment; - } - if(copyIntoBuffers(channel, src, len, segments)) - { - mSegments.insert(segment, segments.begin(), segments.end()); - return true; - } - return false; + segment_iterator_t segment, + S32 channel, + const U8* src, + S32 len) +{ + std::vector<LLSegment> segments; + + LLMutexLock lock(mMutexp) ; + if(mSegments.end() != segment) + { + ++segment; + } + if(copyIntoBuffers(channel, src, len, segments)) + { + mSegments.insert(segment, segments.begin(), segments.end()); + return true; + } + return false; } //mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address) { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - - segment_iterator_t end = mSegments.end(); - segment_iterator_t it = getSegment(address); - if(it == end) - { - return end; - } - - // We have the location and the segment. - U8* base = (*it).data(); - S32 size = (*it).size(); - if(address == (base + size)) - { - // No need to split, since this is the last byte of the - // segment. We do not want to have zero length segments, since - // that will only incur processing overhead with no advantage. - return it; - } - S32 channel = (*it).getChannel(); - LLSegment segment1(channel, base, (address - base) + 1); - *it = segment1; - segment_iterator_t rv = it; - ++it; - LLSegment segment2(channel, address + 1, size - (address - base) - 1); - mSegments.insert(it, segment2); - return rv; -} - + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + + segment_iterator_t end = mSegments.end(); + segment_iterator_t it = getSegment(address); + if(it == end) + { + return end; + } + + // We have the location and the segment. + U8* base = (*it).data(); + S32 size = (*it).size(); + if(address == (base + size)) + { + // No need to split, since this is the last byte of the + // segment. We do not want to have zero length segments, since + // that will only incur processing overhead with no advantage. + return it; + } + S32 channel = (*it).getChannel(); + LLSegment segment1(channel, base, (address - base) + 1); + *it = segment1; + segment_iterator_t rv = it; + ++it; + LLSegment segment2(channel, address + 1, size - (address - base) - 1); + mSegments.insert(it, segment2); + return rv; +} + //mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::beginSegment() { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - return mSegments.begin(); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + return mSegments.begin(); } //mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::endSegment() { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - return mSegments.end(); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + return mSegments.end(); } //mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter( - U8* address, - LLSegment& segment) -{ - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - segment_iterator_t rv = mSegments.begin(); - segment_iterator_t end = mSegments.end(); - if(!address) - { - if(rv != end) - { - segment = (*rv); - } - } - else - { - // we have an address - find the segment it is in. - for( ; rv != end; ++rv) - { - if((address >= (*rv).data()) - && (address < ((*rv).data() + (*rv).size()))) - { - if((++address) < ((*rv).data() + (*rv).size())) - { - // it's in this segment - construct an appropriate - // sub-segment. - segment = LLSegment( - (*rv).getChannel(), - address, - (*rv).size() - (address - (*rv).data())); - } - else - { - ++rv; - if(rv != end) - { - segment = (*rv); - } - } - break; - } - } - } - if(rv == end) - { - segment = LLSegment(); - } - return rv; + U8* address, + LLSegment& segment) +{ + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + segment_iterator_t rv = mSegments.begin(); + segment_iterator_t end = mSegments.end(); + if(!address) + { + if(rv != end) + { + segment = (*rv); + } + } + else + { + // we have an address - find the segment it is in. + for( ; rv != end; ++rv) + { + if((address >= (*rv).data()) + && (address < ((*rv).data() + (*rv).size()))) + { + if((++address) < ((*rv).data() + (*rv).size())) + { + // it's in this segment - construct an appropriate + // sub-segment. + segment = LLSegment( + (*rv).getChannel(), + address, + (*rv).size() - (address - (*rv).data())); + } + else + { + ++rv; + if(rv != end) + { + segment = (*rv); + } + } + break; + } + } + } + if(rv == end) + { + segment = LLSegment(); + } + return rv; } //mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address) { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - segment_iterator_t end = mSegments.end(); - if(!address) - { - return end; - } - segment_iterator_t it = mSegments.begin(); - for( ; it != end; ++it) - { - if((address >= (*it).data())&&(address < (*it).data() + (*it).size())) - { - // found it. - return it; - } - } - return end; + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + segment_iterator_t end = mSegments.end(); + if(!address) + { + return end; + } + segment_iterator_t it = mSegments.begin(); + for( ; it != end; ++it) + { + if((address >= (*it).data())&&(address < (*it).data() + (*it).size())) + { + // found it. + return it; + } + } + return end; } //mMutexp should be locked before calling this. LLBufferArray::const_segment_iterator_t LLBufferArray::getSegment( - U8* address) const -{ - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - const_segment_iterator_t end = mSegments.end(); - if(!address) - { - return end; - } - const_segment_iterator_t it = mSegments.begin(); - for( ; it != end; ++it) - { - if((address >= (*it).data()) - && (address < (*it).data() + (*it).size())) - { - // found it. - return it; - } - } - return end; + U8* address) const +{ + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + const_segment_iterator_t end = mSegments.end(); + if(!address) + { + return end; + } + const_segment_iterator_t it = mSegments.begin(); + for( ; it != end; ++it) + { + if((address >= (*it).data()) + && (address < (*it).data() + (*it).size())) + { + // found it. + return it; + } + } + return end; } /* -U8* LLBufferArray::getAddressAfter(U8* address) -{ - U8* rv = NULL; - segment_iterator_t it = getSegment(address); - segment_iterator_t end = mSegments.end(); - if(it != end) - { - if(++address < ((*it).data() + (*it).size())) - { - // it's in the same segment - rv = address; - } - else - { - // it's in the next segment - if(++it != end) - { - rv = (*it).data(); - } - } - } - return rv; +U8* LLBufferArray::getAddressAfter(U8* address) +{ + U8* rv = NULL; + segment_iterator_t it = getSegment(address); + segment_iterator_t end = mSegments.end(); + if(it != end) + { + if(++address < ((*it).data() + (*it).size())) + { + // it's in the same segment + rv = address; + } + else + { + // it's in the next segment + if(++it != end) + { + rv = (*it).data(); + } + } + } + return rv; } */ S32 LLBufferArray::countAfter(S32 channel, U8* start) const { - S32 count = 0; - S32 offset = 0; - const_segment_iterator_t it; - - LLMutexLock lock(mMutexp) ; - const_segment_iterator_t end = mSegments.end(); - if(start) - { - it = getSegment(start); - if(it == end) - { - return count; - } - if(++start < ((*it).data() + (*it).size())) - { - // it's in the same segment - offset = start - (*it).data(); - } - else if(++it == end) - { - // it's in the next segment - return count; - } - } - else - { - it = mSegments.begin(); - } - while(it != end) - { - if((*it).isOnChannel(channel)) - { - count += (*it).size() - offset; - } - offset = 0; - ++it; - } - return count; + S32 count = 0; + S32 offset = 0; + const_segment_iterator_t it; + + LLMutexLock lock(mMutexp) ; + const_segment_iterator_t end = mSegments.end(); + if(start) + { + it = getSegment(start); + if(it == end) + { + return count; + } + if(++start < ((*it).data() + (*it).size())) + { + // it's in the same segment + offset = start - (*it).data(); + } + else if(++it == end) + { + // it's in the next segment + return count; + } + } + else + { + it = mSegments.begin(); + } + while(it != end) + { + if((*it).isOnChannel(channel)) + { + count += (*it).size() - offset; + } + offset = 0; + ++it; + } + return count; } U8* LLBufferArray::readAfter( - S32 channel, - U8* start, - U8* dest, - S32& len) const -{ - U8* rv = start; - if(!dest || len <= 0) - { - return rv; - } - S32 bytes_left = len; - len = 0; - S32 bytes_to_copy = 0; - const_segment_iterator_t it; - - LLMutexLock lock(mMutexp) ; - const_segment_iterator_t end = mSegments.end(); - if(start) - { - it = getSegment(start); - if(it == end) - { - return rv; - } - if((++start < ((*it).data() + (*it).size())) - && (*it).isOnChannel(channel)) - { - // copy the data out of this segment - S32 bytes_in_segment = (*it).size() - (start - (*it).data()); - bytes_to_copy = llmin(bytes_left, bytes_in_segment); - memcpy(dest, start, bytes_to_copy); /*Flawfinder: ignore*/ - len += bytes_to_copy; - bytes_left -= bytes_to_copy; - rv = start + bytes_to_copy - 1; - ++it; - } - else - { - ++it; - } - } - else - { - it = mSegments.begin(); - } - while(bytes_left && (it != end)) - { - if(!((*it).isOnChannel(channel))) - { - ++it; - continue; - } - bytes_to_copy = llmin(bytes_left, (*it).size()); - memcpy(dest + len, (*it).data(), bytes_to_copy); /*Flawfinder: ignore*/ - len += bytes_to_copy; - bytes_left -= bytes_to_copy; - rv = (*it).data() + bytes_to_copy - 1; - ++it; - } - return rv; + S32 channel, + U8* start, + U8* dest, + S32& len) const +{ + U8* rv = start; + if(!dest || len <= 0) + { + return rv; + } + S32 bytes_left = len; + len = 0; + S32 bytes_to_copy = 0; + const_segment_iterator_t it; + + LLMutexLock lock(mMutexp) ; + const_segment_iterator_t end = mSegments.end(); + if(start) + { + it = getSegment(start); + if(it == end) + { + return rv; + } + if((++start < ((*it).data() + (*it).size())) + && (*it).isOnChannel(channel)) + { + // copy the data out of this segment + S32 bytes_in_segment = (*it).size() - (start - (*it).data()); + bytes_to_copy = llmin(bytes_left, bytes_in_segment); + memcpy(dest, start, bytes_to_copy); /*Flawfinder: ignore*/ + len += bytes_to_copy; + bytes_left -= bytes_to_copy; + rv = start + bytes_to_copy - 1; + ++it; + } + else + { + ++it; + } + } + else + { + it = mSegments.begin(); + } + while(bytes_left && (it != end)) + { + if(!((*it).isOnChannel(channel))) + { + ++it; + continue; + } + bytes_to_copy = llmin(bytes_left, (*it).size()); + memcpy(dest + len, (*it).data(), bytes_to_copy); /*Flawfinder: ignore*/ + len += bytes_to_copy; + bytes_left -= bytes_to_copy; + rv = (*it).data() + bytes_to_copy - 1; + ++it; + } + return rv; } U8* LLBufferArray::seek( - S32 channel, - U8* start, - S32 delta) const -{ - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - const_segment_iterator_t it; - const_segment_iterator_t end = mSegments.end(); - U8* rv = start; - if(0 == delta) - { - if((U8*)npos == start) - { - // someone is looking for end of data. - segment_list_t::const_reverse_iterator rit = mSegments.rbegin(); - segment_list_t::const_reverse_iterator rend = mSegments.rend(); - while(rit != rend) - { - if(!((*rit).isOnChannel(channel))) - { - ++rit; - continue; - } - rv = (*rit).data() + (*rit).size(); - break; - } - } - else if(start) - { - // This is sort of a weird case - check if zero bytes away - // from current position is on channel and return start if - // that is true. Otherwise, return NULL. - it = getSegment(start); - if((it == end) || !(*it).isOnChannel(channel)) - { - rv = NULL; - } - } - else - { - // Start is NULL, so return the very first byte on the - // channel, or NULL. - it = mSegments.begin(); - while((it != end) && !(*it).isOnChannel(channel)) - { - ++it; - } - if(it != end) - { - rv = (*it).data(); - } - } - return rv; - } - if(start) - { - it = getSegment(start); - if((it != end) && (*it).isOnChannel(channel)) - { - if(delta > 0) - { - S32 bytes_in_segment = (*it).size() - (start - (*it).data()); - S32 local_delta = llmin(delta, bytes_in_segment); - rv += local_delta; - delta -= local_delta; - ++it; - } - else - { - S32 bytes_in_segment = start - (*it).data(); - S32 local_delta = llmin(llabs(delta), bytes_in_segment); - rv -= local_delta; - delta += local_delta; - } - } - } - else if(delta < 0) - { - // start is NULL, and delta indicates seeking backwards - - // return NULL. - return NULL; - } - else - { - // start is NULL and delta > 0 - it = mSegments.begin(); - } - if(delta > 0) - { - // At this point, we have an iterator into the segments, and - // are seeking forward until delta is zero or we run out - while(delta && (it != end)) - { - if(!((*it).isOnChannel(channel))) - { - ++it; - continue; - } - if(delta <= (*it).size()) - { - // it's in this segment - rv = (*it).data() + delta; - } - delta -= (*it).size(); - ++it; - } - if(delta && (it == end)) - { - // Whoops - sought past end. - rv = NULL; - } - } - else //if(delta < 0) - { - // We are at the beginning of a segment, and need to search - // backwards. - segment_list_t::const_reverse_iterator rit(it); - segment_list_t::const_reverse_iterator rend = mSegments.rend(); - while(delta && (rit != rend)) - { - if(!((*rit).isOnChannel(channel))) - { - ++rit; - continue; - } - if(llabs(delta) <= (*rit).size()) - { - // it's in this segment. - rv = (*rit).data() + (*rit).size() + delta; - delta = 0; - } - else - { - delta += (*rit).size(); - } - ++rit; - } - if(delta && (rit == rend)) - { - // sought past the beginning. - rv = NULL; - } - } - return rv; + S32 channel, + U8* start, + S32 delta) const +{ + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + const_segment_iterator_t it; + const_segment_iterator_t end = mSegments.end(); + U8* rv = start; + if(0 == delta) + { + if((U8*)npos == start) + { + // someone is looking for end of data. + segment_list_t::const_reverse_iterator rit = mSegments.rbegin(); + segment_list_t::const_reverse_iterator rend = mSegments.rend(); + while(rit != rend) + { + if(!((*rit).isOnChannel(channel))) + { + ++rit; + continue; + } + rv = (*rit).data() + (*rit).size(); + break; + } + } + else if(start) + { + // This is sort of a weird case - check if zero bytes away + // from current position is on channel and return start if + // that is true. Otherwise, return NULL. + it = getSegment(start); + if((it == end) || !(*it).isOnChannel(channel)) + { + rv = NULL; + } + } + else + { + // Start is NULL, so return the very first byte on the + // channel, or NULL. + it = mSegments.begin(); + while((it != end) && !(*it).isOnChannel(channel)) + { + ++it; + } + if(it != end) + { + rv = (*it).data(); + } + } + return rv; + } + if(start) + { + it = getSegment(start); + if((it != end) && (*it).isOnChannel(channel)) + { + if(delta > 0) + { + S32 bytes_in_segment = (*it).size() - (start - (*it).data()); + S32 local_delta = llmin(delta, bytes_in_segment); + rv += local_delta; + delta -= local_delta; + ++it; + } + else + { + S32 bytes_in_segment = start - (*it).data(); + S32 local_delta = llmin(llabs(delta), bytes_in_segment); + rv -= local_delta; + delta += local_delta; + } + } + } + else if(delta < 0) + { + // start is NULL, and delta indicates seeking backwards - + // return NULL. + return NULL; + } + else + { + // start is NULL and delta > 0 + it = mSegments.begin(); + } + if(delta > 0) + { + // At this point, we have an iterator into the segments, and + // are seeking forward until delta is zero or we run out + while(delta && (it != end)) + { + if(!((*it).isOnChannel(channel))) + { + ++it; + continue; + } + if(delta <= (*it).size()) + { + // it's in this segment + rv = (*it).data() + delta; + } + delta -= (*it).size(); + ++it; + } + if(delta && (it == end)) + { + // Whoops - sought past end. + rv = NULL; + } + } + else //if(delta < 0) + { + // We are at the beginning of a segment, and need to search + // backwards. + segment_list_t::const_reverse_iterator rit(it); + segment_list_t::const_reverse_iterator rend = mSegments.rend(); + while(delta && (rit != rend)) + { + if(!((*rit).isOnChannel(channel))) + { + ++rit; + continue; + } + if(llabs(delta) <= (*rit).size()) + { + // it's in this segment. + rv = (*rit).data() + (*rit).size() + delta; + delta = 0; + } + else + { + delta += (*rit).size(); + } + ++rit; + } + if(delta && (rit == rend)) + { + // sought past the beginning. + rv = NULL; + } + } + return rv; } //test use only bool LLBufferArray::takeContents(LLBufferArray& source) { - LLMutexLock lock(mMutexp); - source.lock(); + LLMutexLock lock(mMutexp); + source.lock(); - std::copy( - source.mBuffers.begin(), - source.mBuffers.end(), - std::back_insert_iterator<buffer_list_t>(mBuffers)); - source.mBuffers.clear(); - std::copy( - source.mSegments.begin(), - source.mSegments.end(), - std::back_insert_iterator<segment_list_t>(mSegments)); - source.mSegments.clear(); - source.mNextBaseChannel = 0; - source.unlock(); + std::copy( + source.mBuffers.begin(), + source.mBuffers.end(), + std::back_insert_iterator<buffer_list_t>(mBuffers)); + source.mBuffers.clear(); + std::copy( + source.mSegments.begin(), + source.mSegments.end(), + std::back_insert_iterator<segment_list_t>(mSegments)); + source.mSegments.clear(); + source.mNextBaseChannel = 0; + source.unlock(); - return true; + return true; } //mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::makeSegment( - S32 channel, - S32 len) -{ - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - // start at the end of the buffers, because it is the most likely - // to have free space. - LLSegment segment; - buffer_list_t::reverse_iterator it = mBuffers.rbegin(); - buffer_list_t::reverse_iterator end = mBuffers.rend(); - bool made_segment = false; - for(; it != end; ++it) - { - if((*it)->createSegment(channel, len, segment)) - { - made_segment = true; - break; - } - } - segment_iterator_t send = mSegments.end(); - if(!made_segment) - { - LLBuffer* buf = new LLHeapBuffer; - mBuffers.push_back(buf); - if(!buf->createSegment(channel, len, segment)) - { - // failed. this should never happen. - return send; - } - } - - // store and return the newly made segment - mSegments.insert(send, segment); - std::list<LLSegment>::reverse_iterator rv = mSegments.rbegin(); - ++rv; - send = rv.base(); - return send; + S32 channel, + S32 len) +{ + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + // start at the end of the buffers, because it is the most likely + // to have free space. + LLSegment segment; + buffer_list_t::reverse_iterator it = mBuffers.rbegin(); + buffer_list_t::reverse_iterator end = mBuffers.rend(); + bool made_segment = false; + for(; it != end; ++it) + { + if((*it)->createSegment(channel, len, segment)) + { + made_segment = true; + break; + } + } + segment_iterator_t send = mSegments.end(); + if(!made_segment) + { + LLBuffer* buf = new LLHeapBuffer; + mBuffers.push_back(buf); + if(!buf->createSegment(channel, len, segment)) + { + // failed. this should never happen. + return send; + } + } + + // store and return the newly made segment + mSegments.insert(send, segment); + std::list<LLSegment>::reverse_iterator rv = mSegments.rbegin(); + ++rv; + send = rv.base(); + return send; } //mMutexp should be locked before calling this. bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter) { - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - - // Find out which buffer contains the segment, and if it is found, - // ask it to reclaim the memory. - bool rv = false; - LLSegment segment(*erase_iter); - buffer_iterator_t iter = mBuffers.begin(); - buffer_iterator_t end = mBuffers.end(); - for(; iter != end; ++iter) - { - // We can safely call reclaimSegment on every buffer, and once - // it returns true, the segment was found. - if((*iter)->reclaimSegment(segment)) - { - rv = true; - break; - } - } - - // No need to get the return value since we are not interested in - // the interator retured by the call. - (void)mSegments.erase(erase_iter); - return rv; + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + + // Find out which buffer contains the segment, and if it is found, + // ask it to reclaim the memory. + bool rv = false; + LLSegment segment(*erase_iter); + buffer_iterator_t iter = mBuffers.begin(); + buffer_iterator_t end = mBuffers.end(); + for(; iter != end; ++iter) + { + // We can safely call reclaimSegment on every buffer, and once + // it returns true, the segment was found. + if((*iter)->reclaimSegment(segment)) + { + rv = true; + break; + } + } + + // No need to get the return value since we are not interested in + // the interator retured by the call. + (void)mSegments.erase(erase_iter); + return rv; } //mMutexp should be locked before calling this. bool LLBufferArray::copyIntoBuffers( - S32 channel, - const U8* src, - S32 len, - std::vector<LLSegment>& segments) -{ - ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); - if(!src || !len) return false; - S32 copied = 0; - LLSegment segment; - buffer_iterator_t it = mBuffers.begin(); - buffer_iterator_t end = mBuffers.end(); - for(; it != end;) - { - if(!(*it)->createSegment(channel, len, segment)) - { - ++it; - continue; - } - segments.push_back(segment); - S32 bytes = llmin(segment.size(), len); - memcpy(segment.data(), src + copied, bytes); /* Flawfinder: Ignore */ - copied += bytes; - len -= bytes; - if(0 == len) - { - break; - } - } - while(len) - { - LLBuffer* buf = new LLHeapBuffer; - mBuffers.push_back(buf); - if(!buf->createSegment(channel, len, segment)) - { - // this totally failed - bail. This is the weird corner - // case were we 'leak' memory. No worries about an actual - // leak - we will still reclaim the memory later, but this - // particular buffer array is hosed for some reason. - // This should never happen. - return false; - } - segments.push_back(segment); - memcpy(segment.data(), src + copied, segment.size()); /*Flawfinder: ignore*/ - copied += segment.size(); - len -= segment.size(); - } - return true; + S32 channel, + const U8* src, + S32 len, + std::vector<LLSegment>& segments) +{ + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + if(!src || !len) return false; + S32 copied = 0; + LLSegment segment; + buffer_iterator_t it = mBuffers.begin(); + buffer_iterator_t end = mBuffers.end(); + for(; it != end;) + { + if(!(*it)->createSegment(channel, len, segment)) + { + ++it; + continue; + } + segments.push_back(segment); + S32 bytes = llmin(segment.size(), len); + memcpy(segment.data(), src + copied, bytes); /* Flawfinder: Ignore */ + copied += bytes; + len -= bytes; + if(0 == len) + { + break; + } + } + while(len) + { + LLBuffer* buf = new LLHeapBuffer; + mBuffers.push_back(buf); + if(!buf->createSegment(channel, len, segment)) + { + // this totally failed - bail. This is the weird corner + // case were we 'leak' memory. No worries about an actual + // leak - we will still reclaim the memory later, but this + // particular buffer array is hosed for some reason. + // This should never happen. + return false; + } + segments.push_back(segment); + memcpy(segment.data(), src + copied, segment.size()); /*Flawfinder: ignore*/ + copied += segment.size(); + len -= segment.size(); + } + return true; } diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h index ccdb9fa7ee..89229ea9d1 100644 --- a/indra/llmessage/llbuffer.h +++ b/indra/llmessage/llbuffer.h @@ -1,4 +1,4 @@ -/** +/** * @file llbuffer.h * @author Phoenix * @date 2005-09-20 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,26 +40,26 @@ #include <vector> class LLMutex; -/** +/** * @class LLChannelDescriptors * @brief A way simple interface to accesss channels inside a buffer */ class LLChannelDescriptors { public: - // enumeration for segmenting the channel information - enum { E_CHANNEL_COUNT = 3 }; - LLChannelDescriptors() : mBaseChannel(0) {} - explicit LLChannelDescriptors(S32 base) : mBaseChannel(base) {} - S32 in() const { return mBaseChannel; } - S32 out() const { return mBaseChannel + 1; } - //S32 err() const { return mBaseChannel + 2; } + // enumeration for segmenting the channel information + enum { E_CHANNEL_COUNT = 3 }; + LLChannelDescriptors() : mBaseChannel(0) {} + explicit LLChannelDescriptors(S32 base) : mBaseChannel(base) {} + S32 in() const { return mBaseChannel; } + S32 out() const { return mBaseChannel + 1; } + //S32 err() const { return mBaseChannel + 2; } protected: - S32 mBaseChannel; + S32 mBaseChannel; }; -/** +/** * @class LLSegment * @brief A segment is a single, contiguous chunk of memory in a buffer * @@ -70,62 +70,62 @@ protected: * as necessary. * This is the preferred interface for working with memory blocks, * since it is the only way to safely, inexpensively, and directly - * access linear blocks of memory. + * access linear blocks of memory. */ class LLSegment { public: - LLSegment(); - LLSegment(S32 channel, U8* data, S32 data_len); - ~LLSegment(); - - /** - * @brief Check if this segment is on the given channel. - * - */ - bool isOnChannel(S32 channel) const; - - /** - * @brief Get the channel - */ - S32 getChannel() const; - - /** - * @brief Set the channel - */ - void setChannel(S32 channel); - - /** - * @brief Return a raw pointer to the current data set. - * - * The pointer returned can be used for reading or even adjustment - * if you are a bit crazy up to size() bytes into memory. - * @return A potentially NULL pointer to the raw buffer data - */ - U8* data() const; - - /** - * @brief Return the size of the segment - */ - S32 size() const; - - /** - * @brief Check if two segments are the same. - * - * Two segments are considered equal if they are on the same - * channel and cover the exact same address range. - * @param rhs the segment to compare with this segment. - * @return Returns true if they are equal. - */ - bool operator==(const LLSegment& rhs) const; + LLSegment(); + LLSegment(S32 channel, U8* data, S32 data_len); + ~LLSegment(); + + /** + * @brief Check if this segment is on the given channel. + * + */ + bool isOnChannel(S32 channel) const; + + /** + * @brief Get the channel + */ + S32 getChannel() const; + + /** + * @brief Set the channel + */ + void setChannel(S32 channel); + + /** + * @brief Return a raw pointer to the current data set. + * + * The pointer returned can be used for reading or even adjustment + * if you are a bit crazy up to size() bytes into memory. + * @return A potentially NULL pointer to the raw buffer data + */ + U8* data() const; + + /** + * @brief Return the size of the segment + */ + S32 size() const; + + /** + * @brief Check if two segments are the same. + * + * Two segments are considered equal if they are on the same + * channel and cover the exact same address range. + * @param rhs the segment to compare with this segment. + * @return Returns true if they are equal. + */ + bool operator==(const LLSegment& rhs) const; protected: - S32 mChannel; - U8* mData; - S32 mSize; + S32 mChannel; + U8* mData; + S32 mSize; }; -/** +/** * @class LLBuffer * @brief Abstract base class for buffers * @@ -136,58 +136,58 @@ protected: class LLBuffer { public: - /** - * @brief The buffer base class should have no responsibilities - * other than an interface. - */ - virtual ~LLBuffer() {} - - /** - * @brief Generate a segment for this buffer. - * - * The segment returned is always contiguous memory. This call can - * fail if no contiguous memory is available, eg, offset is past - * the end. The segment returned may be smaller than the requested - * size. The segment will never be larger than the requested size. - * @param channel The channel for the segment. - * @param offset The offset from zero in the buffer. - * @param size The requested size of the segment. - * @param segment[out] The out-value from the operation - * @return Returns true if a segment was found. - */ - virtual bool createSegment(S32 channel, S32 size, LLSegment& segment) = 0; - - /** - * @brief Reclaim a segment from this buffer. - * - * This method is called on a buffer object when a caller is done - * with a contiguous segment of memory inside this buffer. Since - * segments can be cut arbitrarily outside of the control of the - * buffer, this segment may not match any segment returned from - * <code>createSegment()</code>. - * @param segment The contiguous buffer segment to reclaim. - * @return Returns true if the call was successful. - */ - virtual bool reclaimSegment(const LLSegment& segment) = 0; - - /** - * @brief Test if a segment is inside this buffer. - * - * @param segment The contiguous buffer segment to test. - * @return Returns true if the segment is in the bufffer. - */ - virtual bool containsSegment(const LLSegment& segment) const = 0; - - /** - * @brief Return the current number of bytes allocated. - * - * This was implemented as a debugging tool, and it is not - * necessarily a good idea to use it for anything else. - */ - virtual S32 capacity() const = 0; + /** + * @brief The buffer base class should have no responsibilities + * other than an interface. + */ + virtual ~LLBuffer() {} + + /** + * @brief Generate a segment for this buffer. + * + * The segment returned is always contiguous memory. This call can + * fail if no contiguous memory is available, eg, offset is past + * the end. The segment returned may be smaller than the requested + * size. The segment will never be larger than the requested size. + * @param channel The channel for the segment. + * @param offset The offset from zero in the buffer. + * @param size The requested size of the segment. + * @param segment[out] The out-value from the operation + * @return Returns true if a segment was found. + */ + virtual bool createSegment(S32 channel, S32 size, LLSegment& segment) = 0; + + /** + * @brief Reclaim a segment from this buffer. + * + * This method is called on a buffer object when a caller is done + * with a contiguous segment of memory inside this buffer. Since + * segments can be cut arbitrarily outside of the control of the + * buffer, this segment may not match any segment returned from + * <code>createSegment()</code>. + * @param segment The contiguous buffer segment to reclaim. + * @return Returns true if the call was successful. + */ + virtual bool reclaimSegment(const LLSegment& segment) = 0; + + /** + * @brief Test if a segment is inside this buffer. + * + * @param segment The contiguous buffer segment to test. + * @return Returns true if the segment is in the bufffer. + */ + virtual bool containsSegment(const LLSegment& segment) const = 0; + + /** + * @brief Return the current number of bytes allocated. + * + * This was implemented as a debugging tool, and it is not + * necessarily a good idea to use it for anything else. + */ + virtual S32 capacity() const = 0; }; -/** +/** * @class LLHeapBuffer * @brief A large contiguous buffer allocated on the heap with new[]. * @@ -198,99 +198,99 @@ public: class LLHeapBuffer : public LLBuffer { public: - /** - * @brief Construct a heap buffer with a reasonable default size. - */ - LLHeapBuffer(); - - /** - * @brief Construct a heap buffer with a specified size. - * - * @param size The minimum size of the buffer. - */ - explicit LLHeapBuffer(S32 size); - - /** - * @brief Construct a heap buffer of minimum size len, and copy from src. - * - * @param src The source of the data to be copied. - * @param len The minimum size of the buffer. - */ - LLHeapBuffer(const U8* src, S32 len); - - /** - * @brief Simple destruction. - */ - virtual ~LLHeapBuffer(); - - /** - * @brief Get the number of bytes left in the buffer. - * - * Note that this is not a virtual function, and only available in - * the LLHeapBuffer as a debugging aid. - * @return Returns the number of bytes left. - */ - S32 bytesLeft() const; - - /** - * @brief Generate a segment for this buffer. - * - * The segment returned is always contiguous memory. This call can - * fail if no contiguous memory is available, eg, offset is past - * the end. The segment returned may be smaller than the requested - * size. It is up to the caller to delete the segment returned. - * @param channel The channel for the segment. - * @param offset The offset from zero in the buffer - * @param size The requested size of the segment - * @param segment[out] The out-value from the operation - * @return Returns true if a segment was found. - */ - virtual bool createSegment(S32 channel, S32 size, LLSegment& segment); - - /** - * @brief reclaim a segment from this buffer. - * - * This method is called on a buffer object when a caller is done - * with a contiguous segment of memory inside this buffer. Since - * segments can be cut arbitrarily outside of the control of the - * buffer, this segment may not match any segment returned from - * <code>createSegment()</code>. - * This call will fail if the segment passed in is note completely - * inside the buffer, eg, if the segment starts before this buffer - * in memory or ends after it. - * @param segment The contiguous buffer segment to reclaim. - * @return Returns true if the call was successful. - */ - virtual bool reclaimSegment(const LLSegment& segment); - - /** - * @brief Test if a segment is inside this buffer. - * - * @param segment The contiguous buffer segment to test. - * @return Returns true if the segment is in the bufffer. - */ - virtual bool containsSegment(const LLSegment& segment) const; - - /** - * @brief Return the current number of bytes allocated. - */ - virtual S32 capacity() const { return mSize; } + /** + * @brief Construct a heap buffer with a reasonable default size. + */ + LLHeapBuffer(); + + /** + * @brief Construct a heap buffer with a specified size. + * + * @param size The minimum size of the buffer. + */ + explicit LLHeapBuffer(S32 size); + + /** + * @brief Construct a heap buffer of minimum size len, and copy from src. + * + * @param src The source of the data to be copied. + * @param len The minimum size of the buffer. + */ + LLHeapBuffer(const U8* src, S32 len); + + /** + * @brief Simple destruction. + */ + virtual ~LLHeapBuffer(); + + /** + * @brief Get the number of bytes left in the buffer. + * + * Note that this is not a virtual function, and only available in + * the LLHeapBuffer as a debugging aid. + * @return Returns the number of bytes left. + */ + S32 bytesLeft() const; + + /** + * @brief Generate a segment for this buffer. + * + * The segment returned is always contiguous memory. This call can + * fail if no contiguous memory is available, eg, offset is past + * the end. The segment returned may be smaller than the requested + * size. It is up to the caller to delete the segment returned. + * @param channel The channel for the segment. + * @param offset The offset from zero in the buffer + * @param size The requested size of the segment + * @param segment[out] The out-value from the operation + * @return Returns true if a segment was found. + */ + virtual bool createSegment(S32 channel, S32 size, LLSegment& segment); + + /** + * @brief reclaim a segment from this buffer. + * + * This method is called on a buffer object when a caller is done + * with a contiguous segment of memory inside this buffer. Since + * segments can be cut arbitrarily outside of the control of the + * buffer, this segment may not match any segment returned from + * <code>createSegment()</code>. + * This call will fail if the segment passed in is note completely + * inside the buffer, eg, if the segment starts before this buffer + * in memory or ends after it. + * @param segment The contiguous buffer segment to reclaim. + * @return Returns true if the call was successful. + */ + virtual bool reclaimSegment(const LLSegment& segment); + + /** + * @brief Test if a segment is inside this buffer. + * + * @param segment The contiguous buffer segment to test. + * @return Returns true if the segment is in the bufffer. + */ + virtual bool containsSegment(const LLSegment& segment) const; + + /** + * @brief Return the current number of bytes allocated. + */ + virtual S32 capacity() const { return mSize; } protected: - U8* mBuffer; - S32 mSize; - U8* mNextFree; - S32 mReclaimedBytes; + U8* mBuffer; + S32 mSize; + U8* mNextFree; + S32 mReclaimedBytes; private: - /** - * @brief Helper method to allocate a buffer and correctly set - * intertnal state of this buffer. - */ - void allocate(S32 size); + /** + * @brief Helper method to allocate a buffer and correctly set + * intertnal state of this buffer. + */ + void allocate(S32 size); }; -/** +/** * @class LLBufferArray * @brief Class to represent scattered memory buffers and in-order segments * of that buffered data. @@ -300,326 +300,326 @@ private: class LLBufferArray { public: - typedef std::vector<LLBuffer*> buffer_list_t; - typedef buffer_list_t::iterator buffer_iterator_t; - typedef buffer_list_t::const_iterator const_buffer_iterator_t; - typedef std::list<LLSegment> segment_list_t; - typedef segment_list_t::const_iterator const_segment_iterator_t; - typedef segment_list_t::iterator segment_iterator_t; - enum { npos = 0xffffffff }; - - LLBufferArray(); - ~LLBufferArray(); - - /* @name Channel methods - */ - //@{ - /** - * @brief Generate the a channel descriptor which consumes the - * output for the channel passed in. - */ - static LLChannelDescriptors makeChannelConsumer( - const LLChannelDescriptors& channels); - - /** - * @brief Generate the next channel descriptor for this buffer array. - * - * The channel descriptor interface is how the buffer array - * clients can know where to read and write data. Use this - * interface to get the 'next' channel set for usage. This is a - * bit of a simple hack until it's utility indicates it should be - * extended. - * @return Returns a valid channel descriptor set for input and output. - */ - LLChannelDescriptors nextChannel(); - //@} - - /* @name Data methods - */ - //@{ - - /** - * @brief Return the sum of all allocated bytes. - */ - S32 capacity() const; - - // These methods will be useful once there is any kind of buffer - // besides a heap buffer. - //bool append(EBufferChannel channel, LLBuffer* data); - //bool prepend(EBufferChannel channel, LLBuffer* data); - //bool insertAfter( - // segment_iterator_t segment, - // EBufferChannel channel, - // LLBuffer* data); - - /** - * @brief Put data on a channel at the end of this buffer array. - * - * The data is copied from src into the buffer array. At least one - * new segment is created and put on the end of the array. This - * object will internally allocate new buffers if necessary. - * @param channel The channel for this data - * @param src The start of memory for the data to be copied - * @param len The number of bytes of data to copy - * @return Returns true if the method worked. - */ - bool append(S32 channel, const U8* src, S32 len); - - /** - * @brief Put data on a channel at the front of this buffer array. - * - * The data is copied from src into the buffer array. At least one - * new segment is created and put in the front of the array. This - * object will internally allocate new buffers if necessary. - * @param channel The channel for this data - * @param src The start of memory for the data to be copied - * @param len The number of bytes of data to copy - * @return Returns true if the method worked. - */ - bool prepend(S32 channel, const U8* src, S32 len); - - /** - * @brief Insert data into a buffer array after a particular segment. - * - * The data is copied from src into the buffer array. At least one - * new segment is created and put in the array. This object will - * internally allocate new buffers if necessary. - * @param segment The segment in front of the new segments location - * @param channel The channel for this data - * @param src The start of memory for the data to be copied - * @param len The number of bytes of data to copy - * @return Returns true if the method worked. - */ - bool insertAfter( - segment_iterator_t segment, - S32 channel, - const U8* src, - S32 len); - - /** - * @brief Count bytes in the buffer array on the specified channel - * - * @param channel The channel to count. - * @param start The start address in the array for counting. You - * can specify NULL to start at the beginning. - * @return Returns the number of bytes in the channel after start - */ - S32 countAfter(S32 channel, U8* start) const; - - /** - * @brief Count all bytes on channel. - * - * Helper method which just calls countAfter(). - * @param channel The channel to count. - * @return Returns the number of bytes in the channel. - */ - S32 count(S32 channel) const - { - return countAfter(channel, NULL); - } - - /** - * @brief Read bytes in the buffer array on the specified channel - * - * You should prefer iterating over segments is possible since - * this method requires you to allocate large buffers - precisely - * what this class is trying to prevent. This method will skip - * any segments which are not on the given channel, so this method - * would usually be used to read a channel and copy that to a log - * or a socket buffer or something. - * @param channel The channel to read. - * @param start The start address in the array for reading. You - * can specify NULL to start at the beginning. - * @param dest The destination of the data read. This must be at - * least len bytes long. - * @param len[in,out] <b>in</b> How many bytes to read. <b>out</b> How - * many bytes were read. - * @return Returns the address of the last read byte. - */ - U8* readAfter(S32 channel, U8* start, U8* dest, S32& len) const; - - /** - * @brief Find an address in a buffer array - * - * @param channel The channel to seek in. - * @param start The start address in the array for the seek - * operation. You can specify NULL to start the seek at the - * beginning, or pass in npos to start at the end. - * @param delta How many bytes to seek through the array. - * @return Returns the address of the last read byte. - */ - U8* seek(S32 channel, U8* start, S32 delta) const; - //@} - - /* @name Buffer interaction - */ - //@{ - /** - * @brief Take the contents of another buffer array - * - * This method simply strips the contents out of the source - * buffery array - segments, buffers, etc, and appends them to - * this instance. After this operation, the source is empty and - * ready for reuse. - * @param source The source buffer - * @return Returns true if the operation succeeded. - */ - bool takeContents(LLBufferArray& source); - //@} - - /* @name Segment methods - */ - //@{ - /** - * @brief Split a segments so that address is the last address of - * one segment, and the rest of the original segment becomes - * another segment on the same channel. - * - * After this method call, - * <code>getLastSegmentAddress(*getSegment(address)) == - * address</code> should be true. This call will only create a new - * segment if the statement above is false before the call. Since - * you usually call splitAfter() to change a segment property, use - * getSegment() to perform those operations. - * @param address The address which will become the last address - * of the segment it is in. - * @return Returns an iterator to the segment which contains - * <code>address</code> which is <code>endSegment()</code> on - * failure. - */ - segment_iterator_t splitAfter(U8* address); - - /** - * @brief Get the first segment in the buffer array. - * - * @return Returns the segment if there is one. - */ - segment_iterator_t beginSegment(); - - /** - * @brief Get the one-past-the-end segment in the buffer array - * - * @return Returns the iterator for an invalid segment location. - */ - segment_iterator_t endSegment(); - - /** - * @brief Get the segment which holds the given address. - * - * As opposed to some methods, passing a NULL will result in - * returning the end segment. - * @param address An address in the middle of the sought segment. - * @return Returns the iterator for the segment or endSegment() on - * failure. - */ - const_segment_iterator_t getSegment(U8* address) const; - - /** - * @brief Get the segment which holds the given address. - * - * As opposed to some methods, passing a NULL will result in - * returning the end segment. - * @param address An address in the middle of the sought segment. - * @return Returns the iterator for the segment or endSegment() on - * failure. - */ - segment_iterator_t getSegment(U8* address); - - /** - * @brief Get a segment iterator after address, and a constructed - * segment to represent the next linear block of memory. - * - * This method is a helper by giving you the largest segment - * possible in the out-value param after the address provided. The - * iterator will be useful for iteration, while the segment can be - * used for direct access to memory after address if the return - * values isnot end. Passing in NULL will return beginSegment() - * which may be endSegment(). The segment returned will only be - * zero length if the return value equals end. - * This is really just a helper method, since all the information - * returned could be constructed through other methods. - * @param address An address in the middle of the sought segment. - * @param segment[out] segment to be used for reading or writing - * @return Returns an iterator which contains at least segment or - * endSegment() on failure. - */ - segment_iterator_t constructSegmentAfter(U8* address, LLSegment& segment); - - /** - * @brief Make a new segment at the end of buffer array - * - * This method will attempt to create a new and empty segment of - * the specified length. The segment created may be shorter than - * requested. - * @param channel[in] The channel for the newly created segment. - * @param length[in] The requested length of the segment. - * @return Returns an iterator which contains at least segment or - * endSegment() on failure. - */ - segment_iterator_t makeSegment(S32 channel, S32 length); - - /** - * @brief Erase the segment if it is in the buffer array. - * - * @param iter An iterator referring to the segment to erase. - * @return Returns true on success. - */ - bool eraseSegment(const segment_iterator_t& iter); - - /** - * @brief Lock the mutex if it exists - * This method locks mMutexp to make accessing LLBufferArray thread-safe - */ - void lock(); - - /** - * @brief Unlock the mutex if it exists - */ - void unlock(); - - /** - * @brief Return mMutexp - */ - LLMutex* getMutex(); - - /** - * @brief Set LLBufferArray to be shared across threads or not - * This method is to create mMutexp if is threaded. - * @param threaded Indicates this LLBufferArray instance is shared across threads if true. - */ - void setThreaded(bool threaded); - //@} + typedef std::vector<LLBuffer*> buffer_list_t; + typedef buffer_list_t::iterator buffer_iterator_t; + typedef buffer_list_t::const_iterator const_buffer_iterator_t; + typedef std::list<LLSegment> segment_list_t; + typedef segment_list_t::const_iterator const_segment_iterator_t; + typedef segment_list_t::iterator segment_iterator_t; + enum { npos = 0xffffffff }; + + LLBufferArray(); + ~LLBufferArray(); + + /* @name Channel methods + */ + //@{ + /** + * @brief Generate the a channel descriptor which consumes the + * output for the channel passed in. + */ + static LLChannelDescriptors makeChannelConsumer( + const LLChannelDescriptors& channels); + + /** + * @brief Generate the next channel descriptor for this buffer array. + * + * The channel descriptor interface is how the buffer array + * clients can know where to read and write data. Use this + * interface to get the 'next' channel set for usage. This is a + * bit of a simple hack until it's utility indicates it should be + * extended. + * @return Returns a valid channel descriptor set for input and output. + */ + LLChannelDescriptors nextChannel(); + //@} + + /* @name Data methods + */ + //@{ + + /** + * @brief Return the sum of all allocated bytes. + */ + S32 capacity() const; + + // These methods will be useful once there is any kind of buffer + // besides a heap buffer. + //bool append(EBufferChannel channel, LLBuffer* data); + //bool prepend(EBufferChannel channel, LLBuffer* data); + //bool insertAfter( + // segment_iterator_t segment, + // EBufferChannel channel, + // LLBuffer* data); + + /** + * @brief Put data on a channel at the end of this buffer array. + * + * The data is copied from src into the buffer array. At least one + * new segment is created and put on the end of the array. This + * object will internally allocate new buffers if necessary. + * @param channel The channel for this data + * @param src The start of memory for the data to be copied + * @param len The number of bytes of data to copy + * @return Returns true if the method worked. + */ + bool append(S32 channel, const U8* src, S32 len); + + /** + * @brief Put data on a channel at the front of this buffer array. + * + * The data is copied from src into the buffer array. At least one + * new segment is created and put in the front of the array. This + * object will internally allocate new buffers if necessary. + * @param channel The channel for this data + * @param src The start of memory for the data to be copied + * @param len The number of bytes of data to copy + * @return Returns true if the method worked. + */ + bool prepend(S32 channel, const U8* src, S32 len); + + /** + * @brief Insert data into a buffer array after a particular segment. + * + * The data is copied from src into the buffer array. At least one + * new segment is created and put in the array. This object will + * internally allocate new buffers if necessary. + * @param segment The segment in front of the new segments location + * @param channel The channel for this data + * @param src The start of memory for the data to be copied + * @param len The number of bytes of data to copy + * @return Returns true if the method worked. + */ + bool insertAfter( + segment_iterator_t segment, + S32 channel, + const U8* src, + S32 len); + + /** + * @brief Count bytes in the buffer array on the specified channel + * + * @param channel The channel to count. + * @param start The start address in the array for counting. You + * can specify NULL to start at the beginning. + * @return Returns the number of bytes in the channel after start + */ + S32 countAfter(S32 channel, U8* start) const; + + /** + * @brief Count all bytes on channel. + * + * Helper method which just calls countAfter(). + * @param channel The channel to count. + * @return Returns the number of bytes in the channel. + */ + S32 count(S32 channel) const + { + return countAfter(channel, NULL); + } + + /** + * @brief Read bytes in the buffer array on the specified channel + * + * You should prefer iterating over segments is possible since + * this method requires you to allocate large buffers - precisely + * what this class is trying to prevent. This method will skip + * any segments which are not on the given channel, so this method + * would usually be used to read a channel and copy that to a log + * or a socket buffer or something. + * @param channel The channel to read. + * @param start The start address in the array for reading. You + * can specify NULL to start at the beginning. + * @param dest The destination of the data read. This must be at + * least len bytes long. + * @param len[in,out] <b>in</b> How many bytes to read. <b>out</b> How + * many bytes were read. + * @return Returns the address of the last read byte. + */ + U8* readAfter(S32 channel, U8* start, U8* dest, S32& len) const; + + /** + * @brief Find an address in a buffer array + * + * @param channel The channel to seek in. + * @param start The start address in the array for the seek + * operation. You can specify NULL to start the seek at the + * beginning, or pass in npos to start at the end. + * @param delta How many bytes to seek through the array. + * @return Returns the address of the last read byte. + */ + U8* seek(S32 channel, U8* start, S32 delta) const; + //@} + + /* @name Buffer interaction + */ + //@{ + /** + * @brief Take the contents of another buffer array + * + * This method simply strips the contents out of the source + * buffery array - segments, buffers, etc, and appends them to + * this instance. After this operation, the source is empty and + * ready for reuse. + * @param source The source buffer + * @return Returns true if the operation succeeded. + */ + bool takeContents(LLBufferArray& source); + //@} + + /* @name Segment methods + */ + //@{ + /** + * @brief Split a segments so that address is the last address of + * one segment, and the rest of the original segment becomes + * another segment on the same channel. + * + * After this method call, + * <code>getLastSegmentAddress(*getSegment(address)) == + * address</code> should be true. This call will only create a new + * segment if the statement above is false before the call. Since + * you usually call splitAfter() to change a segment property, use + * getSegment() to perform those operations. + * @param address The address which will become the last address + * of the segment it is in. + * @return Returns an iterator to the segment which contains + * <code>address</code> which is <code>endSegment()</code> on + * failure. + */ + segment_iterator_t splitAfter(U8* address); + + /** + * @brief Get the first segment in the buffer array. + * + * @return Returns the segment if there is one. + */ + segment_iterator_t beginSegment(); + + /** + * @brief Get the one-past-the-end segment in the buffer array + * + * @return Returns the iterator for an invalid segment location. + */ + segment_iterator_t endSegment(); + + /** + * @brief Get the segment which holds the given address. + * + * As opposed to some methods, passing a NULL will result in + * returning the end segment. + * @param address An address in the middle of the sought segment. + * @return Returns the iterator for the segment or endSegment() on + * failure. + */ + const_segment_iterator_t getSegment(U8* address) const; + + /** + * @brief Get the segment which holds the given address. + * + * As opposed to some methods, passing a NULL will result in + * returning the end segment. + * @param address An address in the middle of the sought segment. + * @return Returns the iterator for the segment or endSegment() on + * failure. + */ + segment_iterator_t getSegment(U8* address); + + /** + * @brief Get a segment iterator after address, and a constructed + * segment to represent the next linear block of memory. + * + * This method is a helper by giving you the largest segment + * possible in the out-value param after the address provided. The + * iterator will be useful for iteration, while the segment can be + * used for direct access to memory after address if the return + * values isnot end. Passing in NULL will return beginSegment() + * which may be endSegment(). The segment returned will only be + * zero length if the return value equals end. + * This is really just a helper method, since all the information + * returned could be constructed through other methods. + * @param address An address in the middle of the sought segment. + * @param segment[out] segment to be used for reading or writing + * @return Returns an iterator which contains at least segment or + * endSegment() on failure. + */ + segment_iterator_t constructSegmentAfter(U8* address, LLSegment& segment); + + /** + * @brief Make a new segment at the end of buffer array + * + * This method will attempt to create a new and empty segment of + * the specified length. The segment created may be shorter than + * requested. + * @param channel[in] The channel for the newly created segment. + * @param length[in] The requested length of the segment. + * @return Returns an iterator which contains at least segment or + * endSegment() on failure. + */ + segment_iterator_t makeSegment(S32 channel, S32 length); + + /** + * @brief Erase the segment if it is in the buffer array. + * + * @param iter An iterator referring to the segment to erase. + * @return Returns true on success. + */ + bool eraseSegment(const segment_iterator_t& iter); + + /** + * @brief Lock the mutex if it exists + * This method locks mMutexp to make accessing LLBufferArray thread-safe + */ + void lock(); + + /** + * @brief Unlock the mutex if it exists + */ + void unlock(); + + /** + * @brief Return mMutexp + */ + LLMutex* getMutex(); + + /** + * @brief Set LLBufferArray to be shared across threads or not + * This method is to create mMutexp if is threaded. + * @param threaded Indicates this LLBufferArray instance is shared across threads if true. + */ + void setThreaded(bool threaded); + //@} protected: - /** - * @brief Optimally put data in buffers, and reutrn segments. - * - * This is an internal function used to create buffers as - * necessary, and sequence the segments appropriately for the - * various ways to copy data from src into this. - * If this method fails, it may actually leak some space inside - * buffers, but I am not too worried about the slim possibility - * that we may have some 'dead' space which will be recovered when - * the buffer (which we will not lose) is deleted. Addressing this - * weakness will make the buffers almost as complex as a general - * memory management system. - * @param channel The channel for this data - * @param src The start of memory for the data to be copied - * @param len The number of bytes of data to copy - * @param segments Out-value for the segments created. - * @return Returns true if the method worked. - */ - bool copyIntoBuffers( - S32 channel, - const U8* src, - S32 len, - std::vector<LLSegment>& segments); + /** + * @brief Optimally put data in buffers, and reutrn segments. + * + * This is an internal function used to create buffers as + * necessary, and sequence the segments appropriately for the + * various ways to copy data from src into this. + * If this method fails, it may actually leak some space inside + * buffers, but I am not too worried about the slim possibility + * that we may have some 'dead' space which will be recovered when + * the buffer (which we will not lose) is deleted. Addressing this + * weakness will make the buffers almost as complex as a general + * memory management system. + * @param channel The channel for this data + * @param src The start of memory for the data to be copied + * @param len The number of bytes of data to copy + * @param segments Out-value for the segments created. + * @return Returns true if the method worked. + */ + bool copyIntoBuffers( + S32 channel, + const U8* src, + S32 len, + std::vector<LLSegment>& segments); protected: - S32 mNextBaseChannel; - buffer_list_t mBuffers; - segment_list_t mSegments; - LLMutex* mMutexp; + S32 mNextBaseChannel; + buffer_list_t mBuffers; + segment_list_t mSegments; + LLMutex* mMutexp; }; #endif // LL_LLBUFFER_H diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp index 39508c1c52..e51b489813 100644 --- a/indra/llmessage/llbufferstream.cpp +++ b/indra/llmessage/llbufferstream.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llbufferstream.cpp * @author Phoenix * @date 2005-10-10 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,291 +39,291 @@ static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4; * LLBufferStreamBuf */ LLBufferStreamBuf::LLBufferStreamBuf( - const LLChannelDescriptors& channels, - LLBufferArray* buffer) : - mChannels(channels), - mBuffer(buffer) + const LLChannelDescriptors& channels, + LLBufferArray* buffer) : + mChannels(channels), + mBuffer(buffer) { } LLBufferStreamBuf::~LLBufferStreamBuf() { - sync(); + sync(); } // virtual int LLBufferStreamBuf::underflow() { - //LL_DEBUGS() << "LLBufferStreamBuf::underflow()" << LL_ENDL; - if(!mBuffer) - { - return EOF; - } + //LL_DEBUGS() << "LLBufferStreamBuf::underflow()" << LL_ENDL; + if(!mBuffer) + { + return EOF; + } - LLMutexLock lock(mBuffer->getMutex()); - LLBufferArray::segment_iterator_t iter; - LLBufferArray::segment_iterator_t end = mBuffer->endSegment(); - U8* last_pos = (U8*)gptr(); - LLSegment segment; - if(last_pos) - { - // Back up into a piece of memory we know that we have - // allocated so that calls for the next segment based on - // 'after' will succeed. - --last_pos; - iter = mBuffer->splitAfter(last_pos); - if(iter != end) - { - // We need to clear the read segment just in case we have - // an early exit in the function and never collect the - // next segment. Calling eraseSegment() with the same - // segment twice is just like double deleting -- nothing - // good comes from it. - mBuffer->eraseSegment(iter++); - if(iter != end) segment = (*iter); - } - else - { - // This should never really happen, but somehow, the - // istream is telling the buf that it just finished - // reading memory that is not in the buf. I think this - // would only happen if there were a bug in the c++ stream - // class. Just bail. - // *TODO: can we set the fail bit on the stream somehow? - return EOF; - } - } - else - { - // Get iterator to full segment containing last_pos - // and construct sub-segment starting at last_pos. - // Note: segment may != *it at this point - iter = mBuffer->constructSegmentAfter(last_pos, segment); - } - if(iter == end) - { - return EOF; - } + LLMutexLock lock(mBuffer->getMutex()); + LLBufferArray::segment_iterator_t iter; + LLBufferArray::segment_iterator_t end = mBuffer->endSegment(); + U8* last_pos = (U8*)gptr(); + LLSegment segment; + if(last_pos) + { + // Back up into a piece of memory we know that we have + // allocated so that calls for the next segment based on + // 'after' will succeed. + --last_pos; + iter = mBuffer->splitAfter(last_pos); + if(iter != end) + { + // We need to clear the read segment just in case we have + // an early exit in the function and never collect the + // next segment. Calling eraseSegment() with the same + // segment twice is just like double deleting -- nothing + // good comes from it. + mBuffer->eraseSegment(iter++); + if(iter != end) segment = (*iter); + } + else + { + // This should never really happen, but somehow, the + // istream is telling the buf that it just finished + // reading memory that is not in the buf. I think this + // would only happen if there were a bug in the c++ stream + // class. Just bail. + // *TODO: can we set the fail bit on the stream somehow? + return EOF; + } + } + else + { + // Get iterator to full segment containing last_pos + // and construct sub-segment starting at last_pos. + // Note: segment may != *it at this point + iter = mBuffer->constructSegmentAfter(last_pos, segment); + } + if(iter == end) + { + return EOF; + } - // Iterate through segments to find a non-empty segment on input channel. - while((!segment.isOnChannel(mChannels.in()) || (segment.size() == 0))) - { - ++iter; - if(iter == end) - { - return EOF; - } + // Iterate through segments to find a non-empty segment on input channel. + while((!segment.isOnChannel(mChannels.in()) || (segment.size() == 0))) + { + ++iter; + if(iter == end) + { + return EOF; + } - segment = *(iter); - } + segment = *(iter); + } - // set up the stream to read from the next segment. - char* start = (char*)segment.data(); - setg(start, start, start + segment.size()); - return *gptr(); + // set up the stream to read from the next segment. + char* start = (char*)segment.data(); + setg(start, start, start + segment.size()); + return *gptr(); } // virtual int LLBufferStreamBuf::overflow(int c) { - if(!mBuffer) - { - return EOF; - } - if(EOF == c) - { - // if someone puts an EOF, I suppose we should sync and return - // success. - if(0 == sync()) - { - return 1; - } - else - { - return EOF; - } - } + if(!mBuffer) + { + return EOF; + } + if(EOF == c) + { + // if someone puts an EOF, I suppose we should sync and return + // success. + if(0 == sync()) + { + return 1; + } + else + { + return EOF; + } + } - // since we got here, we have a buffer, and we have a character to - // put on it. - LLBufferArray::segment_iterator_t it; - LLMutexLock lock(mBuffer->getMutex()); - it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE); - if(it != mBuffer->endSegment()) - { - char* start = (char*)(*it).data(); - (*start) = (char)(c); - setp(start + 1, start + (*it).size()); - return c; - } - else - { - return EOF; - } + // since we got here, we have a buffer, and we have a character to + // put on it. + LLBufferArray::segment_iterator_t it; + LLMutexLock lock(mBuffer->getMutex()); + it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE); + if(it != mBuffer->endSegment()) + { + char* start = (char*)(*it).data(); + (*start) = (char)(c); + setp(start + 1, start + (*it).size()); + return c; + } + else + { + return EOF; + } } // virtual int LLBufferStreamBuf::sync() { - int return_value = -1; - if(!mBuffer) - { - return return_value; - } + int return_value = -1; + if(!mBuffer) + { + return return_value; + } - // This chunk of code is not necessary because typically, users of - // the stream will read until EOF. Therefore, underflow was called - // and the segment was discarded before the sync() was called in - // the destructor. Theoretically, we could keep some more data - // around and detect the rare case where an istream was deleted - // before reading to the end, but that will only leave behind some - // unavailable but still referenced memory. Also, if another - // istream is constructed, it will re-read that segment, and then - // discard it. - //U8* last_pos = (U8*)gptr(); - //if(last_pos) - //{ - // // Looks like we read something. Discard what we have read. - // // gptr() actually returns the currrent position, but we call - // // it last_pos because of how it is used in the split call - // // below. - // --last_pos; - // LLBufferArray::segment_iterator_t iter; - // iter = mBuffer->splitAfter(last_pos); - // if(iter != mBuffer->endSegment()) - // { - // // We need to clear the read segment just in case we have - // // an early exit in the function and never collect the - // // next segment. Calling eraseSegment() with the same - // // segment twice is just like double deleting -- nothing - // // good comes from it. - // mBuffer->eraseSegment(iter); - // } - //} + // This chunk of code is not necessary because typically, users of + // the stream will read until EOF. Therefore, underflow was called + // and the segment was discarded before the sync() was called in + // the destructor. Theoretically, we could keep some more data + // around and detect the rare case where an istream was deleted + // before reading to the end, but that will only leave behind some + // unavailable but still referenced memory. Also, if another + // istream is constructed, it will re-read that segment, and then + // discard it. + //U8* last_pos = (U8*)gptr(); + //if(last_pos) + //{ + // // Looks like we read something. Discard what we have read. + // // gptr() actually returns the currrent position, but we call + // // it last_pos because of how it is used in the split call + // // below. + // --last_pos; + // LLBufferArray::segment_iterator_t iter; + // iter = mBuffer->splitAfter(last_pos); + // if(iter != mBuffer->endSegment()) + // { + // // We need to clear the read segment just in case we have + // // an early exit in the function and never collect the + // // next segment. Calling eraseSegment() with the same + // // segment twice is just like double deleting -- nothing + // // good comes from it. + // mBuffer->eraseSegment(iter); + // } + //} - // set the put pointer so that we force an overflow on the next - // write. - U8* address = (U8*)pptr(); - setp(NULL, NULL); + // set the put pointer so that we force an overflow on the next + // write. + U8* address = (U8*)pptr(); + setp(NULL, NULL); - // *NOTE: I bet we could just --address if address is not NULL. - // Need to think about that. - LLMutexLock lock(mBuffer->getMutex()); - address = mBuffer->seek(mChannels.out(), address, -1); - if(address) - { - LLBufferArray::segment_iterator_t it; - it = mBuffer->splitAfter(address); - LLBufferArray::segment_iterator_t end = mBuffer->endSegment(); - if(it != end) - { - ++it; - if(it != end) - { - mBuffer->eraseSegment(it); - } - return_value = 0; - } - } - else - { - // nothing was put on the buffer, so the sync() is a no-op. - return_value = 0; - } - return return_value; + // *NOTE: I bet we could just --address if address is not NULL. + // Need to think about that. + LLMutexLock lock(mBuffer->getMutex()); + address = mBuffer->seek(mChannels.out(), address, -1); + if(address) + { + LLBufferArray::segment_iterator_t it; + it = mBuffer->splitAfter(address); + LLBufferArray::segment_iterator_t end = mBuffer->endSegment(); + if(it != end) + { + ++it; + if(it != end) + { + mBuffer->eraseSegment(it); + } + return_value = 0; + } + } + else + { + // nothing was put on the buffer, so the sync() is a no-op. + return_value = 0; + } + return return_value; } // virtual #if( LL_WINDOWS || __GNUC__ > 2) LLBufferStreamBuf::pos_type LLBufferStreamBuf::seekoff( - LLBufferStreamBuf::off_type off, - std::ios::seekdir way, - std::ios::openmode which) + LLBufferStreamBuf::off_type off, + std::ios::seekdir way, + std::ios::openmode which) #else streampos LLBufferStreamBuf::seekoff( - streamoff off, - std::ios::seekdir way, - std::ios::openmode which) + streamoff off, + std::ios::seekdir way, + std::ios::openmode which) #endif { - if(!mBuffer - || ((way == std::ios::beg) && (off < 0)) - || ((way == std::ios::end) && (off > 0))) - { - return -1; - } - U8* address = NULL; - if(which & std::ios::in) - { - U8* base_addr = NULL; - switch(way) - { - case std::ios::end: - base_addr = (U8*)LLBufferArray::npos; - break; - case std::ios::cur: - // get the current get pointer and adjust it for buffer - // array semantics. - base_addr = (U8*)gptr(); - break; - case std::ios::beg: - default: - // NULL is fine - break; - } + if(!mBuffer + || ((way == std::ios::beg) && (off < 0)) + || ((way == std::ios::end) && (off > 0))) + { + return -1; + } + U8* address = NULL; + if(which & std::ios::in) + { + U8* base_addr = NULL; + switch(way) + { + case std::ios::end: + base_addr = (U8*)LLBufferArray::npos; + break; + case std::ios::cur: + // get the current get pointer and adjust it for buffer + // array semantics. + base_addr = (U8*)gptr(); + break; + case std::ios::beg: + default: + // NULL is fine + break; + } - LLMutexLock lock(mBuffer->getMutex()); - address = mBuffer->seek(mChannels.in(), base_addr, off); - if(address) - { - LLBufferArray::segment_iterator_t iter; - iter = mBuffer->getSegment(address); - char* start = (char*)(*iter).data(); - setg(start, (char*)address, start + (*iter).size()); - } - else - { - address = (U8*)(-1); - } - } - if(which & std::ios::out) - { - U8* base_addr = NULL; - switch(way) - { - case std::ios::end: - base_addr = (U8*)LLBufferArray::npos; - break; - case std::ios::cur: - // get the current put pointer and adjust it for buffer - // array semantics. - base_addr = (U8*)pptr(); - break; - case std::ios::beg: - default: - // NULL is fine - break; - } + LLMutexLock lock(mBuffer->getMutex()); + address = mBuffer->seek(mChannels.in(), base_addr, off); + if(address) + { + LLBufferArray::segment_iterator_t iter; + iter = mBuffer->getSegment(address); + char* start = (char*)(*iter).data(); + setg(start, (char*)address, start + (*iter).size()); + } + else + { + address = (U8*)(-1); + } + } + if(which & std::ios::out) + { + U8* base_addr = NULL; + switch(way) + { + case std::ios::end: + base_addr = (U8*)LLBufferArray::npos; + break; + case std::ios::cur: + // get the current put pointer and adjust it for buffer + // array semantics. + base_addr = (U8*)pptr(); + break; + case std::ios::beg: + default: + // NULL is fine + break; + } - LLMutexLock lock(mBuffer->getMutex()); - address = mBuffer->seek(mChannels.out(), base_addr, off); - if(address) - { - LLBufferArray::segment_iterator_t iter; - iter = mBuffer->getSegment(address); - setp((char*)address, (char*)(*iter).data() + (*iter).size()); - } - else - { - address = (U8*)(-1); - } - } + LLMutexLock lock(mBuffer->getMutex()); + address = mBuffer->seek(mChannels.out(), base_addr, off); + if(address) + { + LLBufferArray::segment_iterator_t iter; + iter = mBuffer->getSegment(address); + setp((char*)address, (char*)(*iter).data() + (*iter).size()); + } + else + { + address = (U8*)(-1); + } + } #if( LL_WINDOWS || __GNUC__ > 2 ) - S32 rv = (S32)(intptr_t)address; - return (pos_type)rv; + S32 rv = (S32)(intptr_t)address; + return (pos_type)rv; #else - return (streampos)address; + return (streampos)address; #endif } @@ -332,10 +332,10 @@ streampos LLBufferStreamBuf::seekoff( * LLBufferStream */ LLBufferStream::LLBufferStream( - const LLChannelDescriptors& channels, - LLBufferArray* buffer) : - std::iostream(&mStreamBuf), - mStreamBuf(channels, buffer) + const LLChannelDescriptors& channels, + LLBufferArray* buffer) : + std::iostream(&mStreamBuf), + mStreamBuf(channels, buffer) { } diff --git a/indra/llmessage/llbufferstream.h b/indra/llmessage/llbufferstream.h index 19749612f3..ac1aa49e81 100644 --- a/indra/llmessage/llbufferstream.h +++ b/indra/llmessage/llbufferstream.h @@ -1,4 +1,4 @@ -/** +/** * @file llbufferstream.h * @author Phoenix * @date 2005-10-10 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,7 +33,7 @@ #include <iostream> #include "llbuffer.h" -/** +/** * @class LLBufferStreamBuf * @brief This implements the buffer wrapper for an istream * @@ -42,92 +42,92 @@ class LLBufferStreamBuf : public std::streambuf { public: - LLBufferStreamBuf( - const LLChannelDescriptors& channels, - LLBufferArray* buffer); - virtual ~LLBufferStreamBuf(); + LLBufferStreamBuf( + const LLChannelDescriptors& channels, + LLBufferArray* buffer); + virtual ~LLBufferStreamBuf(); protected: #if( LL_WINDOWS || __GNUC__ > 2 ) - typedef std::streambuf::pos_type pos_type; - typedef std::streambuf::off_type off_type; + typedef std::streambuf::pos_type pos_type; + typedef std::streambuf::off_type off_type; #endif - /* @name streambuf vrtual implementations - */ - //@{ - /* - * @brief called when we hit the end of input - * - * @return Returns the character at the current position or EOF. - */ - virtual int underflow(); - - /* - * @brief called when we hit the end of output - * - * @param c The character to store at the current put position - * @return Returns EOF if the function failed. Any other value on success. - */ - virtual int overflow(int c); - - /* - * @brief synchronize the buffer - * - * @return Returns 0 on success or -1 on failure. - */ - virtual int sync(); - - /* - * @brief Seek to an offset position in a stream. - * - * @param off Offset value relative to way paramter - * @param way The seek direction. One of ios::beg, ios::cur, and ios::end. - * @param which Which pointer to modify. One of ios::in, ios::out, - * or both masked together. - * @return Returns the new position or an invalid position on failure. - */ + /* @name streambuf vrtual implementations + */ + //@{ + /* + * @brief called when we hit the end of input + * + * @return Returns the character at the current position or EOF. + */ + virtual int underflow(); + + /* + * @brief called when we hit the end of output + * + * @param c The character to store at the current put position + * @return Returns EOF if the function failed. Any other value on success. + */ + virtual int overflow(int c); + + /* + * @brief synchronize the buffer + * + * @return Returns 0 on success or -1 on failure. + */ + virtual int sync(); + + /* + * @brief Seek to an offset position in a stream. + * + * @param off Offset value relative to way paramter + * @param way The seek direction. One of ios::beg, ios::cur, and ios::end. + * @param which Which pointer to modify. One of ios::in, ios::out, + * or both masked together. + * @return Returns the new position or an invalid position on failure. + */ #if( LL_WINDOWS || __GNUC__ > 2) - virtual pos_type seekoff( - off_type off, - std::ios::seekdir way, - std::ios::openmode which); + virtual pos_type seekoff( + off_type off, + std::ios::seekdir way, + std::ios::openmode which); #else - virtual streampos seekoff( - streamoff off, - std::ios::seekdir way, - std::ios::openmode which); + virtual streampos seekoff( + streamoff off, + std::ios::seekdir way, + std::ios::openmode which); #endif - /* - * @brief Get s sequence of characters from the input - * - * @param dst Pointer to a block of memory to accept the characters - * @param length Number of characters to be read - * @return Returns the number of characters read - */ - //virtual streamsize xsgetn(char* dst, streamsize length); - - /* - * @brief Write some characters to output - * - * @param src Pointer to a sequence of characters to be output - * @param length Number of characters to be put - * @return Returns the number of characters written - */ - //virtual streamsize xsputn(char* src, streamsize length); - //@} + /* + * @brief Get s sequence of characters from the input + * + * @param dst Pointer to a block of memory to accept the characters + * @param length Number of characters to be read + * @return Returns the number of characters read + */ + //virtual streamsize xsgetn(char* dst, streamsize length); + + /* + * @brief Write some characters to output + * + * @param src Pointer to a sequence of characters to be output + * @param length Number of characters to be put + * @return Returns the number of characters written + */ + //virtual streamsize xsputn(char* src, streamsize length); + //@} protected: - // This channels we are working on. - LLChannelDescriptors mChannels; + // This channels we are working on. + LLChannelDescriptors mChannels; - // The buffer we work on - LLBufferArray* mBuffer; + // The buffer we work on + LLBufferArray* mBuffer; }; -/** +/** * @class LLBufferStream * @brief This implements an istream based wrapper around an LLBufferArray. * @@ -139,13 +139,13 @@ protected: class LLBufferStream : public std::iostream { public: - LLBufferStream( - const LLChannelDescriptors& channels, - LLBufferArray* buffer); - ~LLBufferStream(); + LLBufferStream( + const LLChannelDescriptors& channels, + LLBufferArray* buffer); + ~LLBufferStream(); protected: - LLBufferStreamBuf mStreamBuf; + LLBufferStreamBuf mStreamBuf; }; diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 5b4f9aded7..6fb21957e0 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llcachename.cpp * @brief A hierarchical cache of first and last names queried based on UUID. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -62,21 +62,21 @@ std::map<std::string, std::string> LLCacheName::sCacheName; class LLCacheNameEntry { public: - LLCacheNameEntry(); + LLCacheNameEntry(); public: - bool mIsGroup; - U32 mCreateTime; // unix time_t - // IDEVO TODO collapse names to one field, which will eliminate - // many string compares on "Resident" - std::string mFirstName; - std::string mLastName; - std::string mGroupName; + bool mIsGroup; + U32 mCreateTime; // unix time_t + // IDEVO TODO collapse names to one field, which will eliminate + // many string compares on "Resident" + std::string mFirstName; + std::string mLastName; + std::string mGroupName; }; LLCacheNameEntry::LLCacheNameEntry() - : mIsGroup(false), - mCreateTime(0) + : mIsGroup(false), + mCreateTime(0) { } @@ -84,155 +84,155 @@ LLCacheNameEntry::LLCacheNameEntry() class PendingReply { public: - LLUUID mID; - LLCacheNameSignal mSignal; - LLHost mHost; - - PendingReply(const LLUUID& id, const LLHost& host) - : mID(id), mHost(host) - { - } - - boost::signals2::connection setCallback(const LLCacheNameCallback& cb) - { - return mSignal.connect(cb); - } - - void done() { mID.setNull(); } - bool isDone() const { return mID.isNull(); } + LLUUID mID; + LLCacheNameSignal mSignal; + LLHost mHost; + + PendingReply(const LLUUID& id, const LLHost& host) + : mID(id), mHost(host) + { + } + + boost::signals2::connection setCallback(const LLCacheNameCallback& cb) + { + return mSignal.connect(cb); + } + + void done() { mID.setNull(); } + bool isDone() const { return mID.isNull(); } }; class ReplySender { public: - ReplySender(LLMessageSystem* msg); - ~ReplySender(); + ReplySender(LLMessageSystem* msg); + ~ReplySender(); - void send(const LLUUID& id, - const LLCacheNameEntry& entry, const LLHost& host); + void send(const LLUUID& id, + const LLCacheNameEntry& entry, const LLHost& host); private: - void flush(); + void flush(); - LLMessageSystem* mMsg; - bool mPending; - bool mCurrIsGroup; - LLHost mCurrHost; + LLMessageSystem* mMsg; + bool mPending; + bool mCurrIsGroup; + LLHost mCurrHost; }; ReplySender::ReplySender(LLMessageSystem* msg) - : mMsg(msg), mPending(false), mCurrIsGroup(false) + : mMsg(msg), mPending(false), mCurrIsGroup(false) { } ReplySender::~ReplySender() { - flush(); + flush(); } void ReplySender::send(const LLUUID& id, - const LLCacheNameEntry& entry, const LLHost& host) -{ - if (mPending) - { - if (mCurrIsGroup != entry.mIsGroup - || mCurrHost != host) - { - flush(); - } - } - - if (!mPending) - { - mPending = true; - mCurrIsGroup = entry.mIsGroup; - mCurrHost = host; - - if(mCurrIsGroup) - mMsg->newMessageFast(_PREHASH_UUIDGroupNameReply); - else - mMsg->newMessageFast(_PREHASH_UUIDNameReply); - } - - mMsg->nextBlockFast(_PREHASH_UUIDNameBlock); - mMsg->addUUIDFast(_PREHASH_ID, id); - if(mCurrIsGroup) - { - mMsg->addStringFast(_PREHASH_GroupName, entry.mGroupName); - } - else - { - mMsg->addStringFast(_PREHASH_FirstName, entry.mFirstName); - mMsg->addStringFast(_PREHASH_LastName, entry.mLastName); - } - - if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock)) - { - flush(); - } + const LLCacheNameEntry& entry, const LLHost& host) +{ + if (mPending) + { + if (mCurrIsGroup != entry.mIsGroup + || mCurrHost != host) + { + flush(); + } + } + + if (!mPending) + { + mPending = true; + mCurrIsGroup = entry.mIsGroup; + mCurrHost = host; + + if(mCurrIsGroup) + mMsg->newMessageFast(_PREHASH_UUIDGroupNameReply); + else + mMsg->newMessageFast(_PREHASH_UUIDNameReply); + } + + mMsg->nextBlockFast(_PREHASH_UUIDNameBlock); + mMsg->addUUIDFast(_PREHASH_ID, id); + if(mCurrIsGroup) + { + mMsg->addStringFast(_PREHASH_GroupName, entry.mGroupName); + } + else + { + mMsg->addStringFast(_PREHASH_FirstName, entry.mFirstName); + mMsg->addStringFast(_PREHASH_LastName, entry.mLastName); + } + + if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock)) + { + flush(); + } } void ReplySender::flush() { - if (mPending) - { - mMsg->sendReliable(mCurrHost); - mPending = false; - } + if (mPending) + { + mMsg->sendReliable(mCurrHost); + mPending = false; + } } -typedef std::set<LLUUID> AskQueue; -typedef std::list<PendingReply*> ReplyQueue; -typedef std::map<LLUUID,U32> PendingQueue; +typedef std::set<LLUUID> AskQueue; +typedef std::list<PendingReply*> ReplyQueue; +typedef std::map<LLUUID,U32> PendingQueue; typedef std::map<LLUUID, LLCacheNameEntry*> Cache; -typedef std::map<std::string, LLUUID> ReverseCache; +typedef std::map<std::string, LLUUID> ReverseCache; class LLCacheName::Impl { public: - LLMessageSystem* mMsg; - LLHost mUpstreamHost; - - Cache mCache; - // the map of UUIDs to names - ReverseCache mReverseCache; - // map of names to UUIDs - - AskQueue mAskNameQueue; - AskQueue mAskGroupQueue; - // UUIDs to ask our upstream host about - - PendingQueue mPendingQueue; - // UUIDs that have been requested but are not in cache yet. - - ReplyQueue mReplyQueue; - // requests awaiting replies from us - - LLCacheNameSignal mSignal; - - LLFrameTimer mProcessTimer; - - Impl(LLMessageSystem* msg); - ~Impl(); - - bool getName(const LLUUID& id, std::string& first, std::string& last); - - boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); - void addPending(const LLUUID& id, const LLHost& host); - - void processPendingAsks(); - void processPendingReplies(); - void sendRequest(const char* msg_name, const AskQueue& queue); - bool isRequestPending(const LLUUID& id); - - // Message system callbacks. - void processUUIDRequest(LLMessageSystem* msg, bool isGroup); - void processUUIDReply(LLMessageSystem* msg, bool isGroup); - - static void handleUUIDNameRequest(LLMessageSystem* msg, void** userdata); - static void handleUUIDNameReply(LLMessageSystem* msg, void** userdata); - static void handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userdata); - static void handleUUIDGroupNameReply(LLMessageSystem* msg, void** userdata); + LLMessageSystem* mMsg; + LLHost mUpstreamHost; + + Cache mCache; + // the map of UUIDs to names + ReverseCache mReverseCache; + // map of names to UUIDs + + AskQueue mAskNameQueue; + AskQueue mAskGroupQueue; + // UUIDs to ask our upstream host about + + PendingQueue mPendingQueue; + // UUIDs that have been requested but are not in cache yet. + + ReplyQueue mReplyQueue; + // requests awaiting replies from us + + LLCacheNameSignal mSignal; + + LLFrameTimer mProcessTimer; + + Impl(LLMessageSystem* msg); + ~Impl(); + + bool getName(const LLUUID& id, std::string& first, std::string& last); + + boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); + void addPending(const LLUUID& id, const LLHost& host); + + void processPendingAsks(); + void processPendingReplies(); + void sendRequest(const char* msg_name, const AskQueue& queue); + bool isRequestPending(const LLUUID& id); + + // Message system callbacks. + void processUUIDRequest(LLMessageSystem* msg, bool isGroup); + void processUUIDReply(LLMessageSystem* msg, bool isGroup); + + static void handleUUIDNameRequest(LLMessageSystem* msg, void** userdata); + static void handleUUIDNameReply(LLMessageSystem* msg, void** userdata); + static void handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userdata); + static void handleUUIDGroupNameReply(LLMessageSystem* msg, void** userdata); }; @@ -241,362 +241,362 @@ public: /// --------------------------------------------------------------------------- LLCacheName::LLCacheName(LLMessageSystem* msg) - : impl(* new Impl(msg)) - { } + : impl(* new Impl(msg)) + { } LLCacheName::LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host) - : impl(* new Impl(msg)) + : impl(* new Impl(msg)) { - sCacheName["waiting"] = "(Loading...)"; - sCacheName["nobody"] = "(nobody)"; - sCacheName["none"] = "(none)"; - setUpstream(upstream_host); + sCacheName["waiting"] = "(Loading...)"; + sCacheName["nobody"] = "(nobody)"; + sCacheName["none"] = "(none)"; + setUpstream(upstream_host); } LLCacheName::~LLCacheName() { - delete &impl; + delete &impl; } LLCacheName::Impl::Impl(LLMessageSystem* msg) - : mMsg(msg), mUpstreamHost(LLHost()) + : mMsg(msg), mUpstreamHost(LLHost()) { - mMsg->setHandlerFuncFast( - _PREHASH_UUIDNameRequest, handleUUIDNameRequest, (void**)this); - mMsg->setHandlerFuncFast( - _PREHASH_UUIDNameReply, handleUUIDNameReply, (void**)this); - mMsg->setHandlerFuncFast( - _PREHASH_UUIDGroupNameRequest, handleUUIDGroupNameRequest, (void**)this); - mMsg->setHandlerFuncFast( - _PREHASH_UUIDGroupNameReply, handleUUIDGroupNameReply, (void**)this); + mMsg->setHandlerFuncFast( + _PREHASH_UUIDNameRequest, handleUUIDNameRequest, (void**)this); + mMsg->setHandlerFuncFast( + _PREHASH_UUIDNameReply, handleUUIDNameReply, (void**)this); + mMsg->setHandlerFuncFast( + _PREHASH_UUIDGroupNameRequest, handleUUIDGroupNameRequest, (void**)this); + mMsg->setHandlerFuncFast( + _PREHASH_UUIDGroupNameReply, handleUUIDGroupNameReply, (void**)this); } LLCacheName::Impl::~Impl() { - for_each(mCache.begin(), mCache.end(), DeletePairedPointer()); - mCache.clear(); - for_each(mReplyQueue.begin(), mReplyQueue.end(), DeletePointer()); - mReplyQueue.clear(); + for_each(mCache.begin(), mCache.end(), DeletePairedPointer()); + mCache.clear(); + for_each(mReplyQueue.begin(), mReplyQueue.end(), DeletePointer()); + mReplyQueue.clear(); } boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback) { - PendingReply* reply = new PendingReply(id, LLHost()); - boost::signals2::connection res = reply->setCallback(callback); - mReplyQueue.push_back(reply); - return res; + PendingReply* reply = new PendingReply(id, LLHost()); + boost::signals2::connection res = reply->setCallback(callback); + mReplyQueue.push_back(reply); + return res; } void LLCacheName::Impl::addPending(const LLUUID& id, const LLHost& host) { - PendingReply* reply = new PendingReply(id, host); - mReplyQueue.push_back(reply); + PendingReply* reply = new PendingReply(id, host); + mReplyQueue.push_back(reply); } void LLCacheName::setUpstream(const LLHost& upstream_host) { - impl.mUpstreamHost = upstream_host; + impl.mUpstreamHost = upstream_host; } boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& callback) { - return impl.mSignal.connect(callback); + return impl.mSignal.connect(callback); } bool LLCacheName::importFile(std::istream& istr) { - LLSD data; - if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) - { - return false; - } - - // We'll expire entries more than a week old - U32 now = (U32)time(NULL); - const U32 SECS_PER_DAY = 60 * 60 * 24; - U32 delete_before_time = now - (7 * SECS_PER_DAY); - - // iterate over the agents - S32 count = 0; - LLSD agents = data[AGENTS]; - LLSD::map_iterator iter = agents.beginMap(); - LLSD::map_iterator end = agents.endMap(); - for( ; iter != end; ++iter) - { - LLUUID id((*iter).first); - LLSD agent = (*iter).second; - U32 ctime = (U32)agent[CTIME].asInteger(); - if(ctime < delete_before_time) continue; - - LLCacheNameEntry* entry = new LLCacheNameEntry(); - entry->mIsGroup = false; - entry->mCreateTime = ctime; - entry->mFirstName = agent[FIRST].asString(); - entry->mLastName = agent[LAST].asString(); - impl.mCache[id] = entry; - std::string fullname = buildFullName(entry->mFirstName, entry->mLastName); - impl.mReverseCache[fullname] = id; - - ++count; - } - LL_INFOS() << "LLCacheName loaded " << count << " agent names" << LL_ENDL; - - count = 0; - LLSD groups = data[GROUPS]; - iter = groups.beginMap(); - end = groups.endMap(); - for( ; iter != end; ++iter) - { - LLUUID id((*iter).first); - LLSD group = (*iter).second; - U32 ctime = (U32)group[CTIME].asInteger(); - if(ctime < delete_before_time) continue; - - LLCacheNameEntry* entry = new LLCacheNameEntry(); - entry->mIsGroup = true; - entry->mCreateTime = ctime; - entry->mGroupName = group[NAME].asString(); - impl.mCache[id] = entry; - impl.mReverseCache[entry->mGroupName] = id; - ++count; - } - LL_INFOS() << "LLCacheName loaded " << count << " group names" << LL_ENDL; - return true; + LLSD data; + if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) + { + return false; + } + + // We'll expire entries more than a week old + U32 now = (U32)time(NULL); + const U32 SECS_PER_DAY = 60 * 60 * 24; + U32 delete_before_time = now - (7 * SECS_PER_DAY); + + // iterate over the agents + S32 count = 0; + LLSD agents = data[AGENTS]; + LLSD::map_iterator iter = agents.beginMap(); + LLSD::map_iterator end = agents.endMap(); + for( ; iter != end; ++iter) + { + LLUUID id((*iter).first); + LLSD agent = (*iter).second; + U32 ctime = (U32)agent[CTIME].asInteger(); + if(ctime < delete_before_time) continue; + + LLCacheNameEntry* entry = new LLCacheNameEntry(); + entry->mIsGroup = false; + entry->mCreateTime = ctime; + entry->mFirstName = agent[FIRST].asString(); + entry->mLastName = agent[LAST].asString(); + impl.mCache[id] = entry; + std::string fullname = buildFullName(entry->mFirstName, entry->mLastName); + impl.mReverseCache[fullname] = id; + + ++count; + } + LL_INFOS() << "LLCacheName loaded " << count << " agent names" << LL_ENDL; + + count = 0; + LLSD groups = data[GROUPS]; + iter = groups.beginMap(); + end = groups.endMap(); + for( ; iter != end; ++iter) + { + LLUUID id((*iter).first); + LLSD group = (*iter).second; + U32 ctime = (U32)group[CTIME].asInteger(); + if(ctime < delete_before_time) continue; + + LLCacheNameEntry* entry = new LLCacheNameEntry(); + entry->mIsGroup = true; + entry->mCreateTime = ctime; + entry->mGroupName = group[NAME].asString(); + impl.mCache[id] = entry; + impl.mReverseCache[entry->mGroupName] = id; + ++count; + } + LL_INFOS() << "LLCacheName loaded " << count << " group names" << LL_ENDL; + return true; } void LLCacheName::exportFile(std::ostream& ostr) { - LLSD data; - Cache::iterator iter = impl.mCache.begin(); - Cache::iterator end = impl.mCache.end(); - for( ; iter != end; ++iter) - { - // Only write entries for which we have valid data. - LLCacheNameEntry* entry = iter->second; - if(!entry - || (std::string::npos != entry->mFirstName.find('?')) - || (std::string::npos != entry->mGroupName.find('?'))) - { - continue; - } - - // store it - LLUUID id = iter->first; - std::string id_str = id.asString(); - // IDEVO TODO: Should we store SLIDs with last name "Resident" or not? - if(!entry->mFirstName.empty() && !entry->mLastName.empty()) - { - data[AGENTS][id_str][FIRST] = entry->mFirstName; - data[AGENTS][id_str][LAST] = entry->mLastName; - data[AGENTS][id_str][CTIME] = (S32)entry->mCreateTime; - } - else if(entry->mIsGroup && !entry->mGroupName.empty()) - { - data[GROUPS][id_str][NAME] = entry->mGroupName; - data[GROUPS][id_str][CTIME] = (S32)entry->mCreateTime; - } - } - - LLSDSerialize::toPrettyXML(data, ostr); + LLSD data; + Cache::iterator iter = impl.mCache.begin(); + Cache::iterator end = impl.mCache.end(); + for( ; iter != end; ++iter) + { + // Only write entries for which we have valid data. + LLCacheNameEntry* entry = iter->second; + if(!entry + || (std::string::npos != entry->mFirstName.find('?')) + || (std::string::npos != entry->mGroupName.find('?'))) + { + continue; + } + + // store it + LLUUID id = iter->first; + std::string id_str = id.asString(); + // IDEVO TODO: Should we store SLIDs with last name "Resident" or not? + if(!entry->mFirstName.empty() && !entry->mLastName.empty()) + { + data[AGENTS][id_str][FIRST] = entry->mFirstName; + data[AGENTS][id_str][LAST] = entry->mLastName; + data[AGENTS][id_str][CTIME] = (S32)entry->mCreateTime; + } + else if(entry->mIsGroup && !entry->mGroupName.empty()) + { + data[GROUPS][id_str][NAME] = entry->mGroupName; + data[GROUPS][id_str][CTIME] = (S32)entry->mCreateTime; + } + } + + LLSDSerialize::toPrettyXML(data, ostr); } bool LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last) { - if(id.isNull()) - { - first = sCacheName["nobody"]; - last.clear(); - return true; - } - - LLCacheNameEntry* entry = get_ptr_in_map(mCache, id ); - if (entry) - { - first = entry->mFirstName; - last = entry->mLastName; - return true; - } - else - { - first = sCacheName["waiting"]; - last.clear(); - if (!isRequestPending(id)) - { - mAskNameQueue.insert(id); - } - return false; - } + if(id.isNull()) + { + first = sCacheName["nobody"]; + last.clear(); + return true; + } + + LLCacheNameEntry* entry = get_ptr_in_map(mCache, id ); + if (entry) + { + first = entry->mFirstName; + last = entry->mLastName; + return true; + } + else + { + first = sCacheName["waiting"]; + last.clear(); + if (!isRequestPending(id)) + { + mAskNameQueue.insert(id); + } + return false; + } } // static void LLCacheName::localizeCacheName(std::string key, std::string value) { - if (key!="" && value!= "" ) - sCacheName[key]=value; - else - LL_WARNS()<< " Error localizing cache key " << key << " To "<< value<<LL_ENDL; + if (key!="" && value!= "" ) + sCacheName[key]=value; + else + LL_WARNS()<< " Error localizing cache key " << key << " To "<< value<<LL_ENDL; } bool LLCacheName::getFullName(const LLUUID& id, std::string& fullname) { - std::string first_name, last_name; - bool res = impl.getName(id, first_name, last_name); - fullname = buildFullName(first_name, last_name); - return res; + std::string first_name, last_name; + bool res = impl.getName(id, first_name, last_name); + fullname = buildFullName(first_name, last_name); + return res; } bool LLCacheName::getGroupName(const LLUUID& id, std::string& group) { - if(id.isNull()) - { - group = sCacheName["none"]; - return true; - } - - LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache,id); - if (entry && entry->mGroupName.empty()) - { - // COUNTER-HACK to combat James' HACK in exportFile()... - // this group name was loaded from a name cache that did not - // bother to save the group name ==> we must ask for it - LL_DEBUGS() << "LLCacheName queuing HACK group request: " << id << LL_ENDL; - entry = NULL; - } - - if (entry) - { - group = entry->mGroupName; - return true; - } - else - { - group = sCacheName["waiting"]; - if (!impl.isRequestPending(id)) - { - impl.mAskGroupQueue.insert(id); - } - return false; - } + if(id.isNull()) + { + group = sCacheName["none"]; + return true; + } + + LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache,id); + if (entry && entry->mGroupName.empty()) + { + // COUNTER-HACK to combat James' HACK in exportFile()... + // this group name was loaded from a name cache that did not + // bother to save the group name ==> we must ask for it + LL_DEBUGS() << "LLCacheName queuing HACK group request: " << id << LL_ENDL; + entry = NULL; + } + + if (entry) + { + group = entry->mGroupName; + return true; + } + else + { + group = sCacheName["waiting"]; + if (!impl.isRequestPending(id)) + { + impl.mAskGroupQueue.insert(id); + } + return false; + } } bool LLCacheName::getUUID(const std::string& first, const std::string& last, LLUUID& id) { - std::string full_name = buildFullName(first, last); - return getUUID(full_name, id); + std::string full_name = buildFullName(first, last); + return getUUID(full_name, id); } bool LLCacheName::getUUID(const std::string& full_name, LLUUID& id) { - ReverseCache::iterator iter = impl.mReverseCache.find(full_name); - if (iter != impl.mReverseCache.end()) - { - id = iter->second; - return true; - } - else - { - return false; - } + ReverseCache::iterator iter = impl.mReverseCache.find(full_name); + if (iter != impl.mReverseCache.end()) + { + id = iter->second; + return true; + } + else + { + return false; + } } //static std::string LLCacheName::buildFullName(const std::string& first, const std::string& last) { - std::string fullname = first; - if (!last.empty() - && last != "Resident") - { - fullname += ' '; - fullname += last; - } - return fullname; + std::string fullname = first; + if (!last.empty() + && last != "Resident") + { + fullname += ' '; + fullname += last; + } + return fullname; } //static std::string LLCacheName::cleanFullName(const std::string& full_name) { - return full_name.substr(0, full_name.find(" Resident")); + return full_name.substr(0, full_name.find(" Resident")); } -//static +//static // Transform hard-coded name provided by server to a more legible username std::string LLCacheName::buildUsername(const std::string& full_name) { - // rare, but handle hard-coded error names returned from server - if (full_name == "(\?\?\?) (\?\?\?)") - { - return "(\?\?\?)"; - } - - std::string::size_type index = full_name.find(' '); - - if (index != std::string::npos) - { - std::string username; - username = full_name.substr(0, index); - std::string lastname = full_name.substr(index+1); - - if (lastname != "Resident") - { - username = username + "." + lastname; - } - - LLStringUtil::toLower(username); - return username; - } - - // if the input wasn't a correctly formatted legacy name, just return it - // cleaned up from a potential terminal "Resident" + // rare, but handle hard-coded error names returned from server + if (full_name == "(\?\?\?) (\?\?\?)") + { + return "(\?\?\?)"; + } + + std::string::size_type index = full_name.find(' '); + + if (index != std::string::npos) + { + std::string username; + username = full_name.substr(0, index); + std::string lastname = full_name.substr(index+1); + + if (lastname != "Resident") + { + username = username + "." + lastname; + } + + LLStringUtil::toLower(username); + return username; + } + + // if the input wasn't a correctly formatted legacy name, just return it + // cleaned up from a potential terminal "Resident" std::string clean_name = cleanFullName(full_name); LLStringUtil::toLower(clean_name); - return clean_name; + return clean_name; } -//static +//static std::string LLCacheName::buildLegacyName(const std::string& complete_name) { - //boost::regexp was showing up in the crashreporter, so doing - //painfully manual parsing using substr. LF - S32 open_paren = complete_name.rfind(" ("); - S32 close_paren = complete_name.rfind(')'); - - if (open_paren != std::string::npos && - close_paren == complete_name.length()-1) - { - S32 length = close_paren - open_paren - 2; - std::string legacy_name = complete_name.substr(open_paren+2, length); - - if (legacy_name.length() > 0) - { - std::string cap_letter = legacy_name.substr(0, 1); - LLStringUtil::toUpper(cap_letter); - legacy_name = cap_letter + legacy_name.substr(1); - - S32 separator = legacy_name.find('.'); - - if (separator != std::string::npos) - { - std::string last_name = legacy_name.substr(separator+1); - legacy_name = legacy_name.substr(0, separator); - - if (last_name.length() > 0) - { - cap_letter = last_name.substr(0, 1); - LLStringUtil::toUpper(cap_letter); - legacy_name = legacy_name + " " + cap_letter + last_name.substr(1); - } - } - - return legacy_name; - } - } - - return complete_name; + //boost::regexp was showing up in the crashreporter, so doing + //painfully manual parsing using substr. LF + S32 open_paren = complete_name.rfind(" ("); + S32 close_paren = complete_name.rfind(')'); + + if (open_paren != std::string::npos && + close_paren == complete_name.length()-1) + { + S32 length = close_paren - open_paren - 2; + std::string legacy_name = complete_name.substr(open_paren+2, length); + + if (legacy_name.length() > 0) + { + std::string cap_letter = legacy_name.substr(0, 1); + LLStringUtil::toUpper(cap_letter); + legacy_name = cap_letter + legacy_name.substr(1); + + S32 separator = legacy_name.find('.'); + + if (separator != std::string::npos) + { + std::string last_name = legacy_name.substr(separator+1); + legacy_name = legacy_name.substr(0, separator); + + if (last_name.length() > 0) + { + cap_letter = last_name.substr(0, 1); + LLStringUtil::toUpper(cap_letter); + legacy_name = legacy_name + " " + cap_letter + last_name.substr(1); + } + } + + return legacy_name; + } + } + + return complete_name; } // This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer. @@ -608,392 +608,392 @@ std::string LLCacheName::buildLegacyName(const std::string& complete_name) // potential need for any parsing should any code need to handle first and last name independently. boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { - boost::signals2::connection res; - - if(id.isNull()) - { - LLCacheNameSignal signal; - signal.connect(callback); - signal(id, sCacheName["nobody"], is_group); - return res; - } - - LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id ); - if (entry) - { - LLCacheNameSignal signal; - signal.connect(callback); - // id found in map therefore we can call the callback immediately. - if (entry->mIsGroup) - { - signal(id, entry->mGroupName, entry->mIsGroup); - } - else - { - std::string fullname = - buildFullName(entry->mFirstName, entry->mLastName); - signal(id, fullname, entry->mIsGroup); - } - } - else - { - // id not found in map so we must queue the callback call until available. - if (!impl.isRequestPending(id)) - { - if (is_group) - { - impl.mAskGroupQueue.insert(id); - } - else - { - impl.mAskNameQueue.insert(id); - } - } - res = impl.addPending(id, callback); - } - return res; + boost::signals2::connection res; + + if(id.isNull()) + { + LLCacheNameSignal signal; + signal.connect(callback); + signal(id, sCacheName["nobody"], is_group); + return res; + } + + LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id ); + if (entry) + { + LLCacheNameSignal signal; + signal.connect(callback); + // id found in map therefore we can call the callback immediately. + if (entry->mIsGroup) + { + signal(id, entry->mGroupName, entry->mIsGroup); + } + else + { + std::string fullname = + buildFullName(entry->mFirstName, entry->mLastName); + signal(id, fullname, entry->mIsGroup); + } + } + else + { + // id not found in map so we must queue the callback call until available. + if (!impl.isRequestPending(id)) + { + if (is_group) + { + impl.mAskGroupQueue.insert(id); + } + else + { + impl.mAskNameQueue.insert(id); + } + } + res = impl.addPending(id, callback); + } + return res; } boost::signals2::connection LLCacheName::getGroup(const LLUUID& group_id, - const LLCacheNameCallback& callback) + const LLCacheNameCallback& callback) { - return get(group_id, true, callback); + return get(group_id, true, callback); } boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data) { - return get(id, is_group, boost::bind(callback, _1, _2, _3, user_data)); + return get(id, is_group, boost::bind(callback, _1, _2, _3, user_data)); } void LLCacheName::processPending() { - const F32 SECS_BETWEEN_PROCESS = 0.1f; - if(!impl.mProcessTimer.checkExpirationAndReset(SECS_BETWEEN_PROCESS)) - { - return; - } + const F32 SECS_BETWEEN_PROCESS = 0.1f; + if(!impl.mProcessTimer.checkExpirationAndReset(SECS_BETWEEN_PROCESS)) + { + return; + } - if(!impl.mUpstreamHost.isOk()) - { - LL_DEBUGS() << "LLCacheName::processPending() - bad upstream host." - << LL_ENDL; - return; - } + if(!impl.mUpstreamHost.isOk()) + { + LL_DEBUGS() << "LLCacheName::processPending() - bad upstream host." + << LL_ENDL; + return; + } - impl.processPendingAsks(); - impl.processPendingReplies(); + impl.processPendingAsks(); + impl.processPendingReplies(); } void LLCacheName::deleteEntriesOlderThan(S32 secs) { - U32 now = (U32)time(NULL); - U32 expire_time = now - secs; - for(Cache::iterator iter = impl.mCache.begin(); iter != impl.mCache.end(); ) - { - Cache::iterator curiter = iter++; - LLCacheNameEntry* entry = curiter->second; - if (entry->mCreateTime < expire_time) - { - delete entry; - impl.mCache.erase(curiter); - } - } - - // These are pending requests that we never heard back from. - U32 pending_expire_time = now - PENDING_TIMEOUT_SECS; - for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin(); - p_iter != impl.mPendingQueue.end(); ) - { - PendingQueue::iterator p_curitor = p_iter++; - - if (p_curitor->second < pending_expire_time) - { - impl.mPendingQueue.erase(p_curitor); - } - } + U32 now = (U32)time(NULL); + U32 expire_time = now - secs; + for(Cache::iterator iter = impl.mCache.begin(); iter != impl.mCache.end(); ) + { + Cache::iterator curiter = iter++; + LLCacheNameEntry* entry = curiter->second; + if (entry->mCreateTime < expire_time) + { + delete entry; + impl.mCache.erase(curiter); + } + } + + // These are pending requests that we never heard back from. + U32 pending_expire_time = now - PENDING_TIMEOUT_SECS; + for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin(); + p_iter != impl.mPendingQueue.end(); ) + { + PendingQueue::iterator p_curitor = p_iter++; + + if (p_curitor->second < pending_expire_time) + { + impl.mPendingQueue.erase(p_curitor); + } + } } void LLCacheName::dump() { - for (Cache::iterator iter = impl.mCache.begin(), - end = impl.mCache.end(); - iter != end; iter++) - { - LLCacheNameEntry* entry = iter->second; - if (entry->mIsGroup) - { - LL_INFOS() - << iter->first << " = (group) " - << entry->mGroupName - << " @ " << entry->mCreateTime - << LL_ENDL; - } - else - { - LL_INFOS() - << iter->first << " = " - << buildFullName(entry->mFirstName, entry->mLastName) - << " @ " << entry->mCreateTime - << LL_ENDL; - } - } + for (Cache::iterator iter = impl.mCache.begin(), + end = impl.mCache.end(); + iter != end; iter++) + { + LLCacheNameEntry* entry = iter->second; + if (entry->mIsGroup) + { + LL_INFOS() + << iter->first << " = (group) " + << entry->mGroupName + << " @ " << entry->mCreateTime + << LL_ENDL; + } + else + { + LL_INFOS() + << iter->first << " = " + << buildFullName(entry->mFirstName, entry->mLastName) + << " @ " << entry->mCreateTime + << LL_ENDL; + } + } } void LLCacheName::dumpStats() { - LL_INFOS() << "Queue sizes: " - << " Cache=" << impl.mCache.size() - << " AskName=" << impl.mAskNameQueue.size() - << " AskGroup=" << impl.mAskGroupQueue.size() - << " Pending=" << impl.mPendingQueue.size() - << " Reply=" << impl.mReplyQueue.size() -// << " Observers=" << impl.mSignal.size() - << LL_ENDL; + LL_INFOS() << "Queue sizes: " + << " Cache=" << impl.mCache.size() + << " AskName=" << impl.mAskNameQueue.size() + << " AskGroup=" << impl.mAskGroupQueue.size() + << " Pending=" << impl.mPendingQueue.size() + << " Reply=" << impl.mReplyQueue.size() +// << " Observers=" << impl.mSignal.size() + << LL_ENDL; } void LLCacheName::clear() { - for_each(impl.mCache.begin(), impl.mCache.end(), DeletePairedPointer()); - impl.mCache.clear(); + for_each(impl.mCache.begin(), impl.mCache.end(), DeletePairedPointer()); + impl.mCache.clear(); } -//static +//static std::string LLCacheName::getDefaultName() { - return sCacheName["waiting"]; + return sCacheName["waiting"]; } -//static +//static std::string LLCacheName::getDefaultLastName() { - return "Resident"; + return "Resident"; } void LLCacheName::Impl::processPendingAsks() { - sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); - sendRequest(_PREHASH_UUIDGroupNameRequest, mAskGroupQueue); - mAskNameQueue.clear(); - mAskGroupQueue.clear(); + sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); + sendRequest(_PREHASH_UUIDGroupNameRequest, mAskGroupQueue); + mAskNameQueue.clear(); + mAskGroupQueue.clear(); } void LLCacheName::Impl::processPendingReplies() { - // First call all the callbacks, because they might send messages. - for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) - { - PendingReply* reply = *it; - LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID); - if(!entry) continue; - - if (!entry->mIsGroup) - { - std::string fullname = - LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); - (reply->mSignal)(reply->mID, fullname, false); - } - else - { - (reply->mSignal)(reply->mID, entry->mGroupName, true); - } - } - - // Forward on all replies, if needed. - ReplySender sender(mMsg); - for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) - { - PendingReply* reply = *it; - LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID); - if(!entry) continue; - - if (reply->mHost.isOk()) - { - sender.send(reply->mID, *entry, reply->mHost); - } - - reply->done(); - } - - for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ) - { - ReplyQueue::iterator curit = it++; - PendingReply* reply = *curit; - if (reply->isDone()) - { - delete reply; - mReplyQueue.erase(curit); - } - } + // First call all the callbacks, because they might send messages. + for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) + { + PendingReply* reply = *it; + LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID); + if(!entry) continue; + + if (!entry->mIsGroup) + { + std::string fullname = + LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); + (reply->mSignal)(reply->mID, fullname, false); + } + else + { + (reply->mSignal)(reply->mID, entry->mGroupName, true); + } + } + + // Forward on all replies, if needed. + ReplySender sender(mMsg); + for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) + { + PendingReply* reply = *it; + LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID); + if(!entry) continue; + + if (reply->mHost.isOk()) + { + sender.send(reply->mID, *entry, reply->mHost); + } + + reply->done(); + } + + for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ) + { + ReplyQueue::iterator curit = it++; + PendingReply* reply = *curit; + if (reply->isDone()) + { + delete reply; + mReplyQueue.erase(curit); + } + } } void LLCacheName::Impl::sendRequest( - const char* msg_name, - const AskQueue& queue) -{ - if(queue.empty()) - { - return; - } - - bool start_new_message = true; - AskQueue::const_iterator it = queue.begin(); - AskQueue::const_iterator end = queue.end(); - for(; it != end; ++it) - { - if(start_new_message) - { - start_new_message = false; - mMsg->newMessageFast(msg_name); - } - mMsg->nextBlockFast(_PREHASH_UUIDNameBlock); - mMsg->addUUIDFast(_PREHASH_ID, (*it)); - - if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock)) - { - start_new_message = true; - mMsg->sendReliable(mUpstreamHost); - } - } - if(!start_new_message) - { - mMsg->sendReliable(mUpstreamHost); - } + const char* msg_name, + const AskQueue& queue) +{ + if(queue.empty()) + { + return; + } + + bool start_new_message = true; + AskQueue::const_iterator it = queue.begin(); + AskQueue::const_iterator end = queue.end(); + for(; it != end; ++it) + { + if(start_new_message) + { + start_new_message = false; + mMsg->newMessageFast(msg_name); + } + mMsg->nextBlockFast(_PREHASH_UUIDNameBlock); + mMsg->addUUIDFast(_PREHASH_ID, (*it)); + + if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock)) + { + start_new_message = true; + mMsg->sendReliable(mUpstreamHost); + } + } + if(!start_new_message) + { + mMsg->sendReliable(mUpstreamHost); + } } bool LLCacheName::Impl::isRequestPending(const LLUUID& id) { - U32 now = (U32)time(NULL); - U32 expire_time = now - PENDING_TIMEOUT_SECS; + U32 now = (U32)time(NULL); + U32 expire_time = now - PENDING_TIMEOUT_SECS; - PendingQueue::iterator iter = mPendingQueue.find(id); + PendingQueue::iterator iter = mPendingQueue.find(id); - if (iter == mPendingQueue.end() - || (iter->second < expire_time) ) - { - mPendingQueue[id] = now; - return false; - } + if (iter == mPendingQueue.end() + || (iter->second < expire_time) ) + { + mPendingQueue[id] = now; + return false; + } - return true; + return true; } - + void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup) { - // You should only get this message if the cache is at the simulator - // level, hence having an upstream provider. - if (!mUpstreamHost.isOk()) - { - LL_WARNS() << "LLCacheName - got UUID name/group request, but no upstream provider!" << LL_ENDL; - return; - } - - LLHost fromHost = msg->getSender(); - ReplySender sender(msg); - - S32 count = msg->getNumberOfBlocksFast(_PREHASH_UUIDNameBlock); - for(S32 i = 0; i < count; ++i) - { - LLUUID id; - msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i); - LLCacheNameEntry* entry = get_ptr_in_map(mCache, id); - if(entry) - { - if (isGroup != entry->mIsGroup) - { - LL_WARNS() << "LLCacheName - Asked for " - << (isGroup ? "group" : "user") << " name, " - << "but found " - << (entry->mIsGroup ? "group" : "user") - << ": " << id << LL_ENDL; - } - else - { - // ...it's in the cache, so send it as the reply - sender.send(id, *entry, fromHost); - } - } - else - { - if (!isRequestPending(id)) - { - if (isGroup) - { - mAskGroupQueue.insert(id); - } - else - { - mAskNameQueue.insert(id); - } - } - - addPending(id, fromHost); - } - } + // You should only get this message if the cache is at the simulator + // level, hence having an upstream provider. + if (!mUpstreamHost.isOk()) + { + LL_WARNS() << "LLCacheName - got UUID name/group request, but no upstream provider!" << LL_ENDL; + return; + } + + LLHost fromHost = msg->getSender(); + ReplySender sender(msg); + + S32 count = msg->getNumberOfBlocksFast(_PREHASH_UUIDNameBlock); + for(S32 i = 0; i < count; ++i) + { + LLUUID id; + msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i); + LLCacheNameEntry* entry = get_ptr_in_map(mCache, id); + if(entry) + { + if (isGroup != entry->mIsGroup) + { + LL_WARNS() << "LLCacheName - Asked for " + << (isGroup ? "group" : "user") << " name, " + << "but found " + << (entry->mIsGroup ? "group" : "user") + << ": " << id << LL_ENDL; + } + else + { + // ...it's in the cache, so send it as the reply + sender.send(id, *entry, fromHost); + } + } + else + { + if (!isRequestPending(id)) + { + if (isGroup) + { + mAskGroupQueue.insert(id); + } + else + { + mAskNameQueue.insert(id); + } + } + + addPending(id, fromHost); + } + } } void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup) { - S32 count = msg->getNumberOfBlocksFast(_PREHASH_UUIDNameBlock); - for(S32 i = 0; i < count; ++i) - { - LLUUID id; - msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i); - LLCacheNameEntry* entry = get_ptr_in_map(mCache, id); - if (!entry) - { - entry = new LLCacheNameEntry; - mCache[id] = entry; - } - - mPendingQueue.erase(id); - - entry->mIsGroup = isGroup; - entry->mCreateTime = (U32)time(NULL); - if (!isGroup) - { - msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_FirstName, entry->mFirstName, i); - msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_LastName, entry->mLastName, i); - } - else - { // is group - msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_GroupName, entry->mGroupName, i); - LLStringFn::replace_ascii_controlchars(entry->mGroupName, LL_UNKNOWN_CHAR); - } - - if (!isGroup) - { - // NOTE: Very occasionally the server sends down a full name - // in the first name field with an empty last name, for example, - // first = "Ladanie1 Resident", last = "". - // I cannot reproduce this, nor can I find a bug in the server code. - // Ensure "Resident" does not appear via cleanFullName, because - // buildFullName only checks last name. JC - std::string full_name; - if (entry->mLastName.empty()) - { - full_name = cleanFullName(entry->mFirstName); - - //fix what we are putting in the cache - entry->mFirstName = full_name; - entry->mLastName = "Resident"; - } - else - { - full_name = LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); - } - mSignal(id, full_name, false); - mReverseCache[full_name] = id; - } - else - { - mSignal(id, entry->mGroupName, true); - mReverseCache[entry->mGroupName] = id; - } - } + S32 count = msg->getNumberOfBlocksFast(_PREHASH_UUIDNameBlock); + for(S32 i = 0; i < count; ++i) + { + LLUUID id; + msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i); + LLCacheNameEntry* entry = get_ptr_in_map(mCache, id); + if (!entry) + { + entry = new LLCacheNameEntry; + mCache[id] = entry; + } + + mPendingQueue.erase(id); + + entry->mIsGroup = isGroup; + entry->mCreateTime = (U32)time(NULL); + if (!isGroup) + { + msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_FirstName, entry->mFirstName, i); + msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_LastName, entry->mLastName, i); + } + else + { // is group + msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_GroupName, entry->mGroupName, i); + LLStringFn::replace_ascii_controlchars(entry->mGroupName, LL_UNKNOWN_CHAR); + } + + if (!isGroup) + { + // NOTE: Very occasionally the server sends down a full name + // in the first name field with an empty last name, for example, + // first = "Ladanie1 Resident", last = "". + // I cannot reproduce this, nor can I find a bug in the server code. + // Ensure "Resident" does not appear via cleanFullName, because + // buildFullName only checks last name. JC + std::string full_name; + if (entry->mLastName.empty()) + { + full_name = cleanFullName(entry->mFirstName); + + //fix what we are putting in the cache + entry->mFirstName = full_name; + entry->mLastName = "Resident"; + } + else + { + full_name = LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); + } + mSignal(id, full_name, false); + mReverseCache[full_name] = id; + } + else + { + mSignal(id, entry->mGroupName, true); + mReverseCache[entry->mGroupName] = id; + } + } } @@ -1002,20 +1002,20 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup) void LLCacheName::Impl::handleUUIDNameReply(LLMessageSystem* msg, void** userData) { - ((LLCacheName::Impl*)userData)->processUUIDReply(msg, false); + ((LLCacheName::Impl*)userData)->processUUIDReply(msg, false); } void LLCacheName::Impl::handleUUIDNameRequest(LLMessageSystem* msg, void** userData) { - ((LLCacheName::Impl*)userData)->processUUIDRequest(msg, false); + ((LLCacheName::Impl*)userData)->processUUIDRequest(msg, false); } void LLCacheName::Impl::handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userData) { - ((LLCacheName::Impl*)userData)->processUUIDRequest(msg, true); + ((LLCacheName::Impl*)userData)->processUUIDRequest(msg, true); } void LLCacheName::Impl::handleUUIDGroupNameReply(LLMessageSystem* msg, void** userData) { - ((LLCacheName::Impl*)userData)->processUUIDReply(msg, true); + ((LLCacheName::Impl*)userData)->processUUIDReply(msg, true); } diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index 8091248151..1df713c7c7 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -1,25 +1,25 @@ -/** +/** * @file llcachename.h * @brief A cache of names from UUIDs. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,7 +45,7 @@ typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*); // Here's the theory: // If you request a name that isn't in the cache, it returns "waiting" -// and requests the data. After the data arrives, you get that on +// and requests the data. After the data arrives, you get that on // subsequent calls. // If the data hasn't been updated in an hour, it requests it again, // but keeps giving you the old value until new data arrives. @@ -53,92 +53,92 @@ typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*); class LLCacheName { public: - LLCacheName(LLMessageSystem* msg); - LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host); - ~LLCacheName(); - - // registers the upstream host - // for viewers, this is the currently connected simulator - // for simulators, this is the data server - void setUpstream(const LLHost& upstream_host); - - boost::signals2::connection addObserver(const LLCacheNameCallback& callback); - - // storing cache on disk; for viewer, in name.cache - bool importFile(std::istream& istr); - void exportFile(std::ostream& ostr); - - // If available, copies name ("bobsmith123" or "James Linden") into string - // If not available, copies the string "waiting". - // Returns true if available. - bool getFullName(const LLUUID& id, std::string& full_name); - - // Reverse lookup of UUID from name - bool getUUID(const std::string& first, const std::string& last, LLUUID& id); - bool getUUID(const std::string& fullname, LLUUID& id); - - // IDEVO Temporary code - // Clean up new-style "bobsmith123 Resident" names to "bobsmith123" for display - static std::string buildFullName(const std::string& first, const std::string& last); - - // Clean up legacy "bobsmith123 Resident" to "bobsmith123" - // If name does not contain "Resident" returns it unchanged. - static std::string cleanFullName(const std::string& full_name); - - // Converts a standard legacy name to a username - // "bobsmith123 Resident" -> "bobsmith" - // "Random Linden" -> "random.linden" - static std::string buildUsername(const std::string& name); - - // Converts a complete display name to a legacy name - // if possible, otherwise returns the input - // "Alias (random.linden)" -> "Random Linden" - // "Something random" -> "Something random" - static std::string buildLegacyName(const std::string& name); - - // If available, this method copies the group name into the string - // provided. The caller must allocate at least - // DB_GROUP_NAME_BUF_SIZE characters. If not available, this - // method copies the string "waiting". Returns true if available. - bool getGroupName(const LLUUID& id, std::string& group); - - // Call the callback with the group or avatar name. - // If the data is currently available, may call the callback immediatly - // otherwise, will request the data, and will call the callback when - // available. There is no garuntee the callback will ever be called. - boost::signals2::connection get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback); - - // Convenience method for looking up a group name, so you can - // tell the difference between avatar lookup and group lookup - // in global searches - boost::signals2::connection getGroup(const LLUUID& group_id, const LLCacheNameCallback& callback); - - // LEGACY - boost::signals2::connection get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data); - // This method needs to be called from time to time to send out - // requests. - void processPending(); - - // Expire entries created more than "secs" seconds ago. - void deleteEntriesOlderThan(S32 secs); - - // Debugging - void dump(); // Dumps the contents of the cache - void dumpStats(); // Dumps the sizes of the cache and associated queues. - void clear(); // Deletes all entries from the cache - - static std::string getDefaultName(); - - // Returns "Resident", the default last name for SLID-based accounts - // that have no last name. - static std::string getDefaultLastName(); - - static void localizeCacheName(std::string key, std::string value); - static std::map<std::string, std::string> sCacheName; + LLCacheName(LLMessageSystem* msg); + LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host); + ~LLCacheName(); + + // registers the upstream host + // for viewers, this is the currently connected simulator + // for simulators, this is the data server + void setUpstream(const LLHost& upstream_host); + + boost::signals2::connection addObserver(const LLCacheNameCallback& callback); + + // storing cache on disk; for viewer, in name.cache + bool importFile(std::istream& istr); + void exportFile(std::ostream& ostr); + + // If available, copies name ("bobsmith123" or "James Linden") into string + // If not available, copies the string "waiting". + // Returns true if available. + bool getFullName(const LLUUID& id, std::string& full_name); + + // Reverse lookup of UUID from name + bool getUUID(const std::string& first, const std::string& last, LLUUID& id); + bool getUUID(const std::string& fullname, LLUUID& id); + + // IDEVO Temporary code + // Clean up new-style "bobsmith123 Resident" names to "bobsmith123" for display + static std::string buildFullName(const std::string& first, const std::string& last); + + // Clean up legacy "bobsmith123 Resident" to "bobsmith123" + // If name does not contain "Resident" returns it unchanged. + static std::string cleanFullName(const std::string& full_name); + + // Converts a standard legacy name to a username + // "bobsmith123 Resident" -> "bobsmith" + // "Random Linden" -> "random.linden" + static std::string buildUsername(const std::string& name); + + // Converts a complete display name to a legacy name + // if possible, otherwise returns the input + // "Alias (random.linden)" -> "Random Linden" + // "Something random" -> "Something random" + static std::string buildLegacyName(const std::string& name); + + // If available, this method copies the group name into the string + // provided. The caller must allocate at least + // DB_GROUP_NAME_BUF_SIZE characters. If not available, this + // method copies the string "waiting". Returns true if available. + bool getGroupName(const LLUUID& id, std::string& group); + + // Call the callback with the group or avatar name. + // If the data is currently available, may call the callback immediatly + // otherwise, will request the data, and will call the callback when + // available. There is no garuntee the callback will ever be called. + boost::signals2::connection get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback); + + // Convenience method for looking up a group name, so you can + // tell the difference between avatar lookup and group lookup + // in global searches + boost::signals2::connection getGroup(const LLUUID& group_id, const LLCacheNameCallback& callback); + + // LEGACY + boost::signals2::connection get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data); + // This method needs to be called from time to time to send out + // requests. + void processPending(); + + // Expire entries created more than "secs" seconds ago. + void deleteEntriesOlderThan(S32 secs); + + // Debugging + void dump(); // Dumps the contents of the cache + void dumpStats(); // Dumps the sizes of the cache and associated queues. + void clear(); // Deletes all entries from the cache + + static std::string getDefaultName(); + + // Returns "Resident", the default last name for SLID-based accounts + // that have no last name. + static std::string getDefaultLastName(); + + static void localizeCacheName(std::string key, std::string value); + static std::map<std::string, std::string> sCacheName; private: - class Impl; - Impl& impl; + class Impl; + Impl& impl; }; diff --git a/indra/llmessage/llchainio.cpp b/indra/llmessage/llchainio.cpp index bcda6746a1..78dff246cb 100644 --- a/indra/llmessage/llchainio.cpp +++ b/indra/llmessage/llchainio.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llchainio.cpp * @author Phoenix * @date 2005-08-04 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,20 +38,20 @@ */ // static bool LLDeferredChain::addToPump( - LLPumpIO* pump, - F32 in_seconds, - const LLPumpIO::chain_t& deferred_chain, - F32 chain_timeout) + LLPumpIO* pump, + F32 in_seconds, + const LLPumpIO::chain_t& deferred_chain, + F32 chain_timeout) { - if(!pump) return false; - LLPumpIO::chain_t sleep_chain; - sleep_chain.push_back(LLIOPipe::ptr_t(new LLIOSleep(in_seconds))); - sleep_chain.push_back( - LLIOPipe::ptr_t(new LLIOAddChain(deferred_chain, chain_timeout))); + if(!pump) return false; + LLPumpIO::chain_t sleep_chain; + sleep_chain.push_back(LLIOPipe::ptr_t(new LLIOSleep(in_seconds))); + sleep_chain.push_back( + LLIOPipe::ptr_t(new LLIOAddChain(deferred_chain, chain_timeout))); - // give it a litle bit of padding. - pump->addChain(sleep_chain, in_seconds + 10.0f); - return true; + // give it a litle bit of padding. + pump->addChain(sleep_chain, in_seconds + 10.0f); + return true; } /** @@ -69,20 +69,20 @@ LLChainIOFactory::~LLChainIOFactory() #if 0 bool LLChainIOFactory::build(LLIOPipe* in, LLIOPipe* out) const { - if(!in || !out) - { - return false; - } - LLIOPipe* first = NULL; - LLIOPipe* last = NULL; - if(build_impl(first, last) && first && last) - { - in->connect(first); - last->connect(out); - return true; - } - LLIOPipe::ptr_t foo(first); - LLIOPipe::ptr_t bar(last); - return false; + if(!in || !out) + { + return false; + } + LLIOPipe* first = NULL; + LLIOPipe* last = NULL; + if(build_impl(first, last) && first && last) + { + in->connect(first); + last->connect(out); + return true; + } + LLIOPipe::ptr_t foo(first); + LLIOPipe::ptr_t bar(last); + return false; } #endif diff --git a/indra/llmessage/llchainio.h b/indra/llmessage/llchainio.h index 6e4d6c2013..3f12189214 100644 --- a/indra/llmessage/llchainio.h +++ b/indra/llmessage/llchainio.h @@ -1,4 +1,4 @@ -/** +/** * @file llchainio.h * @author Phoenix * @date 2005-08-04 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,7 +31,7 @@ #include "llpumpio.h" -/** +/** * @class LLDeferredChain * @brief This class allows easy addition of a chain which will sleep * and then process another chain. @@ -39,23 +39,23 @@ class LLDeferredChain { public: - /** - * @brief Add a chain to a pump in a finite # of seconds - * - * @prarm pump The pump to work on. - * @prarm in_seconds The number of seconds from now when chain should start. - * @prarm chain The chain to add in in_seconds seconds. - * @prarm chain_timeout timeout for chain on the pump. - * @return Returns true if the operation was queued. - */ - static bool addToPump( - LLPumpIO* pump, - F32 in_seconds, - const LLPumpIO::chain_t& chain, - F32 chain_timeout); + /** + * @brief Add a chain to a pump in a finite # of seconds + * + * @prarm pump The pump to work on. + * @prarm in_seconds The number of seconds from now when chain should start. + * @prarm chain The chain to add in in_seconds seconds. + * @prarm chain_timeout timeout for chain on the pump. + * @return Returns true if the operation was queued. + */ + static bool addToPump( + LLPumpIO* pump, + F32 in_seconds, + const LLPumpIO::chain_t& chain, + F32 chain_timeout); }; -/** +/** * @class LLChainIOFactory * @brief This class is an abstract base class for building io chains. * @@ -71,29 +71,29 @@ public: class LLChainIOFactory { public: - // Constructor - LLChainIOFactory(); + // Constructor + LLChainIOFactory(); - // Destructor - virtual ~LLChainIOFactory(); + // Destructor + virtual ~LLChainIOFactory(); - /** - * @brief Build the chian with in as the first and end as the last - * - * The caller of the LLChainIOFactory is responsible for managing - * the memory of the in pipe. All of the chains generated by the - * factory will be ref counted as usual, so the caller will also - * need to break the links in the chain. - * @param chain The chain which will have new pipes appended - * @param context A context for use by this factory if you choose - * @retrun Returns true if the call was successful. - */ - virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const = 0; + /** + * @brief Build the chian with in as the first and end as the last + * + * The caller of the LLChainIOFactory is responsible for managing + * the memory of the in pipe. All of the chains generated by the + * factory will be ref counted as usual, so the caller will also + * need to break the links in the chain. + * @param chain The chain which will have new pipes appended + * @param context A context for use by this factory if you choose + * @retrun Returns true if the call was successful. + */ + virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const = 0; protected: }; -/** +/** * @class LLSimpleIOFactory * @brief Basic implementation for making a factory that returns a * 'chain' of one object @@ -102,14 +102,14 @@ template<class Pipe> class LLSimpleIOFactory : public LLChainIOFactory { public: - virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const - { - chain.push_back(LLIOPipe::ptr_t(new Pipe)); - return true; - } + virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const + { + chain.push_back(LLIOPipe::ptr_t(new Pipe)); + return true; + } }; -/** +/** * @class LLCloneIOFactory * @brief Implementation for a facory which copies a particular pipe. */ @@ -117,19 +117,19 @@ template<class Pipe> class LLCloneIOFactory : public LLChainIOFactory { public: - LLCloneIOFactory(Pipe* original) : - mHandle(original), - mOriginal(original) {} + LLCloneIOFactory(Pipe* original) : + mHandle(original), + mOriginal(original) {} - virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const - { - chain.push_back(LLIOPipe::ptr_t(new Pipe(*mOriginal))); - return true; - } + virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const + { + chain.push_back(LLIOPipe::ptr_t(new Pipe(*mOriginal))); + return true; + } protected: - LLIOPipe::ptr_t mHandle; - Pipe* mOriginal; + LLIOPipe::ptr_t mHandle; + Pipe* mOriginal; }; #endif // LL_LLCHAINIO_H diff --git a/indra/llmessage/llcipher.h b/indra/llmessage/llcipher.h index b3f142c001..bbd7eae1d5 100644 --- a/indra/llmessage/llcipher.h +++ b/indra/llmessage/llcipher.h @@ -1,25 +1,25 @@ -/** +/** * @file llcipher.h * @brief Abstract base class for encryption ciphers. * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,21 +36,21 @@ class LLCipher { public: - virtual ~LLCipher() {} + virtual ~LLCipher() {} - // encrypt src and place result into dst. returns true if - // Returns number of bytes written into dst, or 0 on error. - virtual U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) = 0; + // encrypt src and place result into dst. returns true if + // Returns number of bytes written into dst, or 0 on error. + virtual U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) = 0; - // decrypt src and place result into dst. - // Returns number of bytes written into dst, or 0 on error. - virtual U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) = 0; + // decrypt src and place result into dst. + // Returns number of bytes written into dst, or 0 on error. + virtual U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) = 0; - // returns the minimum amount of space required to encrypt for a - // unencrypted source buffer of length len. - // *NOTE: This is estimated space and you should check the return value - // of the encrypt function. - virtual U32 requiredEncryptionSpace(U32 src_len) const = 0 ; + // returns the minimum amount of space required to encrypt for a + // unencrypted source buffer of length len. + // *NOTE: This is estimated space and you should check the return value + // of the encrypt function. + virtual U32 requiredEncryptionSpace(U32 src_len) const = 0 ; }; #endif diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp index a0bf999dee..fa206d9282 100644 --- a/indra/llmessage/llcircuit.cpp +++ b/indra/llmessage/llcircuit.cpp @@ -1,31 +1,31 @@ -/** +/** * @file llcircuit.cpp * @brief Class to track UDP endpoints for the message system. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "linden_common.h" - + #if LL_WINDOWS #include <process.h> @@ -33,7 +33,7 @@ #else #if LL_LINUX -#include <dlfcn.h> // RTLD_LAZY +#include <dlfcn.h> // RTLD_LAZY #endif #include <sys/types.h> #include <sys/socket.h> @@ -57,1363 +57,1363 @@ #include "lltransfermanager.h" #include "llmodularmath.h" -const S32 PING_START_BLOCK = 3; // How many pings behind we have to be to consider ourself blocked. -const S32 PING_RELEASE_BLOCK = 2; // How many pings behind we have to be to consider ourself unblocked. +const S32 PING_START_BLOCK = 3; // How many pings behind we have to be to consider ourself blocked. +const S32 PING_RELEASE_BLOCK = 2; // How many pings behind we have to be to consider ourself unblocked. const F32Seconds TARGET_PERIOD_LENGTH(5.f); const F32Seconds LL_DUPLICATE_SUPPRESSION_TIMEOUT(60.f); //this can be long, as time-based cleanup is - // only done when wrapping packetids, now... - -LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id, - const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout) -: mHost (host), - mWrapID(0), - mPacketsOutID(0), - mPacketsInID(in_id), - mHighestPacketID(in_id), - mTimeoutCallback(NULL), - mTimeoutUserData(NULL), - mTrusted(false), - mbAllowTimeout(true), - mbAlive(true), - mBlocked(false), - mPingTime(0.0), - mLastPingSendTime(0.0), - mLastPingReceivedTime(0.0), - mNextPingSendTime(0.0), - mPingsInTransit(0), - mLastPingID(0), - mPingDelay(INITIAL_PING_VALUE_MSEC), - mPingDelayAveraged(INITIAL_PING_VALUE_MSEC), - mUnackedPacketCount(0), - mUnackedPacketBytes(0), - mLastPacketInTime(0.0), - mLocalEndPointID(), - mPacketsOut(0), - mPacketsIn(0), - mPacketsLost(0), - mBytesIn(0), - mBytesOut(0), - mLastPeriodLength(-1.f), - mBytesInLastPeriod(0), - mBytesOutLastPeriod(0), - mBytesInThisPeriod(0), - mBytesOutThisPeriod(0), - mPeakBPSIn(0.f), - mPeakBPSOut(0.f), - mPeriodTime(0.0), - mExistenceTimer(), - mAckCreationTime(0.f), - mCurrentResendCount(0), - mLastPacketGap(0), - mHeartbeatInterval(circuit_heartbeat_interval), - mHeartbeatTimeout(circuit_timeout) + // only done when wrapping packetids, now... + +LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id, + const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout) +: mHost (host), + mWrapID(0), + mPacketsOutID(0), + mPacketsInID(in_id), + mHighestPacketID(in_id), + mTimeoutCallback(NULL), + mTimeoutUserData(NULL), + mTrusted(false), + mbAllowTimeout(true), + mbAlive(true), + mBlocked(false), + mPingTime(0.0), + mLastPingSendTime(0.0), + mLastPingReceivedTime(0.0), + mNextPingSendTime(0.0), + mPingsInTransit(0), + mLastPingID(0), + mPingDelay(INITIAL_PING_VALUE_MSEC), + mPingDelayAveraged(INITIAL_PING_VALUE_MSEC), + mUnackedPacketCount(0), + mUnackedPacketBytes(0), + mLastPacketInTime(0.0), + mLocalEndPointID(), + mPacketsOut(0), + mPacketsIn(0), + mPacketsLost(0), + mBytesIn(0), + mBytesOut(0), + mLastPeriodLength(-1.f), + mBytesInLastPeriod(0), + mBytesOutLastPeriod(0), + mBytesInThisPeriod(0), + mBytesOutThisPeriod(0), + mPeakBPSIn(0.f), + mPeakBPSOut(0.f), + mPeriodTime(0.0), + mExistenceTimer(), + mAckCreationTime(0.f), + mCurrentResendCount(0), + mLastPacketGap(0), + mHeartbeatInterval(circuit_heartbeat_interval), + mHeartbeatTimeout(circuit_timeout) { - // Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been - // running a message system loop. - F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(true); - F32 distribution_offset = ll_frand(); - - mPingTime = mt_sec; - mLastPingSendTime = mt_sec + mHeartbeatInterval * distribution_offset; - mLastPingReceivedTime = mt_sec; - mNextPingSendTime = mLastPingSendTime + 0.95*mHeartbeatInterval + F32Seconds(ll_frand(0.1f*mHeartbeatInterval.value())); - mPeriodTime = mt_sec; - - mLocalEndPointID.generate(); + // Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been + // running a message system loop. + F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(true); + F32 distribution_offset = ll_frand(); + + mPingTime = mt_sec; + mLastPingSendTime = mt_sec + mHeartbeatInterval * distribution_offset; + mLastPingReceivedTime = mt_sec; + mNextPingSendTime = mLastPingSendTime + 0.95*mHeartbeatInterval + F32Seconds(ll_frand(0.1f*mHeartbeatInterval.value())); + mPeriodTime = mt_sec; + + mLocalEndPointID.generate(); } LLCircuitData::~LLCircuitData() { - LLReliablePacket *packetp = NULL; - - // Clean up all pending transfers. - gTransferManager.cleanupConnection(mHost); - - // remove all pending reliable messages on this circuit - std::vector<TPACKETID> doomed; - reliable_iter iter; - reliable_iter end = mUnackedPackets.end(); - for(iter = mUnackedPackets.begin(); iter != end; ++iter) - { - packetp = iter->second; - gMessageSystem->mFailedResendPackets++; - if(gMessageSystem->mVerboseLog) - { - doomed.push_back(packetp->mPacketID); - } - if (packetp->mCallback) - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_CIRCUIT_GONE); - } - - // Update stats - mUnackedPacketCount--; - mUnackedPacketBytes -= packetp->mBufferLength; - - delete packetp; - } - - // remove all pending final retry reliable messages on this circuit - end = mFinalRetryPackets.end(); - for(iter = mFinalRetryPackets.begin(); iter != end; ++iter) - { - packetp = iter->second; - gMessageSystem->mFailedResendPackets++; - if(gMessageSystem->mVerboseLog) - { - doomed.push_back(packetp->mPacketID); - } - if (packetp->mCallback) - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_CIRCUIT_GONE); - } - - // Update stats - mUnackedPacketCount--; - mUnackedPacketBytes -= packetp->mBufferLength; - - delete packetp; - } - - // log aborted reliable packets for this circuit. - if(gMessageSystem->mVerboseLog && !doomed.empty()) - { - std::ostringstream str; - std::ostream_iterator<TPACKETID> append(str, " "); - str << "MSG: -> " << mHost << "\tABORTING RELIABLE:\t"; - std::copy(doomed.begin(), doomed.end(), append); - LL_INFOS() << str.str() << LL_ENDL; - } + LLReliablePacket *packetp = NULL; + + // Clean up all pending transfers. + gTransferManager.cleanupConnection(mHost); + + // remove all pending reliable messages on this circuit + std::vector<TPACKETID> doomed; + reliable_iter iter; + reliable_iter end = mUnackedPackets.end(); + for(iter = mUnackedPackets.begin(); iter != end; ++iter) + { + packetp = iter->second; + gMessageSystem->mFailedResendPackets++; + if(gMessageSystem->mVerboseLog) + { + doomed.push_back(packetp->mPacketID); + } + if (packetp->mCallback) + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_CIRCUIT_GONE); + } + + // Update stats + mUnackedPacketCount--; + mUnackedPacketBytes -= packetp->mBufferLength; + + delete packetp; + } + + // remove all pending final retry reliable messages on this circuit + end = mFinalRetryPackets.end(); + for(iter = mFinalRetryPackets.begin(); iter != end; ++iter) + { + packetp = iter->second; + gMessageSystem->mFailedResendPackets++; + if(gMessageSystem->mVerboseLog) + { + doomed.push_back(packetp->mPacketID); + } + if (packetp->mCallback) + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_CIRCUIT_GONE); + } + + // Update stats + mUnackedPacketCount--; + mUnackedPacketBytes -= packetp->mBufferLength; + + delete packetp; + } + + // log aborted reliable packets for this circuit. + if(gMessageSystem->mVerboseLog && !doomed.empty()) + { + std::ostringstream str; + std::ostream_iterator<TPACKETID> append(str, " "); + str << "MSG: -> " << mHost << "\tABORTING RELIABLE:\t"; + std::copy(doomed.begin(), doomed.end(), append); + LL_INFOS() << str.str() << LL_ENDL; + } } void LLCircuitData::ackReliablePacket(TPACKETID packet_num) { - reliable_iter iter; - LLReliablePacket *packetp; - - iter = mUnackedPackets.find(packet_num); - if (iter != mUnackedPackets.end()) - { - packetp = iter->second; - - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << packetp->mHost << "\tRELIABLE ACKED:\t" - << packetp->mPacketID; - LL_INFOS() << str.str() << LL_ENDL; - } - if (packetp->mCallback) - { - if (packetp->mTimeout < F32Seconds(0.f)) // negative timeout will always return timeout even for successful ack, for debugging - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT); - } - else - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_NOERR); - } - } - - // Update stats - mUnackedPacketCount--; - mUnackedPacketBytes -= packetp->mBufferLength; - - // Cleanup - delete packetp; - mUnackedPackets.erase(iter); - return; - } - - iter = mFinalRetryPackets.find(packet_num); - if (iter != mFinalRetryPackets.end()) - { - packetp = iter->second; - // LL_INFOS() << "Packet " << packet_num << " removed from the pending list" << LL_ENDL; - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << packetp->mHost << "\tRELIABLE ACKED:\t" - << packetp->mPacketID; - LL_INFOS() << str.str() << LL_ENDL; - } - if (packetp->mCallback) - { - if (packetp->mTimeout < F32Seconds(0.f)) // negative timeout will always return timeout even for successful ack, for debugging - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT); - } - else - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_NOERR); - } - } - - // Update stats - mUnackedPacketCount--; - mUnackedPacketBytes -= packetp->mBufferLength; - - // Cleanup - delete packetp; - mFinalRetryPackets.erase(iter); - } - else - { - // Couldn't find this packet on either of the unacked lists. - // maybe it's a duplicate ack? - } + reliable_iter iter; + LLReliablePacket *packetp; + + iter = mUnackedPackets.find(packet_num); + if (iter != mUnackedPackets.end()) + { + packetp = iter->second; + + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << packetp->mHost << "\tRELIABLE ACKED:\t" + << packetp->mPacketID; + LL_INFOS() << str.str() << LL_ENDL; + } + if (packetp->mCallback) + { + if (packetp->mTimeout < F32Seconds(0.f)) // negative timeout will always return timeout even for successful ack, for debugging + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT); + } + else + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_NOERR); + } + } + + // Update stats + mUnackedPacketCount--; + mUnackedPacketBytes -= packetp->mBufferLength; + + // Cleanup + delete packetp; + mUnackedPackets.erase(iter); + return; + } + + iter = mFinalRetryPackets.find(packet_num); + if (iter != mFinalRetryPackets.end()) + { + packetp = iter->second; + // LL_INFOS() << "Packet " << packet_num << " removed from the pending list" << LL_ENDL; + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << packetp->mHost << "\tRELIABLE ACKED:\t" + << packetp->mPacketID; + LL_INFOS() << str.str() << LL_ENDL; + } + if (packetp->mCallback) + { + if (packetp->mTimeout < F32Seconds(0.f)) // negative timeout will always return timeout even for successful ack, for debugging + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT); + } + else + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_NOERR); + } + } + + // Update stats + mUnackedPacketCount--; + mUnackedPacketBytes -= packetp->mBufferLength; + + // Cleanup + delete packetp; + mFinalRetryPackets.erase(iter); + } + else + { + // Couldn't find this packet on either of the unacked lists. + // maybe it's a duplicate ack? + } } S32 LLCircuitData::resendUnackedPackets(const F64Seconds now) { - LLReliablePacket *packetp; - - - // - // Theoretically we should search through the list for the packet with the oldest - // packet ID, as otherwise when we WRAP we will resend reliable packets out of order. - // Since resends are ALREADY out of order, and wrapping is highly rare (16+million packets), - // I'm not going to worry about this for now - djs - // - - reliable_iter iter; - bool have_resend_overflow = false; - for (iter = mUnackedPackets.begin(); iter != mUnackedPackets.end();) - { - packetp = iter->second; - - // Only check overflow if we haven't had one yet. - if (!have_resend_overflow) - { - have_resend_overflow = mThrottles.checkOverflow(TC_RESEND, 0); - } - - if (have_resend_overflow) - { - // We've exceeded our bandwidth for resends. - // Time to stop trying to send them. - - // If we have too many unacked packets, we need to start dropping expired ones. - if (mUnackedPacketBytes > 512000) - { - if (now > packetp->mExpirationTime) - { - // This circuit has overflowed. Do not retry. Do not pass go. - packetp->mRetries = 0; - // Remove it from this list and add it to the final list. - mUnackedPackets.erase(iter++); - mFinalRetryPackets[packetp->mPacketID] = packetp; - } - else - { - ++iter; - } - // Move on to the next unacked packet. - continue; - } - - if (mUnackedPacketBytes > 256000 && !(getPacketsOut() % 1024)) - { - // Warn if we've got a lot of resends waiting. - LL_WARNS() << mHost << " has " << mUnackedPacketBytes - << " bytes of reliable messages waiting" << LL_ENDL; - } - // Stop resending. There are less than 512000 unacked packets. - break; - } - - if (now > packetp->mExpirationTime) - { - packetp->mRetries--; - - // retry - mCurrentResendCount++; - - gMessageSystem->mResentPackets++; - - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: -> " << packetp->mHost - << "\tRESENDING RELIABLE:\t" << packetp->mPacketID; - LL_INFOS() << str.str() << LL_ENDL; - } - - packetp->mBuffer[0] |= LL_RESENT_FLAG; // tag packet id as being a resend - - gMessageSystem->mPacketRing.sendPacket(packetp->mSocket, - (char *)packetp->mBuffer, packetp->mBufferLength, - packetp->mHost); - - mThrottles.throttleOverflow(TC_RESEND, packetp->mBufferLength * 8.f); - - // The new method, retry time based on ping - if (packetp->mPingBasedRetry) - { - packetp->mExpirationTime = now + llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, F32Seconds(LL_RELIABLE_TIMEOUT_FACTOR * getPingDelayAveraged())); - } - else - { - // custom, constant retry time - packetp->mExpirationTime = now + packetp->mTimeout; - } - - if (!packetp->mRetries) - { - // Last resend, remove it from this list and add it to the final list. - mUnackedPackets.erase(iter++); - mFinalRetryPackets[packetp->mPacketID] = packetp; - } - else - { - // Don't remove it yet, it still gets to try to resend at least once. - ++iter; - } - } - else - { - // Don't need to do anything with this packet, keep iterating. - ++iter; - } - } - - - for (iter = mFinalRetryPackets.begin(); iter != mFinalRetryPackets.end();) - { - packetp = iter->second; - if (now > packetp->mExpirationTime) - { - // fail (too many retries) - //LL_INFOS() << "Packet " << packetp->mPacketID << " removed from the pending list: exceeded retry limit" << LL_ENDL; - //if (packetp->mMessageName) - //{ - // LL_INFOS() << "Packet name " << packetp->mMessageName << LL_ENDL; - //} - gMessageSystem->mFailedResendPackets++; - - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: -> " << packetp->mHost << "\tABORTING RELIABLE:\t" - << packetp->mPacketID; - LL_INFOS() << str.str() << LL_ENDL; - } - - if (packetp->mCallback) - { - packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT); - } - - // Update stats - mUnackedPacketCount--; - mUnackedPacketBytes -= packetp->mBufferLength; - - mFinalRetryPackets.erase(iter++); - delete packetp; - } - else - { - ++iter; - } - } - - return mUnackedPacketCount; + LLReliablePacket *packetp; + + + // + // Theoretically we should search through the list for the packet with the oldest + // packet ID, as otherwise when we WRAP we will resend reliable packets out of order. + // Since resends are ALREADY out of order, and wrapping is highly rare (16+million packets), + // I'm not going to worry about this for now - djs + // + + reliable_iter iter; + bool have_resend_overflow = false; + for (iter = mUnackedPackets.begin(); iter != mUnackedPackets.end();) + { + packetp = iter->second; + + // Only check overflow if we haven't had one yet. + if (!have_resend_overflow) + { + have_resend_overflow = mThrottles.checkOverflow(TC_RESEND, 0); + } + + if (have_resend_overflow) + { + // We've exceeded our bandwidth for resends. + // Time to stop trying to send them. + + // If we have too many unacked packets, we need to start dropping expired ones. + if (mUnackedPacketBytes > 512000) + { + if (now > packetp->mExpirationTime) + { + // This circuit has overflowed. Do not retry. Do not pass go. + packetp->mRetries = 0; + // Remove it from this list and add it to the final list. + mUnackedPackets.erase(iter++); + mFinalRetryPackets[packetp->mPacketID] = packetp; + } + else + { + ++iter; + } + // Move on to the next unacked packet. + continue; + } + + if (mUnackedPacketBytes > 256000 && !(getPacketsOut() % 1024)) + { + // Warn if we've got a lot of resends waiting. + LL_WARNS() << mHost << " has " << mUnackedPacketBytes + << " bytes of reliable messages waiting" << LL_ENDL; + } + // Stop resending. There are less than 512000 unacked packets. + break; + } + + if (now > packetp->mExpirationTime) + { + packetp->mRetries--; + + // retry + mCurrentResendCount++; + + gMessageSystem->mResentPackets++; + + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: -> " << packetp->mHost + << "\tRESENDING RELIABLE:\t" << packetp->mPacketID; + LL_INFOS() << str.str() << LL_ENDL; + } + + packetp->mBuffer[0] |= LL_RESENT_FLAG; // tag packet id as being a resend + + gMessageSystem->mPacketRing.sendPacket(packetp->mSocket, + (char *)packetp->mBuffer, packetp->mBufferLength, + packetp->mHost); + + mThrottles.throttleOverflow(TC_RESEND, packetp->mBufferLength * 8.f); + + // The new method, retry time based on ping + if (packetp->mPingBasedRetry) + { + packetp->mExpirationTime = now + llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, F32Seconds(LL_RELIABLE_TIMEOUT_FACTOR * getPingDelayAveraged())); + } + else + { + // custom, constant retry time + packetp->mExpirationTime = now + packetp->mTimeout; + } + + if (!packetp->mRetries) + { + // Last resend, remove it from this list and add it to the final list. + mUnackedPackets.erase(iter++); + mFinalRetryPackets[packetp->mPacketID] = packetp; + } + else + { + // Don't remove it yet, it still gets to try to resend at least once. + ++iter; + } + } + else + { + // Don't need to do anything with this packet, keep iterating. + ++iter; + } + } + + + for (iter = mFinalRetryPackets.begin(); iter != mFinalRetryPackets.end();) + { + packetp = iter->second; + if (now > packetp->mExpirationTime) + { + // fail (too many retries) + //LL_INFOS() << "Packet " << packetp->mPacketID << " removed from the pending list: exceeded retry limit" << LL_ENDL; + //if (packetp->mMessageName) + //{ + // LL_INFOS() << "Packet name " << packetp->mMessageName << LL_ENDL; + //} + gMessageSystem->mFailedResendPackets++; + + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: -> " << packetp->mHost << "\tABORTING RELIABLE:\t" + << packetp->mPacketID; + LL_INFOS() << str.str() << LL_ENDL; + } + + if (packetp->mCallback) + { + packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT); + } + + // Update stats + mUnackedPacketCount--; + mUnackedPacketBytes -= packetp->mBufferLength; + + mFinalRetryPackets.erase(iter++); + delete packetp; + } + else + { + ++iter; + } + } + + return mUnackedPacketCount; } -LLCircuit::LLCircuit(const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout) -: mLastCircuit(NULL), - mHeartbeatInterval(circuit_heartbeat_interval), - mHeartbeatTimeout(circuit_timeout) +LLCircuit::LLCircuit(const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout) +: mLastCircuit(NULL), + mHeartbeatInterval(circuit_heartbeat_interval), + mHeartbeatTimeout(circuit_timeout) {} LLCircuit::~LLCircuit() { - // delete pointers in the map. - std::for_each(mCircuitData.begin(), - mCircuitData.end(), - llcompose1( - DeletePointerFunctor<LLCircuitData>(), - llselect2nd<circuit_data_map::value_type>())); + // delete pointers in the map. + std::for_each(mCircuitData.begin(), + mCircuitData.end(), + llcompose1( + DeletePointerFunctor<LLCircuitData>(), + llselect2nd<circuit_data_map::value_type>())); } LLCircuitData *LLCircuit::addCircuitData(const LLHost &host, TPACKETID in_id) { - // This should really validate if one already exists - LL_INFOS() << "LLCircuit::addCircuitData for " << host << LL_ENDL; - LLCircuitData *tempp = new LLCircuitData(host, in_id, mHeartbeatInterval, mHeartbeatTimeout); - mCircuitData.insert(circuit_data_map::value_type(host, tempp)); - mPingSet.insert(tempp); - - mLastCircuit = tempp; - return tempp; + // This should really validate if one already exists + LL_INFOS() << "LLCircuit::addCircuitData for " << host << LL_ENDL; + LLCircuitData *tempp = new LLCircuitData(host, in_id, mHeartbeatInterval, mHeartbeatTimeout); + mCircuitData.insert(circuit_data_map::value_type(host, tempp)); + mPingSet.insert(tempp); + + mLastCircuit = tempp; + return tempp; } void LLCircuit::removeCircuitData(const LLHost &host) { - LL_INFOS() << "LLCircuit::removeCircuitData for " << host << LL_ENDL; - mLastCircuit = NULL; - circuit_data_map::iterator it = mCircuitData.find(host); - if(it != mCircuitData.end()) - { - LLCircuitData *cdp = it->second; - mCircuitData.erase(it); - - LLCircuit::ping_set_t::iterator psit = mPingSet.find(cdp); - if (psit != mPingSet.end()) + LL_INFOS() << "LLCircuit::removeCircuitData for " << host << LL_ENDL; + mLastCircuit = NULL; + circuit_data_map::iterator it = mCircuitData.find(host); + if(it != mCircuitData.end()) + { + LLCircuitData *cdp = it->second; + mCircuitData.erase(it); + + LLCircuit::ping_set_t::iterator psit = mPingSet.find(cdp); + if (psit != mPingSet.end()) + { + mPingSet.erase(psit); + } + else { - mPingSet.erase(psit); - } - else - { - LL_WARNS() << "Couldn't find entry for next ping in ping set!" << LL_ENDL; - } - - // Clean up from optimization maps - mUnackedCircuitMap.erase(host); - mSendAckMap.erase(host); - delete cdp; - } - - // This also has to happen AFTER we nuke the circuit, because various - // callbacks for the circuit may result in messages being sent to - // this circuit, and the setting of mLastCircuit. We don't check - // if the host matches, but we don't really care because mLastCircuit - // is an optimization, and this happens VERY rarely. - mLastCircuit = NULL; + LL_WARNS() << "Couldn't find entry for next ping in ping set!" << LL_ENDL; + } + + // Clean up from optimization maps + mUnackedCircuitMap.erase(host); + mSendAckMap.erase(host); + delete cdp; + } + + // This also has to happen AFTER we nuke the circuit, because various + // callbacks for the circuit may result in messages being sent to + // this circuit, and the setting of mLastCircuit. We don't check + // if the host matches, but we don't really care because mLastCircuit + // is an optimization, and this happens VERY rarely. + mLastCircuit = NULL; } void LLCircuitData::setAlive(bool b_alive) { - if (mbAlive != b_alive) - { - mPacketsOutID = 0; - mPacketsInID = 0; - mbAlive = b_alive; - } - if (b_alive) - { - mLastPingReceivedTime = LLMessageSystem::getMessageTimeSeconds(); - mPingsInTransit = 0; - mBlocked = false; - } + if (mbAlive != b_alive) + { + mPacketsOutID = 0; + mPacketsInID = 0; + mbAlive = b_alive; + } + if (b_alive) + { + mLastPingReceivedTime = LLMessageSystem::getMessageTimeSeconds(); + mPingsInTransit = 0; + mBlocked = false; + } } void LLCircuitData::setAllowTimeout(bool allow) { - mbAllowTimeout = allow; - - if (allow) - { - // resuming circuit - // make sure it's alive - setAlive(true); - } + mbAllowTimeout = allow; + + if (allow) + { + // resuming circuit + // make sure it's alive + setAlive(true); + } } // Reset per-period counters if necessary. void LLCircuitData::checkPeriodTime() { - F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); - F64Seconds period_length = mt_sec - mPeriodTime; - if ( period_length > TARGET_PERIOD_LENGTH) - { - F32 bps_in = F32Bits(mBytesInThisPeriod).value() / period_length.value(); - if (bps_in > mPeakBPSIn) - { - mPeakBPSIn = bps_in; - } - - F32 bps_out = F32Bits(mBytesOutThisPeriod).value() / period_length.value(); - if (bps_out > mPeakBPSOut) - { - mPeakBPSOut = bps_out; - } - - mBytesInLastPeriod = mBytesInThisPeriod; - mBytesOutLastPeriod = mBytesOutThisPeriod; - mBytesInThisPeriod = S32Bytes(0); - mBytesOutThisPeriod = S32Bytes(0); - mLastPeriodLength = F32Seconds::convert(period_length); - - mPeriodTime = mt_sec; - } + F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); + F64Seconds period_length = mt_sec - mPeriodTime; + if ( period_length > TARGET_PERIOD_LENGTH) + { + F32 bps_in = F32Bits(mBytesInThisPeriod).value() / period_length.value(); + if (bps_in > mPeakBPSIn) + { + mPeakBPSIn = bps_in; + } + + F32 bps_out = F32Bits(mBytesOutThisPeriod).value() / period_length.value(); + if (bps_out > mPeakBPSOut) + { + mPeakBPSOut = bps_out; + } + + mBytesInLastPeriod = mBytesInThisPeriod; + mBytesOutLastPeriod = mBytesOutThisPeriod; + mBytesInThisPeriod = S32Bytes(0); + mBytesOutThisPeriod = S32Bytes(0); + mLastPeriodLength = F32Seconds::convert(period_length); + + mPeriodTime = mt_sec; + } } void LLCircuitData::addBytesIn(S32Bytes bytes) { - mBytesIn += bytes; - mBytesInThisPeriod += bytes; + mBytesIn += bytes; + mBytesInThisPeriod += bytes; } void LLCircuitData::addBytesOut(S32Bytes bytes) { - mBytesOut += bytes; - mBytesOutThisPeriod += bytes; + mBytesOut += bytes; + mBytesOutThisPeriod += bytes; } void LLCircuitData::addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params) { - LLReliablePacket *packet_info; + LLReliablePacket *packet_info; - packet_info = new LLReliablePacket(mSocket, buf_ptr, buf_len, params); + packet_info = new LLReliablePacket(mSocket, buf_ptr, buf_len, params); - mUnackedPacketCount++; - mUnackedPacketBytes += packet_info->mBufferLength; + mUnackedPacketCount++; + mUnackedPacketBytes += packet_info->mBufferLength; - if (params && params->mRetries) - { - mUnackedPackets[packet_info->mPacketID] = packet_info; - } - else - { - mFinalRetryPackets[packet_info->mPacketID] = packet_info; - } + if (params && params->mRetries) + { + mUnackedPackets[packet_info->mPacketID] = packet_info; + } + else + { + mFinalRetryPackets[packet_info->mPacketID] = packet_info; + } } void LLCircuit::resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size) { - F64Seconds now = LLMessageSystem::getMessageTimeSeconds(); - unacked_list_length = 0; - unacked_list_size = 0; - - LLCircuitData* circ; - circuit_data_map::iterator end = mUnackedCircuitMap.end(); - for(circuit_data_map::iterator it = mUnackedCircuitMap.begin(); it != end; ++it) - { - circ = (*it).second; - unacked_list_length += circ->resendUnackedPackets(now); - unacked_list_size += circ->getUnackedPacketBytes(); - } + F64Seconds now = LLMessageSystem::getMessageTimeSeconds(); + unacked_list_length = 0; + unacked_list_size = 0; + + LLCircuitData* circ; + circuit_data_map::iterator end = mUnackedCircuitMap.end(); + for(circuit_data_map::iterator it = mUnackedCircuitMap.begin(); it != end; ++it) + { + circ = (*it).second; + unacked_list_length += circ->resendUnackedPackets(now); + unacked_list_size += circ->getUnackedPacketBytes(); + } } bool LLCircuitData::isDuplicateResend(TPACKETID packetnum) { - return (mRecentlyReceivedReliablePackets.find(packetnum) != mRecentlyReceivedReliablePackets.end()); + return (mRecentlyReceivedReliablePackets.find(packetnum) != mRecentlyReceivedReliablePackets.end()); } void LLCircuit::dumpResends() { - circuit_data_map::iterator end = mCircuitData.end(); - for(circuit_data_map::iterator it = mCircuitData.begin(); it != end; ++it) - { - (*it).second->dumpResendCountAndReset(); - } + circuit_data_map::iterator end = mCircuitData.end(); + for(circuit_data_map::iterator it = mCircuitData.begin(); it != end; ++it) + { + (*it).second->dumpResendCountAndReset(); + } } LLCircuitData* LLCircuit::findCircuit(const LLHost& host) const { - // An optimization on finding the previously found circuit. - if (mLastCircuit && (mLastCircuit->mHost == host)) - { - return mLastCircuit; - } - - circuit_data_map::const_iterator it = mCircuitData.find(host); - if(it == mCircuitData.end()) - { - return NULL; - } - mLastCircuit = it->second; - return mLastCircuit; + // An optimization on finding the previously found circuit. + if (mLastCircuit && (mLastCircuit->mHost == host)) + { + return mLastCircuit; + } + + circuit_data_map::const_iterator it = mCircuitData.find(host); + if(it == mCircuitData.end()) + { + return NULL; + } + mLastCircuit = it->second; + return mLastCircuit; } bool LLCircuit::isCircuitAlive(const LLHost& host) const { - LLCircuitData *cdp = findCircuit(host); - if(cdp) - { - return cdp->mbAlive; - } + LLCircuitData *cdp = findCircuit(host); + if(cdp) + { + return cdp->mbAlive; + } - return false; + return false; } void LLCircuitData::setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data) { - mTimeoutCallback = callback_func; - mTimeoutUserData = user_data; + mTimeoutCallback = callback_func; + mTimeoutUserData = user_data; } void LLCircuitData::checkPacketInID(TPACKETID id, bool receive_resent) { - // Done as floats so we don't have to worry about running out of room - // with U32 getting poked into an S32. - F32 delta = (F32)mHighestPacketID - (F32)id; - if (delta > (0.5f*LL_MAX_OUT_PACKET_ID)) - { - // We've almost definitely wrapped, reset the mLastPacketID to be low again. - mHighestPacketID = id; - } - else if (delta < (-0.5f*LL_MAX_OUT_PACKET_ID)) - { - // This is almost definitely an old packet coming in after a wrap, ignore it. - } - else - { - mHighestPacketID = llmax(mHighestPacketID, id); - } - - // Save packet arrival time - mLastPacketInTime = LLMessageSystem::getMessageTimeSeconds(); - - // Have we received anything on this circuit yet? - if (0 == mPacketsIn) - { - // Must be first packet from unclosed circuit. - mPacketsIn++; - setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID); + // Done as floats so we don't have to worry about running out of room + // with U32 getting poked into an S32. + F32 delta = (F32)mHighestPacketID - (F32)id; + if (delta > (0.5f*LL_MAX_OUT_PACKET_ID)) + { + // We've almost definitely wrapped, reset the mLastPacketID to be low again. + mHighestPacketID = id; + } + else if (delta < (-0.5f*LL_MAX_OUT_PACKET_ID)) + { + // This is almost definitely an old packet coming in after a wrap, ignore it. + } + else + { + mHighestPacketID = llmax(mHighestPacketID, id); + } + + // Save packet arrival time + mLastPacketInTime = LLMessageSystem::getMessageTimeSeconds(); + + // Have we received anything on this circuit yet? + if (0 == mPacketsIn) + { + // Must be first packet from unclosed circuit. + mPacketsIn++; + setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID); mLastPacketGap = 0; - return; - } + return; + } - mPacketsIn++; + mPacketsIn++; - // now, check to see if we've got a gap + // now, check to see if we've got a gap U32 gap = 0; - if (mPacketsInID == id) - { - // nope! bump and wrap the counter, then return - mPacketsInID++; - mPacketsInID = (mPacketsInID) % LL_MAX_OUT_PACKET_ID; - } - else if (id < mWrapID) - { - // id < mWrapID will happen if the first few packets are out of order. . . - // at that point we haven't marked anything "potentially lost" and - // the out-of-order packet will cause a full wrap marking all the IDs "potentially lost" - - // do nothing - } - else - { - // we have a gap! if that id is in the map, remove it from the map, leave mCurrentCircuit->mPacketsInID - // alone - // otherwise, walk from mCurrentCircuit->mPacketsInID to id with wrapping, adding the values to the map - // and setting mPacketsInID to id + 1 % LL_MAX_OUT_PACKET_ID - - // babbage: all operands in expression are unsigned, so modular - // arithmetic will always find correct gap, regardless of wrap arounds. - const U8 width = 24; - gap = LLModularMath::subtract<width>(mPacketsInID, id); - - if (mPotentialLostPackets.find(id) != mPotentialLostPackets.end()) - { - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << mHost << "\tRECOVERING LOST:\t" << id; - LL_INFOS() << str.str() << LL_ENDL; - } - // LL_INFOS() << "removing potential lost: " << id << LL_ENDL; - mPotentialLostPackets.erase(id); - } - else if (!receive_resent) // don't freak out over out-of-order reliable resends - { - U64Microseconds time = LLMessageSystem::getMessageTimeUsecs(); - TPACKETID index = mPacketsInID; - S32 gap_count = 0; - if ((index < id) && ((id - index) < 16)) - { - while (index != id) - { - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << mHost << "\tPACKET GAP:\t" - << index; - LL_INFOS() << str.str() << LL_ENDL; - } - -// LL_INFOS() << "adding potential lost: " << index << LL_ENDL; - mPotentialLostPackets[index] = time; - index++; - index = index % LL_MAX_OUT_PACKET_ID; - gap_count++; - } - } - else - { - LL_INFOS() << "packet_out_of_order - got packet " << id << " expecting " << index << " from " << mHost << LL_ENDL; - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << mHost << "\tPACKET GAP:\t" - << id << " expected " << index; - LL_INFOS() << str.str() << LL_ENDL; - } - } - - mPacketsInID = id + 1; - mPacketsInID = (mPacketsInID) % LL_MAX_OUT_PACKET_ID; - - if (gap_count > 128) - { - LL_WARNS() << "Packet loss gap filler running amok!" << LL_ENDL; - } - else if (gap_count > 16) - { - LL_WARNS() << "Sustaining large amounts of packet loss!" << LL_ENDL; - } - - } - } + if (mPacketsInID == id) + { + // nope! bump and wrap the counter, then return + mPacketsInID++; + mPacketsInID = (mPacketsInID) % LL_MAX_OUT_PACKET_ID; + } + else if (id < mWrapID) + { + // id < mWrapID will happen if the first few packets are out of order. . . + // at that point we haven't marked anything "potentially lost" and + // the out-of-order packet will cause a full wrap marking all the IDs "potentially lost" + + // do nothing + } + else + { + // we have a gap! if that id is in the map, remove it from the map, leave mCurrentCircuit->mPacketsInID + // alone + // otherwise, walk from mCurrentCircuit->mPacketsInID to id with wrapping, adding the values to the map + // and setting mPacketsInID to id + 1 % LL_MAX_OUT_PACKET_ID + + // babbage: all operands in expression are unsigned, so modular + // arithmetic will always find correct gap, regardless of wrap arounds. + const U8 width = 24; + gap = LLModularMath::subtract<width>(mPacketsInID, id); + + if (mPotentialLostPackets.find(id) != mPotentialLostPackets.end()) + { + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << mHost << "\tRECOVERING LOST:\t" << id; + LL_INFOS() << str.str() << LL_ENDL; + } + // LL_INFOS() << "removing potential lost: " << id << LL_ENDL; + mPotentialLostPackets.erase(id); + } + else if (!receive_resent) // don't freak out over out-of-order reliable resends + { + U64Microseconds time = LLMessageSystem::getMessageTimeUsecs(); + TPACKETID index = mPacketsInID; + S32 gap_count = 0; + if ((index < id) && ((id - index) < 16)) + { + while (index != id) + { + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << mHost << "\tPACKET GAP:\t" + << index; + LL_INFOS() << str.str() << LL_ENDL; + } + +// LL_INFOS() << "adding potential lost: " << index << LL_ENDL; + mPotentialLostPackets[index] = time; + index++; + index = index % LL_MAX_OUT_PACKET_ID; + gap_count++; + } + } + else + { + LL_INFOS() << "packet_out_of_order - got packet " << id << " expecting " << index << " from " << mHost << LL_ENDL; + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << mHost << "\tPACKET GAP:\t" + << id << " expected " << index; + LL_INFOS() << str.str() << LL_ENDL; + } + } + + mPacketsInID = id + 1; + mPacketsInID = (mPacketsInID) % LL_MAX_OUT_PACKET_ID; + + if (gap_count > 128) + { + LL_WARNS() << "Packet loss gap filler running amok!" << LL_ENDL; + } + else if (gap_count > 16) + { + LL_WARNS() << "Sustaining large amounts of packet loss!" << LL_ENDL; + } + + } + } mLastPacketGap = gap; } void LLCircuit::updateWatchDogTimers(LLMessageSystem *msgsys) { - F64Seconds cur_time = LLMessageSystem::getMessageTimeSeconds(); - S32 count = mPingSet.size(); - S32 cur = 0; - - // Only process each circuit once at most, stop processing if no circuits - while((cur < count) && !mPingSet.empty()) - { - cur++; - - LLCircuit::ping_set_t::iterator psit = mPingSet.begin(); - LLCircuitData *cdp = *psit; - - if (!cdp->mbAlive) - { - // We suspect that this case should never happen, given how - // the alive status is set. - // Skip over dead circuits, just add the ping interval and push it to the back - // Always remember to remove it from the set before changing the sorting - // key (mNextPingSendTime) - mPingSet.erase(psit); - cdp->mNextPingSendTime = cur_time + mHeartbeatInterval; - mPingSet.insert(cdp); - continue; - } - else - { - // Check to see if this needs a ping - if (cur_time < cdp->mNextPingSendTime) - { - // This circuit doesn't need a ping, break out because - // we have a sorted list, thus no more circuits need pings - break; - } - - // Update watchdog timers - if (cdp->updateWatchDogTimers(msgsys)) + F64Seconds cur_time = LLMessageSystem::getMessageTimeSeconds(); + S32 count = mPingSet.size(); + S32 cur = 0; + + // Only process each circuit once at most, stop processing if no circuits + while((cur < count) && !mPingSet.empty()) + { + cur++; + + LLCircuit::ping_set_t::iterator psit = mPingSet.begin(); + LLCircuitData *cdp = *psit; + + if (!cdp->mbAlive) + { + // We suspect that this case should never happen, given how + // the alive status is set. + // Skip over dead circuits, just add the ping interval and push it to the back + // Always remember to remove it from the set before changing the sorting + // key (mNextPingSendTime) + mPingSet.erase(psit); + cdp->mNextPingSendTime = cur_time + mHeartbeatInterval; + mPingSet.insert(cdp); + continue; + } + else + { + // Check to see if this needs a ping + if (cur_time < cdp->mNextPingSendTime) { - // Randomize our pings a bit by doing some up to 5% early or late - F64Seconds dt = 0.95f*mHeartbeatInterval + F32Seconds(ll_frand(0.1f*mHeartbeatInterval.value())); - - // Remove it, and reinsert it with the new next ping time. - // Always remove before changing the sorting key. - mPingSet.erase(psit); - cdp->mNextPingSendTime = cur_time + dt; - mPingSet.insert(cdp); - - // Update our throttles - cdp->mThrottles.dynamicAdjust(); - - // Update some stats, this is not terribly important - cdp->checkPeriodTime(); - } - else - { - // This mPingSet.erase isn't necessary, because removing the circuit will - // remove the ping set. - //mPingSet.erase(psit); - removeCircuitData(cdp->mHost); - } - } - } + // This circuit doesn't need a ping, break out because + // we have a sorted list, thus no more circuits need pings + break; + } + + // Update watchdog timers + if (cdp->updateWatchDogTimers(msgsys)) + { + // Randomize our pings a bit by doing some up to 5% early or late + F64Seconds dt = 0.95f*mHeartbeatInterval + F32Seconds(ll_frand(0.1f*mHeartbeatInterval.value())); + + // Remove it, and reinsert it with the new next ping time. + // Always remove before changing the sorting key. + mPingSet.erase(psit); + cdp->mNextPingSendTime = cur_time + dt; + mPingSet.insert(cdp); + + // Update our throttles + cdp->mThrottles.dynamicAdjust(); + + // Update some stats, this is not terribly important + cdp->checkPeriodTime(); + } + else + { + // This mPingSet.erase isn't necessary, because removing the circuit will + // remove the ping set. + //mPingSet.erase(psit); + removeCircuitData(cdp->mHost); + } + } + } } bool LLCircuitData::updateWatchDogTimers(LLMessageSystem *msgsys) { - F64Seconds cur_time = LLMessageSystem::getMessageTimeSeconds(); - mLastPingSendTime = cur_time; - - if (!checkCircuitTimeout()) - { - // Pass this back to the calling LLCircuit, this circuit needs to be cleaned up. - return false; - } - - // WARNING! - // Duplicate suppression can FAIL if packets are delivered out of - // order, although it's EXTREMELY unlikely. It would require - // that the ping get delivered out of order enough that the ACK - // for the packet that it was out of order with was received BEFORE - // the ping was sent. - - // Find the current oldest reliable packetID - // This is to handle the case if we actually manage to wrap our - // packet IDs - the oldest will actually have a higher packet ID - // than the current. - bool wrapped = false; - reliable_iter iter; - iter = mUnackedPackets.upper_bound(getPacketOutID()); - if (iter == mUnackedPackets.end()) - { - // Nothing AFTER this one, so we want the lowest packet ID - // then. - iter = mUnackedPackets.begin(); - wrapped = true; - } - - TPACKETID packet_id = 0; - - // Check against the "final" packets - bool wrapped_final = false; - reliable_iter iter_final; - iter_final = mFinalRetryPackets.upper_bound(getPacketOutID()); - if (iter_final == mFinalRetryPackets.end()) - { - iter_final = mFinalRetryPackets.begin(); - wrapped_final = true; - } - - //LL_INFOS() << mHost << " - unacked count " << mUnackedPackets.size() << LL_ENDL; - //LL_INFOS() << mHost << " - final count " << mFinalRetryPackets.size() << LL_ENDL; - if (wrapped != wrapped_final) - { - // One of the "unacked" or "final" lists hasn't wrapped. Whichever one - // hasn't has the oldest packet. - if (!wrapped) - { - // Hasn't wrapped, so the one on the - // unacked packet list is older - packet_id = iter->first; - //LL_INFOS() << mHost << ": nowrapped unacked" << LL_ENDL; - } - else - { - packet_id = iter_final->first; - //LL_INFOS() << mHost << ": nowrapped final" << LL_ENDL; - } - } - else - { - // They both wrapped, we can just use the minimum of the two. - if ((iter == mUnackedPackets.end()) && (iter_final == mFinalRetryPackets.end())) - { - // Wow! No unacked packets at all! - // Send the ID of the last packet we sent out. - // This will flush all of the destination's - // unacked packets, theoretically. - //LL_INFOS() << mHost << ": No unacked!" << LL_ENDL; - packet_id = getPacketOutID(); - } - else - { - bool had_unacked = false; - if (iter != mUnackedPackets.end()) - { - // Unacked list has the lowest so far - packet_id = iter->first; - had_unacked = true; - //LL_INFOS() << mHost << ": Unacked" << LL_ENDL; - } - - if (iter_final != mFinalRetryPackets.end()) - { - // Use the lowest of the unacked list and the final list - if (had_unacked) - { - // Both had a packet, use the lowest. - packet_id = llmin(packet_id, iter_final->first); - //LL_INFOS() << mHost << ": Min of unacked/final" << LL_ENDL; - } - else - { - // Only the final had a packet, use it. - packet_id = iter_final->first; - //LL_INFOS() << mHost << ": Final!" << LL_ENDL; - } - } - } - } - - // Send off the another ping. - pingTimerStart(); - msgsys->newMessageFast(_PREHASH_StartPingCheck); - msgsys->nextBlock(_PREHASH_PingID); - msgsys->addU8Fast(_PREHASH_PingID, nextPingID()); - msgsys->addU32Fast(_PREHASH_OldestUnacked, packet_id); - msgsys->sendMessage(mHost); - - // Also do lost packet accounting. - // Check to see if anything on our lost list is old enough to - // be considered lost - - LLCircuitData::packet_time_map::iterator it; - U64Microseconds timeout = llmin(LL_MAX_LOST_TIMEOUT, F32Seconds(getPingDelayAveraged()) * LL_LOST_TIMEOUT_FACTOR); - - U64Microseconds mt_usec = LLMessageSystem::getMessageTimeUsecs(); - for (it = mPotentialLostPackets.begin(); it != mPotentialLostPackets.end(); ) - { - U64Microseconds delta_t_usec = mt_usec - (*it).second; - if (delta_t_usec > timeout) - { - // let's call this one a loss! - mPacketsLost++; - gMessageSystem->mDroppedPackets++; - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << mHost << "\tLOST PACKET:\t" - << (*it).first; - LL_INFOS() << str.str() << LL_ENDL; - } - mPotentialLostPackets.erase(it++); - } - else - { - ++it; - } - } - - return true; + F64Seconds cur_time = LLMessageSystem::getMessageTimeSeconds(); + mLastPingSendTime = cur_time; + + if (!checkCircuitTimeout()) + { + // Pass this back to the calling LLCircuit, this circuit needs to be cleaned up. + return false; + } + + // WARNING! + // Duplicate suppression can FAIL if packets are delivered out of + // order, although it's EXTREMELY unlikely. It would require + // that the ping get delivered out of order enough that the ACK + // for the packet that it was out of order with was received BEFORE + // the ping was sent. + + // Find the current oldest reliable packetID + // This is to handle the case if we actually manage to wrap our + // packet IDs - the oldest will actually have a higher packet ID + // than the current. + bool wrapped = false; + reliable_iter iter; + iter = mUnackedPackets.upper_bound(getPacketOutID()); + if (iter == mUnackedPackets.end()) + { + // Nothing AFTER this one, so we want the lowest packet ID + // then. + iter = mUnackedPackets.begin(); + wrapped = true; + } + + TPACKETID packet_id = 0; + + // Check against the "final" packets + bool wrapped_final = false; + reliable_iter iter_final; + iter_final = mFinalRetryPackets.upper_bound(getPacketOutID()); + if (iter_final == mFinalRetryPackets.end()) + { + iter_final = mFinalRetryPackets.begin(); + wrapped_final = true; + } + + //LL_INFOS() << mHost << " - unacked count " << mUnackedPackets.size() << LL_ENDL; + //LL_INFOS() << mHost << " - final count " << mFinalRetryPackets.size() << LL_ENDL; + if (wrapped != wrapped_final) + { + // One of the "unacked" or "final" lists hasn't wrapped. Whichever one + // hasn't has the oldest packet. + if (!wrapped) + { + // Hasn't wrapped, so the one on the + // unacked packet list is older + packet_id = iter->first; + //LL_INFOS() << mHost << ": nowrapped unacked" << LL_ENDL; + } + else + { + packet_id = iter_final->first; + //LL_INFOS() << mHost << ": nowrapped final" << LL_ENDL; + } + } + else + { + // They both wrapped, we can just use the minimum of the two. + if ((iter == mUnackedPackets.end()) && (iter_final == mFinalRetryPackets.end())) + { + // Wow! No unacked packets at all! + // Send the ID of the last packet we sent out. + // This will flush all of the destination's + // unacked packets, theoretically. + //LL_INFOS() << mHost << ": No unacked!" << LL_ENDL; + packet_id = getPacketOutID(); + } + else + { + bool had_unacked = false; + if (iter != mUnackedPackets.end()) + { + // Unacked list has the lowest so far + packet_id = iter->first; + had_unacked = true; + //LL_INFOS() << mHost << ": Unacked" << LL_ENDL; + } + + if (iter_final != mFinalRetryPackets.end()) + { + // Use the lowest of the unacked list and the final list + if (had_unacked) + { + // Both had a packet, use the lowest. + packet_id = llmin(packet_id, iter_final->first); + //LL_INFOS() << mHost << ": Min of unacked/final" << LL_ENDL; + } + else + { + // Only the final had a packet, use it. + packet_id = iter_final->first; + //LL_INFOS() << mHost << ": Final!" << LL_ENDL; + } + } + } + } + + // Send off the another ping. + pingTimerStart(); + msgsys->newMessageFast(_PREHASH_StartPingCheck); + msgsys->nextBlock(_PREHASH_PingID); + msgsys->addU8Fast(_PREHASH_PingID, nextPingID()); + msgsys->addU32Fast(_PREHASH_OldestUnacked, packet_id); + msgsys->sendMessage(mHost); + + // Also do lost packet accounting. + // Check to see if anything on our lost list is old enough to + // be considered lost + + LLCircuitData::packet_time_map::iterator it; + U64Microseconds timeout = llmin(LL_MAX_LOST_TIMEOUT, F32Seconds(getPingDelayAveraged()) * LL_LOST_TIMEOUT_FACTOR); + + U64Microseconds mt_usec = LLMessageSystem::getMessageTimeUsecs(); + for (it = mPotentialLostPackets.begin(); it != mPotentialLostPackets.end(); ) + { + U64Microseconds delta_t_usec = mt_usec - (*it).second; + if (delta_t_usec > timeout) + { + // let's call this one a loss! + mPacketsLost++; + gMessageSystem->mDroppedPackets++; + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << mHost << "\tLOST PACKET:\t" + << (*it).first; + LL_INFOS() << str.str() << LL_ENDL; + } + mPotentialLostPackets.erase(it++); + } + else + { + ++it; + } + } + + return true; } void LLCircuitData::clearDuplicateList(TPACKETID oldest_id) { - // purge old data from the duplicate suppression queue - - // we want to KEEP all x where oldest_id <= x <= last incoming packet, and delete everything else. - - //LL_INFOS() << mHost << ": clearing before oldest " << oldest_id << LL_ENDL; - //LL_INFOS() << "Recent list before: " << mRecentlyReceivedReliablePackets.size() << LL_ENDL; - if (oldest_id < mHighestPacketID) - { - // Clean up everything with a packet ID less than oldest_id. - packet_time_map::iterator pit_start; - packet_time_map::iterator pit_end; - pit_start = mRecentlyReceivedReliablePackets.begin(); - pit_end = mRecentlyReceivedReliablePackets.lower_bound(oldest_id); - mRecentlyReceivedReliablePackets.erase(pit_start, pit_end); - } - - // Do timeout checks on everything with an ID > mHighestPacketID. - // This should be empty except for wrapping IDs. Thus, this should be - // highly rare. - U64Microseconds mt_usec = LLMessageSystem::getMessageTimeUsecs(); - - packet_time_map::iterator pit; - for(pit = mRecentlyReceivedReliablePackets.upper_bound(mHighestPacketID); - pit != mRecentlyReceivedReliablePackets.end(); ) - { - // Validate that the packet ID seems far enough away - if ((pit->first - mHighestPacketID) < 100) - { - LL_WARNS() << "Probably incorrectly timing out non-wrapped packets!" << LL_ENDL; - } - U64Microseconds delta_t_usec = mt_usec - (*pit).second; - F64Seconds delta_t_sec = delta_t_usec; - if (delta_t_sec > LL_DUPLICATE_SUPPRESSION_TIMEOUT) - { - // enough time has elapsed we're not likely to get a duplicate on this one - LL_INFOS() << "Clearing " << pit->first << " from recent list" << LL_ENDL; - mRecentlyReceivedReliablePackets.erase(pit++); - } - else - { - ++pit; - } - } - //LL_INFOS() << "Recent list after: " << mRecentlyReceivedReliablePackets.size() << LL_ENDL; + // purge old data from the duplicate suppression queue + + // we want to KEEP all x where oldest_id <= x <= last incoming packet, and delete everything else. + + //LL_INFOS() << mHost << ": clearing before oldest " << oldest_id << LL_ENDL; + //LL_INFOS() << "Recent list before: " << mRecentlyReceivedReliablePackets.size() << LL_ENDL; + if (oldest_id < mHighestPacketID) + { + // Clean up everything with a packet ID less than oldest_id. + packet_time_map::iterator pit_start; + packet_time_map::iterator pit_end; + pit_start = mRecentlyReceivedReliablePackets.begin(); + pit_end = mRecentlyReceivedReliablePackets.lower_bound(oldest_id); + mRecentlyReceivedReliablePackets.erase(pit_start, pit_end); + } + + // Do timeout checks on everything with an ID > mHighestPacketID. + // This should be empty except for wrapping IDs. Thus, this should be + // highly rare. + U64Microseconds mt_usec = LLMessageSystem::getMessageTimeUsecs(); + + packet_time_map::iterator pit; + for(pit = mRecentlyReceivedReliablePackets.upper_bound(mHighestPacketID); + pit != mRecentlyReceivedReliablePackets.end(); ) + { + // Validate that the packet ID seems far enough away + if ((pit->first - mHighestPacketID) < 100) + { + LL_WARNS() << "Probably incorrectly timing out non-wrapped packets!" << LL_ENDL; + } + U64Microseconds delta_t_usec = mt_usec - (*pit).second; + F64Seconds delta_t_sec = delta_t_usec; + if (delta_t_sec > LL_DUPLICATE_SUPPRESSION_TIMEOUT) + { + // enough time has elapsed we're not likely to get a duplicate on this one + LL_INFOS() << "Clearing " << pit->first << " from recent list" << LL_ENDL; + mRecentlyReceivedReliablePackets.erase(pit++); + } + else + { + ++pit; + } + } + //LL_INFOS() << "Recent list after: " << mRecentlyReceivedReliablePackets.size() << LL_ENDL; } bool LLCircuitData::checkCircuitTimeout() { - F64Seconds time_since_last_ping = LLMessageSystem::getMessageTimeSeconds() - mLastPingReceivedTime; - - // Nota Bene: This needs to be turned off if you are debugging multiple simulators - if (time_since_last_ping > mHeartbeatTimeout) - { - LL_WARNS() << "LLCircuitData::checkCircuitTimeout for " << mHost << " last ping " << time_since_last_ping << " seconds ago." <<LL_ENDL; - setAlive(false); - if (mTimeoutCallback) - { - LL_WARNS() << "LLCircuitData::checkCircuitTimeout for " << mHost << " calling callback." << LL_ENDL; - mTimeoutCallback(mHost, mTimeoutUserData); - } - if (!isAlive()) - { - // The callback didn't try and resurrect the circuit. We should kill it. - LL_WARNS() << "LLCircuitData::checkCircuitTimeout for " << mHost << " still dead, dropping." << LL_ENDL; - return false; - } - } - - return true; + F64Seconds time_since_last_ping = LLMessageSystem::getMessageTimeSeconds() - mLastPingReceivedTime; + + // Nota Bene: This needs to be turned off if you are debugging multiple simulators + if (time_since_last_ping > mHeartbeatTimeout) + { + LL_WARNS() << "LLCircuitData::checkCircuitTimeout for " << mHost << " last ping " << time_since_last_ping << " seconds ago." <<LL_ENDL; + setAlive(false); + if (mTimeoutCallback) + { + LL_WARNS() << "LLCircuitData::checkCircuitTimeout for " << mHost << " calling callback." << LL_ENDL; + mTimeoutCallback(mHost, mTimeoutUserData); + } + if (!isAlive()) + { + // The callback didn't try and resurrect the circuit. We should kill it. + LL_WARNS() << "LLCircuitData::checkCircuitTimeout for " << mHost << " still dead, dropping." << LL_ENDL; + return false; + } + } + + return true; } // Call this method when a reliable message comes in - this will // correctly place the packet in the correct list to be acked later. bool LLCircuitData::collectRAck(TPACKETID packet_num) { - if (mAcks.empty()) - { - // First extra ack, we need to add ourselves to the list of circuits that need to send acks - gMessageSystem->mCircuitInfo.mSendAckMap[mHost] = this; - } - - mAcks.push_back(packet_num); - if (mAckCreationTime == 0) - { - mAckCreationTime = getAgeInSeconds(); - } - return true; + if (mAcks.empty()) + { + // First extra ack, we need to add ourselves to the list of circuits that need to send acks + gMessageSystem->mCircuitInfo.mSendAckMap[mHost] = this; + } + + mAcks.push_back(packet_num); + if (mAckCreationTime == 0) + { + mAckCreationTime = getAgeInSeconds(); + } + return true; } // this method is called during the message system processAcks() to // send out any acks that did not get sent already. void LLCircuit::sendAcks(F32 collect_time) { - collect_time = llclamp(collect_time, 0.f, LL_COLLECT_ACK_TIME_MAX); - LLCircuitData* cd; - circuit_data_map::iterator it = mSendAckMap.begin(); - while (it != mSendAckMap.end()) - { - circuit_data_map::iterator cur_it = it++; - cd = (*cur_it).second; - S32 count = (S32)cd->mAcks.size(); - F32 age = cd->getAgeInSeconds() - cd->mAckCreationTime; - if (age > collect_time || count == 0) - { - if (count>0) - { - // send the packet acks - S32 acks_this_packet = 0; - for(S32 i = 0; i < count; ++i) - { - if(acks_this_packet == 0) - { - gMessageSystem->newMessageFast(_PREHASH_PacketAck); - } - gMessageSystem->nextBlockFast(_PREHASH_Packets); - gMessageSystem->addU32Fast(_PREHASH_ID, cd->mAcks[i]); - ++acks_this_packet; - if(acks_this_packet > 250) - { - gMessageSystem->sendMessage(cd->mHost); - acks_this_packet = 0; - } - } - if(acks_this_packet > 0) - { - gMessageSystem->sendMessage(cd->mHost); - } - - if(gMessageSystem->mVerboseLog) - { - std::ostringstream str; - str << "MSG: -> " << cd->mHost << "\tPACKET ACKS:\t"; - std::ostream_iterator<TPACKETID> append(str, " "); - std::copy(cd->mAcks.begin(), cd->mAcks.end(), append); - LL_INFOS() << str.str() << LL_ENDL; - } - - // empty out the acks list - cd->mAcks.clear(); - cd->mAckCreationTime = 0.f; - } - // remove data map - mSendAckMap.erase(cur_it); - } - } + collect_time = llclamp(collect_time, 0.f, LL_COLLECT_ACK_TIME_MAX); + LLCircuitData* cd; + circuit_data_map::iterator it = mSendAckMap.begin(); + while (it != mSendAckMap.end()) + { + circuit_data_map::iterator cur_it = it++; + cd = (*cur_it).second; + S32 count = (S32)cd->mAcks.size(); + F32 age = cd->getAgeInSeconds() - cd->mAckCreationTime; + if (age > collect_time || count == 0) + { + if (count>0) + { + // send the packet acks + S32 acks_this_packet = 0; + for(S32 i = 0; i < count; ++i) + { + if(acks_this_packet == 0) + { + gMessageSystem->newMessageFast(_PREHASH_PacketAck); + } + gMessageSystem->nextBlockFast(_PREHASH_Packets); + gMessageSystem->addU32Fast(_PREHASH_ID, cd->mAcks[i]); + ++acks_this_packet; + if(acks_this_packet > 250) + { + gMessageSystem->sendMessage(cd->mHost); + acks_this_packet = 0; + } + } + if(acks_this_packet > 0) + { + gMessageSystem->sendMessage(cd->mHost); + } + + if(gMessageSystem->mVerboseLog) + { + std::ostringstream str; + str << "MSG: -> " << cd->mHost << "\tPACKET ACKS:\t"; + std::ostream_iterator<TPACKETID> append(str, " "); + std::copy(cd->mAcks.begin(), cd->mAcks.end(), append); + LL_INFOS() << str.str() << LL_ENDL; + } + + // empty out the acks list + cd->mAcks.clear(); + cd->mAckCreationTime = 0.f; + } + // remove data map + mSendAckMap.erase(cur_it); + } + } } std::ostream& operator<<(std::ostream& s, LLCircuitData& circuit) { - F32 age = circuit.mExistenceTimer.getElapsedTimeF32(); - - using namespace std; - s << "Circuit " << circuit.mHost << " " - << circuit.mRemoteID << " " - << (circuit.mbAlive ? "Alive" : "Not Alive") << " " - << (circuit.mbAllowTimeout ? "Timeout Allowed" : "Timeout Not Allowed") - << endl; - - s << " Packets Lost: " << circuit.mPacketsLost - << " Measured Ping: " << circuit.mPingDelay - << " Averaged Ping: " << circuit.mPingDelayAveraged - << endl; - - s << "Global In/Out " << S32(age) << " sec" - << " KBytes: " << circuit.mBytesIn.valueInUnits<LLUnits::Kilobytes>() << "/" << circuit.mBytesOut.valueInUnits<LLUnits::Kilobytes>() - << " Kbps: " - << S32(circuit.mBytesIn.valueInUnits<LLUnits::Kilobits>() / circuit.mExistenceTimer.getElapsedTimeF32().value()) - << "/" - << S32(circuit.mBytesOut.valueInUnits<LLUnits::Kilobits>() / circuit.mExistenceTimer.getElapsedTimeF32().value()) - << " Packets: " << circuit.mPacketsIn << "/" << circuit.mPacketsOut - << endl; - - s << "Recent In/Out " << circuit.mLastPeriodLength - << " KBytes: " - << circuit.mBytesInLastPeriod.valueInUnits<LLUnits::Kilobytes>() - << "/" - << circuit.mBytesOutLastPeriod.valueInUnits<LLUnits::Kilobytes>() - << " Kbps: " - << (S32)(circuit.mBytesInLastPeriod.valueInUnits<LLUnits::Kilobits>() / circuit.mLastPeriodLength.value()) - << "/" - << (S32)(circuit.mBytesOutLastPeriod.valueInUnits<LLUnits::Kilobits>() / circuit.mLastPeriodLength.value()) - << " Peak kbps: " - << S32(circuit.mPeakBPSIn / 1024.f) - << "/" - << S32(circuit.mPeakBPSOut / 1024.f) - << endl; - - return s; + F32 age = circuit.mExistenceTimer.getElapsedTimeF32(); + + using namespace std; + s << "Circuit " << circuit.mHost << " " + << circuit.mRemoteID << " " + << (circuit.mbAlive ? "Alive" : "Not Alive") << " " + << (circuit.mbAllowTimeout ? "Timeout Allowed" : "Timeout Not Allowed") + << endl; + + s << " Packets Lost: " << circuit.mPacketsLost + << " Measured Ping: " << circuit.mPingDelay + << " Averaged Ping: " << circuit.mPingDelayAveraged + << endl; + + s << "Global In/Out " << S32(age) << " sec" + << " KBytes: " << circuit.mBytesIn.valueInUnits<LLUnits::Kilobytes>() << "/" << circuit.mBytesOut.valueInUnits<LLUnits::Kilobytes>() + << " Kbps: " + << S32(circuit.mBytesIn.valueInUnits<LLUnits::Kilobits>() / circuit.mExistenceTimer.getElapsedTimeF32().value()) + << "/" + << S32(circuit.mBytesOut.valueInUnits<LLUnits::Kilobits>() / circuit.mExistenceTimer.getElapsedTimeF32().value()) + << " Packets: " << circuit.mPacketsIn << "/" << circuit.mPacketsOut + << endl; + + s << "Recent In/Out " << circuit.mLastPeriodLength + << " KBytes: " + << circuit.mBytesInLastPeriod.valueInUnits<LLUnits::Kilobytes>() + << "/" + << circuit.mBytesOutLastPeriod.valueInUnits<LLUnits::Kilobytes>() + << " Kbps: " + << (S32)(circuit.mBytesInLastPeriod.valueInUnits<LLUnits::Kilobits>() / circuit.mLastPeriodLength.value()) + << "/" + << (S32)(circuit.mBytesOutLastPeriod.valueInUnits<LLUnits::Kilobits>() / circuit.mLastPeriodLength.value()) + << " Peak kbps: " + << S32(circuit.mPeakBPSIn / 1024.f) + << "/" + << S32(circuit.mPeakBPSOut / 1024.f) + << endl; + + return s; } void LLCircuitData::getInfo(LLSD& info) const { - info["Host"] = mHost.getIPandPort(); - info["Alive"] = mbAlive; - info["Age"] = mExistenceTimer.getElapsedTimeF32(); + info["Host"] = mHost.getIPandPort(); + info["Alive"] = mbAlive; + info["Age"] = mExistenceTimer.getElapsedTimeF32(); } void LLCircuitData::dumpResendCountAndReset() { - if (mCurrentResendCount) - { - LL_INFOS() << "Circuit: " << mHost << " resent " << mCurrentResendCount << " packets" << LL_ENDL; - mCurrentResendCount = 0; - } + if (mCurrentResendCount) + { + LL_INFOS() << "Circuit: " << mHost << " resent " << mCurrentResendCount << " packets" << LL_ENDL; + mCurrentResendCount = 0; + } } std::ostream& operator<<(std::ostream& s, LLCircuit &circuit) { - s << "Circuit Info:" << std::endl; - LLCircuit::circuit_data_map::iterator end = circuit.mCircuitData.end(); - LLCircuit::circuit_data_map::iterator it; - for(it = circuit.mCircuitData.begin(); it != end; ++it) - { - s << *((*it).second) << std::endl; - } - return s; + s << "Circuit Info:" << std::endl; + LLCircuit::circuit_data_map::iterator end = circuit.mCircuitData.end(); + LLCircuit::circuit_data_map::iterator it; + for(it = circuit.mCircuitData.begin(); it != end; ++it) + { + s << *((*it).second) << std::endl; + } + return s; } void LLCircuit::getInfo(LLSD& info) const { - LLCircuit::circuit_data_map::const_iterator end = mCircuitData.end(); - LLCircuit::circuit_data_map::const_iterator it; - LLSD circuit_info; - for(it = mCircuitData.begin(); it != end; ++it) - { - (*it).second->getInfo(circuit_info); - info["Circuits"].append(circuit_info); - } + LLCircuit::circuit_data_map::const_iterator end = mCircuitData.end(); + LLCircuit::circuit_data_map::const_iterator it; + LLSD circuit_info; + for(it = mCircuitData.begin(); it != end; ++it) + { + (*it).second->getInfo(circuit_info); + info["Circuits"].append(circuit_info); + } } void LLCircuit::getCircuitRange( - const LLHost& key, - LLCircuit::circuit_data_map::iterator& first, - LLCircuit::circuit_data_map::iterator& end) + const LLHost& key, + LLCircuit::circuit_data_map::iterator& first, + LLCircuit::circuit_data_map::iterator& end) { - end = mCircuitData.end(); - first = mCircuitData.upper_bound(key); + end = mCircuitData.end(); + first = mCircuitData.upper_bound(key); } TPACKETID LLCircuitData::nextPacketOutID() { - mPacketsOut++; - - TPACKETID id; - - id = (mPacketsOutID + 1) % LL_MAX_OUT_PACKET_ID; - - if (id < mPacketsOutID) - { - // we just wrapped on a circuit, reset the wrap ID to zero - mWrapID = 0; - } - mPacketsOutID = id; - return id; + mPacketsOut++; + + TPACKETID id; + + id = (mPacketsOutID + 1) % LL_MAX_OUT_PACKET_ID; + + if (id < mPacketsOutID) + { + // we just wrapped on a circuit, reset the wrap ID to zero + mWrapID = 0; + } + mPacketsOutID = id; + return id; } void LLCircuitData::setPacketInID(TPACKETID id) { - id = id % LL_MAX_OUT_PACKET_ID; - mPacketsInID = id; - mRecentlyReceivedReliablePackets.clear(); + id = id % LL_MAX_OUT_PACKET_ID; + mPacketsInID = id; + mRecentlyReceivedReliablePackets.clear(); - mWrapID = id; + mWrapID = id; } void LLCircuitData::pingTimerStop(const U8 ping_id) { - F64Seconds mt_secs = LLMessageSystem::getMessageTimeSeconds(); - - // Nota Bene: no averaging of ping times until we get a feel for how this works - F64Seconds time = mt_secs - mPingTime; - if (time == F32Seconds(0.0)) - { - // Ack, we got our ping response on the same frame! Sigh, let's get a real time otherwise - // all of our ping calculations will be skewed. - mt_secs = LLMessageSystem::getMessageTimeSeconds(true); - } - mLastPingReceivedTime = mt_secs; - - // If ping is longer than 1 second, we'll get sequence deltas in the ping. - // Approximate by assuming each ping counts for 1 second (slightly low, probably) - S32 delta_ping = (S32)mLastPingID - (S32) ping_id; - if (delta_ping < 0) - { - delta_ping += 256; - } - - U32Milliseconds msec = delta_ping*mHeartbeatInterval + time; - setPingDelay(msec); - - mPingsInTransit = delta_ping; - if (mBlocked && (mPingsInTransit <= PING_RELEASE_BLOCK)) - { - mBlocked = false; - } + F64Seconds mt_secs = LLMessageSystem::getMessageTimeSeconds(); + + // Nota Bene: no averaging of ping times until we get a feel for how this works + F64Seconds time = mt_secs - mPingTime; + if (time == F32Seconds(0.0)) + { + // Ack, we got our ping response on the same frame! Sigh, let's get a real time otherwise + // all of our ping calculations will be skewed. + mt_secs = LLMessageSystem::getMessageTimeSeconds(true); + } + mLastPingReceivedTime = mt_secs; + + // If ping is longer than 1 second, we'll get sequence deltas in the ping. + // Approximate by assuming each ping counts for 1 second (slightly low, probably) + S32 delta_ping = (S32)mLastPingID - (S32) ping_id; + if (delta_ping < 0) + { + delta_ping += 256; + } + + U32Milliseconds msec = delta_ping*mHeartbeatInterval + time; + setPingDelay(msec); + + mPingsInTransit = delta_ping; + if (mBlocked && (mPingsInTransit <= PING_RELEASE_BLOCK)) + { + mBlocked = false; + } } void LLCircuitData::pingTimerStart() { - mPingTime = LLMessageSystem::getMessageTimeSeconds(); - mPingsInTransit++; + mPingTime = LLMessageSystem::getMessageTimeSeconds(); + mPingsInTransit++; - if (!mBlocked && (mPingsInTransit > PING_START_BLOCK)) - { - mBlocked = true; - } + if (!mBlocked && (mPingsInTransit > PING_START_BLOCK)) + { + mBlocked = true; + } } U32 LLCircuitData::getPacketsIn() const { - return mPacketsIn; + return mPacketsIn; } S32Bytes LLCircuitData::getBytesIn() const { - return mBytesIn; + return mBytesIn; } S32Bytes LLCircuitData::getBytesOut() const { - return mBytesOut; + return mBytesOut; } U32 LLCircuitData::getPacketsOut() const { - return mPacketsOut; + return mPacketsOut; } TPACKETID LLCircuitData::getPacketOutID() const { - return mPacketsOutID; + return mPacketsOutID; } U32 LLCircuitData::getPacketsLost() const { - return mPacketsLost; + return mPacketsLost; } bool LLCircuitData::isAlive() const { - return mbAlive; + return mbAlive; } bool LLCircuitData::isBlocked() const { - return mBlocked; + return mBlocked; } bool LLCircuitData::getAllowTimeout() const { - return mbAllowTimeout; + return mbAllowTimeout; } U32Milliseconds LLCircuitData::getPingDelay() const { - return mPingDelay; + return mPingDelay; } F32Milliseconds LLCircuitData::getPingInTransitTime() { - // This may be inaccurate in the case of a circuit that was "dead" and then revived, - // but only until the first round trip ping is sent - djs - F32Milliseconds time_since_ping_was_sent(0); + // This may be inaccurate in the case of a circuit that was "dead" and then revived, + // but only until the first round trip ping is sent - djs + F32Milliseconds time_since_ping_was_sent(0); - if (mPingsInTransit) - { - time_since_ping_was_sent = F32Milliseconds::convert(((mPingsInTransit*mHeartbeatInterval - F32Seconds(1)) - + (LLMessageSystem::getMessageTimeSeconds() - mPingTime))); - } + if (mPingsInTransit) + { + time_since_ping_was_sent = F32Milliseconds::convert(((mPingsInTransit*mHeartbeatInterval - F32Seconds(1)) + + (LLMessageSystem::getMessageTimeSeconds() - mPingTime))); + } - return time_since_ping_was_sent; + return time_since_ping_was_sent; } void LLCircuitData::setPingDelay(U32Milliseconds ping) { - mPingDelay = ping; - mPingDelayAveraged = llmax((F32Milliseconds)ping, getPingDelayAveraged()); - mPingDelayAveraged = ((1.f - LL_AVERAGED_PING_ALPHA) * mPingDelayAveraged) - + (LL_AVERAGED_PING_ALPHA * (F32Milliseconds) ping); - mPingDelayAveraged = llclamp(mPingDelayAveraged, - LL_AVERAGED_PING_MIN, - LL_AVERAGED_PING_MAX); + mPingDelay = ping; + mPingDelayAveraged = llmax((F32Milliseconds)ping, getPingDelayAveraged()); + mPingDelayAveraged = ((1.f - LL_AVERAGED_PING_ALPHA) * mPingDelayAveraged) + + (LL_AVERAGED_PING_ALPHA * (F32Milliseconds) ping); + mPingDelayAveraged = llclamp(mPingDelayAveraged, + LL_AVERAGED_PING_MIN, + LL_AVERAGED_PING_MAX); } F32Milliseconds LLCircuitData::getPingDelayAveraged() { - return llmin(llmax(getPingInTransitTime(), mPingDelayAveraged), LL_AVERAGED_PING_MAX); + return llmin(llmax(getPingInTransitTime(), mPingDelayAveraged), LL_AVERAGED_PING_MAX); } bool LLCircuitData::getTrusted() const { - return mTrusted; + return mTrusted; } void LLCircuitData::setTrusted(bool t) { - mTrusted = t; + mTrusted = t; } F32 LLCircuitData::getAgeInSeconds() const { - return mExistenceTimer.getElapsedTimeF32(); + return mExistenceTimer.getElapsedTimeF32(); } diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h index 95e470b543..521982d7b1 100644 --- a/indra/llmessage/llcircuit.h +++ b/indra/llmessage/llcircuit.h @@ -1,4 +1,4 @@ -/** +/** * @file llcircuit.h * @brief Provides a method for tracking network circuit information * for the UDP message system @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,7 +44,7 @@ // Constants // const F32 LL_AVERAGED_PING_ALPHA = 0.2f; // relaxation constant on ping running average -const F32Milliseconds LL_AVERAGED_PING_MAX(2000); +const F32Milliseconds LL_AVERAGED_PING_MAX(2000); const F32Milliseconds LL_AVERAGED_PING_MIN(100); // increased to avoid retransmits when a process is slow const U32Milliseconds INITIAL_PING_VALUE_MSEC(1000); // initial value for the ping delay, or for ping delay for an unknown circuit @@ -77,208 +77,208 @@ class LLSD; class LLCircuitData { public: - LLCircuitData(const LLHost &host, TPACKETID in_id, - const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout); - ~LLCircuitData(); - - S32 resendUnackedPackets(const F64Seconds now); - void clearDuplicateList(TPACKETID oldest_id); - - - void dumpResendCountAndReset(); // Used for tracking how many resends are being done on a circuit. - - - - // Public because stupid message system callbacks uses it. - void pingTimerStart(); - void pingTimerStop(const U8 ping_id); - void ackReliablePacket(TPACKETID packet_num); - - // remote computer information - const LLUUID& getRemoteID() const { return mRemoteID; } - const LLUUID& getRemoteSessionID() const { return mRemoteSessionID; } - void setRemoteID(const LLUUID& id) { mRemoteID = id; } - void setRemoteSessionID(const LLUUID& id) { mRemoteSessionID = id; } - - void setTrusted(bool t); - - // The local end point ID is used when establishing a trusted circuit. - // no matching set function for getLocalEndPointID() - // mLocalEndPointID should only ever be setup in the LLCircuitData constructor - const LLUUID& getLocalEndPointID() const { return mLocalEndPointID; } - - U32Milliseconds getPingDelay() const; - S32 getPingsInTransit() const { return mPingsInTransit; } - - // ACCESSORS - bool isAlive() const; - bool isBlocked() const; - bool getAllowTimeout() const; - F32Milliseconds getPingDelayAveraged(); - F32Milliseconds getPingInTransitTime(); - U32 getPacketsIn() const; - S32Bytes getBytesIn() const; - S32Bytes getBytesOut() const; - U32 getPacketsOut() const; - U32 getPacketsLost() const; - TPACKETID getPacketOutID() const; - bool getTrusted() const; - F32 getAgeInSeconds() const; - S32 getUnackedPacketCount() const { return mUnackedPacketCount; } - S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; } - F64Seconds getNextPingSendTime() const { return mNextPingSendTime; } + LLCircuitData(const LLHost &host, TPACKETID in_id, + const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout); + ~LLCircuitData(); + + S32 resendUnackedPackets(const F64Seconds now); + void clearDuplicateList(TPACKETID oldest_id); + + + void dumpResendCountAndReset(); // Used for tracking how many resends are being done on a circuit. + + + + // Public because stupid message system callbacks uses it. + void pingTimerStart(); + void pingTimerStop(const U8 ping_id); + void ackReliablePacket(TPACKETID packet_num); + + // remote computer information + const LLUUID& getRemoteID() const { return mRemoteID; } + const LLUUID& getRemoteSessionID() const { return mRemoteSessionID; } + void setRemoteID(const LLUUID& id) { mRemoteID = id; } + void setRemoteSessionID(const LLUUID& id) { mRemoteSessionID = id; } + + void setTrusted(bool t); + + // The local end point ID is used when establishing a trusted circuit. + // no matching set function for getLocalEndPointID() + // mLocalEndPointID should only ever be setup in the LLCircuitData constructor + const LLUUID& getLocalEndPointID() const { return mLocalEndPointID; } + + U32Milliseconds getPingDelay() const; + S32 getPingsInTransit() const { return mPingsInTransit; } + + // ACCESSORS + bool isAlive() const; + bool isBlocked() const; + bool getAllowTimeout() const; + F32Milliseconds getPingDelayAveraged(); + F32Milliseconds getPingInTransitTime(); + U32 getPacketsIn() const; + S32Bytes getBytesIn() const; + S32Bytes getBytesOut() const; + U32 getPacketsOut() const; + U32 getPacketsLost() const; + TPACKETID getPacketOutID() const; + bool getTrusted() const; + F32 getAgeInSeconds() const; + S32 getUnackedPacketCount() const { return mUnackedPacketCount; } + S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; } + F64Seconds getNextPingSendTime() const { return mNextPingSendTime; } U32 getLastPacketGap() const { return mLastPacketGap; } LLHost getHost() const { return mHost; } - F64Seconds getLastPacketInTime() const { return mLastPacketInTime; } - - LLThrottleGroup &getThrottleGroup() { return mThrottles; } - - class less - { - public: - bool operator()(const LLCircuitData* lhs, const LLCircuitData* rhs) const - { - if (lhs->getNextPingSendTime() < rhs->getNextPingSendTime()) - { - return true; - } - else if (lhs->getNextPingSendTime() > rhs->getNextPingSendTime()) - { - return false; - } - else return lhs > rhs; - } - }; - - // - // Debugging stuff (not necessary for operation) - // - void checkPeriodTime(); // Reset per-period counters if necessary. - friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit); - void getInfo(LLSD& info) const; - - friend class LLCircuit; - friend class LLMessageSystem; - friend class LLEncodedDatagramService; - friend void crash_on_spaceserver_timeout (const LLHost &host, void *); // HACK, so it has access to setAlive() so it can send a final shutdown message. + F64Seconds getLastPacketInTime() const { return mLastPacketInTime; } + + LLThrottleGroup &getThrottleGroup() { return mThrottles; } + + class less + { + public: + bool operator()(const LLCircuitData* lhs, const LLCircuitData* rhs) const + { + if (lhs->getNextPingSendTime() < rhs->getNextPingSendTime()) + { + return true; + } + else if (lhs->getNextPingSendTime() > rhs->getNextPingSendTime()) + { + return false; + } + else return lhs > rhs; + } + }; + + // + // Debugging stuff (not necessary for operation) + // + void checkPeriodTime(); // Reset per-period counters if necessary. + friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit); + void getInfo(LLSD& info) const; + + friend class LLCircuit; + friend class LLMessageSystem; + friend class LLEncodedDatagramService; + friend void crash_on_spaceserver_timeout (const LLHost &host, void *); // HACK, so it has access to setAlive() so it can send a final shutdown message. protected: - TPACKETID nextPacketOutID(); - void setPacketInID(TPACKETID id); - void checkPacketInID(TPACKETID id, bool receive_resent); - void setPingDelay(U32Milliseconds ping); - bool checkCircuitTimeout(); // Return false if the circuit is dead and should be cleaned up + TPACKETID nextPacketOutID(); + void setPacketInID(TPACKETID id); + void checkPacketInID(TPACKETID id, bool receive_resent); + void setPingDelay(U32Milliseconds ping); + bool checkCircuitTimeout(); // Return false if the circuit is dead and should be cleaned up - void addBytesIn(S32Bytes bytes); - void addBytesOut(S32Bytes bytes); + void addBytesIn(S32Bytes bytes); + void addBytesOut(S32Bytes bytes); - U8 nextPingID() { mLastPingID++; return mLastPingID; } + U8 nextPingID() { mLastPingID++; return mLastPingID; } - bool updateWatchDogTimers(LLMessageSystem *msgsys); // Return false if the circuit is dead and should be cleaned up + bool updateWatchDogTimers(LLMessageSystem *msgsys); // Return false if the circuit is dead and should be cleaned up - void addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params); - bool isDuplicateResend(TPACKETID packetnum); - // Call this method when a reliable message comes in - this will - // correctly place the packet in the correct list to be acked - // later. RAack = requested ack - bool collectRAck(TPACKETID packet_num); + void addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params); + bool isDuplicateResend(TPACKETID packetnum); + // Call this method when a reliable message comes in - this will + // correctly place the packet in the correct list to be acked + // later. RAack = requested ack + bool collectRAck(TPACKETID packet_num); - void setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data); + void setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data); - void setAlive(bool b_alive); - void setAllowTimeout(bool allow); + void setAlive(bool b_alive); + void setAllowTimeout(bool allow); protected: - // Identification for this circuit. - LLHost mHost; - LLUUID mRemoteID; - LLUUID mRemoteSessionID; + // Identification for this circuit. + LLHost mHost; + LLUUID mRemoteID; + LLUUID mRemoteSessionID; - LLThrottleGroup mThrottles; + LLThrottleGroup mThrottles; - TPACKETID mWrapID; + TPACKETID mWrapID; - // Current packet IDs of incoming/outgoing packets - // Used for packet sequencing/packet loss detection. - TPACKETID mPacketsOutID; - TPACKETID mPacketsInID; - TPACKETID mHighestPacketID; + // Current packet IDs of incoming/outgoing packets + // Used for packet sequencing/packet loss detection. + TPACKETID mPacketsOutID; + TPACKETID mPacketsInID; + TPACKETID mHighestPacketID; - // Callback and data to run in the case of a circuit timeout. - // Used primarily to try and reconnect to servers if they crash/die. - void (*mTimeoutCallback)(const LLHost &host, void *user_data); - void *mTimeoutUserData; + // Callback and data to run in the case of a circuit timeout. + // Used primarily to try and reconnect to servers if they crash/die. + void (*mTimeoutCallback)(const LLHost &host, void *user_data); + void *mTimeoutUserData; - bool mTrusted; // Is this circuit trusted? - bool mbAllowTimeout; // Machines can "pause" circuits, forcing them not to be dropped + bool mTrusted; // Is this circuit trusted? + bool mbAllowTimeout; // Machines can "pause" circuits, forcing them not to be dropped - bool mbAlive; // Indicates whether a circuit is "alive", i.e. responded to pings + bool mbAlive; // Indicates whether a circuit is "alive", i.e. responded to pings - bool mBlocked; // Blocked is true if the circuit is hosed, i.e. far behind on pings + bool mBlocked; // Blocked is true if the circuit is hosed, i.e. far behind on pings - // Not sure what the difference between this and mLastPingSendTime is - F64Seconds mPingTime; // Time at which a ping was sent. + // Not sure what the difference between this and mLastPingSendTime is + F64Seconds mPingTime; // Time at which a ping was sent. - F64Seconds mLastPingSendTime; // Time we last sent a ping - F64Seconds mLastPingReceivedTime; // Time we last received a ping - F64Seconds mNextPingSendTime; // Time to try and send the next ping - S32 mPingsInTransit; // Number of pings in transit - U8 mLastPingID; // ID of the last ping that we sent out + F64Seconds mLastPingSendTime; // Time we last sent a ping + F64Seconds mLastPingReceivedTime; // Time we last received a ping + F64Seconds mNextPingSendTime; // Time to try and send the next ping + S32 mPingsInTransit; // Number of pings in transit + U8 mLastPingID; // ID of the last ping that we sent out - // Used for determining the resend time for reliable resends. - U32Milliseconds mPingDelay; // raw ping delay - F32Milliseconds mPingDelayAveraged; // averaged ping delay (fast attack/slow decay) + // Used for determining the resend time for reliable resends. + U32Milliseconds mPingDelay; // raw ping delay + F32Milliseconds mPingDelayAveraged; // averaged ping delay (fast attack/slow decay) - typedef std::map<TPACKETID, U64Microseconds> packet_time_map; + typedef std::map<TPACKETID, U64Microseconds> packet_time_map; - packet_time_map mPotentialLostPackets; - packet_time_map mRecentlyReceivedReliablePackets; - std::vector<TPACKETID> mAcks; - F32 mAckCreationTime; // first ack creation time + packet_time_map mPotentialLostPackets; + packet_time_map mRecentlyReceivedReliablePackets; + std::vector<TPACKETID> mAcks; + F32 mAckCreationTime; // first ack creation time - typedef std::map<TPACKETID, LLReliablePacket *> reliable_map; - typedef reliable_map::iterator reliable_iter; + typedef std::map<TPACKETID, LLReliablePacket *> reliable_map; + typedef reliable_map::iterator reliable_iter; - reliable_map mUnackedPackets; - reliable_map mFinalRetryPackets; + reliable_map mUnackedPackets; + reliable_map mFinalRetryPackets; - S32 mUnackedPacketCount; - S32 mUnackedPacketBytes; + S32 mUnackedPacketCount; + S32 mUnackedPacketBytes; - F64Seconds mLastPacketInTime; // Time of last packet arrival + F64Seconds mLastPacketInTime; // Time of last packet arrival - LLUUID mLocalEndPointID; + LLUUID mLocalEndPointID; - // - // These variables are being used for statistical and debugging purpose ONLY, - // as far as I can tell. - // + // + // These variables are being used for statistical and debugging purpose ONLY, + // as far as I can tell. + // - U32 mPacketsOut; - U32 mPacketsIn; - S32 mPacketsLost; - S32Bytes mBytesIn, - mBytesOut; + U32 mPacketsOut; + U32 mPacketsIn; + S32 mPacketsLost; + S32Bytes mBytesIn, + mBytesOut; - F32Seconds mLastPeriodLength; - S32Bytes mBytesInLastPeriod; - S32Bytes mBytesOutLastPeriod; - S32Bytes mBytesInThisPeriod; - S32Bytes mBytesOutThisPeriod; - F32 mPeakBPSIn; // bits per second, max of all period bps - F32 mPeakBPSOut; // bits per second, max of all period bps - F64Seconds mPeriodTime; - LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers + F32Seconds mLastPeriodLength; + S32Bytes mBytesInLastPeriod; + S32Bytes mBytesOutLastPeriod; + S32Bytes mBytesInThisPeriod; + S32Bytes mBytesOutThisPeriod; + F32 mPeakBPSIn; // bits per second, max of all period bps + F32 mPeakBPSOut; // bits per second, max of all period bps + F64Seconds mPeriodTime; + LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers - S32 mCurrentResendCount; // Number of resent packets since last spam + S32 mCurrentResendCount; // Number of resent packets since last spam U32 mLastPacketGap; // Gap in sequence number of last packet. - const F32Seconds mHeartbeatInterval; - const F32Seconds mHeartbeatTimeout; + const F32Seconds mHeartbeatInterval; + const F32Seconds mHeartbeatTimeout; }; @@ -287,64 +287,64 @@ protected: class LLCircuit { public: - // CREATORS - LLCircuit(const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout); - ~LLCircuit(); - - // ACCESSORS - LLCircuitData* findCircuit(const LLHost& host) const; - bool isCircuitAlive(const LLHost& host) const; - - // MANIPULATORS - LLCircuitData *addCircuitData(const LLHost &host, TPACKETID in_id); - void removeCircuitData(const LLHost &host); - - void updateWatchDogTimers(LLMessageSystem *msgsys); - void resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size); - - // this method is called during the message system processAcks() - // to send out any acks that did not get sent already. - void sendAcks(F32 collect_time); - - friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit); - void getInfo(LLSD& info) const; - - void dumpResends(); - - typedef std::map<LLHost, LLCircuitData*> circuit_data_map; - - /** - * @brief This method gets an iterator range starting after key in - * the circuit data map. - * - * @param key The the host before first. - * @param first[out] The first matching value after key. This - * value will equal end if there are no entries. - * @param end[out] The end of the iteration sequence. - */ - void getCircuitRange( - const LLHost& key, - circuit_data_map::iterator& first, - circuit_data_map::iterator& end); - - // Lists that optimize how many circuits we need to traverse a frame - // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up. - circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data - circuit_data_map mSendAckMap; // Map of circuits which need to send acks + // CREATORS + LLCircuit(const F32Seconds circuit_heartbeat_interval, const F32Seconds circuit_timeout); + ~LLCircuit(); + + // ACCESSORS + LLCircuitData* findCircuit(const LLHost& host) const; + bool isCircuitAlive(const LLHost& host) const; + + // MANIPULATORS + LLCircuitData *addCircuitData(const LLHost &host, TPACKETID in_id); + void removeCircuitData(const LLHost &host); + + void updateWatchDogTimers(LLMessageSystem *msgsys); + void resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size); + + // this method is called during the message system processAcks() + // to send out any acks that did not get sent already. + void sendAcks(F32 collect_time); + + friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit); + void getInfo(LLSD& info) const; + + void dumpResends(); + + typedef std::map<LLHost, LLCircuitData*> circuit_data_map; + + /** + * @brief This method gets an iterator range starting after key in + * the circuit data map. + * + * @param key The the host before first. + * @param first[out] The first matching value after key. This + * value will equal end if there are no entries. + * @param end[out] The end of the iteration sequence. + */ + void getCircuitRange( + const LLHost& key, + circuit_data_map::iterator& first, + circuit_data_map::iterator& end); + + // Lists that optimize how many circuits we need to traverse a frame + // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up. + circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data + circuit_data_map mSendAckMap; // Map of circuits which need to send acks protected: - circuit_data_map mCircuitData; + circuit_data_map mCircuitData; - typedef std::set<LLCircuitData *, LLCircuitData::less> ping_set_t; // Circuits sorted by next ping time + typedef std::set<LLCircuitData *, LLCircuitData::less> ping_set_t; // Circuits sorted by next ping time - ping_set_t mPingSet; + ping_set_t mPingSet; - // This variable points to the last circuit data we found to - // optimize the many, many times we call findCircuit. This may be - // set in otherwise const methods, so it is declared mutable. - mutable LLCircuitData* mLastCircuit; + // This variable points to the last circuit data we found to + // optimize the many, many times we call findCircuit. This may be + // set in otherwise const methods, so it is declared mutable. + mutable LLCircuitData* mLastCircuit; private: - const F32Seconds mHeartbeatInterval; - const F32Seconds mHeartbeatTimeout; + const F32Seconds mHeartbeatInterval; + const F32Seconds mHeartbeatTimeout; }; #endif diff --git a/indra/llmessage/llclassifiedflags.cpp b/indra/llmessage/llclassifiedflags.cpp index bf8c9171a7..0df249d035 100644 --- a/indra/llmessage/llclassifiedflags.cpp +++ b/indra/llmessage/llclassifiedflags.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llclassifiedflags.cpp - * @brief + * @brief * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,47 +38,47 @@ ClassifiedFlags pack_classified_flags_request(bool auto_renew, bool inc_pg, bool inc_mature, bool inc_adult) { - U8 rv = 0; - if(inc_pg) rv |= CLASSIFIED_QUERY_INC_PG; - if(inc_mature) rv |= CLASSIFIED_QUERY_INC_MATURE; - if (inc_pg && !inc_mature) rv |= CLASSIFIED_FLAG_MATURE; - if(inc_adult) rv |= CLASSIFIED_QUERY_INC_ADULT; - if(auto_renew) rv |= CLASSIFIED_FLAG_AUTO_RENEW; - return rv; + U8 rv = 0; + if(inc_pg) rv |= CLASSIFIED_QUERY_INC_PG; + if(inc_mature) rv |= CLASSIFIED_QUERY_INC_MATURE; + if (inc_pg && !inc_mature) rv |= CLASSIFIED_FLAG_MATURE; + if(inc_adult) rv |= CLASSIFIED_QUERY_INC_ADULT; + if(auto_renew) rv |= CLASSIFIED_FLAG_AUTO_RENEW; + return rv; } ClassifiedFlags pack_classified_flags(bool auto_renew, bool inc_pg, bool inc_mature, bool inc_adult) { - U8 rv = 0; - if(inc_pg) rv |= CLASSIFIED_QUERY_INC_PG; - if(inc_mature) + U8 rv = 0; + if(inc_pg) rv |= CLASSIFIED_QUERY_INC_PG; + if(inc_mature) { rv |= CLASSIFIED_QUERY_INC_MATURE; rv |= CLASSIFIED_FLAG_MATURE; } - if(inc_adult) rv |= CLASSIFIED_QUERY_INC_ADULT; - if(auto_renew) rv |= CLASSIFIED_FLAG_AUTO_RENEW; - return rv; + if(inc_adult) rv |= CLASSIFIED_QUERY_INC_ADULT; + if(auto_renew) rv |= CLASSIFIED_FLAG_AUTO_RENEW; + return rv; } bool is_cf_mature(ClassifiedFlags flags) { - return ((flags & CLASSIFIED_FLAG_MATURE) != 0) || ((flags & CLASSIFIED_QUERY_INC_MATURE) != 0); + return ((flags & CLASSIFIED_FLAG_MATURE) != 0) || ((flags & CLASSIFIED_QUERY_INC_MATURE) != 0); } // Deprecated, but leaving commented out because someday we might // want to let users enable/disable classifieds. JC //bool is_cf_enabled(ClassifiedFlags flags) //{ -// return ((flags & CLASSIFIED_FLAG_ENABLED) == CLASSIFIED_FLAG_ENABLED); +// return ((flags & CLASSIFIED_FLAG_ENABLED) == CLASSIFIED_FLAG_ENABLED); //} bool is_cf_update_time(ClassifiedFlags flags) { - return ((flags & CLASSIFIED_FLAG_UPDATE_TIME) != 0); + return ((flags & CLASSIFIED_FLAG_UPDATE_TIME) != 0); } bool is_cf_auto_renew(ClassifiedFlags flags) { - return ((flags & CLASSIFIED_FLAG_AUTO_RENEW) != 0); + return ((flags & CLASSIFIED_FLAG_AUTO_RENEW) != 0); } diff --git a/indra/llmessage/llclassifiedflags.h b/indra/llmessage/llclassifiedflags.h index 9298b90357..ee29e4ed13 100644 --- a/indra/llmessage/llclassifiedflags.h +++ b/indra/llmessage/llclassifiedflags.h @@ -1,25 +1,25 @@ -/** +/** * @file llclassifiedflags.h * @brief Flags used in the classifieds. * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,26 +29,26 @@ typedef U8 ClassifiedFlags; -const U8 CLASSIFIED_FLAG_NONE = 1 << 0; -const U8 CLASSIFIED_FLAG_MATURE = 1 << 1; -//const U8 CLASSIFIED_FLAG_ENABLED = 1 << 2; // see llclassifiedflags.cpp +const U8 CLASSIFIED_FLAG_NONE = 1 << 0; +const U8 CLASSIFIED_FLAG_MATURE = 1 << 1; +//const U8 CLASSIFIED_FLAG_ENABLED = 1 << 2; // see llclassifiedflags.cpp //const U8 CLASSIFIED_FLAG_HAS_PRICE= 1 << 3; // deprecated const U8 CLASSIFIED_FLAG_UPDATE_TIME= 1 << 4; const U8 CLASSIFIED_FLAG_AUTO_RENEW = 1 << 5; -const U8 CLASSIFIED_QUERY_FILTER_MATURE = 1 << 1; -//const U8 CLASSIFIED_QUERY_FILTER_ENABLED = 1 << 2; -//const U8 CLASSIFIED_QUERY_FILTER_PRICE = 1 << 3; +const U8 CLASSIFIED_QUERY_FILTER_MATURE = 1 << 1; +//const U8 CLASSIFIED_QUERY_FILTER_ENABLED = 1 << 2; +//const U8 CLASSIFIED_QUERY_FILTER_PRICE = 1 << 3; // These are new with Adult-enabled viewers (1.23 and later) -const U8 CLASSIFIED_QUERY_INC_PG = 1 << 2; -const U8 CLASSIFIED_QUERY_INC_MATURE = 1 << 3; -const U8 CLASSIFIED_QUERY_INC_ADULT = 1 << 6; -const U8 CLASSIFIED_QUERY_INC_NEW_VIEWER = (CLASSIFIED_QUERY_INC_PG | CLASSIFIED_QUERY_INC_MATURE | CLASSIFIED_QUERY_INC_ADULT); +const U8 CLASSIFIED_QUERY_INC_PG = 1 << 2; +const U8 CLASSIFIED_QUERY_INC_MATURE = 1 << 3; +const U8 CLASSIFIED_QUERY_INC_ADULT = 1 << 6; +const U8 CLASSIFIED_QUERY_INC_NEW_VIEWER = (CLASSIFIED_QUERY_INC_PG | CLASSIFIED_QUERY_INC_MATURE | CLASSIFIED_QUERY_INC_ADULT); const S32 MAX_CLASSIFIEDS = 100; -// This function is used in AO viewers to pack old query flags into the request +// This function is used in AO viewers to pack old query flags into the request // so that they can talk to old dataservers properly. When the AO servers are deployed on agni // we can revert back to ClassifiedFlags pack_classified_flags and get rider of this one. ClassifiedFlags pack_classified_flags_request(bool auto_renew, bool is_pg, bool is_mature, bool is_adult); diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index c0a5e361b1..959cfb2762 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -41,7 +41,7 @@ //========================================================================= // Map of pool sizes for known pools static const std::map<std::string, U32> DefaultPoolSizes{ - {std::string("Upload"), 1}, + {std::string("Upload"), 1}, {std::string("AIS"), 1}, // *TODO: Rider for the moment keep AIS calls serialized otherwise the COF will tend to get out of sync. }; @@ -61,11 +61,11 @@ public: LLCoprocedurePool(const std::string &name, size_t size); ~LLCoprocedurePool(); - /// Places the coprocedure on the queue for processing. - /// + /// Places the coprocedure on the queue for processing. + /// /// @param name Is used for debugging and should identify this coroutine. - /// @param proc Is a bound function to be executed - /// + /// @param proc Is a bound function to be executed + /// /// @return This method returns a UUID that can be used later to cancel execution. LLUUID enqueueCoprocedure(const std::string &name, CoProcedure_t proc); @@ -91,7 +91,7 @@ public: } void close(); - + private: struct QueuedCoproc { @@ -108,7 +108,7 @@ private: CoProcedure_t mProc; }; - // we use a buffered_channel here rather than unbuffered_channel since we want to be able to + // we use a buffered_channel here rather than unbuffered_channel since we want to be able to // push values without blocking,even if there's currently no one calling a pop operation (due to // fiber running right now) typedef boost::fibers::buffered_channel<QueuedCoproc::ptr_t> CoprocQueue_t; @@ -167,7 +167,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName) if (size == 0) { - // if not found grab the know default... if there is no known + // if not found grab the know default... if there is no known // default use a reasonable number like 5. auto it = DefaultPoolSizes.find(poolName); size = (it != DefaultPoolSizes.end()) ? it->second : DEFAULT_POOL_SIZE; @@ -190,7 +190,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName) //------------------------------------------------------------------------- LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const std::string &name, CoProcedure_t proc) { - // Attempt to find the pool and enqueue the procedure. If the pool does + // Attempt to find the pool and enqueue the procedure. If the pool does // not exist, create it. poolMap_t::iterator it = mPoolMap.find(pool); @@ -355,7 +355,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL; } -LLCoprocedurePool::~LLCoprocedurePool() +LLCoprocedurePool::~LLCoprocedurePool() { } diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index c5bc37dd0e..6c6e506654 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -46,15 +46,15 @@ public: typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t; - /// Places the coprocedure on the queue for processing. - /// + /// Places the coprocedure on the queue for processing. + /// /// @param name Is used for debugging and should identify this coroutine. - /// @param proc Is a bound function to be executed - /// + /// @param proc Is a bound function to be executed + /// /// @return This method returns a UUID that can be used later to cancel execution. LLUUID enqueueCoprocedure(const std::string &pool, const std::string &name, CoProcedure_t proc); - /// Cancel a coprocedure. If the coprocedure is already being actively executed + /// Cancel a coprocedure. If the coprocedure is already being actively executed /// this method calls cancelYieldingOperation() on the associated HttpAdapter /// If it has not yet been dequeued it is simply removed from the queue. //void cancelCoprocedure(const LLUUID &id); @@ -80,7 +80,7 @@ public: void close(const std::string &pool); void initializePool(const std::string &poolName); - + private: typedef std::shared_ptr<LLCoprocedurePool> poolPtr_t; diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index fc561c6b0f..45b673b9d5 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -1,4 +1,4 @@ -/** +/** * @file llcorehttputil.h * @date 2014-08-25 * @brief Adapter and utility classes expanding the llcorehttp interfaces. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2014&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2014, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -75,20 +75,20 @@ extern const F32 HTTP_REQUEST_EXPIRY_SECS; /// the output LLSD object, out_llsd, is written with the /// result and true is returned. /// -/// @arg response Response object as returned in -/// in an HttpHandler onCompleted() callback. -/// @arg log If true, LLSD parser will emit errors -/// as LL_INFOS-level messages as it parses. -/// Otherwise, it *should* be a quiet parse. -/// @arg out_llsd Output LLSD object written only upon -/// successful parse of the response object. +/// @arg response Response object as returned in +/// in an HttpHandler onCompleted() callback. +/// @arg log If true, LLSD parser will emit errors +/// as LL_INFOS-level messages as it parses. +/// Otherwise, it *should* be a quiet parse. +/// @arg out_llsd Output LLSD object written only upon +/// successful parse of the response object. /// -/// @return Returns true (and writes to out_llsd) if -/// parse was successful. False otherwise. +/// @return Returns true (and writes to out_llsd) if +/// parse was successful. False otherwise. /// bool responseToLLSD(LLCore::HttpResponse * response, - bool log, - LLSD & out_llsd); + bool log, + LLSD & out_llsd); /// Create a std::string representation of a response object /// suitable for logging. Mainly intended for logging of @@ -104,15 +104,15 @@ std::string responseToString(LLCore::HttpResponse * response); /// One will not be provided by this call. You might look after /// the 'Accept:' header as well. /// -/// @return If request is successfully issued, the -/// HttpHandle representing the request. -/// On error, LLCORE_HTTP_HANDLE_INVALID -/// is returned and caller can fetch detailed -/// status with the getStatus() method on the -/// request object. In case of error, no -/// request is queued and caller may need to -/// perform additional cleanup such as freeing -/// a now-useless HttpHandler object. +/// @return If request is successfully issued, the +/// HttpHandle representing the request. +/// On error, LLCORE_HTTP_HANDLE_INVALID +/// is returned and caller can fetch detailed +/// status with the getStatus() method on the +/// request object. In case of error, no +/// request is queued and caller may need to +/// perform additional cleanup such as freeing +/// a now-useless HttpHandler object. /// LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request, LLCore::HttpRequest::policy_t policy_id, @@ -123,11 +123,11 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request, const LLCore::HttpHandler::ptr_t &handler); inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request, - LLCore::HttpRequest::policy_t policy_id, - const std::string & url, - const LLSD & body, - const LLCore::HttpOptions::ptr_t & options, - const LLCore::HttpHeaders::ptr_t & headers, + LLCore::HttpRequest::policy_t policy_id, + const std::string & url, + const LLSD & body, + const LLCore::HttpOptions::ptr_t & options, + const LLCore::HttpHeaders::ptr_t & headers, const LLCore::HttpHandler::ptr_t & handler) { return requestPostWithLLSD(request.get(), policy_id, @@ -154,30 +154,30 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque /// an HttpHeaders object with a correct 'Content-Type:' header. /// One will not be provided by this call. /// -/// @return If request is successfully issued, the -/// HttpHandle representing the request. -/// On error, LLCORE_HTTP_HANDLE_INVALID -/// is returned and caller can fetch detailed -/// status with the getStatus() method on the -/// request object. In case of error, no -/// request is queued and caller may need to -/// perform additional cleanup such as freeing -/// a now-useless HttpHandler object. +/// @return If request is successfully issued, the +/// HttpHandle representing the request. +/// On error, LLCORE_HTTP_HANDLE_INVALID +/// is returned and caller can fetch detailed +/// status with the getStatus() method on the +/// request object. In case of error, no +/// request is queued and caller may need to +/// perform additional cleanup such as freeing +/// a now-useless HttpHandler object. /// LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request, - LLCore::HttpRequest::policy_t policy_id, - const std::string & url, - const LLSD & body, - const LLCore::HttpOptions::ptr_t &options, - const LLCore::HttpHeaders::ptr_t &headers, + LLCore::HttpRequest::policy_t policy_id, + const std::string & url, + const LLSD & body, + const LLCore::HttpOptions::ptr_t &options, + const LLCore::HttpHeaders::ptr_t &headers, const LLCore::HttpHandler::ptr_t &handler); inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request, - LLCore::HttpRequest::policy_t policy_id, - const std::string & url, - const LLSD & body, - const LLCore::HttpOptions::ptr_t & options, - const LLCore::HttpHeaders::ptr_t & headers, + LLCore::HttpRequest::policy_t policy_id, + const std::string & url, + const LLSD & body, + const LLCore::HttpOptions::ptr_t & options, + const LLCore::HttpHeaders::ptr_t & headers, LLCore::HttpHandler::ptr_t handler) { return requestPutWithLLSD(request.get(), policy_id, @@ -203,15 +203,15 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques /// an HttpHeaders object with a correct 'Content-Type:' header. /// One will not be provided by this call. /// -/// @return If request is successfully issued, the -/// HttpHandle representing the request. -/// On error, LLCORE_HTTP_HANDLE_INVALID -/// is returned and caller can fetch detailed -/// status with the getStatus() method on the -/// request object. In case of error, no -/// request is queued and caller may need to -/// perform additional cleanup such as freeing -/// a now-useless HttpHandler object. +/// @return If request is successfully issued, the +/// HttpHandle representing the request. +/// On error, LLCORE_HTTP_HANDLE_INVALID +/// is returned and caller can fetch detailed +/// status with the getStatus() method on the +/// request object. In case of error, no +/// request is queued and caller may need to +/// perform additional cleanup such as freeing +/// a now-useless HttpHandler object. /// LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request, LLCore::HttpRequest::policy_t policy_id, @@ -247,10 +247,10 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ } //========================================================================= -/// The HttpCoroHandler is a specialization of the LLCore::HttpHandler for -/// interacting with coroutines. When the request is completed the response +/// The HttpCoroHandler is a specialization of the LLCore::HttpHandler for +/// interacting with coroutines. When the request is completed the response /// will be posted onto the supplied Event Pump. -/// +/// /// The LLSD posted back to the coroutine will have the following additions: /// llsd["http_result"] -+- ["message"] - An error message returned from the HTTP status /// +- ["status"] - The status code associated with the HTTP call @@ -258,7 +258,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ /// +- ["type"] - The LLCore::HttpStatus type associted with the HTTP call /// +- ["url"] - The URL used to make the call. /// +- ["headers"] - A map of name name value pairs with the HTTP headers. -/// +/// class HttpCoroHandler : public LLCore::HttpHandler { public: @@ -289,21 +289,21 @@ private: }; //========================================================================= -/// An adapter to handle some of the boilerplate code surrounding HTTP and coroutine +/// An adapter to handle some of the boilerplate code surrounding HTTP and coroutine /// interaction. -/// -/// Construct an HttpCoroutineAdapter giving it a name and policy Id. After -/// any application specific setup call the post, put or get method. The request +/// +/// Construct an HttpCoroutineAdapter giving it a name and policy Id. After +/// any application specific setup call the post, put or get method. The request /// will be automatically pumped and the method will return with an LLSD describing -/// the result of the operation. See HttpCoroHandler for a description of the +/// the result of the operation. See HttpCoroHandler for a description of the /// decoration done to the returned LLSD. -/// -/// Posting through the adapter will automatically add the following headers to -/// the request if they have not been previously specified in a supplied +/// +/// Posting through the adapter will automatically add the following headers to +/// the request if they have not been previously specified in a supplied /// HttpHeaders object: /// "Accept=application/llsd+xml" /// "X-SecondLife-UDP-Listen-Port=###" -/// +/// class HttpCoroutineAdapter { public: @@ -323,9 +323,9 @@ public: HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId); ~HttpCoroutineAdapter(); - /// Execute a Post transaction on the supplied URL and yield execution of - /// the coroutine until a result is available. - /// + /// Execute a Post transaction on the supplied URL and yield execution of + /// the coroutine until a result is available. + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. LLSD postAndSuspend(LLCore::HttpRequest::ptr_t request, @@ -407,9 +407,9 @@ public: - /// Execute a Put transaction on the supplied URL and yield execution of + /// Execute a Put transaction on the supplied URL and yield execution of /// the coroutine until a result is available. - /// + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. LLSD putAndSuspend(LLCore::HttpRequest::ptr_t request, @@ -437,12 +437,12 @@ public: LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers); } - /// Execute a Get transaction on the supplied URL and yield execution of + /// Execute a Get transaction on the supplied URL and yield execution of /// the coroutine until a result is available. - /// + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. - /// + /// LLSD getAndSuspend(LLCore::HttpRequest::ptr_t request, const std::string & url, LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), @@ -467,9 +467,9 @@ public: headers); } - /// These methods have the same behavior as @getAndSuspend() however they are - /// expecting the server to return the results formatted in a JSON string. - /// On a successful GET call the JSON results will be converted into LLSD + /// These methods have the same behavior as @getAndSuspend() however they are + /// expecting the server to return the results formatted in a JSON string. + /// On a successful GET call the JSON results will be converted into LLSD /// before being returned to the caller. LLSD getJsonAndSuspend(LLCore::HttpRequest::ptr_t request, const std::string & url, @@ -484,9 +484,9 @@ public: } - /// Execute a DELETE transaction on the supplied URL and yield execution of + /// Execute a DELETE transaction on the supplied URL and yield execution of /// the coroutine until a result is available. - /// + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. LLSD deleteAndSuspend(LLCore::HttpRequest::ptr_t request, @@ -501,9 +501,9 @@ public: headers); } - /// These methods have the same behavior as @deleteAndSuspend() however they are - /// expecting the server to return any results formatted in a JSON string. - /// On a successful DELETE call the JSON results will be converted into LLSD + /// These methods have the same behavior as @deleteAndSuspend() however they are + /// expecting the server to return any results formatted in a JSON string. + /// On a successful DELETE call the JSON results will be converted into LLSD /// before being returned to the caller. LLSD deleteJsonAndSuspend(LLCore::HttpRequest::ptr_t request, const std::string & url, @@ -518,9 +518,9 @@ public: } - /// Execute a PATCH transaction on the supplied URL and yield execution of - /// the coroutine until a result is available. - /// + /// Execute a PATCH transaction on the supplied URL and yield execution of + /// the coroutine until a result is available. + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. LLSD patchAndSuspend(LLCore::HttpRequest::ptr_t request, @@ -535,12 +535,12 @@ public: LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers); } - /// Execute a COPY transaction on the supplied URL and yield execution of - /// the coroutine until a result is available. - /// + /// Execute a COPY transaction on the supplied URL and yield execution of + /// the coroutine until a result is available. + /// /// @Note: The destination is passed through the HTTP pipe as a header /// The header used is defined as: HTTP_OUT_HEADER_DESTINATION("Destination"); - /// + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. LLSD copyAndSuspend(LLCore::HttpRequest::ptr_t request, @@ -555,12 +555,12 @@ public: LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers); } - /// Execute a MOVE transaction on the supplied URL and yield execution of - /// the coroutine until a result is available. - /// + /// Execute a MOVE transaction on the supplied URL and yield execution of + /// the coroutine until a result is available. + /// /// @Note: The destination is passed through the HTTP pipe in the headers. /// The header used is defined as: HTTP_OUT_HEADER_DESTINATION("Destination"); - /// + /// /// @Note: the request's smart pointer is passed by value so that it will /// not be deallocated during the yield. LLSD moveAndSuspend(LLCore::HttpRequest::ptr_t request, @@ -580,7 +580,7 @@ public: static LLCore::HttpStatus getStatusFromLLSD(const LLSD &httpResults); - /// The convenience routines below can be provided with callback functors + /// The convenience routines below can be provided with callback functors /// which will be invoked in the case of success or failure. These callbacks /// should match this form. /// @sa callbackHttpGet @@ -603,9 +603,9 @@ public: /// Generic Get and post routines for HTTP via coroutines. /// These static methods do all required setup for the GET or POST operation. - /// When the operation completes successfully they will put the success message in the log at INFO level, + /// When the operation completes successfully they will put the success message in the log at INFO level, /// If the operation fails the failure message is written to the log at WARN level. - /// + /// static void messageHttpGet(const std::string &url, const std::string &success = std::string(), const std::string &failure = std::string()); static void messageHttpPost(const std::string &url, const LLSD &postData, const std::string &success, const std::string &failure); @@ -638,7 +638,7 @@ private: HttpCoroHandler::ptr_t &handler); LLSD getAndSuspend_(LLCore::HttpRequest::ptr_t &request, - const std::string & url, LLCore::HttpOptions::ptr_t &options, + const std::string & url, LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, HttpCoroHandler::ptr_t &handler); LLSD deleteAndSuspend_(LLCore::HttpRequest::ptr_t &request, @@ -651,7 +651,7 @@ private: HttpCoroHandler::ptr_t &handler); LLSD copyAndSuspend_(LLCore::HttpRequest::ptr_t &request, - const std::string & url, + const std::string & url, LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, HttpCoroHandler::ptr_t &handler); diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index 1545443798..134f34aafa 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldatapacker.cpp * @brief Data packer implementation. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,118 +52,118 @@ LLDataPacker::LLDataPacker() : mPassFlags(0), mWriteEnabled(false) //virtual void LLDataPacker::reset() { - LL_ERRS() << "Using unimplemented datapacker reset!" << LL_ENDL; + LL_ERRS() << "Using unimplemented datapacker reset!" << LL_ENDL; } //virtual void LLDataPacker::dumpBufferToLog() { - LL_ERRS() << "dumpBufferToLog not implemented for this type!" << LL_ENDL; + LL_ERRS() << "dumpBufferToLog not implemented for this type!" << LL_ENDL; } bool LLDataPacker::packFixed(const F32 value, const char *name, - const bool is_signed, const U32 int_bits, const U32 frac_bits) -{ - bool success = true; - S32 unsigned_bits = int_bits + frac_bits; - S32 total_bits = unsigned_bits; - - if (is_signed) - { - total_bits++; - } - - S32 min_val; - U32 max_val; - if (is_signed) - { - min_val = 1 << int_bits; - min_val *= -1; - } - else - { - min_val = 0; - } - max_val = 1 << int_bits; - - // Clamp to be within range - F32 fixed_val = llclamp(value, (F32)min_val, (F32)max_val); - if (is_signed) - { - fixed_val += max_val; - } - fixed_val *= 1 << frac_bits; - - if (total_bits <= 8) - { - packU8((U8)fixed_val, name); - } - else if (total_bits <= 16) - { - packU16((U16)fixed_val, name); - } - else if (total_bits <= 31) - { - packU32((U32)fixed_val, name); - } - else - { - LL_ERRS() << "Using fixed-point packing of " << total_bits << " bits, why?!" << LL_ENDL; - } - return success; + const bool is_signed, const U32 int_bits, const U32 frac_bits) +{ + bool success = true; + S32 unsigned_bits = int_bits + frac_bits; + S32 total_bits = unsigned_bits; + + if (is_signed) + { + total_bits++; + } + + S32 min_val; + U32 max_val; + if (is_signed) + { + min_val = 1 << int_bits; + min_val *= -1; + } + else + { + min_val = 0; + } + max_val = 1 << int_bits; + + // Clamp to be within range + F32 fixed_val = llclamp(value, (F32)min_val, (F32)max_val); + if (is_signed) + { + fixed_val += max_val; + } + fixed_val *= 1 << frac_bits; + + if (total_bits <= 8) + { + packU8((U8)fixed_val, name); + } + else if (total_bits <= 16) + { + packU16((U16)fixed_val, name); + } + else if (total_bits <= 31) + { + packU32((U32)fixed_val, name); + } + else + { + LL_ERRS() << "Using fixed-point packing of " << total_bits << " bits, why?!" << LL_ENDL; + } + return success; } bool LLDataPacker::unpackFixed(F32 &value, const char *name, - const bool is_signed, const U32 int_bits, const U32 frac_bits) -{ - bool success = true; - //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL; - S32 unsigned_bits = int_bits + frac_bits; - S32 total_bits = unsigned_bits; - - if (is_signed) - { - total_bits++; - } - - U32 max_val; - max_val = 1 << int_bits; - - F32 fixed_val; - if (total_bits <= 8) - { - U8 fixed_8; - success = unpackU8(fixed_8, name); - fixed_val = (F32)fixed_8; - } - else if (total_bits <= 16) - { - U16 fixed_16; - success = unpackU16(fixed_16, name); - fixed_val = (F32)fixed_16; - } - else if (total_bits <= 31) - { - U32 fixed_32; - success = unpackU32(fixed_32, name); - fixed_val = (F32)fixed_32; - } - else - { - fixed_val = 0; - LL_ERRS() << "Bad bit count: " << total_bits << LL_ENDL; - } - - //LL_INFOS() << "Fixed_val:" << fixed_val << LL_ENDL; - - fixed_val /= (F32)(1 << frac_bits); - if (is_signed) - { - fixed_val -= max_val; - } - value = fixed_val; - //LL_INFOS() << "Value: " << value << LL_ENDL; - return success; + const bool is_signed, const U32 int_bits, const U32 frac_bits) +{ + bool success = true; + //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL; + S32 unsigned_bits = int_bits + frac_bits; + S32 total_bits = unsigned_bits; + + if (is_signed) + { + total_bits++; + } + + U32 max_val; + max_val = 1 << int_bits; + + F32 fixed_val; + if (total_bits <= 8) + { + U8 fixed_8; + success = unpackU8(fixed_8, name); + fixed_val = (F32)fixed_8; + } + else if (total_bits <= 16) + { + U16 fixed_16; + success = unpackU16(fixed_16, name); + fixed_val = (F32)fixed_16; + } + else if (total_bits <= 31) + { + U32 fixed_32; + success = unpackU32(fixed_32, name); + fixed_val = (F32)fixed_32; + } + else + { + fixed_val = 0; + LL_ERRS() << "Bad bit count: " << total_bits << LL_ENDL; + } + + //LL_INFOS() << "Fixed_val:" << fixed_val << LL_ENDL; + + fixed_val /= (F32)(1 << frac_bits); + if (is_signed) + { + fixed_val -= max_val; + } + value = fixed_val; + //LL_INFOS() << "Value: " << value << LL_ENDL; + return success; } bool LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name) @@ -237,67 +237,67 @@ bool LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name) bool LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name) { - S32 length = value.length()+1; + S32 length = value.length()+1; - if (!verifyLength(length, name)) - { - return false; - } + if (!verifyLength(length, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length); - } - mCurBufferp += length; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length); + } + mCurBufferp += length; + return true; } bool LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name) { - S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ + S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ - if (!verifyLength(length, name)) - { - return false; - } + if (!verifyLength(length, name)) + { + return false; + } + + value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen() - value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen() - - mCurBufferp += length; - return true; + mCurBufferp += length; + return true; } bool LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name) { - if (!verifyLength(size + 4, name)) - { - return false; - } + if (!verifyLength(size + 4, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, &size, MVT_S32, 4); - } - mCurBufferp += 4; - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); - } - mCurBufferp += size; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &size, MVT_S32, 4); + } + mCurBufferp += 4; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); + } + mCurBufferp += size; + return true; } bool LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) { - if (!verifyLength(4, name)) - { - LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; - return false; - } + if (!verifyLength(4, name)) + { + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return false; + } - htolememcpy(&size, mCurBufferp, MVT_S32, 4); + htolememcpy(&size, mCurBufferp, MVT_S32, 4); if (size < 0) { @@ -305,104 +305,104 @@ bool LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char return false; } - mCurBufferp += 4; + mCurBufferp += 4; - if (!verifyLength(size, name)) - { - LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; - return false; - } + if (!verifyLength(size, name)) + { + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return false; + } - htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); - mCurBufferp += size; + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; - return true; + return true; } bool LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) { - if (!verifyLength(size, name)) - { - return false; - } + if (!verifyLength(size, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); - } - mCurBufferp += size; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); + } + mCurBufferp += size; + return true; } bool LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) { - if (!verifyLength(size, name)) - { - return false; - } - htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); - mCurBufferp += size; - return true; + if (!verifyLength(size, name)) + { + return false; + } + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + return true; } bool LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name) { - if (!verifyLength(sizeof(U8), name)) - { - return false; - } + if (!verifyLength(sizeof(U8), name)) + { + return false; + } - if (mWriteEnabled) - { - *mCurBufferp = value; - } - mCurBufferp++; - return true; + if (mWriteEnabled) + { + *mCurBufferp = value; + } + mCurBufferp++; + return true; } bool LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name) { - if (!verifyLength(sizeof(U8), name)) - { - return false; - } + if (!verifyLength(sizeof(U8), name)) + { + return false; + } - value = *mCurBufferp; - mCurBufferp++; - return true; + value = *mCurBufferp; + mCurBufferp++; + return true; } bool LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name) { - if (!verifyLength(sizeof(U16), name)) - { - return false; - } + if (!verifyLength(sizeof(U16), name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, &value, MVT_U16, 2); - } - mCurBufferp += 2; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_U16, 2); + } + mCurBufferp += 2; + return true; } bool LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name) { - if (!verifyLength(sizeof(U16), name)) - { - return false; - } + if (!verifyLength(sizeof(U16), name)) + { + return false; + } - htolememcpy(&value, mCurBufferp, MVT_U16, 2); - mCurBufferp += 2; - return true; + htolememcpy(&value, mCurBufferp, MVT_U16, 2); + mCurBufferp += 2; + return true; } bool LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name) @@ -431,299 +431,299 @@ bool LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name) bool LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name) { - if (!verifyLength(sizeof(U32), name)) - { - return false; - } + if (!verifyLength(sizeof(U32), name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, &value, MVT_U32, 4); - } - mCurBufferp += 4; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_U32, 4); + } + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name) { - if (!verifyLength(sizeof(U32), name)) - { - return false; - } + if (!verifyLength(sizeof(U32), name)) + { + return false; + } - htolememcpy(&value, mCurBufferp, MVT_U32, 4); - mCurBufferp += 4; - return true; + htolememcpy(&value, mCurBufferp, MVT_U32, 4); + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name) { - if (!verifyLength(sizeof(S32), name)) - { - return false; - } + if (!verifyLength(sizeof(S32), name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, &value, MVT_S32, 4); - } - mCurBufferp += 4; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_S32, 4); + } + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name) { - if(!verifyLength(sizeof(S32), name)) - { - return false; - } + if(!verifyLength(sizeof(S32), name)) + { + return false; + } - htolememcpy(&value, mCurBufferp, MVT_S32, 4); - mCurBufferp += 4; - return true; + htolememcpy(&value, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name) { - if (!verifyLength(sizeof(F32), name)) - { - return false; - } + if (!verifyLength(sizeof(F32), name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, &value, MVT_F32, 4); - } - mCurBufferp += 4; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_F32, 4); + } + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name) { - if (!verifyLength(sizeof(F32), name)) - { - return false; - } + if (!verifyLength(sizeof(F32), name)) + { + return false; + } - htolememcpy(&value, mCurBufferp, MVT_F32, 4); - mCurBufferp += 4; - return true; + htolememcpy(&value, mCurBufferp, MVT_F32, 4); + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name) { - if (!verifyLength(16, name)) - { - return false; - } + if (!verifyLength(16, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); - } - mCurBufferp += 16; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); + } + mCurBufferp += 16; + return true; } bool LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name) { - if (!verifyLength(16, name)) - { - return false; - } + if (!verifyLength(16, name)) + { + return false; + } - htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); - mCurBufferp += 16; - return true; + htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); + mCurBufferp += 16; + return true; } bool LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name) { - if (!verifyLength(4, name)) - { - return false; - } + if (!verifyLength(4, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); - } - mCurBufferp += 4; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); + } + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name) { - if (!verifyLength(4, name)) - { - return false; - } + if (!verifyLength(4, name)) + { + return false; + } - htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); - mCurBufferp += 4; - return true; + htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); + mCurBufferp += 4; + return true; } bool LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name) { - if (!verifyLength(8, name)) - { - return false; - } + if (!verifyLength(8, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, &value.mV[0], MVT_F32, 4); - htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); - } - mCurBufferp += 8; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value.mV[0], MVT_F32, 4); + htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); + } + mCurBufferp += 8; + return true; } bool LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name) { - if (!verifyLength(8, name)) - { - return false; - } + if (!verifyLength(8, name)) + { + return false; + } - htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); - htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); - mCurBufferp += 8; - return true; + htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); + htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); + mCurBufferp += 8; + return true; } bool LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name) { - if (!verifyLength(12, name)) - { - return false; - } + if (!verifyLength(12, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); - } - mCurBufferp += 12; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); + } + mCurBufferp += 12; + return true; } bool LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name) { - if (!verifyLength(12, name)) - { - return false; - } + if (!verifyLength(12, name)) + { + return false; + } - htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); - mCurBufferp += 12; - return true; + htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); + mCurBufferp += 12; + return true; } bool LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name) { - if (!verifyLength(16, name)) - { - return false; - } + if (!verifyLength(16, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); - } - mCurBufferp += 16; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); + } + mCurBufferp += 16; + return true; } bool LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name) { - if (!verifyLength(16, name)) - { - return false; - } + if (!verifyLength(16, name)) + { + return false; + } - htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); - mCurBufferp += 16; - return true; + htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); + mCurBufferp += 16; + return true; } bool LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name) { - if (!verifyLength(16, name)) - { - return false; - } + if (!verifyLength(16, name)) + { + return false; + } - if (mWriteEnabled) - { - htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); - } - mCurBufferp += 16; - return true; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); + } + mCurBufferp += 16; + return true; } bool LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name) { - if (!verifyLength(16, name)) - { - return false; - } + if (!verifyLength(16, name)) + { + return false; + } - htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); - mCurBufferp += 16; - return true; + htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); + mCurBufferp += 16; + return true; } -const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) +const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) { - if (a.getBufferSize() > getBufferSize()) - { - // We've got problems, ack! - LL_ERRS() << "Trying to do an assignment with not enough room in the target." << LL_ENDL; - } - memcpy(mBufferp, a.mBufferp, a.getBufferSize()); /*Flawfinder: ignore*/ - return *this; + if (a.getBufferSize() > getBufferSize()) + { + // We've got problems, ack! + LL_ERRS() << "Trying to do an assignment with not enough room in the target." << LL_ENDL; + } + memcpy(mBufferp, a.mBufferp, a.getBufferSize()); /*Flawfinder: ignore*/ + return *this; } void LLDataPackerBinaryBuffer::dumpBufferToLog() { - LL_WARNS() << "Binary Buffer Dump, size: " << mBufferSize << LL_ENDL; - char line_buffer[256]; /*Flawfinder: ignore*/ - S32 i; - S32 cur_line_pos = 0; - - S32 cur_line = 0; - for (i = 0; i < mBufferSize; i++) - { - snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer) - cur_line_pos*3, "%02x ", mBufferp[i]); /* Flawfinder: ignore */ - cur_line_pos++; - if (cur_line_pos >= 16) - { - cur_line_pos = 0; - LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL; - cur_line++; - } - } - if (cur_line_pos) - { - LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL; - } + LL_WARNS() << "Binary Buffer Dump, size: " << mBufferSize << LL_ENDL; + char line_buffer[256]; /*Flawfinder: ignore*/ + S32 i; + S32 cur_line_pos = 0; + + S32 cur_line = 0; + for (i = 0; i < mBufferSize; i++) + { + snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer) - cur_line_pos*3, "%02x ", mBufferp[i]); /* Flawfinder: ignore */ + cur_line_pos++; + if (cur_line_pos >= 16) + { + cur_line_pos = 0; + LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL; + cur_line++; + } + } + if (cur_line_pos) + { + LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL; + } } //--------------------------------------------------------------------------- @@ -731,300 +731,300 @@ void LLDataPackerBinaryBuffer::dumpBufferToLog() //--------------------------------------------------------------------------- bool LLDataPackerAsciiBuffer::packString(const std::string& value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", value.c_str()); /* Flawfinder: ignore */ - } - else - { - numCopied = value.length() + 1; /*Flawfinder: ignore*/ - } - - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - // *NOTE: I believe we need to mark a failure bit at this point. - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packString: string truncated: " << value << LL_ENDL; - } - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", value.c_str()); /* Flawfinder: ignore */ + } + else + { + numCopied = value.length() + 1; /*Flawfinder: ignore*/ + } + + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + // *NOTE: I believe we need to mark a failure bit at this point. + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packString: string truncated: " << value << LL_ENDL; + } + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name) { - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated - { - return false; - } - value = valuestr; - return true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated + { + return false; + } + value = valuestr; + return true; } bool LLDataPackerAsciiBuffer::packBinaryData(const U8 *value, S32 size, const char *name) { - bool success = true; - writeIndentedName(name); - - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%010d ", size); /* Flawfinder: ignore */ - - // snprintf returns number of bytes that would have been - // written had the output not being truncated. In that case, - // it will retuen >= passed in size value. so a check needs - // to be added to detect truncation, and if there is any, only - // account for the actual number of bytes written..and not - // what could have been written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: number truncated: " << size << LL_ENDL; - } - mCurBufferp += numCopied; - - - S32 i; - bool bBufferFull = false; - for (i = 0; i < size && !bBufferFull; i++) - { - numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */ - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: data truncated: " << LL_ENDL; - bBufferFull = true; - } - mCurBufferp += numCopied; - } - - if (!bBufferFull) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: newline truncated: " << LL_ENDL; - } - mCurBufferp += numCopied; - } - } - else - { - // why +10 ?? XXXCHECK - numCopied = 10 + 1; // size plus newline - numCopied += size; - if (numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - } - mCurBufferp += numCopied; - } - - return success; + bool success = true; + writeIndentedName(name); + + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%010d ", size); /* Flawfinder: ignore */ + + // snprintf returns number of bytes that would have been + // written had the output not being truncated. In that case, + // it will retuen >= passed in size value. so a check needs + // to be added to detect truncation, and if there is any, only + // account for the actual number of bytes written..and not + // what could have been written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: number truncated: " << size << LL_ENDL; + } + mCurBufferp += numCopied; + + + S32 i; + bool bBufferFull = false; + for (i = 0; i < size && !bBufferFull; i++) + { + numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */ + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: data truncated: " << LL_ENDL; + bBufferFull = true; + } + mCurBufferp += numCopied; + } + + if (!bBufferFull) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: newline truncated: " << LL_ENDL; + } + mCurBufferp += numCopied; + } + } + else + { + // why +10 ?? XXXCHECK + numCopied = 10 + 1; // size plus newline + numCopied += size; + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + } + + return success; } bool LLDataPackerAsciiBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - char *cur_pos = &valuestr[0]; - sscanf(valuestr,"%010d", &size); - cur_pos += 11; + char *cur_pos = &valuestr[0]; + sscanf(valuestr,"%010d", &size); + cur_pos += 11; - S32 i; - for (i = 0; i < size; i++) - { - S32 val; - sscanf(cur_pos,"%02x", &val); - value[i] = val; - cur_pos += 3; - } - return success; + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; } bool LLDataPackerAsciiBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) { - bool success = true; - writeIndentedName(name); - - if (mWriteEnabled) - { - S32 i; - int numCopied = 0; - bool bBufferFull = false; - for (i = 0; i < size && !bBufferFull; i++) - { - numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */ - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: data truncated: " << LL_ENDL; - bBufferFull = true; - } - mCurBufferp += numCopied; - - } - if (!bBufferFull) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: newline truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - } - } - else - { - int numCopied = 2 * size + 1; //hex bytes plus newline - if (numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - } - mCurBufferp += numCopied; - } - return success; + bool success = true; + writeIndentedName(name); + + if (mWriteEnabled) + { + S32 i; + int numCopied = 0; + bool bBufferFull = false; + for (i = 0; i < size && !bBufferFull; i++) + { + numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */ + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: data truncated: " << LL_ENDL; + bBufferFull = true; + } + mCurBufferp += numCopied; + + } + if (!bBufferFull) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: newline truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + } + } + else + { + int numCopied = 2 * size + 1; //hex bytes plus newline + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + } + return success; } bool LLDataPackerAsciiBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - char *cur_pos = &valuestr[0]; + char *cur_pos = &valuestr[0]; - S32 i; - for (i = 0; i < size; i++) - { - S32 val; - sscanf(cur_pos,"%02x", &val); - value[i] = val; - cur_pos += 3; - } - return success; + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; } bool LLDataPackerAsciiBuffer::packU8(const U8 value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ - } - else - { - // just do the write to a temp buffer to get the length - numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ - } - - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packU8: val truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ + } + else + { + // just do the write to a temp buffer to get the length + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ + } + + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packU8: val truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + + return success; } bool LLDataPackerAsciiBuffer::unpackU8(U8 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - S32 in_val; - sscanf(valuestr,"%d", &in_val); - value = in_val; - return success; + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; } bool LLDataPackerAsciiBuffer::packU16(const U16 value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ - } + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ + } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packU16: val truncated: " << LL_ENDL; - } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packU16: val truncated: " << LL_ENDL; + } - mCurBufferp += numCopied; + mCurBufferp += numCopied; - return success; + return success; } bool LLDataPackerAsciiBuffer::unpackU16(U16 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - S32 in_val; - sscanf(valuestr,"%d", &in_val); - value = in_val; - return success; + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; } bool LLDataPackerAsciiBuffer::packS16(const S16 value, const char *name) @@ -1076,497 +1076,497 @@ bool LLDataPackerAsciiBuffer::unpackS16(S16 &value, const char *name) bool LLDataPackerAsciiBuffer::packU32(const U32 value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%u\n", value); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%u\n", value); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packU32: val truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%u\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%u\n", value); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packU32: val truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackU32(U32 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%u", &value); - return success; + sscanf(valuestr,"%u", &value); + return success; } bool LLDataPackerAsciiBuffer::packS32(const S32 value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packS32: val truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packS32: val truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackS32(S32 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%d", &value); - return success; + sscanf(valuestr,"%d", &value); + return success; } bool LLDataPackerAsciiBuffer::packF32(const F32 value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f\n", value); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\n", value); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packF32: val truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\n", value); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packF32: val truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackF32(F32 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f", &value); - return success; + sscanf(valuestr,"%f", &value); + return success; } bool LLDataPackerAsciiBuffer::packColor4(const LLColor4 &value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4: truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackColor4(LLColor4 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); - return success; + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; } bool LLDataPackerAsciiBuffer::packColor4U(const LLColor4U &value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4U: truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4U: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackColor4U(LLColor4U &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - S32 r, g, b, a; + S32 r, g, b, a; - sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a); - value.mV[0] = r; - value.mV[1] = g; - value.mV[2] = b; - value.mV[3] = a; - return success; + sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a); + value.mV[0] = r; + value.mV[1] = g; + value.mV[2] = b; + value.mV[3] = a; + return success; } bool LLDataPackerAsciiBuffer::packVector2(const LLVector2 &value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packVector2: truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packVector2: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackVector2(LLVector2 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]); - return success; + sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]); + return success; } bool LLDataPackerAsciiBuffer::packVector3(const LLVector3 &value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packVector3: truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packVector3: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackVector3(LLVector3 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]); - return success; + sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]); + return success; } bool LLDataPackerAsciiBuffer::packVector4(const LLVector4 &value, const char *name) { - bool success = true; - writeIndentedName(name); - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ - } - else - { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packVector4: truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packVector4: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackVector4(LLVector4 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); - return success; + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; } bool LLDataPackerAsciiBuffer::packUUID(const LLUUID &value, const char *name) { - bool success = true; - writeIndentedName(name); - - int numCopied = 0; - if (mWriteEnabled) - { - std::string tmp_str; - value.toString(tmp_str); - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", tmp_str.c_str()); /* Flawfinder: ignore */ - } - else - { - numCopied = 64 + 1; // UUID + newline - } - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::packUUID: truncated: " << LL_ENDL; - success = false; - } - mCurBufferp += numCopied; - return success; + bool success = true; + writeIndentedName(name); + + int numCopied = 0; + if (mWriteEnabled) + { + std::string tmp_str; + value.toString(tmp_str); + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", tmp_str.c_str()); /* Flawfinder: ignore */ + } + else + { + numCopied = 64 + 1; // UUID + newline + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packUUID: truncated: " << LL_ENDL; + success = false; + } + mCurBufferp += numCopied; + return success; } bool LLDataPackerAsciiBuffer::unpackUUID(LLUUID &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - char tmp_str[64]; /* Flawfinder: ignore */ - sscanf(valuestr, "%63s", tmp_str); /* Flawfinder: ignore */ - value.set(tmp_str); + char tmp_str[64]; /* Flawfinder: ignore */ + sscanf(valuestr, "%63s", tmp_str); /* Flawfinder: ignore */ + value.set(tmp_str); - return success; + return success; } void LLDataPackerAsciiBuffer::dump() { - LL_INFOS() << "Buffer: " << mBufferp << LL_ENDL; + LL_INFOS() << "Buffer: " << mBufferp << LL_ENDL; } void LLDataPackerAsciiBuffer::writeIndentedName(const char *name) { - if (mIncludeNames) - { - int numCopied = 0; - if (mWriteEnabled) - { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\t", name); /* Flawfinder: ignore */ - } - else - { - numCopied = (S32)strlen(name) + 1; /* Flawfinder: ignore */ //name + tab - } - - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) - { - numCopied = getBufferSize()-getCurrentSize(); - LL_WARNS() << "LLDataPackerAsciiBuffer::writeIndentedName: truncated: " << LL_ENDL; - } - - mCurBufferp += numCopied; - } + if (mIncludeNames) + { + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\t", name); /* Flawfinder: ignore */ + } + else + { + numCopied = (S32)strlen(name) + 1; /* Flawfinder: ignore */ //name + tab + } + + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::writeIndentedName: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + } } bool LLDataPackerAsciiBuffer::getValueStr(const char *name, char *out_value, S32 value_len) { - bool success = true; - char buffer[DP_BUFSIZE]; /* Flawfinder: ignore */ - char keyword[DP_BUFSIZE]; /* Flawfinder: ignore */ - char value[DP_BUFSIZE]; /* Flawfinder: ignore */ - - buffer[0] = '\0'; - keyword[0] = '\0'; - value[0] = '\0'; - - if (mIncludeNames) - { - // Read both the name and the value, and validate the name. - sscanf(mCurBufferp, "%511[^\n]", buffer); - // Skip the \n - mCurBufferp += (S32)strlen(buffer) + 1; /* Flawfinder: ignore */ - - sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ - - if (strcmp(keyword, name)) - { - LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; - return false; - } - } - else - { - // Just the value exists - sscanf(mCurBufferp, "%511[^\n]", value); - // Skip the \n - mCurBufferp += (S32)strlen(value) + 1; /* Flawfinder: ignore */ - } - - S32 in_value_len = (S32)strlen(value)+1; /* Flawfinder: ignore */ - S32 min_len = llmin(in_value_len, value_len); - memcpy(out_value, value, min_len); /* Flawfinder: ignore */ - out_value[min_len-1] = 0; - - return success; + bool success = true; + char buffer[DP_BUFSIZE]; /* Flawfinder: ignore */ + char keyword[DP_BUFSIZE]; /* Flawfinder: ignore */ + char value[DP_BUFSIZE]; /* Flawfinder: ignore */ + + buffer[0] = '\0'; + keyword[0] = '\0'; + value[0] = '\0'; + + if (mIncludeNames) + { + // Read both the name and the value, and validate the name. + sscanf(mCurBufferp, "%511[^\n]", buffer); + // Skip the \n + mCurBufferp += (S32)strlen(buffer) + 1; /* Flawfinder: ignore */ + + sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ + + if (strcmp(keyword, name)) + { + LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; + return false; + } + } + else + { + // Just the value exists + sscanf(mCurBufferp, "%511[^\n]", value); + // Skip the \n + mCurBufferp += (S32)strlen(value) + 1; /* Flawfinder: ignore */ + } + + S32 in_value_len = (S32)strlen(value)+1; /* Flawfinder: ignore */ + S32 min_len = llmin(in_value_len, value_len); + memcpy(out_value, value, min_len); /* Flawfinder: ignore */ + out_value[min_len-1] = 0; + + return success; } // helper function used by LLDataPackerAsciiFile // to convert F32 into a string. This is to avoid -// << operator writing F32 value into a stream +// << operator writing F32 value into a stream // since it does not seem to preserve the float value std::string convertF32ToString(F32 val) { - std::string str; - char buf[20]; - snprintf(buf, 20, "%f", val); - str = buf; - return str; + std::string str; + char buf[20]; + snprintf(buf, 20, "%f", val); + str = buf; + return str; } //--------------------------------------------------------------------------- @@ -1574,206 +1574,206 @@ std::string convertF32ToString(F32 val) //--------------------------------------------------------------------------- bool LLDataPackerAsciiFile::packString(const std::string& value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%s\n", value.c_str()); - } - else if (mOutputStream) - { - *mOutputStream << value << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%s\n", value.c_str()); + } + else if (mOutputStream) + { + *mOutputStream << value << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackString(std::string& value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } - value = valuestr; - return success; + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } + value = valuestr; + return success; } bool LLDataPackerAsciiFile::packBinaryData(const U8 *value, S32 size, const char *name) { - bool success = true; - writeIndentedName(name); - - if (mFP) - { - fprintf(mFP, "%010d ", size); - - S32 i; - for (i = 0; i < size; i++) - { - fprintf(mFP, "%02x ", value[i]); - } - fprintf(mFP, "\n"); - } - else if (mOutputStream) - { - char buffer[32]; /* Flawfinder: ignore */ - snprintf(buffer,sizeof(buffer), "%010d ", size); /* Flawfinder: ignore */ - *mOutputStream << buffer; - - S32 i; - for (i = 0; i < size; i++) - { - snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */ - *mOutputStream << buffer; - } - *mOutputStream << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + + if (mFP) + { + fprintf(mFP, "%010d ", size); + + S32 i; + for (i = 0; i < size; i++) + { + fprintf(mFP, "%02x ", value[i]); + } + fprintf(mFP, "\n"); + } + else if (mOutputStream) + { + char buffer[32]; /* Flawfinder: ignore */ + snprintf(buffer,sizeof(buffer), "%010d ", size); /* Flawfinder: ignore */ + *mOutputStream << buffer; + + S32 i; + for (i = 0; i < size; i++) + { + snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */ + *mOutputStream << buffer; + } + *mOutputStream << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackBinaryData(U8 *value, S32 &size, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - char *cur_pos = &valuestr[0]; - sscanf(valuestr,"%010d", &size); - cur_pos += 11; + char *cur_pos = &valuestr[0]; + sscanf(valuestr,"%010d", &size); + cur_pos += 11; - S32 i; - for (i = 0; i < size; i++) - { - S32 val; - sscanf(cur_pos,"%02x", &val); - value[i] = val; - cur_pos += 3; - } - return success; + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; } bool LLDataPackerAsciiFile::packBinaryDataFixed(const U8 *value, S32 size, const char *name) { - bool success = true; - writeIndentedName(name); - - if (mFP) - { - S32 i; - for (i = 0; i < size; i++) - { - fprintf(mFP, "%02x ", value[i]); - } - fprintf(mFP, "\n"); - } - else if (mOutputStream) - { - char buffer[32]; /*Flawfinder: ignore*/ - S32 i; - for (i = 0; i < size; i++) - { - snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */ - *mOutputStream << buffer; - } - *mOutputStream << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + + if (mFP) + { + S32 i; + for (i = 0; i < size; i++) + { + fprintf(mFP, "%02x ", value[i]); + } + fprintf(mFP, "\n"); + } + else if (mOutputStream) + { + char buffer[32]; /*Flawfinder: ignore*/ + S32 i; + for (i = 0; i < size; i++) + { + snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */ + *mOutputStream << buffer; + } + *mOutputStream << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - char *cur_pos = &valuestr[0]; + char *cur_pos = &valuestr[0]; - S32 i; - for (i = 0; i < size; i++) - { - S32 val; - sscanf(cur_pos,"%02x", &val); - value[i] = val; - cur_pos += 3; - } - return success; + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; } bool LLDataPackerAsciiFile::packU8(const U8 value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%d\n", value); - } - else if (mOutputStream) - { - // We have to cast this to an integer because streams serialize - // bytes as bytes - not as text. - *mOutputStream << (S32)value << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d\n", value); + } + else if (mOutputStream) + { + // We have to cast this to an integer because streams serialize + // bytes as bytes - not as text. + *mOutputStream << (S32)value << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackU8(U8 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - S32 in_val; - sscanf(valuestr,"%d", &in_val); - value = in_val; - return success; + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; } bool LLDataPackerAsciiFile::packU16(const U16 value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%d\n", value); - } - else if (mOutputStream) - { - *mOutputStream <<"" << value << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackU16(U16 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - S32 in_val; - sscanf(valuestr,"%d", &in_val); - value = in_val; - return success; + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; } bool LLDataPackerAsciiFile::packS16(const S16 value, const char *name) @@ -1782,7 +1782,7 @@ bool LLDataPackerAsciiFile::packS16(const S16 value, const char *name) writeIndentedName(name); if (mFP) { - fprintf(mFP, "%d\n", value); + fprintf(mFP, "%d\n", value); } else if (mOutputStream) { @@ -1809,372 +1809,372 @@ bool LLDataPackerAsciiFile::unpackS16(S16 &value, const char *name) bool LLDataPackerAsciiFile::packU32(const U32 value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%u\n", value); - } - else if (mOutputStream) - { - *mOutputStream <<"" << value << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%u\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackU32(U32 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%u", &value); - return success; + sscanf(valuestr,"%u", &value); + return success; } bool LLDataPackerAsciiFile::packS32(const S32 value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%d\n", value); - } - else if (mOutputStream) - { - *mOutputStream <<"" << value << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackS32(S32 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%d", &value); - return success; + sscanf(valuestr,"%d", &value); + return success; } bool LLDataPackerAsciiFile::packF32(const F32 value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%f\n", value); - } - else if (mOutputStream) - { - *mOutputStream <<"" << convertF32ToString(value) << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%f\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << convertF32ToString(value) << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackF32(F32 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f", &value); - return success; + sscanf(valuestr,"%f", &value); + return success; } bool LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); - } - else if (mOutputStream) - { - *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackColor4(LLColor4 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); - return success; + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; } bool LLDataPackerAsciiFile::packColor4U(const LLColor4U &value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); - } - else if (mOutputStream) - { - *mOutputStream << (S32)(value.mV[0]) << " " << (S32)(value.mV[1]) << " " << (S32)(value.mV[2]) << " " << (S32)(value.mV[3]) << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << (S32)(value.mV[0]) << " " << (S32)(value.mV[1]) << " " << (S32)(value.mV[2]) << " " << (S32)(value.mV[3]) << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackColor4U(LLColor4U &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - S32 r, g, b, a; + S32 r, g, b, a; - sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a); - value.mV[0] = r; - value.mV[1] = g; - value.mV[2] = b; - value.mV[3] = a; - return success; + sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a); + value.mV[0] = r; + value.mV[1] = g; + value.mV[2] = b; + value.mV[3] = a; + return success; } bool LLDataPackerAsciiFile::packVector2(const LLVector2 &value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%f %f\n", value.mV[0], value.mV[1]); - } - else if (mOutputStream) - { - *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%f %f\n", value.mV[0], value.mV[1]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackVector2(LLVector2 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]); - return success; + sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]); + return success; } bool LLDataPackerAsciiFile::packVector3(const LLVector3 &value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); - } - else if (mOutputStream) - { - *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackVector3(LLVector3 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]); - return success; + sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]); + return success; } bool LLDataPackerAsciiFile::packVector4(const LLVector4 &value, const char *name) { - bool success = true; - writeIndentedName(name); - if (mFP) - { - fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); - } - else if (mOutputStream) - { - *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackVector4(LLVector4 &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); - return success; + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; } bool LLDataPackerAsciiFile::packUUID(const LLUUID &value, const char *name) { - bool success = true; - writeIndentedName(name); - std::string tmp_str; - value.toString(tmp_str); - if (mFP) - { - fprintf(mFP,"%s\n", tmp_str.c_str()); - } - else if (mOutputStream) - { - *mOutputStream <<"" << tmp_str << "\n"; - } - return success; + bool success = true; + writeIndentedName(name); + std::string tmp_str; + value.toString(tmp_str); + if (mFP) + { + fprintf(mFP,"%s\n", tmp_str.c_str()); + } + else if (mOutputStream) + { + *mOutputStream <<"" << tmp_str << "\n"; + } + return success; } bool LLDataPackerAsciiFile::unpackUUID(LLUUID &value, const char *name) { - bool success = true; - char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ - if (!getValueStr(name, valuestr, DP_BUFSIZE)) - { - return false; - } + bool success = true; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } - char tmp_str[64]; /*Flawfinder: ignore */ - sscanf(valuestr,"%63s",tmp_str); /* Flawfinder: ignore */ - value.set(tmp_str); + char tmp_str[64]; /*Flawfinder: ignore */ + sscanf(valuestr,"%63s",tmp_str); /* Flawfinder: ignore */ + value.set(tmp_str); - return success; + return success; } void LLDataPackerAsciiFile::writeIndentedName(const char *name) { - std::string indent_buf; - indent_buf.reserve(mIndent+1); - - S32 i; - for(i = 0; i < mIndent; i++) - { - indent_buf[i] = '\t'; - } - indent_buf[i] = 0; - if (mFP) - { - fprintf(mFP,"%s%s\t",indent_buf.c_str(), name); - } - else if (mOutputStream) - { - *mOutputStream << indent_buf << name << "\t"; - } + std::string indent_buf; + indent_buf.reserve(mIndent+1); + + S32 i; + for(i = 0; i < mIndent; i++) + { + indent_buf[i] = '\t'; + } + indent_buf[i] = 0; + if (mFP) + { + fprintf(mFP,"%s%s\t",indent_buf.c_str(), name); + } + else if (mOutputStream) + { + *mOutputStream << indent_buf << name << "\t"; + } } bool LLDataPackerAsciiFile::getValueStr(const char *name, char *out_value, S32 value_len) { - bool success = false; - char buffer[DP_BUFSIZE]; /*Flawfinder: ignore*/ - char keyword[DP_BUFSIZE]; /*Flawfinder: ignore*/ - char value[DP_BUFSIZE]; /*Flawfinder: ignore*/ - - buffer[0] = '\0'; - keyword[0] = '\0'; - value[0] = '\0'; - - if (mFP) - { - fpos_t last_pos; - if (0 != fgetpos(mFP, &last_pos)) // 0==success for fgetpos - { - LL_WARNS() << "Data packer failed to fgetpos" << LL_ENDL; - return false; - } - - if (fgets(buffer, DP_BUFSIZE, mFP) == NULL) - { - buffer[0] = '\0'; - } - - sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ - - if (!keyword[0]) - { - LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL; - fsetpos(mFP, &last_pos); - return false; - } - if (strcmp(keyword, name)) - { - LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; - fsetpos(mFP, &last_pos); - return false; - } - - S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/ - S32 min_len = llmin(in_value_len, value_len); - memcpy(out_value, value, min_len); /*Flawfinder: ignore*/ - out_value[min_len-1] = 0; - success = true; - } - else if (mInputStream) - { - mInputStream->getline(buffer, DP_BUFSIZE); - - sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ - if (!keyword[0]) - { - LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL; - return false; - } - if (strcmp(keyword, name)) - { - LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; - return false; - } - - S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/ - S32 min_len = llmin(in_value_len, value_len); - memcpy(out_value, value, min_len); /*Flawfinder: ignore*/ - out_value[min_len-1] = 0; - success = true; - } - - return success; + bool success = false; + char buffer[DP_BUFSIZE]; /*Flawfinder: ignore*/ + char keyword[DP_BUFSIZE]; /*Flawfinder: ignore*/ + char value[DP_BUFSIZE]; /*Flawfinder: ignore*/ + + buffer[0] = '\0'; + keyword[0] = '\0'; + value[0] = '\0'; + + if (mFP) + { + fpos_t last_pos; + if (0 != fgetpos(mFP, &last_pos)) // 0==success for fgetpos + { + LL_WARNS() << "Data packer failed to fgetpos" << LL_ENDL; + return false; + } + + if (fgets(buffer, DP_BUFSIZE, mFP) == NULL) + { + buffer[0] = '\0'; + } + + sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ + + if (!keyword[0]) + { + LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL; + fsetpos(mFP, &last_pos); + return false; + } + if (strcmp(keyword, name)) + { + LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; + fsetpos(mFP, &last_pos); + return false; + } + + S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/ + S32 min_len = llmin(in_value_len, value_len); + memcpy(out_value, value, min_len); /*Flawfinder: ignore*/ + out_value[min_len-1] = 0; + success = true; + } + else if (mInputStream) + { + mInputStream->getline(buffer, DP_BUFSIZE); + + sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ + if (!keyword[0]) + { + LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL; + return false; + } + if (strcmp(keyword, name)) + { + LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; + return false; + } + + S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/ + S32 min_len = llmin(in_value_len, value_len); + memcpy(out_value, value, min_len); /*Flawfinder: ignore*/ + out_value[min_len-1] = 0; + success = true; + } + + return success; } diff --git a/indra/llmessage/lldatapacker.h b/indra/llmessage/lldatapacker.h index 8e980d8611..167c102b43 100644 --- a/indra/llmessage/lldatapacker.h +++ b/indra/llmessage/lldatapacker.h @@ -1,30 +1,30 @@ -/** +/** * @file lldatapacker.h * @brief Data packer declaration for tightly storing binary data. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef LL_LLDATAPACKER_H +#ifndef LL_LLDATAPACKER_H #define LL_LLDATAPACKER_H class LLColor4; @@ -37,398 +37,398 @@ class LLUUID; class LLDataPacker { public: - virtual ~LLDataPacker() {} - - // Not required to override, but error to call? - virtual void reset(); - virtual void dumpBufferToLog(); + virtual ~LLDataPacker() {} - virtual bool hasNext() const = 0; + // Not required to override, but error to call? + virtual void reset(); + virtual void dumpBufferToLog(); - virtual bool packString(const std::string& value, const char *name) = 0; - virtual bool unpackString(std::string& value, const char *name) = 0; + virtual bool hasNext() const = 0; - virtual bool packBinaryData(const U8 *value, S32 size, const char *name) = 0; - virtual bool unpackBinaryData(U8 *value, S32 &size, const char *name) = 0; + virtual bool packString(const std::string& value, const char *name) = 0; + virtual bool unpackString(std::string& value, const char *name) = 0; - // Constant size binary data packing - virtual bool packBinaryDataFixed(const U8 *value, S32 size, const char *name) = 0; - virtual bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name) = 0; + virtual bool packBinaryData(const U8 *value, S32 size, const char *name) = 0; + virtual bool unpackBinaryData(U8 *value, S32 &size, const char *name) = 0; - virtual bool packU8(const U8 value, const char *name) = 0; - virtual bool unpackU8(U8 &value, const char *name) = 0; + // Constant size binary data packing + virtual bool packBinaryDataFixed(const U8 *value, S32 size, const char *name) = 0; + virtual bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name) = 0; - virtual bool packU16(const U16 value, const char *name) = 0; - virtual bool unpackU16(U16 &value, const char *name) = 0; + virtual bool packU8(const U8 value, const char *name) = 0; + virtual bool unpackU8(U8 &value, const char *name) = 0; + + virtual bool packU16(const U16 value, const char *name) = 0; + virtual bool unpackU16(U16 &value, const char *name) = 0; bool unpackU16s(U16 *value, S32 count, const char *name); - - virtual bool packS16(const S16 value, const char *name) = 0; - virtual bool unpackS16(S16 &value, const char *name) = 0; + + virtual bool packS16(const S16 value, const char *name) = 0; + virtual bool unpackS16(S16 &value, const char *name) = 0; bool unpackS16s(S16 *value, S32 count, const char *name); - virtual bool packU32(const U32 value, const char *name) = 0; - virtual bool unpackU32(U32 &value, const char *name) = 0; + virtual bool packU32(const U32 value, const char *name) = 0; + virtual bool unpackU32(U32 &value, const char *name) = 0; - virtual bool packS32(const S32 value, const char *name) = 0; - virtual bool unpackS32(S32 &value, const char *name) = 0; + virtual bool packS32(const S32 value, const char *name) = 0; + virtual bool unpackS32(S32 &value, const char *name) = 0; - virtual bool packF32(const F32 value, const char *name) = 0; - virtual bool unpackF32(F32 &value, const char *name) = 0; + virtual bool packF32(const F32 value, const char *name) = 0; + virtual bool unpackF32(F32 &value, const char *name) = 0; bool unpackF32s(F32 *values, S32 count, const char *name); - // Packs a float into an integer, using the given size - // and picks the right U* data type to pack into. - bool packFixed(const F32 value, const char *name, - const bool is_signed, const U32 int_bits, const U32 frac_bits); - bool unpackFixed(F32 &value, const char *name, - const bool is_signed, const U32 int_bits, const U32 frac_bits); + // Packs a float into an integer, using the given size + // and picks the right U* data type to pack into. + bool packFixed(const F32 value, const char *name, + const bool is_signed, const U32 int_bits, const U32 frac_bits); + bool unpackFixed(F32 &value, const char *name, + const bool is_signed, const U32 int_bits, const U32 frac_bits); - virtual bool packColor4(const LLColor4 &value, const char *name) = 0; - virtual bool unpackColor4(LLColor4 &value, const char *name) = 0; + virtual bool packColor4(const LLColor4 &value, const char *name) = 0; + virtual bool unpackColor4(LLColor4 &value, const char *name) = 0; - virtual bool packColor4U(const LLColor4U &value, const char *name) = 0; - virtual bool unpackColor4U(LLColor4U &value, const char *name) = 0; + virtual bool packColor4U(const LLColor4U &value, const char *name) = 0; + virtual bool unpackColor4U(LLColor4U &value, const char *name) = 0; bool unpackColor4Us(LLColor4U *values, S32 count, const char *name); - virtual bool packVector2(const LLVector2 &value, const char *name) = 0; - virtual bool unpackVector2(LLVector2 &value, const char *name) = 0; + virtual bool packVector2(const LLVector2 &value, const char *name) = 0; + virtual bool unpackVector2(LLVector2 &value, const char *name) = 0; - virtual bool packVector3(const LLVector3 &value, const char *name) = 0; - virtual bool unpackVector3(LLVector3 &value, const char *name) = 0; + virtual bool packVector3(const LLVector3 &value, const char *name) = 0; + virtual bool unpackVector3(LLVector3 &value, const char *name) = 0; - virtual bool packVector4(const LLVector4 &value, const char *name) = 0; - virtual bool unpackVector4(LLVector4 &value, const char *name) = 0; + virtual bool packVector4(const LLVector4 &value, const char *name) = 0; + virtual bool unpackVector4(LLVector4 &value, const char *name) = 0; - virtual bool packUUID(const LLUUID &value, const char *name) = 0; - virtual bool unpackUUID(LLUUID &value, const char *name) = 0; + virtual bool packUUID(const LLUUID &value, const char *name) = 0; + virtual bool unpackUUID(LLUUID &value, const char *name) = 0; bool unpackUUIDs(LLUUID *values, S32 count, const char *name); - U32 getPassFlags() const { return mPassFlags; } - void setPassFlags(U32 flags) { mPassFlags = flags; } + U32 getPassFlags() const { return mPassFlags; } + void setPassFlags(U32 flags) { mPassFlags = flags; } protected: - LLDataPacker(); + LLDataPacker(); protected: - U32 mPassFlags; - bool mWriteEnabled; // disable this to do things like determine filesize without actually copying data + U32 mPassFlags; + bool mWriteEnabled; // disable this to do things like determine filesize without actually copying data }; class LLDataPackerBinaryBuffer : public LLDataPacker { public: - LLDataPackerBinaryBuffer(U8 *bufferp, S32 size) - : LLDataPacker(), - mBufferp(bufferp), - mCurBufferp(bufferp), - mBufferSize(size) - { - mWriteEnabled = true; - } - - LLDataPackerBinaryBuffer() - : LLDataPacker(), - mBufferp(NULL), - mCurBufferp(NULL), - mBufferSize(0) - { - } - - /*virtual*/ bool packString(const std::string& value, const char *name); - /*virtual*/ bool unpackString(std::string& value, const char *name); - - /*virtual*/ bool packBinaryData(const U8 *value, S32 size, const char *name); - /*virtual*/ bool unpackBinaryData(U8 *value, S32 &size, const char *name); - - // Constant size binary data packing - /*virtual*/ bool packBinaryDataFixed(const U8 *value, S32 size, const char *name); - /*virtual*/ bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name); - - /*virtual*/ bool packU8(const U8 value, const char *name); - /*virtual*/ bool unpackU8(U8 &value, const char *name); - - /*virtual*/ bool packU16(const U16 value, const char *name); - /*virtual*/ bool unpackU16(U16 &value, const char *name); - - /*virtual*/ bool packS16(const S16 value, const char *name); - /*virtual*/ bool unpackS16(S16 &value, const char *name); - - /*virtual*/ bool packU32(const U32 value, const char *name); - /*virtual*/ bool unpackU32(U32 &value, const char *name); - - /*virtual*/ bool packS32(const S32 value, const char *name); - /*virtual*/ bool unpackS32(S32 &value, const char *name); - - /*virtual*/ bool packF32(const F32 value, const char *name); - /*virtual*/ bool unpackF32(F32 &value, const char *name); - - /*virtual*/ bool packColor4(const LLColor4 &value, const char *name); - /*virtual*/ bool unpackColor4(LLColor4 &value, const char *name); - - /*virtual*/ bool packColor4U(const LLColor4U &value, const char *name); - /*virtual*/ bool unpackColor4U(LLColor4U &value, const char *name); - - /*virtual*/ bool packVector2(const LLVector2 &value, const char *name); - /*virtual*/ bool unpackVector2(LLVector2 &value, const char *name); - - /*virtual*/ bool packVector3(const LLVector3 &value, const char *name); - /*virtual*/ bool unpackVector3(LLVector3 &value, const char *name); - - /*virtual*/ bool packVector4(const LLVector4 &value, const char *name); - /*virtual*/ bool unpackVector4(LLVector4 &value, const char *name); - - /*virtual*/ bool packUUID(const LLUUID &value, const char *name); - /*virtual*/ bool unpackUUID(LLUUID &value, const char *name); - - S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp); } - S32 getBufferSize() const { return mBufferSize; } - const U8* getBuffer() const { return mBufferp; } - void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); } - void shift(S32 offset) { reset(); mCurBufferp += offset;} - void freeBuffer() { delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = false; } - void assignBuffer(U8 *bufferp, S32 size) - { - if(mBufferp && mBufferp != bufferp) - { - freeBuffer() ; - } - mBufferp = bufferp; - mCurBufferp = bufferp; - mBufferSize = size; - mWriteEnabled = true; - } - const LLDataPackerBinaryBuffer& operator=(const LLDataPackerBinaryBuffer &a); - - /*virtual*/ bool hasNext() const { return getCurrentSize() < getBufferSize(); } - - /*virtual*/ void dumpBufferToLog(); + LLDataPackerBinaryBuffer(U8 *bufferp, S32 size) + : LLDataPacker(), + mBufferp(bufferp), + mCurBufferp(bufferp), + mBufferSize(size) + { + mWriteEnabled = true; + } + + LLDataPackerBinaryBuffer() + : LLDataPacker(), + mBufferp(NULL), + mCurBufferp(NULL), + mBufferSize(0) + { + } + + /*virtual*/ bool packString(const std::string& value, const char *name); + /*virtual*/ bool unpackString(std::string& value, const char *name); + + /*virtual*/ bool packBinaryData(const U8 *value, S32 size, const char *name); + /*virtual*/ bool unpackBinaryData(U8 *value, S32 &size, const char *name); + + // Constant size binary data packing + /*virtual*/ bool packBinaryDataFixed(const U8 *value, S32 size, const char *name); + /*virtual*/ bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name); + + /*virtual*/ bool packU8(const U8 value, const char *name); + /*virtual*/ bool unpackU8(U8 &value, const char *name); + + /*virtual*/ bool packU16(const U16 value, const char *name); + /*virtual*/ bool unpackU16(U16 &value, const char *name); + + /*virtual*/ bool packS16(const S16 value, const char *name); + /*virtual*/ bool unpackS16(S16 &value, const char *name); + + /*virtual*/ bool packU32(const U32 value, const char *name); + /*virtual*/ bool unpackU32(U32 &value, const char *name); + + /*virtual*/ bool packS32(const S32 value, const char *name); + /*virtual*/ bool unpackS32(S32 &value, const char *name); + + /*virtual*/ bool packF32(const F32 value, const char *name); + /*virtual*/ bool unpackF32(F32 &value, const char *name); + + /*virtual*/ bool packColor4(const LLColor4 &value, const char *name); + /*virtual*/ bool unpackColor4(LLColor4 &value, const char *name); + + /*virtual*/ bool packColor4U(const LLColor4U &value, const char *name); + /*virtual*/ bool unpackColor4U(LLColor4U &value, const char *name); + + /*virtual*/ bool packVector2(const LLVector2 &value, const char *name); + /*virtual*/ bool unpackVector2(LLVector2 &value, const char *name); + + /*virtual*/ bool packVector3(const LLVector3 &value, const char *name); + /*virtual*/ bool unpackVector3(LLVector3 &value, const char *name); + + /*virtual*/ bool packVector4(const LLVector4 &value, const char *name); + /*virtual*/ bool unpackVector4(LLVector4 &value, const char *name); + + /*virtual*/ bool packUUID(const LLUUID &value, const char *name); + /*virtual*/ bool unpackUUID(LLUUID &value, const char *name); + + S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp); } + S32 getBufferSize() const { return mBufferSize; } + const U8* getBuffer() const { return mBufferp; } + void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); } + void shift(S32 offset) { reset(); mCurBufferp += offset;} + void freeBuffer() { delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = false; } + void assignBuffer(U8 *bufferp, S32 size) + { + if(mBufferp && mBufferp != bufferp) + { + freeBuffer() ; + } + mBufferp = bufferp; + mCurBufferp = bufferp; + mBufferSize = size; + mWriteEnabled = true; + } + const LLDataPackerBinaryBuffer& operator=(const LLDataPackerBinaryBuffer &a); + + /*virtual*/ bool hasNext() const { return getCurrentSize() < getBufferSize(); } + + /*virtual*/ void dumpBufferToLog(); protected: - inline bool verifyLength(const S32 data_size, const char *name); + inline bool verifyLength(const S32 data_size, const char *name); - U8 *mBufferp; - U8 *mCurBufferp; - S32 mBufferSize; + U8 *mBufferp; + U8 *mCurBufferp; + S32 mBufferSize; }; inline bool LLDataPackerBinaryBuffer::verifyLength(const S32 data_size, const char *name) { - if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size) - { - LL_WARNS() << "Buffer overflow in BinaryBuffer length verify, field name " << name << "!" << LL_ENDL; - LL_WARNS() << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << LL_ENDL; - return false; - } - - return true; + if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size) + { + LL_WARNS() << "Buffer overflow in BinaryBuffer length verify, field name " << name << "!" << LL_ENDL; + LL_WARNS() << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << LL_ENDL; + return false; + } + + return true; } class LLDataPackerAsciiBuffer : public LLDataPacker { public: - LLDataPackerAsciiBuffer(char* bufferp, S32 size) - { - mBufferp = bufferp; - mCurBufferp = bufferp; - mBufferSize = size; - mPassFlags = 0; - mIncludeNames = false; - mWriteEnabled = true; - } + LLDataPackerAsciiBuffer(char* bufferp, S32 size) + { + mBufferp = bufferp; + mCurBufferp = bufferp; + mBufferSize = size; + mPassFlags = 0; + mIncludeNames = false; + mWriteEnabled = true; + } - LLDataPackerAsciiBuffer() - { - mBufferp = NULL; - mCurBufferp = NULL; - mBufferSize = 0; - mPassFlags = 0; - mIncludeNames = false; - mWriteEnabled = false; - } + LLDataPackerAsciiBuffer() + { + mBufferp = NULL; + mCurBufferp = NULL; + mBufferSize = 0; + mPassFlags = 0; + mIncludeNames = false; + mWriteEnabled = false; + } - /*virtual*/ bool packString(const std::string& value, const char *name); - /*virtual*/ bool unpackString(std::string& value, const char *name); + /*virtual*/ bool packString(const std::string& value, const char *name); + /*virtual*/ bool unpackString(std::string& value, const char *name); - /*virtual*/ bool packBinaryData(const U8 *value, S32 size, const char *name); - /*virtual*/ bool unpackBinaryData(U8 *value, S32 &size, const char *name); + /*virtual*/ bool packBinaryData(const U8 *value, S32 size, const char *name); + /*virtual*/ bool unpackBinaryData(U8 *value, S32 &size, const char *name); - // Constant size binary data packing - /*virtual*/ bool packBinaryDataFixed(const U8 *value, S32 size, const char *name); - /*virtual*/ bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name); + // Constant size binary data packing + /*virtual*/ bool packBinaryDataFixed(const U8 *value, S32 size, const char *name); + /*virtual*/ bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name); - /*virtual*/ bool packU8(const U8 value, const char *name); - /*virtual*/ bool unpackU8(U8 &value, const char *name); + /*virtual*/ bool packU8(const U8 value, const char *name); + /*virtual*/ bool unpackU8(U8 &value, const char *name); - /*virtual*/ bool packU16(const U16 value, const char *name); - /*virtual*/ bool unpackU16(U16 &value, const char *name); + /*virtual*/ bool packU16(const U16 value, const char *name); + /*virtual*/ bool unpackU16(U16 &value, const char *name); - /*virtual*/ bool packS16(const S16 value, const char *name); - /*virtual*/ bool unpackS16(S16 &value, const char *name); + /*virtual*/ bool packS16(const S16 value, const char *name); + /*virtual*/ bool unpackS16(S16 &value, const char *name); - /*virtual*/ bool packU32(const U32 value, const char *name); - /*virtual*/ bool unpackU32(U32 &value, const char *name); + /*virtual*/ bool packU32(const U32 value, const char *name); + /*virtual*/ bool unpackU32(U32 &value, const char *name); - /*virtual*/ bool packS32(const S32 value, const char *name); - /*virtual*/ bool unpackS32(S32 &value, const char *name); + /*virtual*/ bool packS32(const S32 value, const char *name); + /*virtual*/ bool unpackS32(S32 &value, const char *name); - /*virtual*/ bool packF32(const F32 value, const char *name); - /*virtual*/ bool unpackF32(F32 &value, const char *name); + /*virtual*/ bool packF32(const F32 value, const char *name); + /*virtual*/ bool unpackF32(F32 &value, const char *name); - /*virtual*/ bool packColor4(const LLColor4 &value, const char *name); - /*virtual*/ bool unpackColor4(LLColor4 &value, const char *name); + /*virtual*/ bool packColor4(const LLColor4 &value, const char *name); + /*virtual*/ bool unpackColor4(LLColor4 &value, const char *name); - /*virtual*/ bool packColor4U(const LLColor4U &value, const char *name); - /*virtual*/ bool unpackColor4U(LLColor4U &value, const char *name); + /*virtual*/ bool packColor4U(const LLColor4U &value, const char *name); + /*virtual*/ bool unpackColor4U(LLColor4U &value, const char *name); - /*virtual*/ bool packVector2(const LLVector2 &value, const char *name); - /*virtual*/ bool unpackVector2(LLVector2 &value, const char *name); + /*virtual*/ bool packVector2(const LLVector2 &value, const char *name); + /*virtual*/ bool unpackVector2(LLVector2 &value, const char *name); - /*virtual*/ bool packVector3(const LLVector3 &value, const char *name); - /*virtual*/ bool unpackVector3(LLVector3 &value, const char *name); + /*virtual*/ bool packVector3(const LLVector3 &value, const char *name); + /*virtual*/ bool unpackVector3(LLVector3 &value, const char *name); - /*virtual*/ bool packVector4(const LLVector4 &value, const char *name); - /*virtual*/ bool unpackVector4(LLVector4 &value, const char *name); + /*virtual*/ bool packVector4(const LLVector4 &value, const char *name); + /*virtual*/ bool unpackVector4(LLVector4 &value, const char *name); - /*virtual*/ bool packUUID(const LLUUID &value, const char *name); - /*virtual*/ bool unpackUUID(LLUUID &value, const char *name); + /*virtual*/ bool packUUID(const LLUUID &value, const char *name); + /*virtual*/ bool unpackUUID(LLUUID &value, const char *name); - void setIncludeNames(bool b) { mIncludeNames = b; } + void setIncludeNames(bool b) { mIncludeNames = b; } - // Include the trailing NULL so it's always a valid string - S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp) + 1; } + // Include the trailing NULL so it's always a valid string + S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp) + 1; } - S32 getBufferSize() const { return mBufferSize; } - /*virtual*/ void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); } + S32 getBufferSize() const { return mBufferSize; } + /*virtual*/ void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); } - /*virtual*/ bool hasNext() const { return getCurrentSize() < getBufferSize(); } + /*virtual*/ bool hasNext() const { return getCurrentSize() < getBufferSize(); } - inline void freeBuffer(); - inline void assignBuffer(char* bufferp, S32 size); - void dump(); + inline void freeBuffer(); + inline void assignBuffer(char* bufferp, S32 size); + void dump(); protected: - void writeIndentedName(const char *name); - bool getValueStr(const char *name, char *out_value, const S32 value_len); - + void writeIndentedName(const char *name); + bool getValueStr(const char *name, char *out_value, const S32 value_len); + protected: - inline bool verifyLength(const S32 data_size, const char *name); + inline bool verifyLength(const S32 data_size, const char *name); - char *mBufferp; - char *mCurBufferp; - S32 mBufferSize; - bool mIncludeNames; // useful for debugging, print the name of each field + char *mBufferp; + char *mCurBufferp; + S32 mBufferSize; + bool mIncludeNames; // useful for debugging, print the name of each field }; -inline void LLDataPackerAsciiBuffer::freeBuffer() +inline void LLDataPackerAsciiBuffer::freeBuffer() { - delete [] mBufferp; - mBufferp = mCurBufferp = NULL; - mBufferSize = 0; - mWriteEnabled = false; + delete [] mBufferp; + mBufferp = mCurBufferp = NULL; + mBufferSize = 0; + mWriteEnabled = false; } -inline void LLDataPackerAsciiBuffer::assignBuffer(char* bufferp, S32 size) +inline void LLDataPackerAsciiBuffer::assignBuffer(char* bufferp, S32 size) { - mBufferp = bufferp; - mCurBufferp = bufferp; - mBufferSize = size; - mWriteEnabled = true; + mBufferp = bufferp; + mCurBufferp = bufferp; + mBufferSize = size; + mWriteEnabled = true; } inline bool LLDataPackerAsciiBuffer::verifyLength(const S32 data_size, const char *name) { - if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size) - { - LL_WARNS() << "Buffer overflow in AsciiBuffer length verify, field name " << name << "!" << LL_ENDL; - LL_WARNS() << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << LL_ENDL; - return false; - } - - return true; + if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size) + { + LL_WARNS() << "Buffer overflow in AsciiBuffer length verify, field name " << name << "!" << LL_ENDL; + LL_WARNS() << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << LL_ENDL; + return false; + } + + return true; } class LLDataPackerAsciiFile : public LLDataPacker { public: - LLDataPackerAsciiFile(LLFILE *fp, const S32 indent = 2) - : LLDataPacker(), - mIndent(indent), - mFP(fp), - mOutputStream(NULL), - mInputStream(NULL) - { - } - - LLDataPackerAsciiFile(std::ostream& output_stream, const S32 indent = 2) - : LLDataPacker(), - mIndent(indent), - mFP(NULL), - mOutputStream(&output_stream), - mInputStream(NULL) - { - mWriteEnabled = true; - } - - LLDataPackerAsciiFile(std::istream& input_stream, const S32 indent = 2) - : LLDataPacker(), - mIndent(indent), - mFP(NULL), - mOutputStream(NULL), - mInputStream(&input_stream) - { - } - - /*virtual*/ bool packString(const std::string& value, const char *name); - /*virtual*/ bool unpackString(std::string& value, const char *name); - - /*virtual*/ bool packBinaryData(const U8 *value, S32 size, const char *name); - /*virtual*/ bool unpackBinaryData(U8 *value, S32 &size, const char *name); - - /*virtual*/ bool packBinaryDataFixed(const U8 *value, S32 size, const char *name); - /*virtual*/ bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name); - - /*virtual*/ bool packU8(const U8 value, const char *name); - /*virtual*/ bool unpackU8(U8 &value, const char *name); - - /*virtual*/ bool packU16(const U16 value, const char *name); - /*virtual*/ bool unpackU16(U16 &value, const char *name); - - /*virtual*/ bool packS16(const S16 value, const char *name); - /*virtual*/ bool unpackS16(S16 &value, const char *name); - - /*virtual*/ bool packU32(const U32 value, const char *name); - /*virtual*/ bool unpackU32(U32 &value, const char *name); - - /*virtual*/ bool packS32(const S32 value, const char *name); - /*virtual*/ bool unpackS32(S32 &value, const char *name); - - /*virtual*/ bool packF32(const F32 value, const char *name); - /*virtual*/ bool unpackF32(F32 &value, const char *name); - - /*virtual*/ bool packColor4(const LLColor4 &value, const char *name); - /*virtual*/ bool unpackColor4(LLColor4 &value, const char *name); - - /*virtual*/ bool packColor4U(const LLColor4U &value, const char *name); - /*virtual*/ bool unpackColor4U(LLColor4U &value, const char *name); - - /*virtual*/ bool packVector2(const LLVector2 &value, const char *name); - /*virtual*/ bool unpackVector2(LLVector2 &value, const char *name); - - /*virtual*/ bool packVector3(const LLVector3 &value, const char *name); - /*virtual*/ bool unpackVector3(LLVector3 &value, const char *name); - - /*virtual*/ bool packVector4(const LLVector4 &value, const char *name); - /*virtual*/ bool unpackVector4(LLVector4 &value, const char *name); - - /*virtual*/ bool packUUID(const LLUUID &value, const char *name); - /*virtual*/ bool unpackUUID(LLUUID &value, const char *name); + LLDataPackerAsciiFile(LLFILE *fp, const S32 indent = 2) + : LLDataPacker(), + mIndent(indent), + mFP(fp), + mOutputStream(NULL), + mInputStream(NULL) + { + } + + LLDataPackerAsciiFile(std::ostream& output_stream, const S32 indent = 2) + : LLDataPacker(), + mIndent(indent), + mFP(NULL), + mOutputStream(&output_stream), + mInputStream(NULL) + { + mWriteEnabled = true; + } + + LLDataPackerAsciiFile(std::istream& input_stream, const S32 indent = 2) + : LLDataPacker(), + mIndent(indent), + mFP(NULL), + mOutputStream(NULL), + mInputStream(&input_stream) + { + } + + /*virtual*/ bool packString(const std::string& value, const char *name); + /*virtual*/ bool unpackString(std::string& value, const char *name); + + /*virtual*/ bool packBinaryData(const U8 *value, S32 size, const char *name); + /*virtual*/ bool unpackBinaryData(U8 *value, S32 &size, const char *name); + + /*virtual*/ bool packBinaryDataFixed(const U8 *value, S32 size, const char *name); + /*virtual*/ bool unpackBinaryDataFixed(U8 *value, S32 size, const char *name); + + /*virtual*/ bool packU8(const U8 value, const char *name); + /*virtual*/ bool unpackU8(U8 &value, const char *name); + + /*virtual*/ bool packU16(const U16 value, const char *name); + /*virtual*/ bool unpackU16(U16 &value, const char *name); + + /*virtual*/ bool packS16(const S16 value, const char *name); + /*virtual*/ bool unpackS16(S16 &value, const char *name); + + /*virtual*/ bool packU32(const U32 value, const char *name); + /*virtual*/ bool unpackU32(U32 &value, const char *name); + + /*virtual*/ bool packS32(const S32 value, const char *name); + /*virtual*/ bool unpackS32(S32 &value, const char *name); + + /*virtual*/ bool packF32(const F32 value, const char *name); + /*virtual*/ bool unpackF32(F32 &value, const char *name); + + /*virtual*/ bool packColor4(const LLColor4 &value, const char *name); + /*virtual*/ bool unpackColor4(LLColor4 &value, const char *name); + + /*virtual*/ bool packColor4U(const LLColor4U &value, const char *name); + /*virtual*/ bool unpackColor4U(LLColor4U &value, const char *name); + + /*virtual*/ bool packVector2(const LLVector2 &value, const char *name); + /*virtual*/ bool unpackVector2(LLVector2 &value, const char *name); + + /*virtual*/ bool packVector3(const LLVector3 &value, const char *name); + /*virtual*/ bool unpackVector3(LLVector3 &value, const char *name); + + /*virtual*/ bool packVector4(const LLVector4 &value, const char *name); + /*virtual*/ bool unpackVector4(LLVector4 &value, const char *name); + + /*virtual*/ bool packUUID(const LLUUID &value, const char *name); + /*virtual*/ bool unpackUUID(LLUUID &value, const char *name); protected: - void writeIndentedName(const char *name); - bool getValueStr(const char *name, char *out_value, const S32 value_len); - - /*virtual*/ bool hasNext() const { return true; } + void writeIndentedName(const char *name); + bool getValueStr(const char *name, char *out_value, const S32 value_len); + + /*virtual*/ bool hasNext() const { return true; } protected: - S32 mIndent; - LLFILE *mFP; - std::ostream* mOutputStream; - std::istream* mInputStream; + S32 mIndent; + LLFILE *mFP; + std::ostream* mOutputStream; + std::istream* mInputStream; }; #endif // LL_LLDATAPACKER diff --git a/indra/llmessage/lldbstrings.h b/indra/llmessage/lldbstrings.h index e23d17d5b6..cca407b03d 100644 --- a/indra/llmessage/lldbstrings.h +++ b/indra/llmessage/lldbstrings.h @@ -1,25 +1,25 @@ -/** +/** * @file lldbstrings.h * @brief Database String Lengths. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,25 +32,25 @@ * the size of the buffer large enough to hold each one) */ -// asset.name varchar(63) +// asset.name varchar(63) // -also- -// user_inventory_item.name varchar(63) +// user_inventory_item.name varchar(63) // -also- -// user_inventory_folder.name varchar(63) was CAT_NAME_SIZE +// user_inventory_folder.name varchar(63) was CAT_NAME_SIZE // Must be >= DB_FULL_NAME_STR_LEN so that calling cards work -const S32 DB_INV_ITEM_NAME_STR_LEN = 63; // was MAX_ASSET_NAME_LENGTH -const S32 DB_INV_ITEM_NAME_BUF_SIZE = 64; // was ITEM_NAME_SIZE +const S32 DB_INV_ITEM_NAME_STR_LEN = 63; // was MAX_ASSET_NAME_LENGTH +const S32 DB_INV_ITEM_NAME_BUF_SIZE = 64; // was ITEM_NAME_SIZE -// asset.description varchar(127) +// asset.description varchar(127) // -also- -// user_inventory_item.description varchar(127) -const S32 DB_INV_ITEM_DESC_STR_LEN = 127; // was MAX_ASSET_DESCRIPTION_LENGTH -const S32 DB_INV_ITEM_DESC_BUF_SIZE = 128; // was ITEM_DESC_SIZE +// user_inventory_item.description varchar(127) +const S32 DB_INV_ITEM_DESC_STR_LEN = 127; // was MAX_ASSET_DESCRIPTION_LENGTH +const S32 DB_INV_ITEM_DESC_BUF_SIZE = 128; // was ITEM_DESC_SIZE -// groups.name varchar(35) -const S32 DB_GROUP_NAME_STR_LEN = 35; -const S32 DB_GROUP_NAME_BUF_SIZE = 36; -const S32 DB_GROUP_NAME_MIN_LEN = 4; +// groups.name varchar(35) +const S32 DB_GROUP_NAME_STR_LEN = 35; +const S32 DB_GROUP_NAME_BUF_SIZE = 36; +const S32 DB_GROUP_NAME_MIN_LEN = 4; //group_roles.name const U32 DB_GROUP_ROLE_NAME_STR_LEN = 20; @@ -61,154 +61,154 @@ const U32 DB_GROUP_ROLE_TITLE_STR_LEN = 20; const U32 DB_GROUP_ROLE_TITLE_BUF_SIZE = DB_GROUP_ROLE_TITLE_STR_LEN + 1; -// group.charter text -const S32 DB_GROUP_CHARTER_STR_LEN = 511; -const S32 DB_GROUP_CHARTER_BUF_SIZE = 512; +// group.charter text +const S32 DB_GROUP_CHARTER_STR_LEN = 511; +const S32 DB_GROUP_CHARTER_BUF_SIZE = 512; -// group.officer_title varchar(20) +// group.officer_title varchar(20) // -also- -// group.member_title varchar(20) -const S32 DB_GROUP_TITLE_STR_LEN = 20; -const S32 DB_GROUP_TITLE_BUF_SIZE = 21; +// group.member_title varchar(20) +const S32 DB_GROUP_TITLE_STR_LEN = 20; +const S32 DB_GROUP_TITLE_BUF_SIZE = 21; // Since chat and im both dump into the database text message log, // they derive their max size from the same constant. const S32 MAX_MSG_STR_LEN = 1023; const S32 MAX_MSG_BUF_SIZE = 1024; -// instant_message.message text -const S32 DB_IM_MSG_STR_LEN = MAX_MSG_STR_LEN; -const S32 DB_IM_MSG_BUF_SIZE = MAX_MSG_BUF_SIZE; +// instant_message.message text +const S32 DB_IM_MSG_STR_LEN = MAX_MSG_STR_LEN; +const S32 DB_IM_MSG_BUF_SIZE = MAX_MSG_BUF_SIZE; // groupnotices -const S32 DB_GROUP_NOTICE_SUBJ_STR_LEN = 63; -const S32 DB_GROUP_NOTICE_SUBJ_STR_SIZE = 64; -const S32 DB_GROUP_NOTICE_MSG_STR_LEN = MAX_MSG_STR_LEN - DB_GROUP_NOTICE_SUBJ_STR_LEN; -const S32 DB_GROUP_NOTICE_MSG_STR_SIZE = MAX_MSG_BUF_SIZE - DB_GROUP_NOTICE_SUBJ_STR_SIZE; - -// log_text_message.message text -const S32 DB_CHAT_MSG_STR_LEN = MAX_MSG_STR_LEN; -const S32 DB_CHAT_MSG_BUF_SIZE = MAX_MSG_BUF_SIZE; - -// money_stipend.description varchar(254) -const S32 DB_STIPEND_DESC_STR_LEN = 254; -const S32 DB_STIPEND_DESC_BUF_SIZE = 255; - -// script_email_message.from_email varchar(78) -const S32 DB_EMAIL_FROM_STR_LEN = 78; -const S32 DB_EMAIL_FROM_BUF_SIZE = 79; - -// script_email_message.subject varchar(72) -const S32 DB_EMAIL_SUBJECT_STR_LEN = 72; -const S32 DB_EMAIL_SUBJECT_BUF_SIZE = 73; - -// system_globals.motd varchar(254) -const S32 DB_MOTD_STR_LEN = 254; -const S32 DB_MOTD_BUF_SIZE = 255; - -// Must be <= user_inventory_item.name so that calling cards work +const S32 DB_GROUP_NOTICE_SUBJ_STR_LEN = 63; +const S32 DB_GROUP_NOTICE_SUBJ_STR_SIZE = 64; +const S32 DB_GROUP_NOTICE_MSG_STR_LEN = MAX_MSG_STR_LEN - DB_GROUP_NOTICE_SUBJ_STR_LEN; +const S32 DB_GROUP_NOTICE_MSG_STR_SIZE = MAX_MSG_BUF_SIZE - DB_GROUP_NOTICE_SUBJ_STR_SIZE; + +// log_text_message.message text +const S32 DB_CHAT_MSG_STR_LEN = MAX_MSG_STR_LEN; +const S32 DB_CHAT_MSG_BUF_SIZE = MAX_MSG_BUF_SIZE; + +// money_stipend.description varchar(254) +const S32 DB_STIPEND_DESC_STR_LEN = 254; +const S32 DB_STIPEND_DESC_BUF_SIZE = 255; + +// script_email_message.from_email varchar(78) +const S32 DB_EMAIL_FROM_STR_LEN = 78; +const S32 DB_EMAIL_FROM_BUF_SIZE = 79; + +// script_email_message.subject varchar(72) +const S32 DB_EMAIL_SUBJECT_STR_LEN = 72; +const S32 DB_EMAIL_SUBJECT_BUF_SIZE = 73; + +// system_globals.motd varchar(254) +const S32 DB_MOTD_STR_LEN = 254; +const S32 DB_MOTD_BUF_SIZE = 255; + +// Must be <= user_inventory_item.name so that calling cards work // First name + " " + last name...or a system assigned "from" name -// instant_message.from_agent_name varchar(63) +// instant_message.from_agent_name varchar(63) // -also- -// user_mute.mute_agent_name varchar(63) -const S32 DB_FULL_NAME_STR_LEN = 63; -const S32 DB_FULL_NAME_BUF_SIZE = 64; // was USER_NAME_SIZE +// user_mute.mute_agent_name varchar(63) +const S32 DB_FULL_NAME_STR_LEN = 63; +const S32 DB_FULL_NAME_BUF_SIZE = 64; // was USER_NAME_SIZE -// user.username varchar(31) -const S32 DB_FIRST_NAME_STR_LEN = 31; -const S32 DB_FIRST_NAME_BUF_SIZE = 32; // was MAX_FIRST_NAME +// user.username varchar(31) +const S32 DB_FIRST_NAME_STR_LEN = 31; +const S32 DB_FIRST_NAME_BUF_SIZE = 32; // was MAX_FIRST_NAME -// user_last_name.name varchar(31) -const S32 DB_LAST_NAME_STR_LEN = 31; -const S32 DB_LAST_NAME_BUF_SIZE = 32; // was MAX_LAST_NAME +// user_last_name.name varchar(31) +const S32 DB_LAST_NAME_STR_LEN = 31; +const S32 DB_LAST_NAME_BUF_SIZE = 32; // was MAX_LAST_NAME -// user.password varchar(100) -const S32 DB_USER_PASSWORD_STR_LEN = 100; -const S32 DB_USER_PASSWORD_BUF_SIZE = 101; // was MAX_PASSWORD +// user.password varchar(100) +const S32 DB_USER_PASSWORD_STR_LEN = 100; +const S32 DB_USER_PASSWORD_BUF_SIZE = 101; // was MAX_PASSWORD -// user.email varchar(254) -const S32 DB_USER_EMAIL_ADDR_STR_LEN = 254; -const S32 DB_USER_EMAIL_ADDR_BUF_SIZE = 255; +// user.email varchar(254) +const S32 DB_USER_EMAIL_ADDR_STR_LEN = 254; +const S32 DB_USER_EMAIL_ADDR_BUF_SIZE = 255; -// user.about text -const S32 DB_USER_ABOUT_STR_LEN = 511; -const S32 DB_USER_ABOUT_BUF_SIZE = 512; +// user.about text +const S32 DB_USER_ABOUT_STR_LEN = 511; +const S32 DB_USER_ABOUT_BUF_SIZE = 512; -// user.fl_about_text text +// user.fl_about_text text // Must be 255 not 256 as gets packed into message Variable 1 -const S32 DB_USER_FL_ABOUT_STR_LEN = 254; -const S32 DB_USER_FL_ABOUT_BUF_SIZE = 255; +const S32 DB_USER_FL_ABOUT_STR_LEN = 254; +const S32 DB_USER_FL_ABOUT_BUF_SIZE = 255; -// user.profile_url text +// user.profile_url text // Must be 255 not 256 as gets packed into message Variable 1 -const S32 DB_USER_PROFILE_URL_STR_LEN = 254; -const S32 DB_USER_PROFILE_URL_BUF_SIZE = 255; +const S32 DB_USER_PROFILE_URL_STR_LEN = 254; +const S32 DB_USER_PROFILE_URL_BUF_SIZE = 255; -// user.want_to varchar(254) -const S32 DB_USER_WANT_TO_STR_LEN = 254; -const S32 DB_USER_WANT_TO_BUF_SIZE = 255; +// user.want_to varchar(254) +const S32 DB_USER_WANT_TO_STR_LEN = 254; +const S32 DB_USER_WANT_TO_BUF_SIZE = 255; -// user.skills varchar(254) -const S32 DB_USER_SKILLS_STR_LEN = 254; -const S32 DB_USER_SKILLS_BUF_SIZE = 255; +// user.skills varchar(254) +const S32 DB_USER_SKILLS_STR_LEN = 254; +const S32 DB_USER_SKILLS_BUF_SIZE = 255; -// user_nv.name varchar(128) -const S32 DB_NV_NAME_STR_LEN = 128; -const S32 DB_NV_NAME_BUF_SIZE = 129; +// user_nv.name varchar(128) +const S32 DB_NV_NAME_STR_LEN = 128; +const S32 DB_NV_NAME_BUF_SIZE = 129; -// user_start_location.location_name varchar(254) -const S32 DB_START_LOCATION_STR_LEN = 254; -const S32 DB_START_LOCATION_BUF_SIZE = 255; +// user_start_location.location_name varchar(254) +const S32 DB_START_LOCATION_STR_LEN = 254; +const S32 DB_START_LOCATION_BUF_SIZE = 255; -// money_tax_assessment.sim varchar(100) -//const S32 DB_SIM_NAME_STR_LEN = 100; -//const S32 DB_SIM_NAME_BUF_SIZE = 101; +// money_tax_assessment.sim varchar(100) +//const S32 DB_SIM_NAME_STR_LEN = 100; +//const S32 DB_SIM_NAME_BUF_SIZE = 101; -// born on date date -const S32 DB_BORN_STR_LEN = 15; -const S32 DB_BORN_BUF_SIZE = 16; +// born on date date +const S32 DB_BORN_STR_LEN = 15; +const S32 DB_BORN_BUF_SIZE = 16; // place.name -const S32 DB_PLACE_NAME_LEN = 63; -const S32 DB_PLACE_NAME_SIZE = 64; -const S32 DB_PARCEL_NAME_LEN = 63; -const S32 DB_PARCEL_NAME_SIZE = 64; +const S32 DB_PLACE_NAME_LEN = 63; +const S32 DB_PLACE_NAME_SIZE = 64; +const S32 DB_PARCEL_NAME_LEN = 63; +const S32 DB_PARCEL_NAME_SIZE = 64; // place.desc -const S32 DB_PLACE_DESC_LEN = 255; -const S32 DB_PLACE_DESC_SIZE = 256; -const S32 DB_PARCEL_DESC_LEN = 255; -const S32 DB_PARCEL_DESC_SIZE = 256; -const S32 DB_PARCEL_MUSIC_URL_LEN = 255; -const S32 DB_PARCEL_MEDIA_URL_LEN = 255; -const S32 DB_PARCEL_MUSIC_URL_SIZE = 256; +const S32 DB_PLACE_DESC_LEN = 255; +const S32 DB_PLACE_DESC_SIZE = 256; +const S32 DB_PARCEL_DESC_LEN = 255; +const S32 DB_PARCEL_DESC_SIZE = 256; +const S32 DB_PARCEL_MUSIC_URL_LEN = 255; +const S32 DB_PARCEL_MEDIA_URL_LEN = 255; +const S32 DB_PARCEL_MUSIC_URL_SIZE = 256; // date time that is easily human readable -const S32 DB_DATETIME_STR_LEN = 35; -const S32 DB_DATETIME_BUF_SIZE = 36; +const S32 DB_DATETIME_STR_LEN = 35; +const S32 DB_DATETIME_BUF_SIZE = 36; // date time that isn't easily human readable -const S32 DB_TERSE_DATETIME_STR_LEN = 15; -const S32 DB_TERSE_DATETIME_BUF_SIZE = 16; +const S32 DB_TERSE_DATETIME_STR_LEN = 15; +const S32 DB_TERSE_DATETIME_BUF_SIZE = 16; // indra.simulator constants -const S32 DB_SIM_NAME_STR_LEN = 35; -const S32 DB_SIM_NAME_BUF_SIZE = 36; -const S32 DB_HOST_NAME_STR_LEN = 100; -const S32 DB_HOST_NAME_BUF_SIZE = 101; -const S32 DB_ESTATE_NAME_STR_LEN = 63; -const S32 DB_ESTATE_NAME_BUF_SIZE = DB_ESTATE_NAME_STR_LEN + 1; +const S32 DB_SIM_NAME_STR_LEN = 35; +const S32 DB_SIM_NAME_BUF_SIZE = 36; +const S32 DB_HOST_NAME_STR_LEN = 100; +const S32 DB_HOST_NAME_BUF_SIZE = 101; +const S32 DB_ESTATE_NAME_STR_LEN = 63; +const S32 DB_ESTATE_NAME_BUF_SIZE = DB_ESTATE_NAME_STR_LEN + 1; // user_note.note -const S32 DB_USER_NOTE_LEN = 1023; -const S32 DB_USER_NOTE_SIZE = 1024; +const S32 DB_USER_NOTE_LEN = 1023; +const S32 DB_USER_NOTE_SIZE = 1024; // pick.name -const S32 DB_PICK_NAME_LEN = 63; -const S32 DB_PICK_NAME_SIZE = 64; +const S32 DB_PICK_NAME_LEN = 63; +const S32 DB_PICK_NAME_SIZE = 64; // pick.desc -const S32 DB_PICK_DESC_LEN = 1023; -const S32 DB_PICK_DESC_SIZE = 1024; +const S32 DB_PICK_DESC_LEN = 1023; +const S32 DB_PICK_DESC_SIZE = 1024; #endif // LL_LLDBSTRINGS_H diff --git a/indra/llmessage/lldispatcher.cpp b/indra/llmessage/lldispatcher.cpp index 717ef10f70..f02a5fd37f 100644 --- a/indra/llmessage/lldispatcher.cpp +++ b/indra/llmessage/lldispatcher.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldispatcher.cpp * @brief Implementation of the dispatcher object. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,55 +48,55 @@ LLDispatcher::~LLDispatcher() bool LLDispatcher::isHandlerPresent(const key_t& name) const { - if(mHandlers.find(name) != mHandlers.end()) - { - return true; - } - return false; + if(mHandlers.find(name) != mHandlers.end()) + { + return true; + } + return false; } void LLDispatcher::copyAllHandlerNames(keys_t& names) const { - // copy the names onto the vector we are given - std::transform( - mHandlers.begin(), - mHandlers.end(), - std::back_insert_iterator<keys_t>(names), - llselect1st<dispatch_map_t::value_type>()); + // copy the names onto the vector we are given + std::transform( + mHandlers.begin(), + mHandlers.end(), + std::back_insert_iterator<keys_t>(names), + llselect1st<dispatch_map_t::value_type>()); } bool LLDispatcher::dispatch( - const key_t& name, - const LLUUID& invoice, - const sparam_t& strings) const + const key_t& name, + const LLUUID& invoice, + const sparam_t& strings) const { - dispatch_map_t::const_iterator it = mHandlers.find(name); - if(it != mHandlers.end()) - { - LLDispatchHandler* func = (*it).second; - return (*func)(this, name, invoice, strings); - } - LL_WARNS() << "Unable to find handler for Generic message: " << name << LL_ENDL; - return false; + dispatch_map_t::const_iterator it = mHandlers.find(name); + if(it != mHandlers.end()) + { + LLDispatchHandler* func = (*it).second; + return (*func)(this, name, invoice, strings); + } + LL_WARNS() << "Unable to find handler for Generic message: " << name << LL_ENDL; + return false; } LLDispatchHandler* LLDispatcher::addHandler( - const key_t& name, LLDispatchHandler* func) + const key_t& name, LLDispatchHandler* func) { - dispatch_map_t::iterator it = mHandlers.find(name); - LLDispatchHandler* old_handler = NULL; - if(it != mHandlers.end()) - { - old_handler = (*it).second; - mHandlers.erase(it); - } - if(func) - { - // only non-null handlers so that we don't have to worry about - // it later. - mHandlers.insert(dispatch_map_t::value_type(name, func)); - } - return old_handler; + dispatch_map_t::iterator it = mHandlers.find(name); + LLDispatchHandler* old_handler = NULL; + if(it != mHandlers.end()) + { + old_handler = (*it).second; + mHandlers.erase(it); + } + if(func) + { + // only non-null handlers so that we don't have to worry about + // it later. + mHandlers.insert(dispatch_map_t::value_type(name, func)); + } + return old_handler; } // static @@ -106,14 +106,14 @@ bool LLDispatcher::unpackMessage( LLUUID& invoice, LLDispatcher::sparam_t& parameters) { - char buf[MAX_STRING]; /*Flawfinder: ignore*/ + char buf[MAX_STRING]; /*Flawfinder: ignore*/ msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method); msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice); S32 size; S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList); for (S32 i = 0; i < count; ++i) { - // we treat the SParam as binary data (since it might be an + // we treat the SParam as binary data (since it might be an // LLUUID in compressed form which may have embedded \0's,) size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter); if (size >= 0) @@ -137,7 +137,7 @@ bool LLDispatcher::unpackMessage( } else { - // This is either a NULL string, or a string that was packed + // This is either a NULL string, or a string that was packed // incorrectly as binary data, without the usual trailing '\0'. std::string string_data(buf, size); parameters.push_back(string_data); @@ -160,7 +160,7 @@ bool LLDispatcher::unpackLargeMessage( for (S32 i = 0; i < count; ++i) { // This method treats all Parameter List params as strings and unpacks - // them regardless of length. If there is binary data it is the callers + // them regardless of length. If there is binary data it is the callers // responsibility to decode it. std::string param; msg->getStringFast(_PREHASH_ParamList, _PREHASH_Parameter, param, i); diff --git a/indra/llmessage/lldispatcher.h b/indra/llmessage/lldispatcher.h index 43c63ac4df..87b029b8a4 100644 --- a/indra/llmessage/lldispatcher.h +++ b/indra/llmessage/lldispatcher.h @@ -1,25 +1,25 @@ -/** +/** * @file lldispatcher.h * @brief LLDispatcher class header file. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,16 +46,16 @@ class LLUUID; class LLDispatchHandler { public: - typedef std::vector<std::string> sparam_t; - //typedef std::vector<S32> iparam_t; - LLDispatchHandler() {} - virtual ~LLDispatchHandler() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& string) = 0; - //const iparam_t& integers) = 0; + typedef std::vector<std::string> sparam_t; + //typedef std::vector<S32> iparam_t; + LLDispatchHandler() {} + virtual ~LLDispatchHandler() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& string) = 0; + //const iparam_t& integers) = 0; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -67,43 +67,43 @@ public: class LLDispatcher { public: - typedef std::string key_t; - typedef std::vector<std::string> keys_t; - typedef std::vector<std::string> sparam_t; - //typedef std::vector<S32> iparam_t; + typedef std::string key_t; + typedef std::vector<std::string> keys_t; + typedef std::vector<std::string> sparam_t; + //typedef std::vector<S32> iparam_t; - // construct a dispatcher. - LLDispatcher(); - virtual ~LLDispatcher(); + // construct a dispatcher. + LLDispatcher(); + virtual ~LLDispatcher(); - // Returns if they keyed handler exists in this dispatcher. - bool isHandlerPresent(const key_t& name) const; + // Returns if they keyed handler exists in this dispatcher. + bool isHandlerPresent(const key_t& name) const; - // copy all known keys onto keys_t structure - void copyAllHandlerNames(keys_t& names) const; + // copy all known keys onto keys_t structure + void copyAllHandlerNames(keys_t& names) const; - // Call this method with the name of the request that has come - // in. If the handler is present, it is called with the params and - // returns the return value from - bool dispatch( - const key_t& name, - const LLUUID& invoice, - const sparam_t& strings) const; - //const iparam_t& itegers) const; + // Call this method with the name of the request that has come + // in. If the handler is present, it is called with the params and + // returns the return value from + bool dispatch( + const key_t& name, + const LLUUID& invoice, + const sparam_t& strings) const; + //const iparam_t& itegers) const; - // Add a handler. If one with the same key already exists, its - // pointer is returned, otherwise returns NULL. This object does - // not do memory management of the LLDispatchHandler, and relies - // on the caller to delete the object if necessary. - LLDispatchHandler* addHandler(const key_t& name, LLDispatchHandler* func); + // Add a handler. If one with the same key already exists, its + // pointer is returned, otherwise returns NULL. This object does + // not do memory management of the LLDispatchHandler, and relies + // on the caller to delete the object if necessary. + LLDispatchHandler* addHandler(const key_t& name, LLDispatchHandler* func); - // Helper method to unpack the dispatcher message bus - // format. Returns true on success. - static bool unpackMessage( - LLMessageSystem* msg, - key_t& method, - LLUUID& invoice, - sparam_t& parameters); + // Helper method to unpack the dispatcher message bus + // format. Returns true on success. + static bool unpackMessage( + LLMessageSystem* msg, + key_t& method, + LLUUID& invoice, + sparam_t& parameters); static bool unpackLargeMessage( LLMessageSystem* msg, @@ -112,8 +112,8 @@ public: sparam_t& parameters); protected: - typedef std::map<key_t, LLDispatchHandler*> dispatch_map_t; - dispatch_map_t mHandlers; + typedef std::map<key_t, LLDispatchHandler*> dispatch_map_t; + dispatch_map_t mHandlers; }; #endif // LL_LLDISPATCHER_H diff --git a/indra/llmessage/lleventflags.h b/indra/llmessage/lleventflags.h index 75d79071b1..e1b0f9f460 100644 --- a/indra/llmessage/lleventflags.h +++ b/indra/llmessage/lleventflags.h @@ -1,25 +1,25 @@ -/** +/** * @file lleventflags.h * @brief Flags for events. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index db22ad2ea3..b5d0c93376 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llexperiencecache.cpp * @brief llexperiencecache and related class definitions * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2012, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,7 +40,7 @@ //========================================================================= namespace LLExperienceCacheImpl { - void mapKeys(const LLSD& legacyKeys); + void mapKeys(const LLSD& legacyKeys); F64 getErrorRetryDeltaTime(S32 status, LLSD headers); bool maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age); @@ -57,32 +57,32 @@ namespace LLExperienceCacheImpl } //========================================================================= -const std::string LLExperienceCache::PRIVATE_KEY = "private_id"; -const std::string LLExperienceCache::MISSING = "DoesNotExist"; +const std::string LLExperienceCache::PRIVATE_KEY = "private_id"; +const std::string LLExperienceCache::MISSING = "DoesNotExist"; const std::string LLExperienceCache::AGENT_ID = "agent_id"; const std::string LLExperienceCache::GROUP_ID = "group_id"; -const std::string LLExperienceCache::EXPERIENCE_ID = "public_id"; -const std::string LLExperienceCache::NAME = "name"; -const std::string LLExperienceCache::PROPERTIES = "properties"; -const std::string LLExperienceCache::EXPIRES = "expiration"; -const std::string LLExperienceCache::DESCRIPTION = "description"; -const std::string LLExperienceCache::QUOTA = "quota"; +const std::string LLExperienceCache::EXPERIENCE_ID = "public_id"; +const std::string LLExperienceCache::NAME = "name"; +const std::string LLExperienceCache::PROPERTIES = "properties"; +const std::string LLExperienceCache::EXPIRES = "expiration"; +const std::string LLExperienceCache::DESCRIPTION = "description"; +const std::string LLExperienceCache::QUOTA = "quota"; const std::string LLExperienceCache::MATURITY = "maturity"; const std::string LLExperienceCache::METADATA = "extended_metadata"; -const std::string LLExperienceCache::SLURL = "slurl"; +const std::string LLExperienceCache::SLURL = "slurl"; // should be in sync with experience-api/experiences/models.py -const int LLExperienceCache::PROPERTY_INVALID = 1 << 0; -const int LLExperienceCache::PROPERTY_PRIVILEGED = 1 << 3; -const int LLExperienceCache::PROPERTY_GRID = 1 << 4; -const int LLExperienceCache::PROPERTY_PRIVATE = 1 << 5; -const int LLExperienceCache::PROPERTY_DISABLED = 1 << 6; -const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7; +const int LLExperienceCache::PROPERTY_INVALID = 1 << 0; +const int LLExperienceCache::PROPERTY_PRIVILEGED = 1 << 3; +const int LLExperienceCache::PROPERTY_GRID = 1 << 4; +const int LLExperienceCache::PROPERTY_PRIVATE = 1 << 5; +const int LLExperienceCache::PROPERTY_DISABLED = 1 << 6; +const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7; // default values -const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0; -const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes +const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0; +const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes const int LLExperienceCache::SEARCH_PAGE_SIZE = 30; bool LLExperienceCache::sShutdown = false; @@ -170,7 +170,7 @@ void LLExperienceCache::exportFile(std::ostream& ostr) const // *TODO$: Rider: This method does not seem to be used... it may be useful in testing. void LLExperienceCache::bootstrap(const LLSD& legacyKeys, int initialExpiration) { - LLExperienceCacheImpl::mapKeys(legacyKeys); + LLExperienceCacheImpl::mapKeys(legacyKeys); LLSD::array_const_iterator it = legacyKeys.beginArray(); for (/**/; it != legacyKeys.endArray(); ++it) { @@ -215,33 +215,33 @@ void LLExperienceCache::processExperience(const LLUUID& public_key, const LLSD& { LL_INFOS("ExperienceCache") << "Processing experience \"" << experience[NAME] << "\" with key " << public_key.asString() << LL_ENDL; - mCache[public_key]=experience; - LLSD & row = mCache[public_key]; + mCache[public_key]=experience; + LLSD & row = mCache[public_key]; - if(row.has(EXPIRES)) - { - row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds(); - } + if(row.has(EXPIRES)) + { + row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds(); + } - if(row.has(EXPERIENCE_ID)) - { - mPendingQueue.erase(row[EXPERIENCE_ID].asUUID()); - } + if(row.has(EXPERIENCE_ID)) + { + mPendingQueue.erase(row[EXPERIENCE_ID].asUUID()); + } - //signal - signal_map_t::iterator sig_it = mSignalMap.find(public_key); - if (sig_it != mSignalMap.end()) - { - signal_ptr signal = sig_it->second; - (*signal)(experience); + //signal + signal_map_t::iterator sig_it = mSignalMap.find(public_key); + if (sig_it != mSignalMap.end()) + { + signal_ptr signal = sig_it->second; + (*signal)(experience); - mSignalMap.erase(public_key); - } + mSignalMap.erase(public_key); + } } const LLExperienceCache::cache_t& LLExperienceCache::getCached() { - return mCache; + return mCache; } void LLExperienceCache::requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, std::string url, RequestQueue_t requests) @@ -251,7 +251,7 @@ void LLExperienceCache::requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdap //LL_INFOS("requestExperiencesCoro") << "url: " << url << LL_ENDL; LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -282,8 +282,8 @@ void LLExperienceCache::requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdap } LLSD experiences = result["experience_keys"]; - - for (LLSD::array_const_iterator it = experiences.beginArray(); + + for (LLSD::array_const_iterator it = experiences.beginArray(); it != experiences.endArray(); ++it) { const LLSD& row = *it; @@ -296,8 +296,8 @@ void LLExperienceCache::requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdap } LLSD error_ids = result["error_ids"]; - - for (LLSD::array_const_iterator errIt = error_ids.beginArray(); + + for (LLSD::array_const_iterator errIt = error_ids.beginArray(); errIt != error_ids.endArray(); ++errIt) { LLUUID id = errIt->asUUID(); @@ -337,7 +337,7 @@ void LLExperienceCache::requestExperiences() urlBase += "id/"; - F64 now = LLFrameTimer::getTotalSeconds(); + F64 now = LLFrameTimer::getTotalSeconds(); const U32 EXP_URL_SEND_THRESHOLD = 3000; const U32 PAGE_SIZE1 = EXP_URL_SEND_THRESHOLD / UUID_STR_LENGTH; @@ -355,7 +355,7 @@ void LLExperienceCache::requestExperiences() ostr << "&" << EXPERIENCE_ID << "=" << key.asString(); mPendingQueue[key] = now; - + if (mRequestQueue.empty() || (ostr.tellp() > EXP_URL_SEND_THRESHOLD)) { // request is placed in the coprocedure pool for the ExpCache cache. Throttling is done by the pool itself. LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "RequestExperiences", @@ -372,18 +372,18 @@ void LLExperienceCache::requestExperiences() bool LLExperienceCache::isRequestPending(const LLUUID& public_key) { - bool isPending = false; - const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; + bool isPending = false; + const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; PendingQueue_t::const_iterator it = mPendingQueue.find(public_key); - if(it != mPendingQueue.end()) - { - F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; - isPending = (it->second > expire_time); - } + if(it != mPendingQueue.end()) + { + F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; + isPending = (it->second > expire_time); + } - return isPending; + return isPending; } void LLExperienceCache::setCapabilityQuery(LLExperienceCache::CapabilityQuery_t queryfn) @@ -398,7 +398,7 @@ void LLExperienceCache::idleCoro() const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds LL_INFOS("ExperienceCache") << "Launching Experience cache idle coro." << LL_ENDL; - do + do { if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT)) { @@ -420,116 +420,116 @@ void LLExperienceCache::idleCoro() void LLExperienceCache::erase(const LLUUID& key) { - cache_t::iterator it = mCache.find(key); - - if(it != mCache.end()) - { - mCache.erase(it); - } + cache_t::iterator it = mCache.find(key); + + if(it != mCache.end()) + { + mCache.erase(it); + } } void LLExperienceCache::eraseExpired() { - F64 now = LLFrameTimer::getTotalSeconds(); - cache_t::iterator it = mCache.begin(); - while (it != mCache.end()) - { - cache_t::iterator cur = it; - LLSD& exp = cur->second; - ++it; + F64 now = LLFrameTimer::getTotalSeconds(); + cache_t::iterator it = mCache.begin(); + while (it != mCache.end()) + { + cache_t::iterator cur = it; + LLSD& exp = cur->second; + ++it; //LL_INFOS("ExperienceCache") << "Testing experience \"" << exp[NAME] << "\" with exp time " << exp[EXPIRES].asReal() << "(now = " << now << ")" << LL_ENDL; - if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now) - { + if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now) + { if(!exp.has(EXPERIENCE_ID)) - { + { LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ; mCache.erase(cur); - } + } else { LLUUID id = exp[EXPERIENCE_ID].asUUID(); LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null; if(private_key.notNull() || !exp.has("DoesNotExist")) - { - fetch(id, true); - } - else - { + { + fetch(id, true); + } + else + { LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ; - mCache.erase(cur); - } - } - } - } + mCache.erase(cur); + } + } + } + } } - + bool LLExperienceCache::fetch(const LLUUID& key, bool refresh/* = true*/) { - if(!key.isNull() && !isRequestPending(key) && (refresh || mCache.find(key)==mCache.end())) - { - LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL; + if(!key.isNull() && !isRequestPending(key) && (refresh || mCache.find(key)==mCache.end())) + { + LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL; mRequestQueue.insert(key); - return true; - } - return false; + return true; + } + return false; } void LLExperienceCache::insert(const LLSD& experience_data) { - if(experience_data.has(EXPERIENCE_ID)) - { + if(experience_data.has(EXPERIENCE_ID)) + { processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data); - } - else - { - LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL; - } + } + else + { + LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL; + } } const LLSD& LLExperienceCache::get(const LLUUID& key) { - static const LLSD empty; - - if(key.isNull()) - return empty; - cache_t::const_iterator it = mCache.find(key); - - if (it != mCache.end()) - { - return it->second; - } - fetch(key); - - return empty; + static const LLSD empty; + + if(key.isNull()) + return empty; + cache_t::const_iterator it = mCache.find(key); + + if (it != mCache.end()) + { + return it->second; + } + fetch(key); + + return empty; } void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::ExperienceGetFn_t slot) { - if(key.isNull()) - return; - - cache_t::const_iterator it = mCache.find(key); - if (it != mCache.end()) - { - // ...name already exists in cache, fire callback now - callback_signal_t signal; - signal.connect(slot); - - signal(it->second); - return; - } - - fetch(key); - - signal_ptr signal = signal_ptr(new callback_signal_t()); - - std::pair<signal_map_t::iterator, bool> result = mSignalMap.insert(signal_map_t::value_type(key, signal)); - if (!result.second) - signal = (*result.first).second; - signal->connect(slot); + if(key.isNull()) + return; + + cache_t::const_iterator it = mCache.find(key); + if (it != mCache.end()) + { + // ...name already exists in cache, fire callback now + callback_signal_t signal; + signal.connect(slot); + + signal(it->second); + return; + } + + fetch(key); + + signal_ptr signal = signal_ptr(new callback_signal_t()); + + std::pair<signal_map_t::iterator, bool> result = mSignalMap.insert(signal_map_t::value_type(key, signal)); + if (!result.second) + signal = (*result.first).second; + signal->connect(slot); } //========================================================================= @@ -592,7 +592,7 @@ void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCorout failure["error"] = (LLSD::Integer)status.getType(); failure["message"] = status.getMessage(); } - else + else { failure["error"] = -1; failure["message"] = "no experience"; @@ -747,7 +747,7 @@ void LLExperienceCache::getExperiencePermission(const LLUUID &experienceId, Expe } std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString(); - + permissionInvoker_fn invoker(boost::bind( // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> @@ -903,15 +903,15 @@ void LLExperienceCache::updateExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapte //========================================================================= void LLExperienceCacheImpl::mapKeys(const LLSD& legacyKeys) { - LLSD::array_const_iterator exp = legacyKeys.beginArray(); - for (/**/; exp != legacyKeys.endArray(); ++exp) - { + LLSD::array_const_iterator exp = legacyKeys.beginArray(); + for (/**/; exp != legacyKeys.endArray(); ++exp) + { if (exp->has(LLExperienceCacheImpl::EXPERIENCE_ID) && exp->has(LLExperienceCacheImpl::PRIVATE_KEY)) - { - LLExperienceCacheImpl::privateToPublicKeyMap[(*exp)[LLExperienceCacheImpl::PRIVATE_KEY].asUUID()] = + { + LLExperienceCacheImpl::privateToPublicKeyMap[(*exp)[LLExperienceCacheImpl::PRIVATE_KEY].asUUID()] = (*exp)[LLExperienceCacheImpl::EXPERIENCE_ID].asUUID(); - } - } + } + } } // Return time to retry a request that generated an error, based on @@ -972,56 +972,56 @@ F64 LLExperienceCacheImpl::getErrorRetryDeltaTime(S32 status, LLSD headers) bool LLExperienceCacheImpl::maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age) { - // Split the string on "," to get a list of directives - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - tokenizer directives(cache_control, COMMA_SEPARATOR); - - tokenizer::iterator token_it = directives.begin(); - for ( ; token_it != directives.end(); ++token_it) - { - // Tokens may have leading or trailing whitespace - std::string token = *token_it; - LLStringUtil::trim(token); - - if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0) - { - // ...this token starts with max-age, so let's chop it up by "=" - tokenizer subtokens(token, EQUALS_SEPARATOR); - tokenizer::iterator subtoken_it = subtokens.begin(); - - // Must have a token - if (subtoken_it == subtokens.end()) return false; - std::string subtoken = *subtoken_it; - - // Must exactly equal "max-age" - LLStringUtil::trim(subtoken); - if (subtoken != MAX_AGE) return false; - - // Must have another token - ++subtoken_it; - if (subtoken_it == subtokens.end()) return false; - subtoken = *subtoken_it; - - // Must be a valid integer - // *NOTE: atoi() returns 0 for invalid values, so we have to - // check the string first. - // *TODO: Do servers ever send "0000" for zero? We don't handle it - LLStringUtil::trim(subtoken); - if (subtoken == "0") - { - *max_age = 0; - return true; - } - S32 val = atoi( subtoken.c_str() ); - if (val > 0 && val < S32_MAX) - { - *max_age = val; - return true; - } - return false; - } - } - return false; + // Split the string on "," to get a list of directives + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + tokenizer directives(cache_control, COMMA_SEPARATOR); + + tokenizer::iterator token_it = directives.begin(); + for ( ; token_it != directives.end(); ++token_it) + { + // Tokens may have leading or trailing whitespace + std::string token = *token_it; + LLStringUtil::trim(token); + + if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0) + { + // ...this token starts with max-age, so let's chop it up by "=" + tokenizer subtokens(token, EQUALS_SEPARATOR); + tokenizer::iterator subtoken_it = subtokens.begin(); + + // Must have a token + if (subtoken_it == subtokens.end()) return false; + std::string subtoken = *subtoken_it; + + // Must exactly equal "max-age" + LLStringUtil::trim(subtoken); + if (subtoken != MAX_AGE) return false; + + // Must have another token + ++subtoken_it; + if (subtoken_it == subtokens.end()) return false; + subtoken = *subtoken_it; + + // Must be a valid integer + // *NOTE: atoi() returns 0 for invalid values, so we have to + // check the string first. + // *TODO: Do servers ever send "0000" for zero? We don't handle it + LLStringUtil::trim(subtoken); + if (subtoken == "0") + { + *max_age = 0; + return true; + } + S32 val = atoi( subtoken.c_str() ); + if (val > 0 && val < S32_MAX) + { + *max_age = val; + return true; + } + return false; + } + } + return false; } diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h index 3ee45da2e7..81e904107f 100644 --- a/indra/llmessage/llexperiencecache.h +++ b/indra/llmessage/llexperiencecache.h @@ -1,25 +1,25 @@ -/** +/** * @file llexperiencecache.h * @brief Caches information relating to experience keys * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2012, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -53,7 +53,7 @@ public: void cleanup(); //------------------------------------------- - // Cache methods + // Cache methods void erase(const LLUUID& key); bool fetch(const LLUUID& key, bool refresh = false); void insert(const LLSD& experience_data); @@ -68,7 +68,7 @@ public: void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn); void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn); - // the Get/Set Region Experiences take a CapabilityQuery to get the capability since + // the Get/Set Region Experiences take a CapabilityQuery to get the capability since // the region being queried may not be the region that the agent is standing on. void getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn); void setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn); @@ -81,13 +81,13 @@ public: void updateExperience(LLSD updateData, ExperienceGetFn_t fn); //------------------------------------------- - static const std::string NAME; // "name" - static const std::string EXPERIENCE_ID; // "public_id" + static const std::string NAME; // "name" + static const std::string EXPERIENCE_ID; // "public_id" static const std::string AGENT_ID; // "agent_id" static const std::string GROUP_ID; // "group_id" - static const std::string PROPERTIES; // "properties" - static const std::string EXPIRES; // "expiration" - static const std::string DESCRIPTION; // "description" + static const std::string PROPERTIES; // "properties" + static const std::string EXPIRES; // "expiration" + static const std::string DESCRIPTION; // "description" static const std::string QUOTA; // "quota" static const std::string MATURITY; // "maturity" static const std::string METADATA; // "extended_metadata" @@ -96,12 +96,12 @@ public: static const std::string MISSING; // "DoesNotExist" // should be in sync with experience-api/experiences/models.py - static const int PROPERTY_INVALID; // 1 << 0 - static const int PROPERTY_PRIVILEGED; // 1 << 3 - static const int PROPERTY_GRID; // 1 << 4 - static const int PROPERTY_PRIVATE; // 1 << 5 - static const int PROPERTY_DISABLED; // 1 << 6 - static const int PROPERTY_SUSPENDED; // 1 << 7 + static const int PROPERTY_INVALID; // 1 << 0 + static const int PROPERTY_PRIVILEGED; // 1 << 3 + static const int PROPERTY_GRID; // 1 << 4 + static const int PROPERTY_PRIVATE; // 1 << 5 + static const int PROPERTY_DISABLED; // 1 << 6 + static const int PROPERTY_SUSPENDED; // 1 << 7 private: virtual ~LLExperienceCache(); @@ -110,33 +110,33 @@ private: typedef boost::function<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLCore::HttpRequest::ptr_t, std::string)> permissionInvoker_fn; - // Callback types for get() + // Callback types for get() typedef boost::signals2::signal < void(const LLSD &) > callback_signal_t; - typedef std::shared_ptr<callback_signal_t> signal_ptr; - // May have multiple callbacks for a single ID, which are - // represented as multiple slots bound to the signal. - // Avoid copying signals via pointers. - typedef std::map<LLUUID, signal_ptr> signal_map_t; - typedef std::map<LLUUID, LLSD> cache_t; - - typedef std::set<LLUUID> RequestQueue_t; + typedef std::shared_ptr<callback_signal_t> signal_ptr; + // May have multiple callbacks for a single ID, which are + // represented as multiple slots bound to the signal. + // Avoid copying signals via pointers. + typedef std::map<LLUUID, signal_ptr> signal_map_t; + typedef std::map<LLUUID, LLSD> cache_t; + + typedef std::set<LLUUID> RequestQueue_t; typedef std::map<LLUUID, F64> PendingQueue_t; - //-------------------------------------------- - static const std::string PRIVATE_KEY; // "private_id" - - // default values - static const F64 DEFAULT_EXPIRATION; // 600.0 - static const S32 DEFAULT_QUOTA; // 128 this is megabytes + //-------------------------------------------- + static const std::string PRIVATE_KEY; // "private_id" + + // default values + static const F64 DEFAULT_EXPIRATION; // 600.0 + static const S32 DEFAULT_QUOTA; // 128 this is megabytes static const int SEARCH_PAGE_SIZE; - + //-------------------------------------------- void processExperience(const LLUUID& public_key, const LLSD& experience); //-------------------------------------------- - cache_t mCache; - signal_map_t mSignalMap; - RequestQueue_t mRequestQueue; + cache_t mCache; + signal_map_t mSignalMap; + RequestQueue_t mRequestQueue; PendingQueue_t mPendingQueue; LLFrameTimer mEraseExpiredTimer; // Periodically clean out expired entries from the cache @@ -145,7 +145,7 @@ private: static bool sShutdown; // control for coroutines, they exist out of LLExperienceCache's scope, so they need a static control void idleCoro(); - void eraseExpired(); + void eraseExpired(); void requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, RequestQueue_t); void requestExperiences(); @@ -161,11 +161,11 @@ private: void exportFile(std::ostream& ostr) const; void importFile(std::istream& istr); - // - const cache_t& getCached(); + // + const cache_t& getCached(); - // maps an experience private key to the experience id - LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false); + // maps an experience private key to the experience id + LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false); //===================================================================== inline friend std::ostream &operator << (std::ostream &os, const LLExperienceCache &cache) diff --git a/indra/llmessage/llextendedstatus.h b/indra/llmessage/llextendedstatus.h index 2a53dced80..ed8338daa3 100644 --- a/indra/llmessage/llextendedstatus.h +++ b/indra/llmessage/llextendedstatus.h @@ -1,4 +1,4 @@ -/** +/** * @file llextendedstatus.h * @date August 2007 * @brief extended status codes for curl/resident asset storage and delivery @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,33 +30,33 @@ enum class LLExtStat: uint32_t { - // Status provider groups - Top bits indicate which status type it is - // Zero is common status code (next section) - CURL_RESULT = 1UL<<30, // serviced by curl - use 1L if we really implement the below - RES_RESULT = 2UL<<30, // serviced by resident copy - CACHE_RESULT = 3UL<<30, // serviced by cache - - - // Common Status Codes - // - NONE = 0x00000, // No extra info here - sorry! - NULL_UUID = 0x10001, // null asset ID - NO_UPSTREAM = 0x10002, // attempt to upload without a valid upstream method/provider - REQUEST_DROPPED = 0x10003, // request was dropped unserviced - NONEXISTENT_FILE= 0x10004, // trying to upload a file that doesn't exist - BLOCKED_FILE = 0x10005, // trying to upload a file that we can't open - - // curl status codes: - // - // Mask off CURL_RESULT for original result and - // see: libraries/include/curl/curl.h - - // Memory-Resident status codes: - // None at present - - // CACHE status codes: - CACHE_CACHED = CACHE_RESULT | 0x0001, - CACHE_CORRUPT = CACHE_RESULT | 0x0002, + // Status provider groups - Top bits indicate which status type it is + // Zero is common status code (next section) + CURL_RESULT = 1UL<<30, // serviced by curl - use 1L if we really implement the below + RES_RESULT = 2UL<<30, // serviced by resident copy + CACHE_RESULT = 3UL<<30, // serviced by cache + + + // Common Status Codes + // + NONE = 0x00000, // No extra info here - sorry! + NULL_UUID = 0x10001, // null asset ID + NO_UPSTREAM = 0x10002, // attempt to upload without a valid upstream method/provider + REQUEST_DROPPED = 0x10003, // request was dropped unserviced + NONEXISTENT_FILE= 0x10004, // trying to upload a file that doesn't exist + BLOCKED_FILE = 0x10005, // trying to upload a file that we can't open + + // curl status codes: + // + // Mask off CURL_RESULT for original result and + // see: libraries/include/curl/curl.h + + // Memory-Resident status codes: + // None at present + + // CACHE status codes: + CACHE_CACHED = CACHE_RESULT | 0x0001, + CACHE_CORRUPT = CACHE_RESULT | 0x0002, }; diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index c63ce5f441..df78652361 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llfiltersd2xmlrpc.cpp * @author Phoenix * @date 2005-04-26 @@ -6,27 +6,27 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -/** - * xml rpc request: +/** + * xml rpc request: * <code> * <?xml version="1.0"?> * <methodCall><methodName>examples.getStateName</methodName> @@ -57,17 +57,17 @@ * <code> * { 'method':'...', 'parameter':...]} * </code> - * + * * llsd rpc response: * <code> * { 'response':... } * </code> - * - * llsd rpc fault: + * + * llsd rpc fault: * <code> * { 'fault': {'code':i..., 'description':'...'} } * </code> - * + * */ #include "linden_common.h" @@ -132,174 +132,174 @@ LLFilterSD2XMLRPC::~LLFilterSD2XMLRPC() std::string xml_escape_string(const std::string& in) { - std::ostringstream out; - std::string::const_iterator it = in.begin(); - std::string::const_iterator end = in.end(); - for(; it != end; ++it) - { - switch((*it)) - { - case '<': - out << "<"; - break; - case '>': - out << ">"; - break; - case '&': - out << "&"; - break; - case '\'': - out << "'"; - break; - case '"': - out << """; - break; - default: - out << (*it); - break; - } - } - return out.str(); + std::ostringstream out; + std::string::const_iterator it = in.begin(); + std::string::const_iterator end = in.end(); + for(; it != end; ++it) + { + switch((*it)) + { + case '<': + out << "<"; + break; + case '>': + out << ">"; + break; + case '&': + out << "&"; + break; + case '\'': + out << "'"; + break; + case '"': + out << """; + break; + default: + out << (*it); + break; + } + } + return out.str(); } void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd) { - ostr << "<value>"; - switch(sd.type()) - { - case LLSD::TypeMap: - { + ostr << "<value>"; + switch(sd.type()) + { + case LLSD::TypeMap: + { #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(map) BEGIN" << LL_ENDL; + LL_INFOS() << "streamOut(map) BEGIN" << LL_ENDL; #endif - ostr << "<struct>"; - if(ostr.fail()) - { - LL_INFOS() << "STREAM FAILURE writing struct" << LL_ENDL; - } - LLSD::map_const_iterator it = sd.beginMap(); - LLSD::map_const_iterator end = sd.endMap(); - for(; it != end; ++it) - { - ostr << "<member><name>" << xml_escape_string((*it).first) - << "</name>"; - streamOut(ostr, (*it).second); - if(ostr.fail()) - { - LL_INFOS() << "STREAM FAILURE writing '" << (*it).first - << "' with sd type " << (*it).second.type() << LL_ENDL; - } - ostr << "</member>"; - } - ostr << "</struct>"; + ostr << "<struct>"; + if(ostr.fail()) + { + LL_INFOS() << "STREAM FAILURE writing struct" << LL_ENDL; + } + LLSD::map_const_iterator it = sd.beginMap(); + LLSD::map_const_iterator end = sd.endMap(); + for(; it != end; ++it) + { + ostr << "<member><name>" << xml_escape_string((*it).first) + << "</name>"; + streamOut(ostr, (*it).second); + if(ostr.fail()) + { + LL_INFOS() << "STREAM FAILURE writing '" << (*it).first + << "' with sd type " << (*it).second.type() << LL_ENDL; + } + ostr << "</member>"; + } + ostr << "</struct>"; #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(map) END" << LL_ENDL; + LL_INFOS() << "streamOut(map) END" << LL_ENDL; #endif - break; - } - case LLSD::TypeArray: - { + break; + } + case LLSD::TypeArray: + { #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(array) BEGIN" << LL_ENDL; + LL_INFOS() << "streamOut(array) BEGIN" << LL_ENDL; #endif - ostr << "<array><data>"; - LLSD::array_const_iterator it = sd.beginArray(); - LLSD::array_const_iterator end = sd.endArray(); - for(; it != end; ++it) - { - streamOut(ostr, *it); - if(ostr.fail()) - { - LL_INFOS() << "STREAM FAILURE writing array element sd type " - << (*it).type() << LL_ENDL; - } - } + ostr << "<array><data>"; + LLSD::array_const_iterator it = sd.beginArray(); + LLSD::array_const_iterator end = sd.endArray(); + for(; it != end; ++it) + { + streamOut(ostr, *it); + if(ostr.fail()) + { + LL_INFOS() << "STREAM FAILURE writing array element sd type " + << (*it).type() << LL_ENDL; + } + } #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(array) END" << LL_ENDL; + LL_INFOS() << "streamOut(array) END" << LL_ENDL; #endif - ostr << "</data></array>"; - break; - } - case LLSD::TypeUndefined: - // treat undefined as a bool with a false value. - case LLSD::TypeBoolean: + ostr << "</data></array>"; + break; + } + case LLSD::TypeUndefined: + // treat undefined as a bool with a false value. + case LLSD::TypeBoolean: #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(bool)" << LL_ENDL; + LL_INFOS() << "streamOut(bool)" << LL_ENDL; #endif - ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>"; - break; - case LLSD::TypeInteger: + ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>"; + break; + case LLSD::TypeInteger: #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(int)" << LL_ENDL; + LL_INFOS() << "streamOut(int)" << LL_ENDL; #endif - ostr << "<i4>" << sd.asInteger() << "</i4>"; - break; - case LLSD::TypeReal: + ostr << "<i4>" << sd.asInteger() << "</i4>"; + break; + case LLSD::TypeReal: #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(real)" << LL_ENDL; + LL_INFOS() << "streamOut(real)" << LL_ENDL; #endif - ostr << "<double>" << sd.asReal() << "</double>"; - break; - case LLSD::TypeString: + ostr << "<double>" << sd.asReal() << "</double>"; + break; + case LLSD::TypeString: #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(string)" << LL_ENDL; + LL_INFOS() << "streamOut(string)" << LL_ENDL; #endif - ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; - break; - case LLSD::TypeUUID: + ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; + break; + case LLSD::TypeUUID: #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(uuid)" << LL_ENDL; + LL_INFOS() << "streamOut(uuid)" << LL_ENDL; #endif - // serialize it as a string - ostr << "<string>" << sd.asString() << "</string>"; - break; - case LLSD::TypeURI: - { + // serialize it as a string + ostr << "<string>" << sd.asString() << "</string>"; + break; + case LLSD::TypeURI: + { #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(uri)" << LL_ENDL; + LL_INFOS() << "streamOut(uri)" << LL_ENDL; #endif - // serialize it as a string - ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; - break; - } - case LLSD::TypeBinary: - { + // serialize it as a string + ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; + break; + } + case LLSD::TypeBinary: + { #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(binary)" << LL_ENDL; + LL_INFOS() << "streamOut(binary)" << LL_ENDL; #endif - // this is pretty inefficient, but we'll deal with that - // problem when it becomes one. - ostr << "<base64>"; - LLSD::Binary buffer = sd.asBinary(); - if(!buffer.empty()) - { - // *TODO: convert to LLBase64 - int b64_buffer_length = apr_base64_encode_len(buffer.size()); - char* b64_buffer = new char[b64_buffer_length]; - b64_buffer_length = apr_base64_encode_binary( - b64_buffer, - &buffer[0], - buffer.size()); - ostr.write(b64_buffer, b64_buffer_length - 1); - delete[] b64_buffer; - } - ostr << "</base64>"; - break; - } - case LLSD::TypeDate: + // this is pretty inefficient, but we'll deal with that + // problem when it becomes one. + ostr << "<base64>"; + LLSD::Binary buffer = sd.asBinary(); + if(!buffer.empty()) + { + // *TODO: convert to LLBase64 + int b64_buffer_length = apr_base64_encode_len(buffer.size()); + char* b64_buffer = new char[b64_buffer_length]; + b64_buffer_length = apr_base64_encode_binary( + b64_buffer, + &buffer[0], + buffer.size()); + ostr.write(b64_buffer, b64_buffer_length - 1); + delete[] b64_buffer; + } + ostr << "</base64>"; + break; + } + case LLSD::TypeDate: #if LL_SPEW_STREAM_OUT_DEBUGGING - LL_INFOS() << "streamOut(date)" << LL_ENDL; + LL_INFOS() << "streamOut(date)" << LL_ENDL; #endif - // no need to escape this since it will be alpha-numeric. - ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>"; - break; - default: - // unhandled type - LL_WARNS() << "Unhandled structured data type: " << sd.type() - << LL_ENDL; - break; - } - ostr << "</value>"; + // no need to escape this since it will be alpha-numeric. + ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>"; + break; + default: + // unhandled type + LL_WARNS() << "Unhandled structured data type: " << sd.type() + << LL_ENDL; + break; + } + ostr << "</value>"; } /** @@ -317,59 +317,59 @@ LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse() // virtual LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - // This pipe does not work if it does not have everyting. This - // could be addressed by making a stream parser for llsd which - // handled partial information. - if(!eos) - { - return STATUS_BREAK; - } - - PUMP_DEBUG; - // we have everyting in the buffer, so turn the structure data rpc - // response into an xml rpc response. - LLBufferStream stream(channels, buffer.get()); - stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER; - LLSD sd; - LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); - - PUMP_DEBUG; - LLIOPipe::EStatus rv = STATUS_ERROR; - if(sd.has("response")) - { - PUMP_DEBUG; - // it is a normal response. pack it up and ship it out. - stream.precision(DEFAULT_PRECISION); - stream << XMLRPC_RESPONSE_HEADER; - streamOut(stream, sd["response"]); - stream << XMLRPC_RESPONSE_FOOTER << XMLRPC_METHOD_RESPONSE_FOOTER; - rv = STATUS_DONE; - } - else if(sd.has("fault")) - { - PUMP_DEBUG; - // it is a fault. - stream << XMLRPC_FAULT_1 << sd["fault"]["code"].asInteger() - << XMLRPC_FAULT_2 - << xml_escape_string(sd["fault"]["description"].asString()) - << XMLRPC_FAULT_3 << XMLRPC_METHOD_RESPONSE_FOOTER; - rv = STATUS_DONE; - } - else - { - LL_WARNS() << "Unable to determine the type of LLSD response." << LL_ENDL; - } - PUMP_DEBUG; - return rv; + PUMP_DEBUG; + // This pipe does not work if it does not have everyting. This + // could be addressed by making a stream parser for llsd which + // handled partial information. + if(!eos) + { + return STATUS_BREAK; + } + + PUMP_DEBUG; + // we have everyting in the buffer, so turn the structure data rpc + // response into an xml rpc response. + LLBufferStream stream(channels, buffer.get()); + stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER; + LLSD sd; + LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); + + PUMP_DEBUG; + LLIOPipe::EStatus rv = STATUS_ERROR; + if(sd.has("response")) + { + PUMP_DEBUG; + // it is a normal response. pack it up and ship it out. + stream.precision(DEFAULT_PRECISION); + stream << XMLRPC_RESPONSE_HEADER; + streamOut(stream, sd["response"]); + stream << XMLRPC_RESPONSE_FOOTER << XMLRPC_METHOD_RESPONSE_FOOTER; + rv = STATUS_DONE; + } + else if(sd.has("fault")) + { + PUMP_DEBUG; + // it is a fault. + stream << XMLRPC_FAULT_1 << sd["fault"]["code"].asInteger() + << XMLRPC_FAULT_2 + << xml_escape_string(sd["fault"]["description"].asString()) + << XMLRPC_FAULT_3 << XMLRPC_METHOD_RESPONSE_FOOTER; + rv = STATUS_DONE; + } + else + { + LL_WARNS() << "Unable to determine the type of LLSD response." << LL_ENDL; + } + PUMP_DEBUG; + return rv; } /** @@ -381,10 +381,10 @@ LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest() LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest(const char* method) { - if(method) - { - mMethod.assign(method); - } + if(method) + { + mMethod.assign(method); + } } LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest() @@ -393,103 +393,103 @@ LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest() // virtual LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - // This pipe does not work if it does not have everyting. This - // could be addressed by making a stream parser for llsd which - // handled partial information. - PUMP_DEBUG; - if(!eos) - { - LL_INFOS() << "!eos" << LL_ENDL; - return STATUS_BREAK; - } - - // See if we can parse it - LLBufferStream stream(channels, buffer.get()); - LLSD sd; - LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); - if(stream.fail()) - { - LL_INFOS() << "STREAM FAILURE reading structure data." << LL_ENDL; - } - - PUMP_DEBUG; - // We can get the method and parameters from either the member - // function or passed in via the buffer. We prefer the buffer if - // we found a parameter and a method, or fall back to using - // mMethod and putting everyting in the buffer into the parameter. - std::string method; - LLSD param_sd; - if(sd.has("method") && sd.has("parameter")) - { - method = sd["method"].asString(); - param_sd = sd["parameter"]; - } - else - { - method = mMethod; - param_sd = sd; - } - if(method.empty()) - { - LL_WARNS() << "SD -> XML Request no method found." << LL_ENDL; - return STATUS_ERROR; - } - - PUMP_DEBUG; - // We have a method, and some kind of parameter, so package it up - // and send it out. - LLBufferStream ostream(channels, buffer.get()); - ostream.precision(DEFAULT_PRECISION); - if(ostream.fail()) - { - LL_INFOS() << "STREAM FAILURE setting precision" << LL_ENDL; - } - ostream << XML_HEADER << XMLRPC_REQUEST_HEADER_1 - << xml_escape_string(method) << XMLRPC_REQUEST_HEADER_2; - if(ostream.fail()) - { - LL_INFOS() << "STREAM FAILURE writing method headers" << LL_ENDL; - } - switch(param_sd.type()) - { - case LLSD::TypeMap: - // If the params are a map, then we do not want to iterate - // through them since the iterators returned will be map - // ordered un-named values, which will lose the names, and - // only stream the values, turning it into an array. - ostream << "<param>"; - streamOut(ostream, param_sd); - ostream << "</param>"; - break; - case LLSD::TypeArray: - { - - LLSD::array_iterator it = param_sd.beginArray(); - LLSD::array_iterator end = param_sd.endArray(); - for(; it != end; ++it) - { - ostream << "<param>"; - streamOut(ostream, *it); - ostream << "</param>"; - } - break; - } - default: - ostream << "<param>"; - streamOut(ostream, param_sd); - ostream << "</param>"; - break; - } - - stream << XMLRPC_REQUEST_FOOTER; - return STATUS_DONE; + // This pipe does not work if it does not have everyting. This + // could be addressed by making a stream parser for llsd which + // handled partial information. + PUMP_DEBUG; + if(!eos) + { + LL_INFOS() << "!eos" << LL_ENDL; + return STATUS_BREAK; + } + + // See if we can parse it + LLBufferStream stream(channels, buffer.get()); + LLSD sd; + LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); + if(stream.fail()) + { + LL_INFOS() << "STREAM FAILURE reading structure data." << LL_ENDL; + } + + PUMP_DEBUG; + // We can get the method and parameters from either the member + // function or passed in via the buffer. We prefer the buffer if + // we found a parameter and a method, or fall back to using + // mMethod and putting everyting in the buffer into the parameter. + std::string method; + LLSD param_sd; + if(sd.has("method") && sd.has("parameter")) + { + method = sd["method"].asString(); + param_sd = sd["parameter"]; + } + else + { + method = mMethod; + param_sd = sd; + } + if(method.empty()) + { + LL_WARNS() << "SD -> XML Request no method found." << LL_ENDL; + return STATUS_ERROR; + } + + PUMP_DEBUG; + // We have a method, and some kind of parameter, so package it up + // and send it out. + LLBufferStream ostream(channels, buffer.get()); + ostream.precision(DEFAULT_PRECISION); + if(ostream.fail()) + { + LL_INFOS() << "STREAM FAILURE setting precision" << LL_ENDL; + } + ostream << XML_HEADER << XMLRPC_REQUEST_HEADER_1 + << xml_escape_string(method) << XMLRPC_REQUEST_HEADER_2; + if(ostream.fail()) + { + LL_INFOS() << "STREAM FAILURE writing method headers" << LL_ENDL; + } + switch(param_sd.type()) + { + case LLSD::TypeMap: + // If the params are a map, then we do not want to iterate + // through them since the iterators returned will be map + // ordered un-named values, which will lose the names, and + // only stream the values, turning it into an array. + ostream << "<param>"; + streamOut(ostream, param_sd); + ostream << "</param>"; + break; + case LLSD::TypeArray: + { + + LLSD::array_iterator it = param_sd.beginArray(); + LLSD::array_iterator end = param_sd.endArray(); + for(; it != end; ++it) + { + ostream << "<param>"; + streamOut(ostream, *it); + ostream << "</param>"; + } + break; + } + default: + ostream << "<param>"; + streamOut(ostream, param_sd); + ostream << "</param>"; + break; + } + + stream << XMLRPC_REQUEST_FOOTER; + return STATUS_DONE; } /** @@ -500,92 +500,92 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( // parameters. LLIOPipe::EStatus stream_out(std::ostream& ostr, XMLRPC_VALUE value) { - XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(value); - LLIOPipe::EStatus status = LLIOPipe::STATUS_OK; - switch(type) - { - case xmlrpc_type_base64: - { - S32 len = XMLRPC_GetValueStringLen(value); - const char* buf = XMLRPC_GetValueBase64(value); - ostr << " b("; - if((len > 0) && buf) - { - ostr << len << ")\""; - ostr.write(buf, len); - ostr << "\""; - } - else - { - ostr << "0)\"\""; - } - break; - } - case xmlrpc_type_boolean: - //LL_DEBUGS() << "stream_out() bool" << LL_ENDL; - ostr << " " << (XMLRPC_GetValueBoolean(value) ? "true" : "false"); - break; - case xmlrpc_type_datetime: - ostr << " d\"" << XMLRPC_GetValueDateTime_ISO8601(value) << "\""; - break; - case xmlrpc_type_double: - ostr << " r" << XMLRPC_GetValueDouble(value); - //LL_DEBUGS() << "stream_out() double" << XMLRPC_GetValueDouble(value) - // << LL_ENDL; - break; - case xmlrpc_type_int: - ostr << " i" << XMLRPC_GetValueInt(value); - //LL_DEBUGS() << "stream_out() integer:" << XMLRPC_GetValueInt(value) - // << LL_ENDL; - break; - case xmlrpc_type_string: - //LL_DEBUGS() << "stream_out() string: " << str << LL_ENDL; - ostr << " s(" << XMLRPC_GetValueStringLen(value) << ")'" - << XMLRPC_GetValueString(value) << "'"; - break; - case xmlrpc_type_array: // vector - case xmlrpc_type_mixed: // vector - { - //LL_DEBUGS() << "stream_out() array" << LL_ENDL; - ostr << " ["; - U32 needs_comma = 0; - XMLRPC_VALUE current = XMLRPC_VectorRewind(value); - while(current && (LLIOPipe::STATUS_OK == status)) - { - if(needs_comma++) ostr << ","; - status = stream_out(ostr, current); - current = XMLRPC_VectorNext(value); - } - ostr << "]"; - break; - } - case xmlrpc_type_struct: // still vector - { - //LL_DEBUGS() << "stream_out() struct" << LL_ENDL; - ostr << " {"; - std::string name; - U32 needs_comma = 0; - XMLRPC_VALUE current = XMLRPC_VectorRewind(value); - while(current && (LLIOPipe::STATUS_OK == status)) - { - if(needs_comma++) ostr << ","; - name.assign(XMLRPC_GetValueID(current)); - ostr << "'" << LLSDNotationFormatter::escapeString(name) << "':"; - status = stream_out(ostr, current); - current = XMLRPC_VectorNext(value); - } - ostr << "}"; - break; - } - case xmlrpc_type_empty: - case xmlrpc_type_none: - default: - status = LLIOPipe::STATUS_ERROR; - LL_WARNS() << "Found an empty xmlrpc type.." << LL_ENDL; - // not much we can do here... - break; - }; - return status; + XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(value); + LLIOPipe::EStatus status = LLIOPipe::STATUS_OK; + switch(type) + { + case xmlrpc_type_base64: + { + S32 len = XMLRPC_GetValueStringLen(value); + const char* buf = XMLRPC_GetValueBase64(value); + ostr << " b("; + if((len > 0) && buf) + { + ostr << len << ")\""; + ostr.write(buf, len); + ostr << "\""; + } + else + { + ostr << "0)\"\""; + } + break; + } + case xmlrpc_type_boolean: + //LL_DEBUGS() << "stream_out() bool" << LL_ENDL; + ostr << " " << (XMLRPC_GetValueBoolean(value) ? "true" : "false"); + break; + case xmlrpc_type_datetime: + ostr << " d\"" << XMLRPC_GetValueDateTime_ISO8601(value) << "\""; + break; + case xmlrpc_type_double: + ostr << " r" << XMLRPC_GetValueDouble(value); + //LL_DEBUGS() << "stream_out() double" << XMLRPC_GetValueDouble(value) + // << LL_ENDL; + break; + case xmlrpc_type_int: + ostr << " i" << XMLRPC_GetValueInt(value); + //LL_DEBUGS() << "stream_out() integer:" << XMLRPC_GetValueInt(value) + // << LL_ENDL; + break; + case xmlrpc_type_string: + //LL_DEBUGS() << "stream_out() string: " << str << LL_ENDL; + ostr << " s(" << XMLRPC_GetValueStringLen(value) << ")'" + << XMLRPC_GetValueString(value) << "'"; + break; + case xmlrpc_type_array: // vector + case xmlrpc_type_mixed: // vector + { + //LL_DEBUGS() << "stream_out() array" << LL_ENDL; + ostr << " ["; + U32 needs_comma = 0; + XMLRPC_VALUE current = XMLRPC_VectorRewind(value); + while(current && (LLIOPipe::STATUS_OK == status)) + { + if(needs_comma++) ostr << ","; + status = stream_out(ostr, current); + current = XMLRPC_VectorNext(value); + } + ostr << "]"; + break; + } + case xmlrpc_type_struct: // still vector + { + //LL_DEBUGS() << "stream_out() struct" << LL_ENDL; + ostr << " {"; + std::string name; + U32 needs_comma = 0; + XMLRPC_VALUE current = XMLRPC_VectorRewind(value); + while(current && (LLIOPipe::STATUS_OK == status)) + { + if(needs_comma++) ostr << ","; + name.assign(XMLRPC_GetValueID(current)); + ostr << "'" << LLSDNotationFormatter::escapeString(name) << "':"; + status = stream_out(ostr, current); + current = XMLRPC_VectorNext(value); + } + ostr << "}"; + break; + } + case xmlrpc_type_empty: + case xmlrpc_type_none: + default: + status = LLIOPipe::STATUS_ERROR; + LL_WARNS() << "Found an empty xmlrpc type.." << LL_ENDL; + // not much we can do here... + break; + }; + return status; } LLFilterXMLRPCResponse2LLSD::LLFilterXMLRPCResponse2LLSD() @@ -597,76 +597,76 @@ LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD() } LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - if(!eos) return STATUS_BREAK; - if(!buffer) return STATUS_ERROR; - - PUMP_DEBUG; - // *FIX: This technique for reading data is far from optimal. We - // need to have some kind of istream interface into the xml - // parser... - S32 bytes = buffer->countAfter(channels.in(), NULL); - if(!bytes) return STATUS_ERROR; - char* buf = new char[bytes + 1]; - buf[bytes] = '\0'; - buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); - - //LL_DEBUGS() << "xmlrpc response: " << buf << LL_ENDL; - - PUMP_DEBUG; - XMLRPC_REQUEST response = XMLRPC_REQUEST_FromXML( - buf, - bytes, - NULL); - if(!response) - { - LL_WARNS() << "XML -> SD Response unable to parse xml." << LL_ENDL; - delete[] buf; - return STATUS_ERROR; - } - - PUMP_DEBUG; - LLBufferStream stream(channels, buffer.get()); - stream.precision(DEFAULT_PRECISION); - if(XMLRPC_ResponseIsFault(response)) - { - PUMP_DEBUG; - stream << LLSDRPC_FAULT_HADER_1 - << XMLRPC_GetResponseFaultCode(response) - << LLSDRPC_FAULT_HADER_2; - const char* fault_str = XMLRPC_GetResponseFaultString(response); - std::string fault_string; - if(fault_str) - { - fault_string.assign(fault_str); - } - stream << "'" << LLSDNotationFormatter::escapeString(fault_string) - << "'" <<LLSDRPC_FAULT_FOOTER; - } - else - { - PUMP_DEBUG; - stream << LLSDRPC_RESPONSE_HEADER; - XMLRPC_VALUE param = XMLRPC_RequestGetData(response); - if(param) - { - stream_out(stream, param); - } - stream << LLSDRPC_RESPONSE_FOOTER; - } - PUMP_DEBUG; - XMLRPC_RequestFree(response, 1); - delete[] buf; - PUMP_DEBUG; - return STATUS_DONE; + PUMP_DEBUG; + if(!eos) return STATUS_BREAK; + if(!buffer) return STATUS_ERROR; + + PUMP_DEBUG; + // *FIX: This technique for reading data is far from optimal. We + // need to have some kind of istream interface into the xml + // parser... + S32 bytes = buffer->countAfter(channels.in(), NULL); + if(!bytes) return STATUS_ERROR; + char* buf = new char[bytes + 1]; + buf[bytes] = '\0'; + buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); + + //LL_DEBUGS() << "xmlrpc response: " << buf << LL_ENDL; + + PUMP_DEBUG; + XMLRPC_REQUEST response = XMLRPC_REQUEST_FromXML( + buf, + bytes, + NULL); + if(!response) + { + LL_WARNS() << "XML -> SD Response unable to parse xml." << LL_ENDL; + delete[] buf; + return STATUS_ERROR; + } + + PUMP_DEBUG; + LLBufferStream stream(channels, buffer.get()); + stream.precision(DEFAULT_PRECISION); + if(XMLRPC_ResponseIsFault(response)) + { + PUMP_DEBUG; + stream << LLSDRPC_FAULT_HADER_1 + << XMLRPC_GetResponseFaultCode(response) + << LLSDRPC_FAULT_HADER_2; + const char* fault_str = XMLRPC_GetResponseFaultString(response); + std::string fault_string; + if(fault_str) + { + fault_string.assign(fault_str); + } + stream << "'" << LLSDNotationFormatter::escapeString(fault_string) + << "'" <<LLSDRPC_FAULT_FOOTER; + } + else + { + PUMP_DEBUG; + stream << LLSDRPC_RESPONSE_HEADER; + XMLRPC_VALUE param = XMLRPC_RequestGetData(response); + if(param) + { + stream_out(stream, param); + } + stream << LLSDRPC_RESPONSE_FOOTER; + } + PUMP_DEBUG; + XMLRPC_RequestFree(response, 1); + delete[] buf; + PUMP_DEBUG; + return STATUS_DONE; } /** @@ -681,98 +681,98 @@ LLFilterXMLRPCRequest2LLSD::~LLFilterXMLRPCRequest2LLSD() } LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - if(!eos) return STATUS_BREAK; - if(!buffer) return STATUS_ERROR; - - PUMP_DEBUG; - // *FIX: This technique for reading data is far from optimal. We - // need to have some kind of istream interface into the xml - // parser... - S32 bytes = buffer->countAfter(channels.in(), NULL); - if(!bytes) return STATUS_ERROR; - char* buf = new char[bytes + 1]; - buf[bytes] = '\0'; - buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); - - //LL_DEBUGS() << "xmlrpc request: " << buf << LL_ENDL; - - // Check the value in the buffer. XMLRPC_REQUEST_FromXML will report a error code 4 if - // values that are less than 0x20 are passed to it, except - // 0x09: Horizontal tab; 0x0a: New Line; 0x0d: Carriage - U8* cur_pBuf = (U8*)buf; + PUMP_DEBUG; + if(!eos) return STATUS_BREAK; + if(!buffer) return STATUS_ERROR; + + PUMP_DEBUG; + // *FIX: This technique for reading data is far from optimal. We + // need to have some kind of istream interface into the xml + // parser... + S32 bytes = buffer->countAfter(channels.in(), NULL); + if(!bytes) return STATUS_ERROR; + char* buf = new char[bytes + 1]; + buf[bytes] = '\0'; + buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); + + //LL_DEBUGS() << "xmlrpc request: " << buf << LL_ENDL; + + // Check the value in the buffer. XMLRPC_REQUEST_FromXML will report a error code 4 if + // values that are less than 0x20 are passed to it, except + // 0x09: Horizontal tab; 0x0a: New Line; 0x0d: Carriage + U8* cur_pBuf = (U8*)buf; U8 cur_char; - for (S32 i=0; i<bytes; i++) - { + for (S32 i=0; i<bytes; i++) + { cur_char = *cur_pBuf; - if ( cur_char < 0x20 + if ( cur_char < 0x20 && 0x09 != cur_char && 0x0a != cur_char && 0x0d != cur_char ) { - *cur_pBuf = '?'; + *cur_pBuf = '?'; + } + ++cur_pBuf; + } + + PUMP_DEBUG; + XMLRPC_REQUEST request = XMLRPC_REQUEST_FromXML( + buf, + bytes, + NULL); + if(!request) + { + LL_WARNS() << "XML -> SD Request process parse error." << LL_ENDL; + delete[] buf; + return STATUS_ERROR; + } + + PUMP_DEBUG; + LLBufferStream stream(channels, buffer.get()); + stream.precision(DEFAULT_PRECISION); + const char* name = XMLRPC_RequestGetMethodName(request); + stream << LLSDRPC_REQUEST_HEADER_1 << (name ? name : "") + << LLSDRPC_REQUEST_HEADER_2; + XMLRPC_VALUE param = XMLRPC_RequestGetData(request); + if(param) + { + PUMP_DEBUG; + S32 size = XMLRPC_VectorSize(param); + if(size > 1) + { + // if there are multiple parameters, stuff the values into + // an array so that the next step in the chain can read them. + stream << "["; + } + XMLRPC_VALUE current = XMLRPC_VectorRewind(param); + bool needs_comma = false; + while(current) + { + if(needs_comma) + { + stream << ","; + } + needs_comma = true; + stream_out(stream, current); + current = XMLRPC_VectorNext(param); + } + if(size > 1) + { + // close the array + stream << "]"; } - ++cur_pBuf; - } - - PUMP_DEBUG; - XMLRPC_REQUEST request = XMLRPC_REQUEST_FromXML( - buf, - bytes, - NULL); - if(!request) - { - LL_WARNS() << "XML -> SD Request process parse error." << LL_ENDL; - delete[] buf; - return STATUS_ERROR; - } - - PUMP_DEBUG; - LLBufferStream stream(channels, buffer.get()); - stream.precision(DEFAULT_PRECISION); - const char* name = XMLRPC_RequestGetMethodName(request); - stream << LLSDRPC_REQUEST_HEADER_1 << (name ? name : "") - << LLSDRPC_REQUEST_HEADER_2; - XMLRPC_VALUE param = XMLRPC_RequestGetData(request); - if(param) - { - PUMP_DEBUG; - S32 size = XMLRPC_VectorSize(param); - if(size > 1) - { - // if there are multiple parameters, stuff the values into - // an array so that the next step in the chain can read them. - stream << "["; - } - XMLRPC_VALUE current = XMLRPC_VectorRewind(param); - bool needs_comma = false; - while(current) - { - if(needs_comma) - { - stream << ","; - } - needs_comma = true; - stream_out(stream, current); - current = XMLRPC_VectorNext(param); - } - if(size > 1) - { - // close the array - stream << "]"; - } - } - stream << LLSDRPC_REQUEST_FOOTER; - XMLRPC_RequestFree(request, 1); - delete[] buf; - PUMP_DEBUG; - return STATUS_DONE; + } + stream << LLSDRPC_REQUEST_FOOTER; + XMLRPC_RequestFree(request, 1); + delete[] buf; + PUMP_DEBUG; + return STATUS_DONE; } diff --git a/indra/llmessage/llfiltersd2xmlrpc.h b/indra/llmessage/llfiltersd2xmlrpc.h index 0c9a0dc95b..55938d3e2b 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.h +++ b/indra/llmessage/llfiltersd2xmlrpc.h @@ -1,4 +1,4 @@ -/** +/** * @file llfiltersd2xmlrpc.h * @author Phoenix * @date 2005-04-26 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,9 +38,9 @@ #include <iosfwd> #include "lliopipe.h" -/** +/** * @class LLFilterSD2XMLRPC - * @brief Filter from serialized LLSD to an XMLRPC method call + * @brief Filter from serialized LLSD to an XMLRPC method call * * This clas provides common functionality for the LLFilterSD2XMLRPRC * request and response classes. @@ -48,19 +48,19 @@ class LLFilterSD2XMLRPC : public LLIOPipe { public: - LLFilterSD2XMLRPC(); - virtual ~LLFilterSD2XMLRPC(); + LLFilterSD2XMLRPC(); + virtual ~LLFilterSD2XMLRPC(); protected: - /** - * @brief helper method - */ - void streamOut(std::ostream& ostr, const LLSD& sd); + /** + * @brief helper method + */ + void streamOut(std::ostream& ostr, const LLSD& sd); }; -/** +/** * @class LLFilterSD2XMLRPCResponse - * @brief Filter from serialized LLSD to an XMLRPC response + * @brief Filter from serialized LLSD to an XMLRPC response * * This class filters a serialized LLSD object to an xmlrpc * repsonse. Since resonses are limited to a single param, the xmlrprc @@ -85,31 +85,31 @@ protected: class LLFilterSD2XMLRPCResponse : public LLFilterSD2XMLRPC { public: - // constructor - LLFilterSD2XMLRPCResponse(); + // constructor + LLFilterSD2XMLRPCResponse(); - // destructor - virtual ~LLFilterSD2XMLRPCResponse(); + // destructor + virtual ~LLFilterSD2XMLRPCResponse(); - /* @name LLIOPipe virtual implementations - */ - //@{ + /* @name LLIOPipe virtual implementations + */ + //@{ protected: - /** - * @brief Process the data in buffer. - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /** + * @brief Process the data in buffer. + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} }; -/** +/** * @class LLFilterSD2XMLRPCRequest - * @brief Filter from serialized LLSD to an XMLRPC method call + * @brief Filter from serialized LLSD to an XMLRPC method call * * This class will accept any kind of serialized LLSD object, but you * probably want to have an array on the outer boundary since this @@ -141,38 +141,38 @@ protected: class LLFilterSD2XMLRPCRequest : public LLFilterSD2XMLRPC { public: - // constructor - LLFilterSD2XMLRPCRequest(); + // constructor + LLFilterSD2XMLRPCRequest(); - // constructor - LLFilterSD2XMLRPCRequest(const char* method); + // constructor + LLFilterSD2XMLRPCRequest(const char* method); - // destructor - virtual ~LLFilterSD2XMLRPCRequest(); + // destructor + virtual ~LLFilterSD2XMLRPCRequest(); - /* @name LLIOPipe virtual implementations - */ - //@{ + /* @name LLIOPipe virtual implementations + */ + //@{ protected: - /** - * @brief Process the data in buffer. - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /** + * @brief Process the data in buffer. + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - // The method name of this request. - std::string mMethod; + // The method name of this request. + std::string mMethod; }; -/** +/** * @class LLFilterXMLRPCResponse2LLSD - * @brief Filter from serialized XMLRPC method response to LLSD + * @brief Filter from serialized XMLRPC method response to LLSD * * The xmlrpc spec states that responses can only have one element * which can be of any supported type. @@ -188,33 +188,33 @@ protected: class LLFilterXMLRPCResponse2LLSD : public LLIOPipe { public: - // constructor - LLFilterXMLRPCResponse2LLSD(); + // constructor + LLFilterXMLRPCResponse2LLSD(); - // destructor - virtual ~LLFilterXMLRPCResponse2LLSD(); + // destructor + virtual ~LLFilterXMLRPCResponse2LLSD(); - /* @name LLIOPipe virtual implementations - */ - //@{ + /* @name LLIOPipe virtual implementations + */ + //@{ protected: - /** - * @brief Process the data in buffer. - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /** + * @brief Process the data in buffer. + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: }; -/** +/** * @class LLFilterXMLRPCRequest2LLSD - * @brief Filter from serialized XMLRPC method call to LLSD + * @brief Filter from serialized XMLRPC method call to LLSD * * This takes in xml of the form: * <code> @@ -231,26 +231,26 @@ protected: class LLFilterXMLRPCRequest2LLSD : public LLIOPipe { public: - // constructor - LLFilterXMLRPCRequest2LLSD(); + // constructor + LLFilterXMLRPCRequest2LLSD(); - // destructor - virtual ~LLFilterXMLRPCRequest2LLSD(); + // destructor + virtual ~LLFilterXMLRPCRequest2LLSD(); - /* @name LLIOPipe virtual implementations - */ - //@{ + /* @name LLIOPipe virtual implementations + */ + //@{ protected: - /** - * @brief Process the data in buffer. - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /** + * @brief Process the data in buffer. + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: }; diff --git a/indra/llmessage/llfollowcamparams.h b/indra/llmessage/llfollowcamparams.h index 25208031db..f24b362c08 100644 --- a/indra/llmessage/llfollowcamparams.h +++ b/indra/llmessage/llfollowcamparams.h @@ -1,25 +1,25 @@ -/** +/** * @file llfollowcamparams.h * @brief Follow camera parameters. * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,30 +30,30 @@ //Ventrella Follow Cam Script Stuff enum EFollowCamAttributes { - FOLLOWCAM_PITCH = 0, - FOLLOWCAM_FOCUS_OFFSET, - FOLLOWCAM_FOCUS_OFFSET_X, //this HAS to come after FOLLOWCAM_FOCUS_OFFSET in this list - FOLLOWCAM_FOCUS_OFFSET_Y, - FOLLOWCAM_FOCUS_OFFSET_Z, - FOLLOWCAM_POSITION_LAG, - FOLLOWCAM_FOCUS_LAG, - FOLLOWCAM_DISTANCE, - FOLLOWCAM_BEHINDNESS_ANGLE, - FOLLOWCAM_BEHINDNESS_LAG, - FOLLOWCAM_POSITION_THRESHOLD, - FOLLOWCAM_FOCUS_THRESHOLD, - FOLLOWCAM_ACTIVE, - FOLLOWCAM_POSITION, - FOLLOWCAM_POSITION_X, //this HAS to come after FOLLOWCAM_POSITION in this list - FOLLOWCAM_POSITION_Y, - FOLLOWCAM_POSITION_Z, - FOLLOWCAM_FOCUS, - FOLLOWCAM_FOCUS_X, //this HAS to come after FOLLOWCAM_FOCUS in this list - FOLLOWCAM_FOCUS_Y, - FOLLOWCAM_FOCUS_Z, - FOLLOWCAM_POSITION_LOCKED, - FOLLOWCAM_FOCUS_LOCKED, - NUM_FOLLOWCAM_ATTRIBUTES + FOLLOWCAM_PITCH = 0, + FOLLOWCAM_FOCUS_OFFSET, + FOLLOWCAM_FOCUS_OFFSET_X, //this HAS to come after FOLLOWCAM_FOCUS_OFFSET in this list + FOLLOWCAM_FOCUS_OFFSET_Y, + FOLLOWCAM_FOCUS_OFFSET_Z, + FOLLOWCAM_POSITION_LAG, + FOLLOWCAM_FOCUS_LAG, + FOLLOWCAM_DISTANCE, + FOLLOWCAM_BEHINDNESS_ANGLE, + FOLLOWCAM_BEHINDNESS_LAG, + FOLLOWCAM_POSITION_THRESHOLD, + FOLLOWCAM_FOCUS_THRESHOLD, + FOLLOWCAM_ACTIVE, + FOLLOWCAM_POSITION, + FOLLOWCAM_POSITION_X, //this HAS to come after FOLLOWCAM_POSITION in this list + FOLLOWCAM_POSITION_Y, + FOLLOWCAM_POSITION_Z, + FOLLOWCAM_FOCUS, + FOLLOWCAM_FOCUS_X, //this HAS to come after FOLLOWCAM_FOCUS in this list + FOLLOWCAM_FOCUS_Y, + FOLLOWCAM_FOCUS_Z, + FOLLOWCAM_POSITION_LOCKED, + FOLLOWCAM_FOCUS_LOCKED, + NUM_FOLLOWCAM_ATTRIBUTES }; //end Ventrella diff --git a/indra/llmessage/llgenericstreamingmessage.cpp b/indra/llmessage/llgenericstreamingmessage.cpp index 8627675c54..d7f4860a5f 100644 --- a/indra/llmessage/llgenericstreamingmessage.cpp +++ b/indra/llmessage/llgenericstreamingmessage.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/llgenericstreamingmessage.h b/indra/llmessage/llgenericstreamingmessage.h index 9ac9719ea1..a24e6435bd 100644 --- a/indra/llmessage/llgenericstreamingmessage.h +++ b/indra/llmessage/llgenericstreamingmessage.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp index 30e4109729..ace316512f 100644 --- a/indra/llmessage/llhost.cpp +++ b/indra/llmessage/llhost.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llhost.cpp * @brief Encapsulates an IP address and a port. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,146 +31,146 @@ #include "llerror.h" #if LL_WINDOWS - #define WIN32_LEAN_AND_MEAN - #include <winsock2.h> + #define WIN32_LEAN_AND_MEAN + #include <winsock2.h> #else - #include <netdb.h> - #include <netinet/in.h> // ntonl() - #include <sys/types.h> - #include <sys/socket.h> - #include <arpa/inet.h> + #include <netdb.h> + #include <netinet/in.h> // ntonl() + #include <sys/types.h> + #include <sys/socket.h> + #include <arpa/inet.h> #endif LLHost::LLHost(const std::string& ip_and_port) { - std::string::size_type colon_index = ip_and_port.find(":"); - if (colon_index == std::string::npos) - { - mIP = ip_string_to_u32(ip_and_port.c_str()); - mPort = 0; - } - else - { - std::string ip_str(ip_and_port, 0, colon_index); - std::string port_str(ip_and_port, colon_index+1); - - mIP = ip_string_to_u32(ip_str.c_str()); - mPort = atol(port_str.c_str()); - } + std::string::size_type colon_index = ip_and_port.find(":"); + if (colon_index == std::string::npos) + { + mIP = ip_string_to_u32(ip_and_port.c_str()); + mPort = 0; + } + else + { + std::string ip_str(ip_and_port, 0, colon_index); + std::string port_str(ip_and_port, colon_index+1); + + mIP = ip_string_to_u32(ip_str.c_str()); + mPort = atol(port_str.c_str()); + } } std::string LLHost::getString() const { - return llformat("%s:%u", u32_to_ip_string(mIP), mPort); + return llformat("%s:%u", u32_to_ip_string(mIP), mPort); } std::string LLHost::getIPandPort() const { - return getString(); + return getString(); } std::string LLHost::getIPString() const { - return std::string( u32_to_ip_string( mIP ) ); + return std::string( u32_to_ip_string( mIP ) ); } std::string LLHost::getHostName() const { - hostent* he; - if (INVALID_HOST_IP_ADDRESS == mIP) - { - LL_WARNS() << "LLHost::getHostName() : Invalid IP address" << LL_ENDL; - return std::string(); - } - he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET); - if (!he) - { + hostent* he; + if (INVALID_HOST_IP_ADDRESS == mIP) + { + LL_WARNS() << "LLHost::getHostName() : Invalid IP address" << LL_ENDL; + return std::string(); + } + he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET); + if (!he) + { #if LL_WINDOWS - LL_WARNS() << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " - << WSAGetLastError() << LL_ENDL; + LL_WARNS() << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " + << WSAGetLastError() << LL_ENDL; #else - LL_WARNS() << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " - << h_errno << LL_ENDL; + LL_WARNS() << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " + << h_errno << LL_ENDL; #endif - return std::string(); - } - else - { - return ll_safe_string(he->h_name); - } + return std::string(); + } + else + { + return ll_safe_string(he->h_name); + } } bool LLHost::setHostByName(const std::string& hostname) { - hostent *he; - std::string local_name(hostname); + hostent *he; + std::string local_name(hostname); #if LL_WINDOWS - // We may need an equivalent for Linux, but not sure - djs - LLStringUtil::toUpper(local_name); + // We may need an equivalent for Linux, but not sure - djs + LLStringUtil::toUpper(local_name); #endif - he = gethostbyname(local_name.c_str()); - if(!he) - { - U32 ip_address = ip_string_to_u32(hostname.c_str()); - he = gethostbyaddr((char *)&ip_address, sizeof(ip_address), AF_INET); - } - - if (he) - { - mIP = *(U32 *)he->h_addr_list[0]; - return true; - } - else - { - setAddress(local_name); - - // In windows, h_errno is a macro for WSAGetLastError(), so store value here - S32 error_number = h_errno; - switch(error_number) - { - case TRY_AGAIN: // XXX how to handle this case? - LL_WARNS() << "LLHost::setAddress(): try again" << LL_ENDL; - break; - case HOST_NOT_FOUND: - case NO_ADDRESS: // NO_DATA - LL_WARNS() << "LLHost::setAddress(): host not found" << LL_ENDL; - break; - case NO_RECOVERY: - LL_WARNS() << "LLHost::setAddress(): unrecoverable error" << LL_ENDL; - break; - default: - LL_WARNS() << "LLHost::setAddress(): unknown error - " << error_number << LL_ENDL; - break; - } - return false; - } + he = gethostbyname(local_name.c_str()); + if(!he) + { + U32 ip_address = ip_string_to_u32(hostname.c_str()); + he = gethostbyaddr((char *)&ip_address, sizeof(ip_address), AF_INET); + } + + if (he) + { + mIP = *(U32 *)he->h_addr_list[0]; + return true; + } + else + { + setAddress(local_name); + + // In windows, h_errno is a macro for WSAGetLastError(), so store value here + S32 error_number = h_errno; + switch(error_number) + { + case TRY_AGAIN: // XXX how to handle this case? + LL_WARNS() << "LLHost::setAddress(): try again" << LL_ENDL; + break; + case HOST_NOT_FOUND: + case NO_ADDRESS: // NO_DATA + LL_WARNS() << "LLHost::setAddress(): host not found" << LL_ENDL; + break; + case NO_RECOVERY: + LL_WARNS() << "LLHost::setAddress(): unrecoverable error" << LL_ENDL; + break; + default: + LL_WARNS() << "LLHost::setAddress(): unknown error - " << error_number << LL_ENDL; + break; + } + return false; + } } -LLHost& LLHost::operator=(const LLHost &rhs) -{ - if (this != &rhs) - { - set(rhs.getAddress(), rhs.getPort()); - } - return *this; +LLHost& LLHost::operator=(const LLHost &rhs) +{ + if (this != &rhs) + { + set(rhs.getAddress(), rhs.getPort()); + } + return *this; } std::ostream& operator<< (std::ostream& os, const LLHost &hh) { - os << u32_to_ip_string(hh.mIP) << ":" << hh.mPort ; - return os; + os << u32_to_ip_string(hh.mIP) << ":" << hh.mPort ; + return os; } //std::istream& operator>> (std::istream& is, LLHost &rh) //{ -// is >> rh.mIP; +// is >> rh.mIP; // is >> rh.mPort; // return is; //} diff --git a/indra/llmessage/llhost.h b/indra/llmessage/llhost.h index dd12e381d4..6824fa3d78 100644 --- a/indra/llmessage/llhost.h +++ b/indra/llmessage/llhost.h @@ -1,4 +1,4 @@ -/** +/** * @file llhost.h * @brief a LLHost uniquely defines a host (Simulator, Proxy or other) * across the network @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,116 +38,116 @@ const U32 INVALID_HOST_IP_ADDRESS = 0x0; class LLHost { protected: - U32 mPort; - U32 mIP; + U32 mPort; + U32 mIP; std::string mUntrustedSimCap; public: - // CREATORS - LLHost() - : mPort(INVALID_PORT), - mIP(INVALID_HOST_IP_ADDRESS) - { } // STL's hash_map expect this T() - - LLHost( U32 ipv4_addr, U32 port ) - : mPort( port ) - { - mIP = ipv4_addr; - } - - LLHost( const std::string& ipv4_addr, U32 port ) - : mPort( port ) - { - mIP = ip_string_to_u32(ipv4_addr.c_str()); - } - - explicit LLHost(const U64 ip_port) - { - U32 ip = (U32)(ip_port >> 32); - U32 port = (U32)(ip_port & (U64)0xFFFFFFFF); - mIP = ip; - mPort = port; - } - - explicit LLHost(const std::string& ip_and_port); - - ~LLHost() - { } - - // MANIPULATORS - void set( U32 ip, U32 port ) { mIP = ip; mPort = port; } - void set( const std::string& ipstr, U32 port ) { mIP = ip_string_to_u32(ipstr.c_str()); mPort = port; } - void setAddress( const std::string& ipstr ) { mIP = ip_string_to_u32(ipstr.c_str()); } - void setAddress( U32 ip ) { mIP = ip; } - void setPort( U32 port ) { mPort = port; } - bool setHostByName(const std::string& hname); - - LLHost& operator=(const LLHost &rhs); - void invalidate() { mIP = INVALID_HOST_IP_ADDRESS; mPort = INVALID_PORT;}; - - // READERS - U32 getAddress() const { return mIP; } - U32 getPort() const { return mPort; } - bool isOk() const { return (mIP != INVALID_HOST_IP_ADDRESS) && (mPort != INVALID_PORT); } + // CREATORS + LLHost() + : mPort(INVALID_PORT), + mIP(INVALID_HOST_IP_ADDRESS) + { } // STL's hash_map expect this T() + + LLHost( U32 ipv4_addr, U32 port ) + : mPort( port ) + { + mIP = ipv4_addr; + } + + LLHost( const std::string& ipv4_addr, U32 port ) + : mPort( port ) + { + mIP = ip_string_to_u32(ipv4_addr.c_str()); + } + + explicit LLHost(const U64 ip_port) + { + U32 ip = (U32)(ip_port >> 32); + U32 port = (U32)(ip_port & (U64)0xFFFFFFFF); + mIP = ip; + mPort = port; + } + + explicit LLHost(const std::string& ip_and_port); + + ~LLHost() + { } + + // MANIPULATORS + void set( U32 ip, U32 port ) { mIP = ip; mPort = port; } + void set( const std::string& ipstr, U32 port ) { mIP = ip_string_to_u32(ipstr.c_str()); mPort = port; } + void setAddress( const std::string& ipstr ) { mIP = ip_string_to_u32(ipstr.c_str()); } + void setAddress( U32 ip ) { mIP = ip; } + void setPort( U32 port ) { mPort = port; } + bool setHostByName(const std::string& hname); + + LLHost& operator=(const LLHost &rhs); + void invalidate() { mIP = INVALID_HOST_IP_ADDRESS; mPort = INVALID_PORT;}; + + // READERS + U32 getAddress() const { return mIP; } + U32 getPort() const { return mPort; } + bool isOk() const { return (mIP != INVALID_HOST_IP_ADDRESS) && (mPort != INVALID_PORT); } bool isInvalid() { return (mIP == INVALID_HOST_IP_ADDRESS) || (mPort == INVALID_PORT); } - size_t hash() const { return (mIP << 16) | (mPort & 0xffff); } - std::string getString() const; - std::string getIPString() const; - std::string getHostName() const; - std::string getIPandPort() const; + size_t hash() const { return (mIP << 16) | (mPort & 0xffff); } + std::string getString() const; + std::string getIPString() const; + std::string getHostName() const; + std::string getIPandPort() const; std::string getUntrustedSimulatorCap() const { return mUntrustedSimCap; } void setUntrustedSimulatorCap(const std::string &capurl) { mUntrustedSimCap = capurl; } - friend std::ostream& operator<< (std::ostream& os, const LLHost &hh); + friend std::ostream& operator<< (std::ostream& os, const LLHost &hh); - // This operator is not well defined. does it expect a - // "192.168.1.1:80" notation or "int int" format? Phoenix 2007-05-18 - //friend std::istream& operator>> (std::istream& is, LLHost &hh); + // This operator is not well defined. does it expect a + // "192.168.1.1:80" notation or "int int" format? Phoenix 2007-05-18 + //friend std::istream& operator>> (std::istream& is, LLHost &hh); - friend bool operator==( const LLHost &lhs, const LLHost &rhs ); - friend bool operator!=( const LLHost &lhs, const LLHost &rhs ); - friend bool operator<(const LLHost &lhs, const LLHost &rhs); + friend bool operator==( const LLHost &lhs, const LLHost &rhs ); + friend bool operator!=( const LLHost &lhs, const LLHost &rhs ); + friend bool operator<(const LLHost &lhs, const LLHost &rhs); }; -// Function Object required for STL templates using LLHost as key +// Function Object required for STL templates using LLHost as key class LLHostHash { public: - size_t operator() (const LLHost &hh) const { return hh.hash(); } + size_t operator() (const LLHost &hh) const { return hh.hash(); } }; inline bool operator==( const LLHost &lhs, const LLHost &rhs ) { - return (lhs.mIP == rhs.mIP) && (lhs.mPort == rhs.mPort); + return (lhs.mIP == rhs.mIP) && (lhs.mPort == rhs.mPort); } inline bool operator!=( const LLHost &lhs, const LLHost &rhs ) { - return (lhs.mIP != rhs.mIP) || (lhs.mPort != rhs.mPort); + return (lhs.mIP != rhs.mIP) || (lhs.mPort != rhs.mPort); } inline bool operator<(const LLHost &lhs, const LLHost &rhs) { - if (lhs.mIP < rhs.mIP) - { - return true; - } - if (lhs.mIP > rhs.mIP) - { - return false; - } - - if (lhs.mPort < rhs.mPort) - { - return true; - } - else - { - return false; - } + if (lhs.mIP < rhs.mIP) + { + return true; + } + if (lhs.mIP > rhs.mIP) + { + return false; + } + + if (lhs.mPort < rhs.mPort) + { + return true; + } + else + { + return false; + } } diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 6e9598a0a3..65bdfaff7e 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llhttpnode.cpp * @brief Implementation of classes for generic HTTP/LSL/REST handling. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,77 +44,77 @@ const std::string CONTEXT_WILDCARD("wildcard"); /** * LLHTTPNode */ - + class LLHTTPNode::Impl { public: - typedef std::map<std::string, LLHTTPNode*> ChildMap; - - ChildMap mNamedChildren; - LLHTTPNode* mWildcardChild; - std::string mWildcardName; - std::string mWildcardKey; - LLHTTPNode* mParentNode; - - Impl() : mWildcardChild(NULL), mParentNode(NULL) { } - - LLHTTPNode* findNamedChild(const std::string& name) const; + typedef std::map<std::string, LLHTTPNode*> ChildMap; + + ChildMap mNamedChildren; + LLHTTPNode* mWildcardChild; + std::string mWildcardName; + std::string mWildcardKey; + LLHTTPNode* mParentNode; + + Impl() : mWildcardChild(NULL), mParentNode(NULL) { } + + LLHTTPNode* findNamedChild(const std::string& name) const; }; LLHTTPNode* LLHTTPNode::Impl::findNamedChild(const std::string& name) const { - LLHTTPNode* child = get_ptr_in_map(mNamedChildren, name); + LLHTTPNode* child = get_ptr_in_map(mNamedChildren, name); - if (!child && ((name[0] == '*') || (name == mWildcardName))) - { - child = mWildcardChild; - } - - return child; + if (!child && ((name[0] == '*') || (name == mWildcardName))) + { + child = mWildcardChild; + } + + return child; } LLHTTPNode::LLHTTPNode() - : impl(* new Impl) + : impl(* new Impl) { } // virtual LLHTTPNode::~LLHTTPNode() { - std::for_each(impl.mNamedChildren.begin(), impl.mNamedChildren.end(), DeletePairedPointer()); - impl.mNamedChildren.clear(); + std::for_each(impl.mNamedChildren.begin(), impl.mNamedChildren.end(), DeletePairedPointer()); + impl.mNamedChildren.clear(); + + delete impl.mWildcardChild; - delete impl.mWildcardChild; - - delete &impl; + delete &impl; } namespace { - struct NotImplemented: public LLException - { - NotImplemented(): LLException("LLHTTPNode::NotImplemented") {} - }; + struct NotImplemented: public LLException + { + NotImplemented(): LLException("LLHTTPNode::NotImplemented") {} + }; } // virtual LLSD LLHTTPNode::simpleGet() const { - LLTHROW(NotImplemented()); + LLTHROW(NotImplemented()); } // virtual LLSD LLHTTPNode::simplePut(const LLSD& input) const { - LLTHROW(NotImplemented()); + LLTHROW(NotImplemented()); } // virtual LLSD LLHTTPNode::simplePost(const LLSD& input) const { - LLTHROW(NotImplemented()); + LLTHROW(NotImplemented()); } @@ -122,42 +122,42 @@ LLSD LLHTTPNode::simplePost(const LLSD& input) const void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) const { LL_PROFILE_ZONE_SCOPED; - try - { - response->result(simpleGet()); - } - catch (NotImplemented&) - { - response->methodNotAllowed(); - } + try + { + response->result(simpleGet()); + } + catch (NotImplemented&) + { + response->methodNotAllowed(); + } } // virtual void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const { LL_PROFILE_ZONE_SCOPED; - try - { - response->result(simplePut(input)); - } - catch (NotImplemented&) - { - response->methodNotAllowed(); - } + try + { + response->result(simplePut(input)); + } + catch (NotImplemented&) + { + response->methodNotAllowed(); + } } // virtual void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const { LL_PROFILE_ZONE_SCOPED; - try - { - response->result(simplePost(input)); - } - catch (NotImplemented&) - { - response->methodNotAllowed(); - } + try + { + response->result(simplePost(input)); + } + catch (NotImplemented&) + { + response->methodNotAllowed(); + } } // virtual @@ -166,11 +166,11 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons LL_PROFILE_ZONE_SCOPED; try { - response->result(simpleDel(context)); + response->result(simpleDel(context)); } catch (NotImplemented&) { - response->methodNotAllowed(); + response->methodNotAllowed(); } } @@ -178,218 +178,218 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons // virtual LLSD LLHTTPNode::simpleDel(const LLSD&) const { - LLTHROW(NotImplemented()); + LLTHROW(NotImplemented()); } // virtual void LLHTTPNode::options(ResponsePtr response, const LLSD& context) const { - //LL_INFOS() << "options context: " << context << LL_ENDL; - LL_DEBUGS("LLHTTPNode") << "context: " << context << LL_ENDL; + //LL_INFOS() << "options context: " << context << LL_ENDL; + LL_DEBUGS("LLHTTPNode") << "context: " << context << LL_ENDL; - // default implementation constructs an url to the documentation. - // *TODO: Check for 'Host' header instead of 'host' header? - std::string host( - context[CONTEXT_REQUEST][CONTEXT_HEADERS][HTTP_IN_HEADER_HOST].asString()); - if(host.empty()) - { - response->status(HTTP_BAD_REQUEST, "Bad Request -- need Host header"); - return; - } - std::ostringstream ostr; - ostr << "http://" << host << "/web/server/api"; - ostr << context[CONTEXT_REQUEST][CONTEXT_PATH].asString(); - static const std::string DOC_HEADER("X-Documentation-URL"); - response->addHeader(DOC_HEADER, ostr.str()); - response->status(HTTP_OK, "OK"); + // default implementation constructs an url to the documentation. + // *TODO: Check for 'Host' header instead of 'host' header? + std::string host( + context[CONTEXT_REQUEST][CONTEXT_HEADERS][HTTP_IN_HEADER_HOST].asString()); + if(host.empty()) + { + response->status(HTTP_BAD_REQUEST, "Bad Request -- need Host header"); + return; + } + std::ostringstream ostr; + ostr << "http://" << host << "/web/server/api"; + ostr << context[CONTEXT_REQUEST][CONTEXT_PATH].asString(); + static const std::string DOC_HEADER("X-Documentation-URL"); + response->addHeader(DOC_HEADER, ostr.str()); + response->status(HTTP_OK, "OK"); } // virtual LLHTTPNode* LLHTTPNode::getChild(const std::string& name, LLSD& context) const { - LLHTTPNode* namedChild = get_ptr_in_map(impl.mNamedChildren, name); - if (namedChild) - { - return namedChild; - } - - if (impl.mWildcardChild - && impl.mWildcardChild->validate(name, context)) - { - context[CONTEXT_REQUEST][CONTEXT_WILDCARD][impl.mWildcardKey] = name; - return impl.mWildcardChild; - } - - return NULL; + LLHTTPNode* namedChild = get_ptr_in_map(impl.mNamedChildren, name); + if (namedChild) + { + return namedChild; + } + + if (impl.mWildcardChild + && impl.mWildcardChild->validate(name, context)) + { + context[CONTEXT_REQUEST][CONTEXT_WILDCARD][impl.mWildcardKey] = name; + return impl.mWildcardChild; + } + + return NULL; } // virtual bool LLHTTPNode::handles(const LLSD& remainder, LLSD& context) const { - return remainder.size() == 0; + return remainder.size() == 0; } // virtual bool LLHTTPNode::validate(const std::string& name, LLSD& context) const { - return false; + return false; } const LLHTTPNode* LLHTTPNode::traverse( - const std::string& path, LLSD& context) const + const std::string& path, LLSD& context) const { - typedef boost::tokenizer< boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); - tokenizer tokens(path, sep); - tokenizer::iterator iter = tokens.begin(); - tokenizer::iterator end = tokens.end(); + typedef boost::tokenizer< boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); + tokenizer tokens(path, sep); + tokenizer::iterator iter = tokens.begin(); + tokenizer::iterator end = tokens.end(); - const LLHTTPNode* node = this; - for(; iter != end; ++iter) - { - LLHTTPNode* child = node->getChild(*iter, context); - if(!child) - { - LL_DEBUGS() << "LLHTTPNode::traverse: Couldn't find '" << *iter << "'" << LL_ENDL; - break; - } - LL_DEBUGS() << "LLHTTPNode::traverse: Found '" << *iter << "'" << LL_ENDL; - - node = child; - } + const LLHTTPNode* node = this; + for(; iter != end; ++iter) + { + LLHTTPNode* child = node->getChild(*iter, context); + if(!child) + { + LL_DEBUGS() << "LLHTTPNode::traverse: Couldn't find '" << *iter << "'" << LL_ENDL; + break; + } + LL_DEBUGS() << "LLHTTPNode::traverse: Found '" << *iter << "'" << LL_ENDL; + + node = child; + } - LLSD& remainder = context[CONTEXT_REQUEST]["remainder"]; - for(; iter != end; ++iter) - { - remainder.append(*iter); - } + LLSD& remainder = context[CONTEXT_REQUEST]["remainder"]; + for(; iter != end; ++iter) + { + remainder.append(*iter); + } - return node->handles(remainder, context) ? node : NULL; + return node->handles(remainder, context) ? node : NULL; } void LLHTTPNode::addNode(const std::string& path, LLHTTPNode* nodeToAdd) { - typedef boost::tokenizer< boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); - tokenizer tokens(path, sep); - tokenizer::iterator iter = tokens.begin(); - tokenizer::iterator end = tokens.end(); - - LLHTTPNode* node = this; - for(; iter != end; ++iter) - { - LLHTTPNode* child = node->impl.findNamedChild(*iter); - if (!child) { break; } - node = child; - } - - if (iter == end) - { - LL_WARNS() << "LLHTTPNode::addNode: already a node that handles " - << path << LL_ENDL; - return; - } - - while (true) - { - std::string pathPart = *iter; - - ++iter; - bool lastOne = iter == end; - - LLHTTPNode* nextNode = lastOne ? nodeToAdd : new LLHTTPNode(); - - switch (pathPart[0]) - { - case '<': - // *NOTE: This should really validate that it is of - // the proper form: <wildcardkey> so that the substr() - // generates the correct key name. - node->impl.mWildcardChild = nextNode; - node->impl.mWildcardName = pathPart; - if(node->impl.mWildcardKey.empty()) - { - node->impl.mWildcardKey = pathPart.substr( - 1, - pathPart.size() - 2); - } - break; - case '*': - node->impl.mWildcardChild = nextNode; - if(node->impl.mWildcardName.empty()) - { - node->impl.mWildcardName = pathPart; - } - break; - - default: - node->impl.mNamedChildren[pathPart] = nextNode; - } - nextNode->impl.mParentNode = node; - - if (lastOne) break; - node = nextNode; - } + typedef boost::tokenizer< boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); + tokenizer tokens(path, sep); + tokenizer::iterator iter = tokens.begin(); + tokenizer::iterator end = tokens.end(); + + LLHTTPNode* node = this; + for(; iter != end; ++iter) + { + LLHTTPNode* child = node->impl.findNamedChild(*iter); + if (!child) { break; } + node = child; + } + + if (iter == end) + { + LL_WARNS() << "LLHTTPNode::addNode: already a node that handles " + << path << LL_ENDL; + return; + } + + while (true) + { + std::string pathPart = *iter; + + ++iter; + bool lastOne = iter == end; + + LLHTTPNode* nextNode = lastOne ? nodeToAdd : new LLHTTPNode(); + + switch (pathPart[0]) + { + case '<': + // *NOTE: This should really validate that it is of + // the proper form: <wildcardkey> so that the substr() + // generates the correct key name. + node->impl.mWildcardChild = nextNode; + node->impl.mWildcardName = pathPart; + if(node->impl.mWildcardKey.empty()) + { + node->impl.mWildcardKey = pathPart.substr( + 1, + pathPart.size() - 2); + } + break; + case '*': + node->impl.mWildcardChild = nextNode; + if(node->impl.mWildcardName.empty()) + { + node->impl.mWildcardName = pathPart; + } + break; + + default: + node->impl.mNamedChildren[pathPart] = nextNode; + } + nextNode->impl.mParentNode = node; + + if (lastOne) break; + node = nextNode; + } } static void append_node_paths(LLSD& result, - const std::string& name, const LLHTTPNode* node) + const std::string& name, const LLHTTPNode* node) { - result.append(name); - - LLSD paths = node->allNodePaths(); - LLSD::array_const_iterator i = paths.beginArray(); - LLSD::array_const_iterator end = paths.endArray(); - - for (; i != end; ++i) - { - result.append(name + "/" + (*i).asString()); - } + result.append(name); + + LLSD paths = node->allNodePaths(); + LLSD::array_const_iterator i = paths.beginArray(); + LLSD::array_const_iterator end = paths.endArray(); + + for (; i != end; ++i) + { + result.append(name + "/" + (*i).asString()); + } } LLSD LLHTTPNode::allNodePaths() const { - LLSD result; - - Impl::ChildMap::const_iterator i = impl.mNamedChildren.begin(); - Impl::ChildMap::const_iterator end = impl.mNamedChildren.end(); - for (; i != end; ++i) - { - append_node_paths(result, i->first, i->second); - } - - if (impl.mWildcardChild) - { - append_node_paths(result, impl.mWildcardName, impl.mWildcardChild); - } - - return result; + LLSD result; + + Impl::ChildMap::const_iterator i = impl.mNamedChildren.begin(); + Impl::ChildMap::const_iterator end = impl.mNamedChildren.end(); + for (; i != end; ++i) + { + append_node_paths(result, i->first, i->second); + } + + if (impl.mWildcardChild) + { + append_node_paths(result, impl.mWildcardName, impl.mWildcardChild); + } + + return result; } const LLHTTPNode* LLHTTPNode::rootNode() const { - const LLHTTPNode* node = this; - - while (true) - { - const LLHTTPNode* next = node->impl.mParentNode; - if (!next) - { - return node; - } - node = next; - } + const LLHTTPNode* node = this; + + while (true) + { + const LLHTTPNode* next = node->impl.mParentNode; + if (!next) + { + return node; + } + node = next; + } } const LLHTTPNode* LLHTTPNode::findNode(const std::string& name) const { - return impl.findNamedChild(name); + return impl.findNamedChild(name); } LLHTTPNode::Response::~Response() @@ -398,40 +398,40 @@ LLHTTPNode::Response::~Response() void LLHTTPNode::Response::statusUnknownError(S32 code) { - status(code, "Unknown Error"); + status(code, "Unknown Error"); } void LLHTTPNode::Response::notFound(const std::string& message) { - status(HTTP_NOT_FOUND, message); + status(HTTP_NOT_FOUND, message); } void LLHTTPNode::Response::notFound() { - status(HTTP_NOT_FOUND, "Not Found"); + status(HTTP_NOT_FOUND, "Not Found"); } void LLHTTPNode::Response::methodNotAllowed() { - status(HTTP_METHOD_NOT_ALLOWED, "Method Not Allowed"); + status(HTTP_METHOD_NOT_ALLOWED, "Method Not Allowed"); } void LLHTTPNode::Response::addHeader( - const std::string& name, - const std::string& value) + const std::string& name, + const std::string& value) { - mHeaders[name] = value; + mHeaders[name] = value; } void LLHTTPNode::describe(Description& desc) const { - desc.shortInfo("unknown service (missing describe() method)"); + desc.shortInfo("unknown service (missing describe() method)"); } const LLChainIOFactory* LLHTTPNode::getProtocolHandler() const { - return NULL; + return NULL; } @@ -439,7 +439,7 @@ const LLChainIOFactory* LLHTTPNode::getProtocolHandler() const namespace { typedef std::map<std::string, LLHTTPRegistrar::NodeFactory*> FactoryMap; - + FactoryMap& factoryMap() { static FactoryMap theMap; @@ -452,27 +452,27 @@ LLHTTPRegistrar::NodeFactory::~NodeFactory() { } void LLHTTPRegistrar::registerFactory( const std::string& path, NodeFactory& factory) { - factoryMap()[path] = &factory; + factoryMap()[path] = &factory; } void LLHTTPRegistrar::buildAllServices(LLHTTPNode& root) { const FactoryMap& map = factoryMap(); - + FactoryMap::const_iterator i = map.begin(); FactoryMap::const_iterator end = map.end(); for (; i != end; ++i) { - LL_DEBUGS("AppInit") << "LLHTTPRegistrar::buildAllServices adding node for path " - << i->first << LL_ENDL; - + LL_DEBUGS("AppInit") << "LLHTTPRegistrar::buildAllServices adding node for path " + << i->first << LL_ENDL; + root.addNode(i->first, i->second->build()); } } LLPointer<LLSimpleResponse> LLSimpleResponse::create() { - return new LLSimpleResponse(); + return new LLSimpleResponse(); } LLSimpleResponse::~LLSimpleResponse() @@ -481,33 +481,33 @@ LLSimpleResponse::~LLSimpleResponse() void LLSimpleResponse::result(const LLSD& result) { - status(HTTP_OK, "OK"); + status(HTTP_OK, "OK"); } void LLSimpleResponse::extendedResult(S32 code, const std::string& body, const LLSD& headers) { - status(code,body); + status(code,body); } void LLSimpleResponse::extendedResult(S32 code, const LLSD& r, const LLSD& headers) { - status(code,"(LLSD)"); + status(code,"(LLSD)"); } void LLSimpleResponse::status(S32 code, const std::string& message) { - mCode = code; - mMessage = message; + mCode = code; + mMessage = message; } void LLSimpleResponse::print(std::ostream& out) const { - out << mCode << " " << mMessage; + out << mCode << " " << mMessage; } std::ostream& operator<<(std::ostream& out, const LLSimpleResponse& resp) { - resp.print(out); - return out; + resp.print(out); + return out; } diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h index 1144d88be1..b7b6053f48 100644 --- a/indra/llmessage/llhttpnode.h +++ b/indra/llmessage/llhttpnode.h @@ -1,25 +1,25 @@ -/** +/** * @file llhttpnode.h * @brief Declaration of classes for generic HTTP/LSL/REST handling. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,16 +47,16 @@ class LLChainIOFactory; /** * These classes represent the HTTP framework: The URL tree, and the LLSD * REST interface that such nodes implement. - * + * * To implement a service, in most cases, subclass LLHTTPNode, implement * get() or post(), and create a global instance of LLHTTPRegistration<>. * This can all be done in a .cpp file, with no publically declared parts. - * + * * To implement a server see lliohttpserver.h * @see LLHTTPWireServer */ -/** +/** * @class LLHTTPNode * @brief Base class which handles url traversal, response routing * and support for standard LLSD services @@ -74,226 +74,226 @@ class LLHTTPNode protected: LOG_CLASS(LLHTTPNode); public: - LLHTTPNode(); - virtual ~LLHTTPNode(); - - /** @name Responses - Most subclasses override one or more of these methods to provide - the service. By default, the rest of the LLHTTPNode architecture - will handle requests, create the needed LLIOPump, parse the input - to LLSD, and format the LLSD result to the output. - - The default implementation of each of these is to call - response->methodNotAllowed(); The "simple" versions can be - overridden instead in those cases where the service can return - an immediately computed response. - */ - //@{ -public: - - virtual LLSD simpleGet() const; - virtual LLSD simplePut(const LLSD& input) const; - virtual LLSD simplePost(const LLSD& input) const; - virtual LLSD simpleDel(const LLSD& context) const; - - /** - * @brief Abstract Base Class declaring Response interface. - */ - class Response : public LLRefCount - { - protected: - virtual ~Response(); - - public: - /** - * @brief Return the LLSD content and a 200 OK. - */ - virtual void result(const LLSD&) = 0; - - /** - * @brief return status code and message with headers. - */ - virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers = LLSD()) = 0; - - /** - * @brief return status code and LLSD result with headers. - */ - virtual void extendedResult(S32 code, const LLSD& result, const LLSD& headers = LLSD()) = 0; - - /** - * @brief return status code and reason string on http header, - * but do not return a payload. - */ - virtual void status(S32 code, const std::string& message) = 0; - - /** - * @brief Return no body, just status code and 'UNKNOWN ERROR'. - */ - virtual void statusUnknownError(S32 code); - - virtual void notFound(const std::string& message); - virtual void notFound(); - virtual void methodNotAllowed(); - - /** - * @brief Add a name: value http header. - * - * No effort is made to ensure the response is a valid http - * header. - * The headers are stored as a map of header name : value. - * Though HTTP allows the same header name to be transmitted - * more than once, this implementation only stores a header - * name once. - * @param name The name of the header, eg, "Content-Encoding" - * @param value The value of the header, eg, "gzip" - */ - virtual void addHeader(const std::string& name, const std::string& value); - - protected: - /** - * @brief Headers to be sent back with the HTTP response. - * - * Protected class membership since derived classes are - * expected to use it and there is no use case yet for other - * uses. If such a use case arises, I suggest making a - * headers() public method, and moving this member data into - * private. - */ - LLSD mHeaders; - }; - - typedef LLPointer<Response> ResponsePtr; - - virtual void get(ResponsePtr, const LLSD& context) const; - virtual void put( - ResponsePtr, - const LLSD& context, - const LLSD& input) const; - virtual void post( - ResponsePtr, - const LLSD& context, - const LLSD& input) const; - virtual void del(ResponsePtr, const LLSD& context) const; - virtual void options(ResponsePtr, const LLSD& context) const; - //@} - - - /** @name URL traversal - The tree is traversed by calling getChild() with successive - path components, on successive results. When getChild() returns - null, or there are no more components, the last child responds to - the request. - - The default behavior is generally correct, though wildcard nodes - will want to implement validate(). - */ - //@{ + LLHTTPNode(); + virtual ~LLHTTPNode(); + + /** @name Responses + Most subclasses override one or more of these methods to provide + the service. By default, the rest of the LLHTTPNode architecture + will handle requests, create the needed LLIOPump, parse the input + to LLSD, and format the LLSD result to the output. + + The default implementation of each of these is to call + response->methodNotAllowed(); The "simple" versions can be + overridden instead in those cases where the service can return + an immediately computed response. + */ + //@{ +public: + + virtual LLSD simpleGet() const; + virtual LLSD simplePut(const LLSD& input) const; + virtual LLSD simplePost(const LLSD& input) const; + virtual LLSD simpleDel(const LLSD& context) const; + + /** + * @brief Abstract Base Class declaring Response interface. + */ + class Response : public LLRefCount + { + protected: + virtual ~Response(); + + public: + /** + * @brief Return the LLSD content and a 200 OK. + */ + virtual void result(const LLSD&) = 0; + + /** + * @brief return status code and message with headers. + */ + virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers = LLSD()) = 0; + + /** + * @brief return status code and LLSD result with headers. + */ + virtual void extendedResult(S32 code, const LLSD& result, const LLSD& headers = LLSD()) = 0; + + /** + * @brief return status code and reason string on http header, + * but do not return a payload. + */ + virtual void status(S32 code, const std::string& message) = 0; + + /** + * @brief Return no body, just status code and 'UNKNOWN ERROR'. + */ + virtual void statusUnknownError(S32 code); + + virtual void notFound(const std::string& message); + virtual void notFound(); + virtual void methodNotAllowed(); + + /** + * @brief Add a name: value http header. + * + * No effort is made to ensure the response is a valid http + * header. + * The headers are stored as a map of header name : value. + * Though HTTP allows the same header name to be transmitted + * more than once, this implementation only stores a header + * name once. + * @param name The name of the header, eg, "Content-Encoding" + * @param value The value of the header, eg, "gzip" + */ + virtual void addHeader(const std::string& name, const std::string& value); + + protected: + /** + * @brief Headers to be sent back with the HTTP response. + * + * Protected class membership since derived classes are + * expected to use it and there is no use case yet for other + * uses. If such a use case arises, I suggest making a + * headers() public method, and moving this member data into + * private. + */ + LLSD mHeaders; + }; + + typedef LLPointer<Response> ResponsePtr; + + virtual void get(ResponsePtr, const LLSD& context) const; + virtual void put( + ResponsePtr, + const LLSD& context, + const LLSD& input) const; + virtual void post( + ResponsePtr, + const LLSD& context, + const LLSD& input) const; + virtual void del(ResponsePtr, const LLSD& context) const; + virtual void options(ResponsePtr, const LLSD& context) const; + //@} + + + /** @name URL traversal + The tree is traversed by calling getChild() with successive + path components, on successive results. When getChild() returns + null, or there are no more components, the last child responds to + the request. + + The default behavior is generally correct, though wildcard nodes + will want to implement validate(). + */ + //@{ public: - virtual LLHTTPNode* getChild(const std::string& name, LLSD& context) const; - /**< returns a child node, if any, at the given name - default looks at children and wildcard child (see below) - */ - - virtual bool handles(const LLSD& remainder, LLSD& context) const; - /**< return true if this node can service the remaining components; - default returns true if there are no remaining components - */ - - virtual bool validate(const std::string& name, LLSD& context) const; - /**< called only on wildcard nodes, to check if they will handle - the name; default is false; overrides will want to check - name, and return true if the name will construct to a valid url. - For convenience, the <code>getChild()</code> method above will - automatically insert the name in - context[CONTEXT_REQUEST][CONTEXT_WILDCARD][key] if this method returns true. - For example, the node "agent/<agent_id>/detail" will set - context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["agent_id"] eqaul to the value - found during traversal. - */ - - const LLHTTPNode* traverse(const std::string& path, LLSD& context) const; - /**< find a node, if any, that can service this path - set up context[CONTEXT_REQUEST] information - */ - //@} - - /** @name Child Nodes - The standard node can have any number of child nodes under - fixed names, and optionally one "wildcard" node that can - handle all other names. - - Usually, child nodes are add through LLHTTPRegistration, not - by calling this interface directly. - - The added node will be now owned by the parent node. - */ - //@{ - - virtual void addNode(const std::string& path, LLHTTPNode* nodeToAdd); - - LLSD allNodePaths() const; - ///< Returns an arrary of node paths at and under this node - - const LLHTTPNode* rootNode() const; - const LLHTTPNode* findNode(const std::string& name) const; - - - enum EHTTPNodeContentType - { - CONTENT_TYPE_LLSD, - CONTENT_TYPE_TEXT - }; - - virtual EHTTPNodeContentType getContentType() const { return CONTENT_TYPE_LLSD; } - //@} - - /* @name Description system - The Description object contains information about a service. - All subclasses of LLHTTPNode should override describe() and use - the methods of the Description class to set the various properties. - */ - //@{ - class Description - { - public: - void shortInfo(const std::string& s){ mInfo["description"] = s; } - void longInfo(const std::string& s) { mInfo["details"] = s; } - - // Call this method when the service supports the specified verb. - void getAPI() { mInfo["api"].append("GET"); } - void putAPI() { mInfo["api"].append("PUT"); } - void postAPI() { mInfo["api"].append("POST"); } - void delAPI() { mInfo["api"].append("DELETE"); } - - void input(const std::string& s) { mInfo["input"] = s; } - void output(const std::string& s) { mInfo["output"] = s; } - void source(const char* f, int l) { mInfo["__file__"] = f; - mInfo["__line__"] = l; } - - LLSD getInfo() const { return mInfo; } - - private: - LLSD mInfo; - }; - - virtual void describe(Description&) const; - - //@} - - - virtual const LLChainIOFactory* getProtocolHandler() const; - /**< Return a factory object for handling wire protocols. - * The base class returns NULL, as it doesn't know about - * wire protocols at all. This is okay for most nodes - * as LLIOHTTPServer is smart enough to use a default - * wire protocol for HTTP for such nodes. Specialized - * subclasses that handle things like XML-RPC will want - * to implement this. (See LLXMLSDRPCServerFactory.) - */ + virtual LLHTTPNode* getChild(const std::string& name, LLSD& context) const; + /**< returns a child node, if any, at the given name + default looks at children and wildcard child (see below) + */ + + virtual bool handles(const LLSD& remainder, LLSD& context) const; + /**< return true if this node can service the remaining components; + default returns true if there are no remaining components + */ + + virtual bool validate(const std::string& name, LLSD& context) const; + /**< called only on wildcard nodes, to check if they will handle + the name; default is false; overrides will want to check + name, and return true if the name will construct to a valid url. + For convenience, the <code>getChild()</code> method above will + automatically insert the name in + context[CONTEXT_REQUEST][CONTEXT_WILDCARD][key] if this method returns true. + For example, the node "agent/<agent_id>/detail" will set + context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["agent_id"] eqaul to the value + found during traversal. + */ + + const LLHTTPNode* traverse(const std::string& path, LLSD& context) const; + /**< find a node, if any, that can service this path + set up context[CONTEXT_REQUEST] information + */ + //@} + + /** @name Child Nodes + The standard node can have any number of child nodes under + fixed names, and optionally one "wildcard" node that can + handle all other names. + + Usually, child nodes are add through LLHTTPRegistration, not + by calling this interface directly. + + The added node will be now owned by the parent node. + */ + //@{ + + virtual void addNode(const std::string& path, LLHTTPNode* nodeToAdd); + + LLSD allNodePaths() const; + ///< Returns an arrary of node paths at and under this node + + const LLHTTPNode* rootNode() const; + const LLHTTPNode* findNode(const std::string& name) const; + + + enum EHTTPNodeContentType + { + CONTENT_TYPE_LLSD, + CONTENT_TYPE_TEXT + }; + + virtual EHTTPNodeContentType getContentType() const { return CONTENT_TYPE_LLSD; } + //@} + + /* @name Description system + The Description object contains information about a service. + All subclasses of LLHTTPNode should override describe() and use + the methods of the Description class to set the various properties. + */ + //@{ + class Description + { + public: + void shortInfo(const std::string& s){ mInfo["description"] = s; } + void longInfo(const std::string& s) { mInfo["details"] = s; } + + // Call this method when the service supports the specified verb. + void getAPI() { mInfo["api"].append("GET"); } + void putAPI() { mInfo["api"].append("PUT"); } + void postAPI() { mInfo["api"].append("POST"); } + void delAPI() { mInfo["api"].append("DELETE"); } + + void input(const std::string& s) { mInfo["input"] = s; } + void output(const std::string& s) { mInfo["output"] = s; } + void source(const char* f, int l) { mInfo["__file__"] = f; + mInfo["__line__"] = l; } + + LLSD getInfo() const { return mInfo; } + + private: + LLSD mInfo; + }; + + virtual void describe(Description&) const; + + //@} + + + virtual const LLChainIOFactory* getProtocolHandler() const; + /**< Return a factory object for handling wire protocols. + * The base class returns NULL, as it doesn't know about + * wire protocols at all. This is okay for most nodes + * as LLIOHTTPServer is smart enough to use a default + * wire protocol for HTTP for such nodes. Specialized + * subclasses that handle things like XML-RPC will want + * to implement this. (See LLXMLSDRPCServerFactory.) + */ private: - class Impl; - Impl& impl; + class Impl; + Impl& impl; }; @@ -301,20 +301,20 @@ private: class LLSimpleResponse : public LLHTTPNode::Response { public: - static LLPointer<LLSimpleResponse> create(); - - void result(const LLSD& result); - void extendedResult(S32 code, const std::string& body, const LLSD& headers); - void extendedResult(S32 code, const LLSD& result, const LLSD& headers); - void status(S32 code, const std::string& message); + static LLPointer<LLSimpleResponse> create(); + + void result(const LLSD& result); + void extendedResult(S32 code, const std::string& body, const LLSD& headers); + void extendedResult(S32 code, const LLSD& result, const LLSD& headers); + void status(S32 code, const std::string& message); - void print(std::ostream& out) const; + void print(std::ostream& out) const; - S32 mCode; - std::string mMessage; + S32 mCode; + std::string mMessage; protected: - ~LLSimpleResponse(); + ~LLSimpleResponse(); private: LLSimpleResponse() : mCode(0) {} // Must be accessed through LLPointer. @@ -324,13 +324,13 @@ std::ostream& operator<<(std::ostream& out, const LLSimpleResponse& resp); -/** - * @name Automatic LLHTTPNode registration +/** + * @name Automatic LLHTTPNode registration * * To register a node type at a particular url path, construct a global instance * of LLHTTPRegistration: * - * LLHTTPRegistration<LLMyNodeType> gHTTPServiceAlphaBeta("/alpha/beta"); + * LLHTTPRegistration<LLMyNodeType> gHTTPServiceAlphaBeta("/alpha/beta"); * * (Note the naming convention carefully.) This object must be global and not * static. However, it needn't be declared in your .h file. It can exist @@ -340,68 +340,68 @@ std::ostream& operator<<(std::ostream& out, const LLSimpleResponse& resp); * When constructing a web server, use LLHTTPRegistrar to add all the registered * nodes to the url tree: * - * LLHTTPRegistrar::buidlAllServices(mRootNode); + * LLHTTPRegistrar::buidlAllServices(mRootNode); */ //@{ class LLHTTPRegistrar { public: - class NodeFactory - { - public: - virtual ~NodeFactory(); - virtual LLHTTPNode* build() const = 0; - }; + class NodeFactory + { + public: + virtual ~NodeFactory(); + virtual LLHTTPNode* build() const = 0; + }; - static void buildAllServices(LLHTTPNode& root); + static void buildAllServices(LLHTTPNode& root); - static void registerFactory(const std::string& path, NodeFactory& factory); - ///< construct an LLHTTPRegistration below to call this + static void registerFactory(const std::string& path, NodeFactory& factory); + ///< construct an LLHTTPRegistration below to call this }; template < class NodeType > class LLHTTPRegistration { public: - LLHTTPRegistration(const std::string& path) - { - LLHTTPRegistrar::registerFactory(path, mFactory); - } + LLHTTPRegistration(const std::string& path) + { + LLHTTPRegistrar::registerFactory(path, mFactory); + } private: - class ThisNodeFactory : public LLHTTPRegistrar::NodeFactory - { - public: - virtual LLHTTPNode* build() const { return new NodeType; } - }; - - ThisNodeFactory mFactory; + class ThisNodeFactory : public LLHTTPRegistrar::NodeFactory + { + public: + virtual LLHTTPNode* build() const { return new NodeType; } + }; + + ThisNodeFactory mFactory; }; template < class NodeType> class LLHTTPParamRegistration { public: - LLHTTPParamRegistration(const std::string& path, LLSD params) : - mFactory(params) - { - LLHTTPRegistrar::registerFactory(path, mFactory); - } + LLHTTPParamRegistration(const std::string& path, LLSD params) : + mFactory(params) + { + LLHTTPRegistrar::registerFactory(path, mFactory); + } private: - class ThisNodeFactory : public LLHTTPRegistrar::NodeFactory - { - public: - ThisNodeFactory(LLSD params) : mParams(params) {} - virtual LLHTTPNode* build() const { return new NodeType(mParams); } - private: - LLSD mParams; - }; - - ThisNodeFactory mFactory; + class ThisNodeFactory : public LLHTTPRegistrar::NodeFactory + { + public: + ThisNodeFactory(LLSD params) : mParams(params) {} + virtual LLHTTPNode* build() const { return new NodeType(mParams); } + private: + LLSD mParams; + }; + + ThisNodeFactory mFactory; }; - + //@} #endif // LL_LLHTTPNODE_H diff --git a/indra/llmessage/llhttpnodeadapter.h b/indra/llmessage/llhttpnodeadapter.h index 22984c4478..436de6224f 100644 --- a/indra/llmessage/llhttpnodeadapter.h +++ b/indra/llmessage/llhttpnodeadapter.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,19 +34,19 @@ class LLHTTPNodeAdapter : public LLHTTPNode { public: - virtual bool validate(const std::string& name, LLSD& context) const - { - T node; - return node.validate(name, context); - } - - virtual void post(LLHTTPNode::ResponsePtr response, - const LLSD& context, - const LLSD& input) const - { - T node; - return node.post(response, context, input); - } + virtual bool validate(const std::string& name, LLSD& context) const + { + T node; + return node.validate(name, context); + } + + virtual void post(LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + T node; + return node.post(response, context, input); + } }; #endif // LL_HTTP_NODE_ADAPTER_H diff --git a/indra/llmessage/llhttpsdhandler.cpp b/indra/llmessage/llhttpsdhandler.cpp index 648bc5cfd8..1c5928e187 100644 --- a/indra/llmessage/llhttpsdhandler.cpp +++ b/indra/llmessage/llhttpsdhandler.cpp @@ -42,36 +42,36 @@ LLHttpSDHandler::LLHttpSDHandler() void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) { - LLCore::HttpStatus status = response->getStatus(); + LLCore::HttpStatus status = response->getStatus(); - if (!status) - { - this->onFailure(response, status); - } - else - { - LLSD resplsd; - const bool emit_parse_errors = false; + if (!status) + { + this->onFailure(response, status); + } + else + { + LLSD resplsd; + const bool emit_parse_errors = false; - bool parsed = !((response->getBodySize() == 0) || - !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, resplsd)); + bool parsed = !((response->getBodySize() == 0) || + !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, resplsd)); - if (!parsed) - { - // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml' - LLCore::HttpHeaders::ptr_t headers(response->getHeaders()); - const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL; + if (!parsed) + { + // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml' + LLCore::HttpHeaders::ptr_t headers(response->getHeaders()); + const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL; - if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType)) - { - std::string thebody = LLCoreHttpUtil::responseToString(response); + if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType)) + { + std::string thebody = LLCoreHttpUtil::responseToString(response); - LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] " - << " body: " << thebody << LL_ENDL; - } - } + LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] " + << " body: " << thebody << LL_ENDL; + } + } - this->onSuccess(response, resplsd); - } + this->onSuccess(response, resplsd); + } } diff --git a/indra/llmessage/llhttpsdhandler.h b/indra/llmessage/llhttpsdhandler.h index ce40bdfc08..6390073339 100644 --- a/indra/llmessage/llhttpsdhandler.h +++ b/indra/llmessage/llhttpsdhandler.h @@ -24,30 +24,30 @@ * $/LicenseInfo$ */ -#ifndef _LLHTTPSDHANDLER_H_ -#define _LLHTTPSDHANDLER_H_ +#ifndef _LLHTTPSDHANDLER_H_ +#define _LLHTTPSDHANDLER_H_ #include "httpcommon.h" #include "httphandler.h" #include "lluri.h" -/// Handler class LLCore's HTTP library. Splitting with separate success and -/// failure routines and parsing the result body into LLSD on success. It +/// Handler class LLCore's HTTP library. Splitting with separate success and +/// failure routines and parsing the result body into LLSD on success. It /// is intended to be subclassed for specific capability handling. -/// -// *TODO: This class self deletes at the end of onCompleted method. This is +/// +// *TODO: This class self deletes at the end of onCompleted method. This is // less than ideal and should be revisited. class LLHttpSDHandler : public LLCore::HttpHandler //, // public std::enable_shared_from_this<LLHttpSDHandler> { public: - virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); - + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + protected: LLHttpSDHandler(); - virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content) = 0; - virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) = 0; + virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content) = 0; + virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) = 0; }; diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp index 52102e55c8..4c62c07fcb 100644 --- a/indra/llmessage/llinstantmessage.cpp +++ b/indra/llmessage/llinstantmessage.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llinstantmessage.cpp * @author Phoenix * @date 2005-08-29 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,113 +52,113 @@ const S32 IM_TTL = 1; void pack_instant_message( - LLMessageSystem* msg, - const LLUUID& from_id, - bool from_group, - const LLUUID& session_id, - const LLUUID& to_id, - const std::string& name, - const std::string& message, - U8 offline, - EInstantMessage dialog, - const LLUUID& id, - U32 parent_estate_id, - const LLUUID& region_id, - const LLVector3& position, - U32 timestamp, - const U8* binary_bucket, - S32 binary_bucket_size) + LLMessageSystem* msg, + const LLUUID& from_id, + bool from_group, + const LLUUID& session_id, + const LLUUID& to_id, + const std::string& name, + const std::string& message, + U8 offline, + EInstantMessage dialog, + const LLUUID& id, + U32 parent_estate_id, + const LLUUID& region_id, + const LLVector3& position, + U32 timestamp, + const U8* binary_bucket, + S32 binary_bucket_size) { - LL_DEBUGS() << "pack_instant_message()" << LL_ENDL; - msg->newMessageFast(_PREHASH_ImprovedInstantMessage); - pack_instant_message_block( - msg, - from_id, - from_group, - session_id, - to_id, - name, - message, - offline, - dialog, - id, - parent_estate_id, - region_id, - position, - timestamp, - binary_bucket, - binary_bucket_size); + LL_DEBUGS() << "pack_instant_message()" << LL_ENDL; + msg->newMessageFast(_PREHASH_ImprovedInstantMessage); + pack_instant_message_block( + msg, + from_id, + from_group, + session_id, + to_id, + name, + message, + offline, + dialog, + id, + parent_estate_id, + region_id, + position, + timestamp, + binary_bucket, + binary_bucket_size); } void pack_instant_message_block( - LLMessageSystem* msg, - const LLUUID& from_id, - bool from_group, - const LLUUID& session_id, - const LLUUID& to_id, - const std::string& name, - const std::string& message, - U8 offline, - EInstantMessage dialog, - const LLUUID& id, - U32 parent_estate_id, - const LLUUID& region_id, - const LLVector3& position, - U32 timestamp, - const U8* binary_bucket, - S32 binary_bucket_size) + LLMessageSystem* msg, + const LLUUID& from_id, + bool from_group, + const LLUUID& session_id, + const LLUUID& to_id, + const std::string& name, + const std::string& message, + U8 offline, + EInstantMessage dialog, + const LLUUID& id, + U32 parent_estate_id, + const LLUUID& region_id, + const LLVector3& position, + U32 timestamp, + const U8* binary_bucket, + S32 binary_bucket_size) { - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, from_id); - msg->addUUIDFast(_PREHASH_SessionID, session_id); - msg->nextBlockFast(_PREHASH_MessageBlock); - msg->addBOOLFast(_PREHASH_FromGroup, from_group); - msg->addUUIDFast(_PREHASH_ToAgentID, to_id); - msg->addU32Fast(_PREHASH_ParentEstateID, parent_estate_id); - msg->addUUIDFast(_PREHASH_RegionID, region_id); - msg->addVector3Fast(_PREHASH_Position, position); - msg->addU8Fast(_PREHASH_Offline, offline); - msg->addU8Fast(_PREHASH_Dialog, (U8) dialog); - msg->addUUIDFast(_PREHASH_ID, id); - msg->addU32Fast(_PREHASH_Timestamp, timestamp); - msg->addStringFast(_PREHASH_FromAgentName, name); - S32 bytes_left = MTUBYTES; - if(!message.empty()) - { - char buffer[MTUBYTES]; - int num_written = snprintf(buffer, MTUBYTES, "%s", message.c_str()); /* Flawfinder: ignore */ - // snprintf returns number of bytes that would have been written - // had the output not being truncated. In that case, it will - // return either -1 or value >= passed in size value . So a check needs to be added - // to detect truncation, and if there is any, only account for the - // actual number of bytes written..and not what could have been - // written. - if (num_written < 0 || num_written >= MTUBYTES) - { - num_written = MTUBYTES - 1; - LL_WARNS() << "pack_instant_message_block: message truncated: " << message << LL_ENDL; - } + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, from_id); + msg->addUUIDFast(_PREHASH_SessionID, session_id); + msg->nextBlockFast(_PREHASH_MessageBlock); + msg->addBOOLFast(_PREHASH_FromGroup, from_group); + msg->addUUIDFast(_PREHASH_ToAgentID, to_id); + msg->addU32Fast(_PREHASH_ParentEstateID, parent_estate_id); + msg->addUUIDFast(_PREHASH_RegionID, region_id); + msg->addVector3Fast(_PREHASH_Position, position); + msg->addU8Fast(_PREHASH_Offline, offline); + msg->addU8Fast(_PREHASH_Dialog, (U8) dialog); + msg->addUUIDFast(_PREHASH_ID, id); + msg->addU32Fast(_PREHASH_Timestamp, timestamp); + msg->addStringFast(_PREHASH_FromAgentName, name); + S32 bytes_left = MTUBYTES; + if(!message.empty()) + { + char buffer[MTUBYTES]; + int num_written = snprintf(buffer, MTUBYTES, "%s", message.c_str()); /* Flawfinder: ignore */ + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= passed in size value . So a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (num_written < 0 || num_written >= MTUBYTES) + { + num_written = MTUBYTES - 1; + LL_WARNS() << "pack_instant_message_block: message truncated: " << message << LL_ENDL; + } - bytes_left -= num_written; - bytes_left = llmax(0, bytes_left); - msg->addStringFast(_PREHASH_Message, buffer); - } - else - { - msg->addStringFast(_PREHASH_Message, NULL); - } - const U8* bb; - if(binary_bucket) - { - bb = binary_bucket; - binary_bucket_size = llmin(bytes_left, binary_bucket_size); - } - else - { - bb = (const U8*)EMPTY_BINARY_BUCKET; - binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE; - } - msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size); + bytes_left -= num_written; + bytes_left = llmax(0, bytes_left); + msg->addStringFast(_PREHASH_Message, buffer); + } + else + { + msg->addStringFast(_PREHASH_Message, NULL); + } + const U8* bb; + if(binary_bucket) + { + bb = binary_bucket; + binary_bucket_size = llmin(bytes_left, binary_bucket_size); + } + else + { + bb = (const U8*)EMPTY_BINARY_BUCKET; + binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE; + } + msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size); } diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index 383fe2591a..d413e81c90 100644 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -1,25 +1,25 @@ -/** +/** * @file llinstantmessage.h - * @brief Constants and declarations used by instant messages. + * @brief Constants and declarations used by instant messages. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,127 +40,127 @@ class LLMessageSystem; // field, so don't go past the byte boundary enum EInstantMessage { - // default. ID is meaningless, nothing in the binary bucket. - IM_NOTHING_SPECIAL = 0, - - // pops a messagebox with a single OK button - IM_MESSAGEBOX = 1, - - // pops a countdown messagebox with a single OK button - // IM_MESSAGEBOX_COUNTDOWN = 2, - - // You've been invited to join a group. - // ID is the group id. - - // The binary bucket contains a null terminated string - // representation of the officer/member status and join cost for - // the invitee. (bug # 7672) The format is 1 byte for - // officer/member (O for officer, M for member), and as many bytes - // as necessary for cost. - IM_GROUP_INVITATION = 3, - - // Inventory offer. - // ID is the transaction id - // Binary bucket is a list of inventory uuid and type. - IM_INVENTORY_OFFERED = 4, - IM_INVENTORY_ACCEPTED = 5, - IM_INVENTORY_DECLINED = 6, - - // Group vote - // Name is name of person who called vote. - // ID is vote ID used for internal tracking - // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856 - IM_GROUP_VOTE = 7, - - // Group message - // This means that the message is meant for everyone in the - // agent's group. This will result in a database query to find all - // participants and start an im session. - IM_GROUP_MESSAGE_DEPRECATED = 8, - - // Task inventory offer. - // ID is the transaction id - // Binary bucket is a (mostly) complete packed inventory item - IM_TASK_INVENTORY_OFFERED = 9, - IM_TASK_INVENTORY_ACCEPTED = 10, - IM_TASK_INVENTORY_DECLINED = 11, - - // Copied as pending, type LL_NOTHING_SPECIAL, for new users - // used by offline tools - IM_NEW_USER_DEFAULT = 12, - - // - // session based messaging - the way that people usually actually - // communicate with each other. - // - - // Invite users to a session. - IM_SESSION_INVITE = 13, - - IM_SESSION_P2P_INVITE = 14, - - // start a session with your gruop - IM_SESSION_GROUP_START = 15, - - // start a session without a calling card (finder or objects) - IM_SESSION_CONFERENCE_START = 16, - - // send a message to a session. - IM_SESSION_SEND = 17, - - // leave a session - IM_SESSION_LEAVE = 18, - - // an instant message from an object - for differentiation on the - // viewer, since you can't IM an object yet. - IM_FROM_TASK = 19, - - // sent an IM to a do not disturb user, this is the auto response - IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20, - - // Shows the message in the console and chat history - IM_CONSOLE_AND_CHAT_HISTORY = 21, - - // IM Types used for luring your friends - IM_LURE_USER = 22, - IM_LURE_ACCEPTED = 23, - IM_LURE_DECLINED = 24, - IM_GODLIKE_LURE_USER = 25, - IM_TELEPORT_REQUEST = 26, - - // IM that notifie of a new group election. - // Name is name of person who called vote. - // ID is election ID used for internal tracking - IM_GROUP_ELECTION_DEPRECATED = 27, - - // IM to tell the user to go to an URL. Put a text message in the - // message field, and put the url with a trailing \0 in the binary - // bucket. - IM_GOTO_URL = 28, - - // a message generated by a script which we don't want to - // be sent through e-mail. Similar to IM_FROM_TASK, but - // it is shown as an alert on the viewer. - IM_FROM_TASK_AS_ALERT = 31, + // default. ID is meaningless, nothing in the binary bucket. + IM_NOTHING_SPECIAL = 0, + + // pops a messagebox with a single OK button + IM_MESSAGEBOX = 1, + + // pops a countdown messagebox with a single OK button + // IM_MESSAGEBOX_COUNTDOWN = 2, + + // You've been invited to join a group. + // ID is the group id. + + // The binary bucket contains a null terminated string + // representation of the officer/member status and join cost for + // the invitee. (bug # 7672) The format is 1 byte for + // officer/member (O for officer, M for member), and as many bytes + // as necessary for cost. + IM_GROUP_INVITATION = 3, + + // Inventory offer. + // ID is the transaction id + // Binary bucket is a list of inventory uuid and type. + IM_INVENTORY_OFFERED = 4, + IM_INVENTORY_ACCEPTED = 5, + IM_INVENTORY_DECLINED = 6, + + // Group vote + // Name is name of person who called vote. + // ID is vote ID used for internal tracking + // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856 + IM_GROUP_VOTE = 7, + + // Group message + // This means that the message is meant for everyone in the + // agent's group. This will result in a database query to find all + // participants and start an im session. + IM_GROUP_MESSAGE_DEPRECATED = 8, + + // Task inventory offer. + // ID is the transaction id + // Binary bucket is a (mostly) complete packed inventory item + IM_TASK_INVENTORY_OFFERED = 9, + IM_TASK_INVENTORY_ACCEPTED = 10, + IM_TASK_INVENTORY_DECLINED = 11, + + // Copied as pending, type LL_NOTHING_SPECIAL, for new users + // used by offline tools + IM_NEW_USER_DEFAULT = 12, + + // + // session based messaging - the way that people usually actually + // communicate with each other. + // + + // Invite users to a session. + IM_SESSION_INVITE = 13, + + IM_SESSION_P2P_INVITE = 14, + + // start a session with your gruop + IM_SESSION_GROUP_START = 15, + + // start a session without a calling card (finder or objects) + IM_SESSION_CONFERENCE_START = 16, + + // send a message to a session. + IM_SESSION_SEND = 17, + + // leave a session + IM_SESSION_LEAVE = 18, + + // an instant message from an object - for differentiation on the + // viewer, since you can't IM an object yet. + IM_FROM_TASK = 19, + + // sent an IM to a do not disturb user, this is the auto response + IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20, + + // Shows the message in the console and chat history + IM_CONSOLE_AND_CHAT_HISTORY = 21, + + // IM Types used for luring your friends + IM_LURE_USER = 22, + IM_LURE_ACCEPTED = 23, + IM_LURE_DECLINED = 24, + IM_GODLIKE_LURE_USER = 25, + IM_TELEPORT_REQUEST = 26, + + // IM that notifie of a new group election. + // Name is name of person who called vote. + // ID is election ID used for internal tracking + IM_GROUP_ELECTION_DEPRECATED = 27, + + // IM to tell the user to go to an URL. Put a text message in the + // message field, and put the url with a trailing \0 in the binary + // bucket. + IM_GOTO_URL = 28, + + // a message generated by a script which we don't want to + // be sent through e-mail. Similar to IM_FROM_TASK, but + // it is shown as an alert on the viewer. + IM_FROM_TASK_AS_ALERT = 31, - // IM from group officer to all group members. - IM_GROUP_NOTICE = 32, - IM_GROUP_NOTICE_INVENTORY_ACCEPTED = 33, - IM_GROUP_NOTICE_INVENTORY_DECLINED = 34, - - IM_GROUP_INVITATION_ACCEPT = 35, - IM_GROUP_INVITATION_DECLINE = 36, - - IM_GROUP_NOTICE_REQUESTED = 37, - - IM_FRIENDSHIP_OFFERED = 38, - IM_FRIENDSHIP_ACCEPTED = 39, - IM_FRIENDSHIP_DECLINED_DEPRECATED = 40, - - IM_TYPING_START = 41, - IM_TYPING_STOP = 42, - - IM_COUNT + // IM from group officer to all group members. + IM_GROUP_NOTICE = 32, + IM_GROUP_NOTICE_INVENTORY_ACCEPTED = 33, + IM_GROUP_NOTICE_INVENTORY_DECLINED = 34, + + IM_GROUP_INVITATION_ACCEPT = 35, + IM_GROUP_INVITATION_DECLINE = 36, + + IM_GROUP_NOTICE_REQUESTED = 37, + + IM_FRIENDSHIP_OFFERED = 38, + IM_FRIENDSHIP_ACCEPTED = 39, + IM_FRIENDSHIP_DECLINED_DEPRECATED = 40, + + IM_TYPING_START = 41, + IM_TYPING_STOP = 42, + + IM_COUNT }; @@ -178,40 +178,40 @@ extern const std::string INTERACTIVE_SYSTEM_FROM; extern const S32 IM_TTL; void pack_instant_message( - LLMessageSystem* msgsystem, - const LLUUID& from_id, - bool from_group, - const LLUUID& session_id, - const LLUUID& to_id, - const std::string& name, - const std::string& message, - U8 offline = IM_ONLINE, - EInstantMessage dialog = IM_NOTHING_SPECIAL, - const LLUUID& id = LLUUID::null, - U32 parent_estate_id = 0, - const LLUUID& region_id = LLUUID::null, - const LLVector3& position = LLVector3::zero, - U32 timestamp = NO_TIMESTAMP, - const U8* binary_bucket = (U8*)EMPTY_BINARY_BUCKET, - S32 binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE); + LLMessageSystem* msgsystem, + const LLUUID& from_id, + bool from_group, + const LLUUID& session_id, + const LLUUID& to_id, + const std::string& name, + const std::string& message, + U8 offline = IM_ONLINE, + EInstantMessage dialog = IM_NOTHING_SPECIAL, + const LLUUID& id = LLUUID::null, + U32 parent_estate_id = 0, + const LLUUID& region_id = LLUUID::null, + const LLVector3& position = LLVector3::zero, + U32 timestamp = NO_TIMESTAMP, + const U8* binary_bucket = (U8*)EMPTY_BINARY_BUCKET, + S32 binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE); void pack_instant_message_block( - LLMessageSystem* msgsystem, - const LLUUID& from_id, - bool from_group, - const LLUUID& session_id, - const LLUUID& to_id, - const std::string& name, - const std::string& message, - U8 offline = IM_ONLINE, - EInstantMessage dialog = IM_NOTHING_SPECIAL, - const LLUUID& id = LLUUID::null, - U32 parent_estate_id = 0, - const LLUUID& region_id = LLUUID::null, - const LLVector3& position = LLVector3::zero, - U32 timestamp = NO_TIMESTAMP, - const U8* binary_bucket = (U8*)EMPTY_BINARY_BUCKET, - S32 binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE); + LLMessageSystem* msgsystem, + const LLUUID& from_id, + bool from_group, + const LLUUID& session_id, + const LLUUID& to_id, + const std::string& name, + const std::string& message, + U8 offline = IM_ONLINE, + EInstantMessage dialog = IM_NOTHING_SPECIAL, + const LLUUID& id = LLUUID::null, + U32 parent_estate_id = 0, + const LLUUID& region_id = LLUUID::null, + const LLVector3& position = LLVector3::zero, + U32 timestamp = NO_TIMESTAMP, + const U8* binary_bucket = (U8*)EMPTY_BINARY_BUCKET, + S32 binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE); #endif // LL_LLINSTANTMESSAGE_H diff --git a/indra/llmessage/llinvite.h b/indra/llmessage/llinvite.h index e5d573c1e3..8655f79982 100644 --- a/indra/llmessage/llinvite.h +++ b/indra/llmessage/llinvite.h @@ -1,25 +1,25 @@ -/** +/** * @file llinvite.h * @brief Constants used for inviting users to join groups. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -27,7 +27,7 @@ #ifndef LL_LLINVITE_H #define LL_LLINVITE_H -const S32 INVITE_LIST_STR_LEN = 324; // Would be larger, but we don't have much room in the CreateGroupRequest msg. -const S32 INVITE_LIST_BUF_SIZE = 325; +const S32 INVITE_LIST_STR_LEN = 324; // Would be larger, but we don't have much room in the CreateGroupRequest msg. +const S32 INVITE_LIST_BUF_SIZE = 325; #endif // LL_LLINVITE_H diff --git a/indra/llmessage/lliobuffer.cpp b/indra/llmessage/lliobuffer.cpp index bbd7b8777d..4f5821b15f 100644 --- a/indra/llmessage/lliobuffer.cpp +++ b/indra/llmessage/lliobuffer.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliobuffer.cpp * @author Phoenix * @date 2005-05-04 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,82 +33,82 @@ // LLIOBuffer // LLIOBuffer::LLIOBuffer() : - mBuffer(NULL), - mBufferSize(0L), - mReadHead(NULL), - mWriteHead(NULL) + mBuffer(NULL), + mBufferSize(0L), + mReadHead(NULL), + mWriteHead(NULL) { } LLIOBuffer::~LLIOBuffer() { - if(mBuffer) - { - delete[] mBuffer; - } + if(mBuffer) + { + delete[] mBuffer; + } } U8* LLIOBuffer::data() const { - return mBuffer; + return mBuffer; } S64 LLIOBuffer::size() const { - return mBufferSize; + return mBufferSize; } U8* LLIOBuffer::current() const { - return mReadHead; + return mReadHead; } S64 LLIOBuffer::bytesLeft() const { - return mWriteHead - mReadHead; + return mWriteHead - mReadHead; } void LLIOBuffer::clear() { - mReadHead = mBuffer; - mWriteHead = mBuffer; + mReadHead = mBuffer; + mWriteHead = mBuffer; } LLIOPipe::EStatus LLIOBuffer::seek(LLIOBuffer::EHead head, S64 delta) { - LLIOPipe::EStatus status = STATUS_ERROR; - switch(head) - { - case READ: - if(((delta >= 0) && ((mReadHead + delta) <= mWriteHead)) - || ((delta < 0) && ((mReadHead + delta) >= mBuffer))) - { - mReadHead += delta; - status = STATUS_OK; - } - break; - case WRITE: - if(((delta >= 0) && ((mWriteHead + delta) < (mBuffer + mBufferSize))) - || ((delta < 0) && ((mWriteHead + delta) > mReadHead))) - { - mWriteHead += delta; - status = STATUS_OK; - } - default: - break; - } - return status; + LLIOPipe::EStatus status = STATUS_ERROR; + switch(head) + { + case READ: + if(((delta >= 0) && ((mReadHead + delta) <= mWriteHead)) + || ((delta < 0) && ((mReadHead + delta) >= mBuffer))) + { + mReadHead += delta; + status = STATUS_OK; + } + break; + case WRITE: + if(((delta >= 0) && ((mWriteHead + delta) < (mBuffer + mBufferSize))) + || ((delta < 0) && ((mWriteHead + delta) > mReadHead))) + { + mWriteHead += delta; + status = STATUS_OK; + } + default: + break; + } + return status; } // virtual LLIOPipe::EStatus LLIOBuffer::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - // no-op (I think) - LL_WARNS() << "You are using an LLIOBuffer which is deprecated." << LL_ENDL; - return STATUS_OK; + // no-op (I think) + LL_WARNS() << "You are using an LLIOBuffer which is deprecated." << LL_ENDL; + return STATUS_OK; } diff --git a/indra/llmessage/lliobuffer.h b/indra/llmessage/lliobuffer.h index 3349848947..4d4fab5fe4 100644 --- a/indra/llmessage/lliobuffer.h +++ b/indra/llmessage/lliobuffer.h @@ -1,4 +1,4 @@ -/** +/** * @file lliobuffer.h * @author Phoenix * @date 2005-05-04 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,7 +31,7 @@ #include "lliopipe.h" -/** +/** * @class LLIOBuffer * @brief This class is an io class that represents an automtically * resizing io buffer. @@ -46,90 +46,90 @@ class LLIOBuffer : public LLIOPipe { public: - LLIOBuffer(); - virtual ~LLIOBuffer(); + LLIOBuffer(); + virtual ~LLIOBuffer(); - /** - * @brief Return a raw pointer to the current data set. - * - * The pointer returned can be used for reading or even adjustment - * if you are a bit crazy up to size() bytes into memory. - * @return A potentially NULL pointer to the raw buffer data - */ - U8* data() const; + /** + * @brief Return a raw pointer to the current data set. + * + * The pointer returned can be used for reading or even adjustment + * if you are a bit crazy up to size() bytes into memory. + * @return A potentially NULL pointer to the raw buffer data + */ + U8* data() const; - /** - * @brief Return the size of the buffer - */ - S64 size() const; + /** + * @brief Return the size of the buffer + */ + S64 size() const; - /** - * @brief Return a raw pointer to the current read position in the data. - * - * The pointer returned can be used for reading or even adjustment - * if you are a bit crazy up to bytesLeft() bytes into memory. - * @return A potentially NULL pointer to the buffer data starting - * at the read point - */ - U8* current() const; + /** + * @brief Return a raw pointer to the current read position in the data. + * + * The pointer returned can be used for reading or even adjustment + * if you are a bit crazy up to bytesLeft() bytes into memory. + * @return A potentially NULL pointer to the buffer data starting + * at the read point + */ + U8* current() const; - /** - * @brief Return the number of unprocessed bytes in buffer. - */ - S64 bytesLeft() const; + /** + * @brief Return the number of unprocessed bytes in buffer. + */ + S64 bytesLeft() const; - /** - * @brief Move the buffer offsets back to the beginning. - * - * This method effectively clears what has been stored here, - * without mucking around with memory allocation. - */ - void clear(); + /** + * @brief Move the buffer offsets back to the beginning. + * + * This method effectively clears what has been stored here, + * without mucking around with memory allocation. + */ + void clear(); - /** - * @brief Enumeration passed into the seek function - * - * The READ head is used for where to start processing data for - * the next link in the chain, while the WRITE head specifies - * where new data processed from the previous link in the chain - * will be written. - */ - enum EHead - { - READ, - WRITE - }; + /** + * @brief Enumeration passed into the seek function + * + * The READ head is used for where to start processing data for + * the next link in the chain, while the WRITE head specifies + * where new data processed from the previous link in the chain + * will be written. + */ + enum EHead + { + READ, + WRITE + }; - /** - * @brief Seek to a place in the buffer - * - * @param head The READ or WRITE head. - * @param delta The offset from the current position to seek. - * @return The status of the operation. status >= if head moved. - */ - EStatus seek(EHead head, S64 delta); + /** + * @brief Seek to a place in the buffer + * + * @param head The READ or WRITE head. + * @param delta The offset from the current position to seek. + * @return The status of the operation. status >= if head moved. + */ + EStatus seek(EHead head, S64 delta); public: - /* @name LLIOPipe virtual implementations - */ - //@{ + /* @name LLIOPipe virtual implementations + */ + //@{ protected: - /** - * @brief Process the data in buffer - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /** + * @brief Process the data in buffer + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - U8* mBuffer; - S64 mBufferSize; - U8* mReadHead; - U8* mWriteHead; + U8* mBuffer; + S64 mBufferSize; + U8* mReadHead; + U8* mWriteHead; }; #endif // LL_LLIOBUFFER_H diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index e302dd2b5e..9791a20743 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliohttpserver.cpp * @author Phoenix * @date 2005-10-05 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -58,89 +58,89 @@ static void* sTimingCallbackData = NULL; class LLHTTPPipe : public LLIOPipe { public: - LLHTTPPipe(const LLHTTPNode& node) - : mNode(node), - mResponse(NULL), - mState(STATE_INVOKE), - mChainLock(0), - mLockedPump(NULL), - mStatusCode(0) - { } - virtual ~LLHTTPPipe() - { - if (mResponse.notNull()) - { - mResponse->nullPipe(); - } - } + LLHTTPPipe(const LLHTTPNode& node) + : mNode(node), + mResponse(NULL), + mState(STATE_INVOKE), + mChainLock(0), + mLockedPump(NULL), + mStatusCode(0) + { } + virtual ~LLHTTPPipe() + { + if (mResponse.notNull()) + { + mResponse->nullPipe(); + } + } private: - // LLIOPipe API implementation. - virtual EStatus process_impl( + // LLIOPipe API implementation. + virtual EStatus process_impl( const LLChannelDescriptors& channels, LLIOPipe::buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump); - const LLHTTPNode& mNode; - - class Response : public LLHTTPNode::Response - { - public: - - static LLPointer<Response> create(LLHTTPPipe* pipe); - virtual ~Response(); - - // from LLHTTPNode::Response - virtual void result(const LLSD&); - virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers); - virtual void extendedResult(S32 code, const LLSD& body, const LLSD& headers); - virtual void status(S32 code, const std::string& message); - - void nullPipe(); - - private: - Response() : mPipe(NULL) {} // Must be accessed through LLPointer. - LLHTTPPipe* mPipe; - }; - friend class Response; - - LLPointer<Response> mResponse; - - enum State - { - STATE_INVOKE, - STATE_DELAYED, - STATE_LOCKED, - STATE_GOOD_RESULT, - STATE_STATUS_RESULT, - STATE_EXTENDED_RESULT, - STATE_EXTENDED_LLSD_RESULT - }; - State mState; - - S32 mChainLock; - LLPumpIO* mLockedPump; - - void lockChain(LLPumpIO*); - void unlockChain(); - - LLSD mResult; - S32 mStatusCode; - std::string mStatusMessage; - LLSD mHeaders; + const LLHTTPNode& mNode; + + class Response : public LLHTTPNode::Response + { + public: + + static LLPointer<Response> create(LLHTTPPipe* pipe); + virtual ~Response(); + + // from LLHTTPNode::Response + virtual void result(const LLSD&); + virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers); + virtual void extendedResult(S32 code, const LLSD& body, const LLSD& headers); + virtual void status(S32 code, const std::string& message); + + void nullPipe(); + + private: + Response() : mPipe(NULL) {} // Must be accessed through LLPointer. + LLHTTPPipe* mPipe; + }; + friend class Response; + + LLPointer<Response> mResponse; + + enum State + { + STATE_INVOKE, + STATE_DELAYED, + STATE_LOCKED, + STATE_GOOD_RESULT, + STATE_STATUS_RESULT, + STATE_EXTENDED_RESULT, + STATE_EXTENDED_LLSD_RESULT + }; + State mState; + + S32 mChainLock; + LLPumpIO* mLockedPump; + + void lockChain(LLPumpIO*); + void unlockChain(); + + LLSD mResult; + S32 mStatusCode; + std::string mStatusMessage; + LLSD mHeaders; }; LLIOPipe::EStatus LLHTTPPipe::process_impl( - const LLChannelDescriptors& channels, + const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; + PUMP_DEBUG; LL_DEBUGS() << "LLSDHTTPServer::process_impl" << LL_ENDL; // Once we have all the data, We need to read the sd on @@ -149,166 +149,166 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( if(!eos) return STATUS_BREAK; if(!pump || !buffer) return STATUS_PRECONDITION_NOT_MET; - PUMP_DEBUG; - if (mState == STATE_INVOKE) - { - PUMP_DEBUG; - mState = STATE_DELAYED; - // assume deferred unless mResponse does otherwise - mResponse = Response::create(this); - - // *TODO: Babbage: Parameterize parser? - // *TODO: We should look at content-type and do the right - // thing. Phoenix 2007-12-31 - LLBufferStream istr(channels, buffer.get()); - - static LLTimer timer; - timer.reset(); - - std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB]; - if(verb == HTTP_VERB_GET) - { - mNode.get(LLHTTPNode::ResponsePtr(mResponse), context); - } - else if(verb == HTTP_VERB_PUT) - { - LLSD input; - if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) - { - LLSDSerialize::fromXML(input, istr); - } - else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) - { - std::ostringstream strstrm; - strstrm << istr.rdbuf(); - input = strstrm.str(); - } - mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input); - } - else if(verb == HTTP_VERB_POST) - { - LLSD input; - if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) - { - LLSDSerialize::fromXML(input, istr); - } - else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) - { - std::ostringstream strstrm; - strstrm << istr.rdbuf(); - input = strstrm.str(); - } - mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input); - } - else if(verb == HTTP_VERB_DELETE) - { - mNode.del(LLHTTPNode::ResponsePtr(mResponse), context); - } - else if(verb == HTTP_VERB_OPTIONS) - { - mNode.options(LLHTTPNode::ResponsePtr(mResponse), context); - } - else - { - mResponse->methodNotAllowed(); - } - - F32 delta = timer.getElapsedTimeF32(); - if (sTimingCallback) - { - LLHTTPNode::Description desc; - mNode.describe(desc); - LLSD info = desc.getInfo(); - std::string timing_name = info["description"]; - timing_name += " "; - timing_name += verb; - sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData); - } - - // Log all HTTP transactions. - // TODO: Add a way to log these to their own file instead of indra.log - // It is just too spammy to be in indra.log. - LL_DEBUGS() << verb << " " << context[CONTEXT_REQUEST][CONTEXT_PATH].asString() - << " " << mStatusCode << " " << mStatusMessage << " " << delta - << "s" << LL_ENDL; - - // Log Internal Server Errors - //if(mStatusCode == HTTP_INTERNAL_SERVER_ERROR) - //{ - // LL_WARNS() << "LLHTTPPipe::process_impl:500:Internal Server Error" - // << LL_ENDL; - //} - } - - PUMP_DEBUG; - switch (mState) - { - case STATE_DELAYED: - lockChain(pump); - mState = STATE_LOCKED; - return STATUS_BREAK; - - case STATE_LOCKED: - // should never ever happen! - return STATUS_ERROR; - - case STATE_GOOD_RESULT: - { - LLSD headers = mHeaders; - headers[HTTP_OUT_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML; - context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; - LLBufferStream ostr(channels, buffer.get()); - LLSDSerialize::toXML(mResult, ostr); - - return STATUS_DONE; - } - - case STATE_STATUS_RESULT: - { - LLSD headers = mHeaders; - headers[HTTP_OUT_HEADER_CONTENT_TYPE] = HTTP_CONTENT_TEXT_PLAIN; - context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; - context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; - context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage; - LLBufferStream ostr(channels, buffer.get()); - ostr << mStatusMessage; - - return STATUS_DONE; - } - case STATE_EXTENDED_RESULT: - { - context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = mHeaders; - context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; - LLBufferStream ostr(channels, buffer.get()); - ostr << mStatusMessage; - - return STATUS_DONE; - } - case STATE_EXTENDED_LLSD_RESULT: - { - LLSD headers = mHeaders; - headers[HTTP_OUT_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML; - context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; - context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; - LLBufferStream ostr(channels, buffer.get()); - LLSDSerialize::toXML(mResult, ostr); - - return STATUS_DONE; - } - default: - LL_WARNS() << "LLHTTPPipe::process_impl: unexpected state " - << mState << LL_ENDL; - - return STATUS_BREAK; - } -// PUMP_DEBUG; // unreachable + PUMP_DEBUG; + if (mState == STATE_INVOKE) + { + PUMP_DEBUG; + mState = STATE_DELAYED; + // assume deferred unless mResponse does otherwise + mResponse = Response::create(this); + + // *TODO: Babbage: Parameterize parser? + // *TODO: We should look at content-type and do the right + // thing. Phoenix 2007-12-31 + LLBufferStream istr(channels, buffer.get()); + + static LLTimer timer; + timer.reset(); + + std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB]; + if(verb == HTTP_VERB_GET) + { + mNode.get(LLHTTPNode::ResponsePtr(mResponse), context); + } + else if(verb == HTTP_VERB_PUT) + { + LLSD input; + if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) + { + LLSDSerialize::fromXML(input, istr); + } + else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) + { + std::ostringstream strstrm; + strstrm << istr.rdbuf(); + input = strstrm.str(); + } + mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input); + } + else if(verb == HTTP_VERB_POST) + { + LLSD input; + if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) + { + LLSDSerialize::fromXML(input, istr); + } + else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) + { + std::ostringstream strstrm; + strstrm << istr.rdbuf(); + input = strstrm.str(); + } + mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input); + } + else if(verb == HTTP_VERB_DELETE) + { + mNode.del(LLHTTPNode::ResponsePtr(mResponse), context); + } + else if(verb == HTTP_VERB_OPTIONS) + { + mNode.options(LLHTTPNode::ResponsePtr(mResponse), context); + } + else + { + mResponse->methodNotAllowed(); + } + + F32 delta = timer.getElapsedTimeF32(); + if (sTimingCallback) + { + LLHTTPNode::Description desc; + mNode.describe(desc); + LLSD info = desc.getInfo(); + std::string timing_name = info["description"]; + timing_name += " "; + timing_name += verb; + sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData); + } + + // Log all HTTP transactions. + // TODO: Add a way to log these to their own file instead of indra.log + // It is just too spammy to be in indra.log. + LL_DEBUGS() << verb << " " << context[CONTEXT_REQUEST][CONTEXT_PATH].asString() + << " " << mStatusCode << " " << mStatusMessage << " " << delta + << "s" << LL_ENDL; + + // Log Internal Server Errors + //if(mStatusCode == HTTP_INTERNAL_SERVER_ERROR) + //{ + // LL_WARNS() << "LLHTTPPipe::process_impl:500:Internal Server Error" + // << LL_ENDL; + //} + } + + PUMP_DEBUG; + switch (mState) + { + case STATE_DELAYED: + lockChain(pump); + mState = STATE_LOCKED; + return STATUS_BREAK; + + case STATE_LOCKED: + // should never ever happen! + return STATUS_ERROR; + + case STATE_GOOD_RESULT: + { + LLSD headers = mHeaders; + headers[HTTP_OUT_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML; + context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; + LLBufferStream ostr(channels, buffer.get()); + LLSDSerialize::toXML(mResult, ostr); + + return STATUS_DONE; + } + + case STATE_STATUS_RESULT: + { + LLSD headers = mHeaders; + headers[HTTP_OUT_HEADER_CONTENT_TYPE] = HTTP_CONTENT_TEXT_PLAIN; + context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; + context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; + context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage; + LLBufferStream ostr(channels, buffer.get()); + ostr << mStatusMessage; + + return STATUS_DONE; + } + case STATE_EXTENDED_RESULT: + { + context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = mHeaders; + context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; + LLBufferStream ostr(channels, buffer.get()); + ostr << mStatusMessage; + + return STATUS_DONE; + } + case STATE_EXTENDED_LLSD_RESULT: + { + LLSD headers = mHeaders; + headers[HTTP_OUT_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML; + context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; + context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; + LLBufferStream ostr(channels, buffer.get()); + LLSDSerialize::toXML(mResult, ostr); + + return STATUS_DONE; + } + default: + LL_WARNS() << "LLHTTPPipe::process_impl: unexpected state " + << mState << LL_ENDL; + + return STATUS_BREAK; + } +// PUMP_DEBUG; // unreachable } LLPointer<LLHTTPPipe::Response> LLHTTPPipe::Response::create(LLHTTPPipe* pipe) { - LLPointer<Response> result = new Response(); - result->mPipe = pipe; - return result; + LLPointer<Response> result = new Response(); + result->mPipe = pipe; + return result; } // virtual @@ -318,93 +318,93 @@ LLHTTPPipe::Response::~Response() void LLHTTPPipe::Response::nullPipe() { - mPipe = NULL; + mPipe = NULL; } // virtual void LLHTTPPipe::Response::result(const LLSD& r) { - if(! mPipe) - { - LL_WARNS() << "LLHTTPPipe::Response::result: NULL pipe" << LL_ENDL; - return; - } - - mPipe->mStatusCode = HTTP_OK; - mPipe->mStatusMessage = "OK"; - mPipe->mResult = r; - mPipe->mState = STATE_GOOD_RESULT; - mPipe->mHeaders = mHeaders; - mPipe->unlockChain(); + if(! mPipe) + { + LL_WARNS() << "LLHTTPPipe::Response::result: NULL pipe" << LL_ENDL; + return; + } + + mPipe->mStatusCode = HTTP_OK; + mPipe->mStatusMessage = "OK"; + mPipe->mResult = r; + mPipe->mState = STATE_GOOD_RESULT; + mPipe->mHeaders = mHeaders; + mPipe->unlockChain(); } void LLHTTPPipe::Response::extendedResult(S32 code, const LLSD& r, const LLSD& headers) { - if(! mPipe) - { - LL_WARNS() << "LLHTTPPipe::Response::extendedResult: NULL pipe" << LL_ENDL; - return; - } - - mPipe->mStatusCode = code; - mPipe->mStatusMessage = "(LLSD)"; - mPipe->mResult = r; - mPipe->mHeaders = headers; - mPipe->mState = STATE_EXTENDED_LLSD_RESULT; - mPipe->unlockChain(); + if(! mPipe) + { + LL_WARNS() << "LLHTTPPipe::Response::extendedResult: NULL pipe" << LL_ENDL; + return; + } + + mPipe->mStatusCode = code; + mPipe->mStatusMessage = "(LLSD)"; + mPipe->mResult = r; + mPipe->mHeaders = headers; + mPipe->mState = STATE_EXTENDED_LLSD_RESULT; + mPipe->unlockChain(); } void LLHTTPPipe::Response::extendedResult(S32 code, const std::string& body, const LLSD& headers) { - if(! mPipe) - { - LL_WARNS() << "LLHTTPPipe::Response::status: NULL pipe" << LL_ENDL; - return; - } - - mPipe->mStatusCode = code; - mPipe->mStatusMessage = body; - mPipe->mHeaders = headers; - mPipe->mState = STATE_EXTENDED_RESULT; - mPipe->unlockChain(); + if(! mPipe) + { + LL_WARNS() << "LLHTTPPipe::Response::status: NULL pipe" << LL_ENDL; + return; + } + + mPipe->mStatusCode = code; + mPipe->mStatusMessage = body; + mPipe->mHeaders = headers; + mPipe->mState = STATE_EXTENDED_RESULT; + mPipe->unlockChain(); } // virtual void LLHTTPPipe::Response::status(S32 code, const std::string& message) { - if(! mPipe) - { - LL_WARNS() << "LLHTTPPipe::Response::status: NULL pipe" << LL_ENDL; - return; - } - - mPipe->mStatusCode = code; - mPipe->mStatusMessage = message; - mPipe->mState = STATE_STATUS_RESULT; - mPipe->mHeaders = mHeaders; - mPipe->unlockChain(); + if(! mPipe) + { + LL_WARNS() << "LLHTTPPipe::Response::status: NULL pipe" << LL_ENDL; + return; + } + + mPipe->mStatusCode = code; + mPipe->mStatusMessage = message; + mPipe->mState = STATE_STATUS_RESULT; + mPipe->mHeaders = mHeaders; + mPipe->unlockChain(); } void LLHTTPPipe::lockChain(LLPumpIO* pump) { - if (mChainLock != 0) { return; } + if (mChainLock != 0) { return; } - mLockedPump = pump; - mChainLock = pump->setLock(); + mLockedPump = pump; + mChainLock = pump->setLock(); } void LLHTTPPipe::unlockChain() { - if (mChainLock == 0) { return; } + if (mChainLock == 0) { return; } - mLockedPump->clearLock(mChainLock); - mLockedPump = NULL; - mChainLock = 0; + mLockedPump->clearLock(mChainLock); + mLockedPump = NULL; + mChainLock = 0; } -/** +/** * @class LLHTTPResponseHeader * @brief Class which correctly builds HTTP headers on a pipe * @see LLIOPipe @@ -418,26 +418,26 @@ void LLHTTPPipe::unlockChain() class LLHTTPResponseHeader : public LLIOPipe { public: - LLHTTPResponseHeader() : mCode(0) {} - virtual ~LLHTTPResponseHeader() {} + LLHTTPResponseHeader() : mCode(0) {} + virtual ~LLHTTPResponseHeader() {} protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Process the data in buffer - */ - EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Process the data in buffer + */ + EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - S32 mCode; + S32 mCode; }; @@ -447,66 +447,66 @@ protected: // virtual LLIOPipe::EStatus LLHTTPResponseHeader::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - if(eos) - { - PUMP_DEBUG; - //mGotEOS = true; - std::ostringstream ostr; - std::string message = context[CONTEXT_RESPONSE]["statusMessage"]; - - int code = context[CONTEXT_RESPONSE]["statusCode"]; - if (code < HTTP_OK) - { - code = HTTP_OK; - message = "OK"; - } - - ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n"; - - S32 content_length = buffer->countAfter(channels.in(), NULL); - if(0 < content_length) - { - ostr << HTTP_OUT_HEADER_CONTENT_LENGTH << ": " << content_length << "\r\n"; - } - // *NOTE: This guard can go away once the LLSD static map - // iterator is available. Phoenix. 2008-05-09 - LLSD headers = context[CONTEXT_RESPONSE][CONTEXT_HEADERS]; - if(headers.isDefined()) - { - LLSD::map_iterator iter = headers.beginMap(); - LLSD::map_iterator end = headers.endMap(); - for(; iter != end; ++iter) - { - ostr << (*iter).first << ": " << (*iter).second.asString() - << "\r\n"; - } - } - ostr << "\r\n"; - - LLChangeChannel change(channels.in(), channels.out()); - std::for_each(buffer->beginSegment(), buffer->endSegment(), change); - std::string header = ostr.str(); - buffer->prepend(channels.out(), (U8*)header.c_str(), header.size()); - PUMP_DEBUG; - return STATUS_DONE; - } - PUMP_DEBUG; - return STATUS_OK; + PUMP_DEBUG; + if(eos) + { + PUMP_DEBUG; + //mGotEOS = true; + std::ostringstream ostr; + std::string message = context[CONTEXT_RESPONSE]["statusMessage"]; + + int code = context[CONTEXT_RESPONSE]["statusCode"]; + if (code < HTTP_OK) + { + code = HTTP_OK; + message = "OK"; + } + + ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n"; + + S32 content_length = buffer->countAfter(channels.in(), NULL); + if(0 < content_length) + { + ostr << HTTP_OUT_HEADER_CONTENT_LENGTH << ": " << content_length << "\r\n"; + } + // *NOTE: This guard can go away once the LLSD static map + // iterator is available. Phoenix. 2008-05-09 + LLSD headers = context[CONTEXT_RESPONSE][CONTEXT_HEADERS]; + if(headers.isDefined()) + { + LLSD::map_iterator iter = headers.beginMap(); + LLSD::map_iterator end = headers.endMap(); + for(; iter != end; ++iter) + { + ostr << (*iter).first << ": " << (*iter).second.asString() + << "\r\n"; + } + } + ostr << "\r\n"; + + LLChangeChannel change(channels.in(), channels.out()); + std::for_each(buffer->beginSegment(), buffer->endSegment(), change); + std::string header = ostr.str(); + buffer->prepend(channels.out(), (U8*)header.c_str(), header.size()); + PUMP_DEBUG; + return STATUS_DONE; + } + PUMP_DEBUG; + return STATUS_OK; } -/** +/** * @class LLHTTPResponder - * @brief This class + * @brief This class * @see LLIOPipe * * <b>NOTE:</b> You should not need to create or use one of these, the @@ -515,464 +515,464 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl( class LLHTTPResponder : public LLIOPipe { public: - LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx); - ~LLHTTPResponder(); + LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx); + ~LLHTTPResponder(); protected: - /** - * @brief Read data off of CHANNEL_IN keeping track of last read position. - * - * This is a quick little hack to read headers. It is not IO - * optimal, but it makes it easier for me to implement the header - * parsing. Plus, there should never be more than a few headers. - * This method will tend to read more than necessary, find the - * newline, make the front part of dest look like a c string, and - * move the read head back to where the newline was found. Thus, - * the next read will pick up on the next line. - * @param channel The channel to read in the buffer - * @param buffer The heap array of processed data - * @param dest Destination for the data to be read - * @param[in,out] len <b>in</b> The size of the buffer. <b>out</b> how - * much was read. This value is not useful for determining where to - * seek orfor string assignment. - * @returns Returns true if a line was found. - */ - bool readHeaderLine( - const LLChannelDescriptors& channels, - buffer_ptr_t buffer, - U8* dest, - S32& len); - - /** - * @brief Mark the request as bad, and handle appropriately - * - * @param channels The channels to use in the buffer. - * @param buffer The heap array of processed data. - */ - void markBad(const LLChannelDescriptors& channels, buffer_ptr_t buffer); + /** + * @brief Read data off of CHANNEL_IN keeping track of last read position. + * + * This is a quick little hack to read headers. It is not IO + * optimal, but it makes it easier for me to implement the header + * parsing. Plus, there should never be more than a few headers. + * This method will tend to read more than necessary, find the + * newline, make the front part of dest look like a c string, and + * move the read head back to where the newline was found. Thus, + * the next read will pick up on the next line. + * @param channel The channel to read in the buffer + * @param buffer The heap array of processed data + * @param dest Destination for the data to be read + * @param[in,out] len <b>in</b> The size of the buffer. <b>out</b> how + * much was read. This value is not useful for determining where to + * seek orfor string assignment. + * @returns Returns true if a line was found. + */ + bool readHeaderLine( + const LLChannelDescriptors& channels, + buffer_ptr_t buffer, + U8* dest, + S32& len); + + /** + * @brief Mark the request as bad, and handle appropriately + * + * @param channels The channels to use in the buffer. + * @param buffer The heap array of processed data. + */ + void markBad(const LLChannelDescriptors& channels, buffer_ptr_t buffer); protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Process the data in buffer - */ - EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Process the data in buffer + */ + EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - enum EState - { - STATE_NOTHING, - STATE_READING_HEADERS, - STATE_LOOKING_FOR_EOS, - STATE_DONE, - STATE_SHORT_CIRCUIT - }; - - LLSD mBuildContext; - EState mState; - U8* mLastRead; - std::string mVerb; - std::string mAbsPathAndQuery; - std::string mPath; - std::string mQuery; - std::string mVersion; - S32 mContentLength; - LLSD mHeaders; - - // handle the urls - const LLHTTPNode& mRootNode; + enum EState + { + STATE_NOTHING, + STATE_READING_HEADERS, + STATE_LOOKING_FOR_EOS, + STATE_DONE, + STATE_SHORT_CIRCUIT + }; + + LLSD mBuildContext; + EState mState; + U8* mLastRead; + std::string mVerb; + std::string mAbsPathAndQuery; + std::string mPath; + std::string mQuery; + std::string mVersion; + S32 mContentLength; + LLSD mHeaders; + + // handle the urls + const LLHTTPNode& mRootNode; }; LLHTTPResponder::LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx) : - mBuildContext(ctx), - mState(STATE_NOTHING), - mLastRead(NULL), - mContentLength(0), - mRootNode(tree) + mBuildContext(ctx), + mState(STATE_NOTHING), + mLastRead(NULL), + mContentLength(0), + mRootNode(tree) { } // virtual LLHTTPResponder::~LLHTTPResponder() { - //LL_DEBUGS() << "destroying LLHTTPResponder" << LL_ENDL; + //LL_DEBUGS() << "destroying LLHTTPResponder" << LL_ENDL; } bool LLHTTPResponder::readHeaderLine( - const LLChannelDescriptors& channels, - buffer_ptr_t buffer, - U8* dest, - S32& len) + const LLChannelDescriptors& channels, + buffer_ptr_t buffer, + U8* dest, + S32& len) { - --len; - U8* last = buffer->readAfter(channels.in(), mLastRead, dest, len); - dest[len] = '\0'; - U8* newline = (U8*)strchr((char*)dest, '\n'); - if(!newline) - { - if(len) - { - LL_DEBUGS() << "readLine failed - too long maybe?" << LL_ENDL; - markBad(channels, buffer); - } - return false; - } - S32 offset = -((len - 1) - (newline - dest)); - ++newline; - *newline = '\0'; - mLastRead = buffer->seek(channels.in(), last, offset); - return true; + --len; + U8* last = buffer->readAfter(channels.in(), mLastRead, dest, len); + dest[len] = '\0'; + U8* newline = (U8*)strchr((char*)dest, '\n'); + if(!newline) + { + if(len) + { + LL_DEBUGS() << "readLine failed - too long maybe?" << LL_ENDL; + markBad(channels, buffer); + } + return false; + } + S32 offset = -((len - 1) - (newline - dest)); + ++newline; + *newline = '\0'; + mLastRead = buffer->seek(channels.in(), last, offset); + return true; } void LLHTTPResponder::markBad( - const LLChannelDescriptors& channels, - buffer_ptr_t buffer) + const LLChannelDescriptors& channels, + buffer_ptr_t buffer) { - mState = STATE_SHORT_CIRCUIT; - LLBufferStream out(channels, buffer.get()); - out << HTTP_VERSION_STR << " 400 Bad Request\r\n\r\n<html>\n" - << "<title>Bad Request</title>\n<body>\nBad Request.\n" - << "</body>\n</html>\n"; + mState = STATE_SHORT_CIRCUIT; + LLBufferStream out(channels, buffer.get()); + out << HTTP_VERSION_STR << " 400 Bad Request\r\n\r\n<html>\n" + << "<title>Bad Request</title>\n<body>\nBad Request.\n" + << "</body>\n</html>\n"; } // virtual LLIOPipe::EStatus LLHTTPResponder::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - LLIOPipe::EStatus status = STATUS_OK; - - // parsing headers - if((STATE_NOTHING == mState) || (STATE_READING_HEADERS == mState)) - { - PUMP_DEBUG; - status = STATUS_BREAK; - mState = STATE_READING_HEADERS; - const S32 HEADER_BUFFER_SIZE = 1024; - char buf[HEADER_BUFFER_SIZE + 1]; /*Flawfinder: ignore*/ - S32 len = HEADER_BUFFER_SIZE; + PUMP_DEBUG; + LLIOPipe::EStatus status = STATUS_OK; + + // parsing headers + if((STATE_NOTHING == mState) || (STATE_READING_HEADERS == mState)) + { + PUMP_DEBUG; + status = STATUS_BREAK; + mState = STATE_READING_HEADERS; + const S32 HEADER_BUFFER_SIZE = 1024; + char buf[HEADER_BUFFER_SIZE + 1]; /*Flawfinder: ignore*/ + S32 len = HEADER_BUFFER_SIZE; #if 0 - if(true) - { - LLBufferArray::segment_iterator_t seg_iter = buffer->beginSegment(); - char buf[1024]; /*Flawfinder: ignore*/ - while(seg_iter != buffer->endSegment()) - { - memcpy(buf, (*seg_iter).data(), (*seg_iter).size()); /*Flawfinder: ignore*/ - buf[(*seg_iter).size()] = '\0'; - LL_INFOS() << (*seg_iter).getChannel() << ": " << buf - << LL_ENDL; - ++seg_iter; - } - } + if(true) + { + LLBufferArray::segment_iterator_t seg_iter = buffer->beginSegment(); + char buf[1024]; /*Flawfinder: ignore*/ + while(seg_iter != buffer->endSegment()) + { + memcpy(buf, (*seg_iter).data(), (*seg_iter).size()); /*Flawfinder: ignore*/ + buf[(*seg_iter).size()] = '\0'; + LL_INFOS() << (*seg_iter).getChannel() << ": " << buf + << LL_ENDL; + ++seg_iter; + } + } #endif - - PUMP_DEBUG; - if(readHeaderLine(channels, buffer, (U8*)buf, len)) - { - bool read_next_line = false; - bool parse_all = true; - if(mVerb.empty()) - { - read_next_line = true; - LLMemoryStream header((U8*)buf, len); - header >> mVerb; - - if((HTTP_VERB_GET == mVerb) - || (HTTP_VERB_POST == mVerb) - || (HTTP_VERB_PUT == mVerb) - || (HTTP_VERB_DELETE == mVerb) - || (HTTP_VERB_OPTIONS == mVerb)) - { - header >> mAbsPathAndQuery; - header >> mVersion; - - LL_DEBUGS() << "http request: " - << mVerb - << " " << mAbsPathAndQuery - << " " << mVersion << LL_ENDL; - - std::string::size_type delimiter - = mAbsPathAndQuery.find('?'); - if (delimiter == std::string::npos) - { - mPath = mAbsPathAndQuery; - mQuery = ""; - } - else - { - mPath = mAbsPathAndQuery.substr(0, delimiter); - mQuery = mAbsPathAndQuery.substr(delimiter+1); - } - - if(!mAbsPathAndQuery.empty()) - { - if(mVersion.empty()) - { - // simple request. - parse_all = false; - mState = STATE_DONE; - mVersion.assign("HTTP/1.0"); - } - } - } - else - { - read_next_line = false; - parse_all = false; - LL_DEBUGS() << "unknown http verb: " << mVerb << LL_ENDL; - markBad(channels, buffer); - } - } - if(parse_all) - { - bool keep_parsing = true; - while(keep_parsing) - { - if(read_next_line) - { - len = HEADER_BUFFER_SIZE; - if (!readHeaderLine(channels, buffer, (U8*)buf, len)) - { - // Failed to read the header line, probably too long. - // readHeaderLine already marked the channel/buffer as bad. - keep_parsing = false; - break; - } - } - if(0 == len) - { - return status; - } - if(buf[0] == '\r' && buf[1] == '\n') - { - // end-o-headers - keep_parsing = false; - mState = STATE_LOOKING_FOR_EOS; - break; - } - char* pos_colon = strchr(buf, ':'); - if(NULL == pos_colon) - { - keep_parsing = false; - LL_DEBUGS() << "bad header: " << buf << LL_ENDL; - markBad(channels, buffer); - break; - } - // we've found a header - read_next_line = true; - std::string name(buf, pos_colon - buf); - std::string value(pos_colon + 2); - LLStringUtil::toLower(name); - if(HTTP_IN_HEADER_CONTENT_LENGTH == name) - { - LL_DEBUGS() << "Content-Length: " << value << LL_ENDL; - mContentLength = atoi(value.c_str()); - } - else - { - LLStringUtil::trimTail(value); - mHeaders[name] = value; - } - } - } - } - } - - PUMP_DEBUG; - // look for the end of stream based on - if(STATE_LOOKING_FOR_EOS == mState) - { - if(0 == mContentLength) - { - mState = STATE_DONE; - } - else if(buffer->countAfter(channels.in(), mLastRead) >= mContentLength) - { - mState = STATE_DONE; - } - // else more bytes should be coming. - } - - PUMP_DEBUG; - if(STATE_DONE == mState) - { - // hey, hey, we should have everything now, so we pass it to - // a content handler. - context[CONTEXT_REQUEST][CONTEXT_VERB] = mVerb; - const LLHTTPNode* node = mRootNode.traverse(mPath, context); - if(node) - { - //LL_INFOS() << "LLHTTPResponder::process_impl found node for " - // << mAbsPathAndQuery << LL_ENDL; - - // Copy everything after mLast read to the out. - LLBufferArray::segment_iterator_t seg_iter; - - buffer->lock(); - seg_iter = buffer->splitAfter(mLastRead); - if(seg_iter != buffer->endSegment()) - { - LLChangeChannel change(channels.in(), channels.out()); - ++seg_iter; - std::for_each(seg_iter, buffer->endSegment(), change); + + PUMP_DEBUG; + if(readHeaderLine(channels, buffer, (U8*)buf, len)) + { + bool read_next_line = false; + bool parse_all = true; + if(mVerb.empty()) + { + read_next_line = true; + LLMemoryStream header((U8*)buf, len); + header >> mVerb; + + if((HTTP_VERB_GET == mVerb) + || (HTTP_VERB_POST == mVerb) + || (HTTP_VERB_PUT == mVerb) + || (HTTP_VERB_DELETE == mVerb) + || (HTTP_VERB_OPTIONS == mVerb)) + { + header >> mAbsPathAndQuery; + header >> mVersion; + + LL_DEBUGS() << "http request: " + << mVerb + << " " << mAbsPathAndQuery + << " " << mVersion << LL_ENDL; + + std::string::size_type delimiter + = mAbsPathAndQuery.find('?'); + if (delimiter == std::string::npos) + { + mPath = mAbsPathAndQuery; + mQuery = ""; + } + else + { + mPath = mAbsPathAndQuery.substr(0, delimiter); + mQuery = mAbsPathAndQuery.substr(delimiter+1); + } + + if(!mAbsPathAndQuery.empty()) + { + if(mVersion.empty()) + { + // simple request. + parse_all = false; + mState = STATE_DONE; + mVersion.assign("HTTP/1.0"); + } + } + } + else + { + read_next_line = false; + parse_all = false; + LL_DEBUGS() << "unknown http verb: " << mVerb << LL_ENDL; + markBad(channels, buffer); + } + } + if(parse_all) + { + bool keep_parsing = true; + while(keep_parsing) + { + if(read_next_line) + { + len = HEADER_BUFFER_SIZE; + if (!readHeaderLine(channels, buffer, (U8*)buf, len)) + { + // Failed to read the header line, probably too long. + // readHeaderLine already marked the channel/buffer as bad. + keep_parsing = false; + break; + } + } + if(0 == len) + { + return status; + } + if(buf[0] == '\r' && buf[1] == '\n') + { + // end-o-headers + keep_parsing = false; + mState = STATE_LOOKING_FOR_EOS; + break; + } + char* pos_colon = strchr(buf, ':'); + if(NULL == pos_colon) + { + keep_parsing = false; + LL_DEBUGS() << "bad header: " << buf << LL_ENDL; + markBad(channels, buffer); + break; + } + // we've found a header + read_next_line = true; + std::string name(buf, pos_colon - buf); + std::string value(pos_colon + 2); + LLStringUtil::toLower(name); + if(HTTP_IN_HEADER_CONTENT_LENGTH == name) + { + LL_DEBUGS() << "Content-Length: " << value << LL_ENDL; + mContentLength = atoi(value.c_str()); + } + else + { + LLStringUtil::trimTail(value); + mHeaders[name] = value; + } + } + } + } + } + + PUMP_DEBUG; + // look for the end of stream based on + if(STATE_LOOKING_FOR_EOS == mState) + { + if(0 == mContentLength) + { + mState = STATE_DONE; + } + else if(buffer->countAfter(channels.in(), mLastRead) >= mContentLength) + { + mState = STATE_DONE; + } + // else more bytes should be coming. + } + + PUMP_DEBUG; + if(STATE_DONE == mState) + { + // hey, hey, we should have everything now, so we pass it to + // a content handler. + context[CONTEXT_REQUEST][CONTEXT_VERB] = mVerb; + const LLHTTPNode* node = mRootNode.traverse(mPath, context); + if(node) + { + //LL_INFOS() << "LLHTTPResponder::process_impl found node for " + // << mAbsPathAndQuery << LL_ENDL; + + // Copy everything after mLast read to the out. + LLBufferArray::segment_iterator_t seg_iter; + + buffer->lock(); + seg_iter = buffer->splitAfter(mLastRead); + if(seg_iter != buffer->endSegment()) + { + LLChangeChannel change(channels.in(), channels.out()); + ++seg_iter; + std::for_each(seg_iter, buffer->endSegment(), change); #if 0 - seg_iter = buffer->beginSegment(); - char buf[1024]; /*Flawfinder: ignore*/ - while(seg_iter != buffer->endSegment()) - { - memcpy(buf, (*seg_iter).data(), (*seg_iter).size()); /*Flawfinder: ignore*/ - buf[(*seg_iter).size()] = '\0'; - LL_INFOS() << (*seg_iter).getChannel() << ": " << buf - << LL_ENDL; - ++seg_iter; - } + seg_iter = buffer->beginSegment(); + char buf[1024]; /*Flawfinder: ignore*/ + while(seg_iter != buffer->endSegment()) + { + memcpy(buf, (*seg_iter).data(), (*seg_iter).size()); /*Flawfinder: ignore*/ + buf[(*seg_iter).size()] = '\0'; + LL_INFOS() << (*seg_iter).getChannel() << ": " << buf + << LL_ENDL; + ++seg_iter; + } #endif - } - buffer->unlock(); - // - // *FIX: get rid of extra bytes off the end - // - - // Set up a chain which will prepend a content length and - // HTTP headers. - LLPumpIO::chain_t chain; - chain.push_back(LLIOPipe::ptr_t(new LLIOFlush)); - context[CONTEXT_REQUEST][CONTEXT_PATH] = mPath; - context[CONTEXT_REQUEST][CONTEXT_QUERY_STRING] = mQuery; - context[CONTEXT_REQUEST][CONTEXT_REMOTE_HOST] - = mBuildContext[CONTEXT_REMOTE_HOST]; - context[CONTEXT_REQUEST][CONTEXT_REMOTE_PORT] - = mBuildContext[CONTEXT_REMOTE_PORT]; - context[CONTEXT_REQUEST][CONTEXT_HEADERS] = mHeaders; - - const LLChainIOFactory* protocolHandler - = node->getProtocolHandler(); - if (protocolHandler) - { - LL_DEBUGS() << "HTTP context: " << context << LL_ENDL; - protocolHandler->build(chain, context); - } - else - { - // this is a simple LLHTTPNode, so use LLHTTPPipe - chain.push_back(LLIOPipe::ptr_t(new LLHTTPPipe(*node))); - } - - // Add the header - which needs to have the same - // channel information as the link before it since it - // is part of the response. - LLIOPipe* header = new LLHTTPResponseHeader; - chain.push_back(LLIOPipe::ptr_t(header)); - - // We need to copy all of the pipes _after_ this so - // that the response goes out correctly. - LLPumpIO::links_t current_links; - pump->copyCurrentLinkInfo(current_links); - LLPumpIO::links_t::iterator link_iter = current_links.begin(); - LLPumpIO::links_t::iterator links_end = current_links.end(); - bool after_this = false; - for(; link_iter < links_end; ++link_iter) - { - if(after_this) - { - chain.push_back((*link_iter).mPipe); - } - else if(this == (*link_iter).mPipe.get()) - { - after_this = true; - } - } - - // Do the final build of the chain, and send it on - // it's way. - LLChannelDescriptors chnl = channels; - LLPumpIO::LLLinkInfo link; - LLPumpIO::links_t links; - LLPumpIO::chain_t::iterator it = chain.begin(); - LLPumpIO::chain_t::iterator end = chain.end(); - while(it != end) - { - link.mPipe = *it; - link.mChannels = chnl; - links.push_back(link); - chnl = LLBufferArray::makeChannelConsumer(chnl); - ++it; - } - pump->addChain( - links, - buffer, - context, - DEFAULT_CHAIN_EXPIRY_SECS); - - status = STATUS_STOP; - } - else - { - LL_WARNS() << "LLHTTPResponder::process_impl didn't find a node for " - << mAbsPathAndQuery << LL_ENDL; - LLBufferStream str(channels, buffer.get()); - mState = STATE_SHORT_CIRCUIT; - str << HTTP_VERSION_STR << " 404 Not Found\r\n\r\n<html>\n" - << "<title>Not Found</title>\n<body>\nNode '" << mAbsPathAndQuery - << "' not found.\n</body>\n</html>\n"; - } - } - - if(STATE_SHORT_CIRCUIT == mState) - { - //status = mNext->process(buffer, true, pump, context); - status = STATUS_DONE; - } - PUMP_DEBUG; - return status; + } + buffer->unlock(); + // + // *FIX: get rid of extra bytes off the end + // + + // Set up a chain which will prepend a content length and + // HTTP headers. + LLPumpIO::chain_t chain; + chain.push_back(LLIOPipe::ptr_t(new LLIOFlush)); + context[CONTEXT_REQUEST][CONTEXT_PATH] = mPath; + context[CONTEXT_REQUEST][CONTEXT_QUERY_STRING] = mQuery; + context[CONTEXT_REQUEST][CONTEXT_REMOTE_HOST] + = mBuildContext[CONTEXT_REMOTE_HOST]; + context[CONTEXT_REQUEST][CONTEXT_REMOTE_PORT] + = mBuildContext[CONTEXT_REMOTE_PORT]; + context[CONTEXT_REQUEST][CONTEXT_HEADERS] = mHeaders; + + const LLChainIOFactory* protocolHandler + = node->getProtocolHandler(); + if (protocolHandler) + { + LL_DEBUGS() << "HTTP context: " << context << LL_ENDL; + protocolHandler->build(chain, context); + } + else + { + // this is a simple LLHTTPNode, so use LLHTTPPipe + chain.push_back(LLIOPipe::ptr_t(new LLHTTPPipe(*node))); + } + + // Add the header - which needs to have the same + // channel information as the link before it since it + // is part of the response. + LLIOPipe* header = new LLHTTPResponseHeader; + chain.push_back(LLIOPipe::ptr_t(header)); + + // We need to copy all of the pipes _after_ this so + // that the response goes out correctly. + LLPumpIO::links_t current_links; + pump->copyCurrentLinkInfo(current_links); + LLPumpIO::links_t::iterator link_iter = current_links.begin(); + LLPumpIO::links_t::iterator links_end = current_links.end(); + bool after_this = false; + for(; link_iter < links_end; ++link_iter) + { + if(after_this) + { + chain.push_back((*link_iter).mPipe); + } + else if(this == (*link_iter).mPipe.get()) + { + after_this = true; + } + } + + // Do the final build of the chain, and send it on + // it's way. + LLChannelDescriptors chnl = channels; + LLPumpIO::LLLinkInfo link; + LLPumpIO::links_t links; + LLPumpIO::chain_t::iterator it = chain.begin(); + LLPumpIO::chain_t::iterator end = chain.end(); + while(it != end) + { + link.mPipe = *it; + link.mChannels = chnl; + links.push_back(link); + chnl = LLBufferArray::makeChannelConsumer(chnl); + ++it; + } + pump->addChain( + links, + buffer, + context, + DEFAULT_CHAIN_EXPIRY_SECS); + + status = STATUS_STOP; + } + else + { + LL_WARNS() << "LLHTTPResponder::process_impl didn't find a node for " + << mAbsPathAndQuery << LL_ENDL; + LLBufferStream str(channels, buffer.get()); + mState = STATE_SHORT_CIRCUIT; + str << HTTP_VERSION_STR << " 404 Not Found\r\n\r\n<html>\n" + << "<title>Not Found</title>\n<body>\nNode '" << mAbsPathAndQuery + << "' not found.\n</body>\n</html>\n"; + } + } + + if(STATE_SHORT_CIRCUIT == mState) + { + //status = mNext->process(buffer, true, pump, context); + status = STATUS_DONE; + } + PUMP_DEBUG; + return status; } -// static -void LLIOHTTPServer::createPipe(LLPumpIO::chain_t& chain, +// static +void LLIOHTTPServer::createPipe(LLPumpIO::chain_t& chain, const LLHTTPNode& root, const LLSD& ctx) { - chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx))); + chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx))); } class LLHTTPResponseFactory : public LLChainIOFactory { public: - bool build(LLPumpIO::chain_t& chain, LLSD ctx) const - { - LLIOHTTPServer::createPipe(chain, mTree, ctx); - return true; - } + bool build(LLPumpIO::chain_t& chain, LLSD ctx) const + { + LLIOHTTPServer::createPipe(chain, mTree, ctx); + return true; + } - LLHTTPNode& getRootNode() { return mTree; } + LLHTTPNode& getRootNode() { return mTree; } private: - LLHTTPNode mTree; + LLHTTPNode mTree; }; // static LLHTTPNode& LLIOHTTPServer::create( - apr_pool_t* pool, LLPumpIO& pump, U16 port) + apr_pool_t* pool, LLPumpIO& pump, U16 port) { - LLSocket::ptr_t socket = LLSocket::create( + LLSocket::ptr_t socket = LLSocket::create( pool, LLSocket::STREAM_TCP, port); @@ -982,21 +982,21 @@ LLHTTPNode& LLIOHTTPServer::create( } LLHTTPResponseFactory* factory = new LLHTTPResponseFactory; - std::shared_ptr<LLChainIOFactory> factory_ptr(factory); + std::shared_ptr<LLChainIOFactory> factory_ptr(factory); LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr); - LLPumpIO::chain_t chain; + LLPumpIO::chain_t chain; chain.push_back(LLIOPipe::ptr_t(server)); pump.addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - return factory->getRootNode(); + return factory->getRootNode(); } // static void LLIOHTTPServer::setTimingCallback(timing_callback_t callback, - void* data) + void* data) { - sTimingCallback = callback; - sTimingCallbackData = data; + sTimingCallback = callback; + sTimingCallbackData = data; } diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h index a23eafe58a..a1ae8736b7 100644 --- a/indra/llmessage/lliohttpserver.h +++ b/indra/llmessage/lliohttpserver.h @@ -1,4 +1,4 @@ -/** +/** * @file lliohttpserver.h * @brief Declaration of function for creating an HTTP wire server * @see LLIOServerSocket, LLPumpIO @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,38 +36,38 @@ class LLPumpIO; class LLIOHTTPServer { public: - typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); - - static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); - /**< Creates an HTTP wire server on the pump for the given TCP port. - * - * Returns the root node of the new server. Add LLHTTPNode instances - * to this root. - * - * Nodes that return NULL for getProtocolHandler(), will use the - * default handler that interprets HTTP on the wire and converts - * it into calls to get(), put(), post(), del() with appropriate - * LLSD arguments and results. - * - * To have nodes that implement some other wire protocol (XML-RPC - * for example), use the helper templates below. - */ - - static void createPipe(LLPumpIO::chain_t& chain, + typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); + + static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); + /**< Creates an HTTP wire server on the pump for the given TCP port. + * + * Returns the root node of the new server. Add LLHTTPNode instances + * to this root. + * + * Nodes that return NULL for getProtocolHandler(), will use the + * default handler that interprets HTTP on the wire and converts + * it into calls to get(), put(), post(), del() with appropriate + * LLSD arguments and results. + * + * To have nodes that implement some other wire protocol (XML-RPC + * for example), use the helper templates below. + */ + + static void createPipe(LLPumpIO::chain_t& chain, const LLHTTPNode& root, const LLSD& ctx); - /**< Create a pipe on the chain that handles HTTP requests. - * The requests are served by the node tree given at root. - * - * This is primarily useful for unit testing. - */ - - static void setTimingCallback(timing_callback_t callback, void* data); - /**< Register a callback function that will be called every time - * a GET, PUT, POST, or DELETE is handled. - * - * This is used to time the LLHTTPNode handler code, which often hits - * the database or does other, slow operations. JC - */ + /**< Create a pipe on the chain that handles HTTP requests. + * The requests are served by the node tree given at root. + * + * This is primarily useful for unit testing. + */ + + static void setTimingCallback(timing_callback_t callback, void* data); + /**< Register a callback function that will be called every time + * a GET, PUT, POST, or DELETE is handled. + * + * This is used to time the LLHTTPNode handler code, which often hits + * the database or does other, slow operations. JC + */ }; /* @name Helper Templates @@ -80,14 +80,14 @@ public: * * The templates are: * - * LLChainIOFactoryForPipe - * - a simple factory that builds instances of a pipe + * LLChainIOFactoryForPipe + * - a simple factory that builds instances of a pipe * - * LLHTTPNodeForFacotry - * - a HTTP node that uses a factory as the protocol handler + * LLHTTPNodeForFacotry + * - a HTTP node that uses a factory as the protocol handler * - * LLHTTPNodeForPipe - * - a HTTP node that uses a simple factory based on a pipe + * LLHTTPNodeForPipe + * - a HTTP node that uses a simple factory based on a pipe */ //@{ @@ -95,22 +95,22 @@ template<class Pipe> class LLChainIOFactoryForPipe : public LLChainIOFactory { public: - virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const - { - chain.push_back(LLIOPipe::ptr_t(new Pipe)); - return true; - } + virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const + { + chain.push_back(LLIOPipe::ptr_t(new Pipe)); + return true; + } }; template<class Factory> class LLHTTPNodeForFactory : public LLHTTPNode { public: - const LLChainIOFactory* getProtocolHandler() const - { return &mProtocolHandler; } + const LLChainIOFactory* getProtocolHandler() const + { return &mProtocolHandler; } private: - Factory mProtocolHandler; + Factory mProtocolHandler; }; //@} @@ -118,7 +118,7 @@ private: template<class Pipe> class LLHTTPNodeForPipe : public LLHTTPNodeForFactory< - LLChainIOFactoryForPipe<Pipe> > + LLChainIOFactoryForPipe<Pipe> > { }; diff --git a/indra/llmessage/lliopipe.cpp b/indra/llmessage/lliopipe.cpp index 4676a9a8f0..75811bf3ce 100644 --- a/indra/llmessage/lliopipe.cpp +++ b/indra/llmessage/lliopipe.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliopipe.cpp * @author Phoenix * @date 2004-11-19 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,32 +33,32 @@ static const std::string STATUS_SUCCESS_NAMES[LLIOPipe::STATUS_SUCCESS_COUNT] = { - std::string("STATUS_OK"), - std::string("STATUS_STOP"), - std::string("STATUS_DONE"), - std::string("STATUS_BREAK"), - std::string("STATUS_NEED_PROCESS"), + std::string("STATUS_OK"), + std::string("STATUS_STOP"), + std::string("STATUS_DONE"), + std::string("STATUS_BREAK"), + std::string("STATUS_NEED_PROCESS"), }; static const std::string STATUS_ERROR_NAMES[LLIOPipe::STATUS_ERROR_COUNT] = { - std::string("STATUS_ERROR"), - std::string("STATUS_NOT_IMPLEMENTED"), - std::string("STATUS_PRECONDITION_NOT_MET"), - std::string("STATUS_NO_CONNECTION"), - std::string("STATUS_LOST_CONNECTION"), - std::string("STATUS_EXPIRED"), + std::string("STATUS_ERROR"), + std::string("STATUS_NOT_IMPLEMENTED"), + std::string("STATUS_PRECONDITION_NOT_MET"), + std::string("STATUS_NO_CONNECTION"), + std::string("STATUS_LOST_CONNECTION"), + std::string("STATUS_EXPIRED"), }; #ifdef LL_DEBUG_PUMPS // Debugging schmutz for deadlock -const char *gPumpFile = ""; -S32 gPumpLine = 0; +const char *gPumpFile = ""; +S32 gPumpLine = 0; void pump_debug(const char *file, S32 line) { - gPumpFile = file; - gPumpLine = line; + gPumpFile = file; + gPumpLine = line; } #endif /* LL_DEBUG_PUMPS */ @@ -66,55 +66,55 @@ void pump_debug(const char *file, S32 line) * LLIOPipe */ LLIOPipe::LLIOPipe() : - mReferenceCount(0) + mReferenceCount(0) { } LLIOPipe::~LLIOPipe() { - //LL_DEBUGS() << "destroying LLIOPipe" << LL_ENDL; + //LL_DEBUGS() << "destroying LLIOPipe" << LL_ENDL; } -//virtual -bool LLIOPipe::isValid() +//virtual +bool LLIOPipe::isValid() { - return true ; + return true ; } // static std::string LLIOPipe::lookupStatusString(EStatus status) { - if((status >= 0) && (status < STATUS_SUCCESS_COUNT)) - { - return STATUS_SUCCESS_NAMES[status]; - } - else - { - S32 error_code = ((S32)status * -1) - 1; - if(error_code < STATUS_ERROR_COUNT) - { - return STATUS_ERROR_NAMES[error_code]; - } - } - std::string rv; - return rv; + if((status >= 0) && (status < STATUS_SUCCESS_COUNT)) + { + return STATUS_SUCCESS_NAMES[status]; + } + else + { + S32 error_code = ((S32)status * -1) - 1; + if(error_code < STATUS_ERROR_COUNT) + { + return STATUS_ERROR_NAMES[error_code]; + } + } + std::string rv; + return rv; } LLIOPipe::EStatus LLIOPipe::process( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - return process_impl(channels, buffer, eos, context, pump); + return process_impl(channels, buffer, eos, context, pump); } // virtual LLIOPipe::EStatus LLIOPipe::handleError( - LLIOPipe::EStatus status, - LLPumpIO* pump) + LLIOPipe::EStatus status, + LLPumpIO* pump) { - // by default, the error is not handled. - return status; + // by default, the error is not handled. + return status; } diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h index e6ac8ebfc2..a58ee045c2 100644 --- a/indra/llmessage/lliopipe.h +++ b/indra/llmessage/lliopipe.h @@ -1,4 +1,4 @@ -/** +/** * @file lliopipe.h * @author Phoenix * @date 2004-11-18 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -59,7 +59,7 @@ void pump_debug(const char *file, S32 line); void intrusive_ptr_add_ref(LLIOPipe* p); void intrusive_ptr_release(LLIOPipe* p); -/** +/** * @class LLIOPipe * @brief This class is an abstract base class for data processing units * @see LLPumpIO @@ -78,191 +78,191 @@ void intrusive_ptr_release(LLIOPipe* p); class LLIOPipe { public: - /** - * @brief I have decided that IO objects should have a reference - * count. In general, you can pass bald LLIOPipe pointers around - * as you need, but if you need to maintain a reference to one, - * you need to hold a ptr_t. - */ - typedef boost::intrusive_ptr<LLIOPipe> ptr_t; - - /** - * @brief Scattered memory container. - */ - typedef std::shared_ptr<LLBufferArray> buffer_ptr_t; - - /** - * @brief Enumeration for IO return codes - * - * A status code a positive integer value is considered a success, - * but may indicate special handling for future calls, for - * example, issuing a STATUS_STOP to an LLIOSocketReader instance - * will tell the instance to stop reading the socket. A status - * code with a negative value means that a problem has been - * encountered which will require further action on the caller or - * a developer to correct. Some mechanisms, such as the LLPumpIO - * may depend on this definition of success and failure. - */ - enum EStatus - { - // Processing occurred normally, future calls will be accepted. - STATUS_OK = 0, - - // Processing occured normally, but stop unsolicited calls to - // process. - STATUS_STOP = 1, - - // This pipe is done with the processing. Future calls to - // process will be accepted as long as new data is available. - STATUS_DONE = 2, - - // This pipe is requesting that it become the head in a process. - STATUS_BREAK = 3, - - // This pipe is requesting that it become the head in a process. - STATUS_NEED_PROCESS = 4, - - // Keep track of the highest number of success codes here. - STATUS_SUCCESS_COUNT = 5, - - // A generic error code. - STATUS_ERROR = -1, - - // This method has not yet been implemented. This usually - // indicates the programmer working on the pipe is not yet - // done. - STATUS_NOT_IMPLEMENTED = -2, - - // This indicates that a pipe precondition was not met. For - // example, many pipes require an element to appear after them - // in a chain (ie, mNext is not null) and will return this in - // response to method calls. To recover from this, it will - // require the caller to adjust the pipe state or may require - // a dev to adjust the code to satisfy the preconditions. - STATUS_PRECONDITION_NOT_MET = -3, - - // This means we could not connect to a remote host. - STATUS_NO_CONNECTION = -4, - - // The connection was lost. - STATUS_LOST_CONNECTION = -5, - - // The totoal process time has exceeded the timeout. - STATUS_EXPIRED = -6, - - // Keep track of the count of codes here. - STATUS_ERROR_COUNT = 6, - }; - - /** - * @brief Helper function to check status. - * - * When writing code to check status codes, if you do not - * specifically check a particular value, use this method for - * checking an error condition. - * @param status The status to check. - * @return Returns true if the code indicates an error occurred. - */ - inline static bool isError(EStatus status) - { - return ((S32)status < 0); - } - - /** - * @brief Helper function to check status. - * - * When writing code to check status codes, if you do not - * specifically check a particular value, use this method for - * checking an error condition. - * @param status The status to check. - * @return Returns true if the code indicates no error was generated. - */ - inline static bool isSuccess(EStatus status) - { - return ((S32)status >= 0); - } - - /** - * @brief Helper function to turn status into a string. - * - * @param status The status to check. - * @return Returns the name of the status code or empty string on failure. - */ - static std::string lookupStatusString(EStatus status); - - /** - * @brief Process the data in buffer. - * - * @param data The data processed - * @param eos True if this function call is the last because end of stream. - * @param pump The pump which is calling process. May be NULL. - * @param context Shared meta-data for the process. - * @return Returns a status code from the operation. - */ - EStatus process( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - - /** - * @brief Give this pipe a chance to handle a generated error - * - * If this pipe is in a chain being processed by a pump, and one - * of the pipes generates an error, the pump will rewind through - * the chain to see if any of the links can handle the error. For - * example, if a connection is refused in a socket connection, the - * socket client can try to find a new destination host. Return an - * error code if this pipe does not handle the error passed in. - * @param status The status code for the error - * @param pump The pump which was calling process before the error - * was generated. - * @return Returns a status code from the operation. Returns an - * error code if the error passed in was not handled. Returns - * STATUS_OK to indicate the error has been handled. - */ - virtual EStatus handleError(EStatus status, LLPumpIO* pump); - - /** - * @brief Base Destructor - do not call <code>delete</code> directly. - */ - virtual ~LLIOPipe(); - - virtual bool isValid() ; + /** + * @brief I have decided that IO objects should have a reference + * count. In general, you can pass bald LLIOPipe pointers around + * as you need, but if you need to maintain a reference to one, + * you need to hold a ptr_t. + */ + typedef boost::intrusive_ptr<LLIOPipe> ptr_t; + + /** + * @brief Scattered memory container. + */ + typedef std::shared_ptr<LLBufferArray> buffer_ptr_t; + + /** + * @brief Enumeration for IO return codes + * + * A status code a positive integer value is considered a success, + * but may indicate special handling for future calls, for + * example, issuing a STATUS_STOP to an LLIOSocketReader instance + * will tell the instance to stop reading the socket. A status + * code with a negative value means that a problem has been + * encountered which will require further action on the caller or + * a developer to correct. Some mechanisms, such as the LLPumpIO + * may depend on this definition of success and failure. + */ + enum EStatus + { + // Processing occurred normally, future calls will be accepted. + STATUS_OK = 0, + + // Processing occured normally, but stop unsolicited calls to + // process. + STATUS_STOP = 1, + + // This pipe is done with the processing. Future calls to + // process will be accepted as long as new data is available. + STATUS_DONE = 2, + + // This pipe is requesting that it become the head in a process. + STATUS_BREAK = 3, + + // This pipe is requesting that it become the head in a process. + STATUS_NEED_PROCESS = 4, + + // Keep track of the highest number of success codes here. + STATUS_SUCCESS_COUNT = 5, + + // A generic error code. + STATUS_ERROR = -1, + + // This method has not yet been implemented. This usually + // indicates the programmer working on the pipe is not yet + // done. + STATUS_NOT_IMPLEMENTED = -2, + + // This indicates that a pipe precondition was not met. For + // example, many pipes require an element to appear after them + // in a chain (ie, mNext is not null) and will return this in + // response to method calls. To recover from this, it will + // require the caller to adjust the pipe state or may require + // a dev to adjust the code to satisfy the preconditions. + STATUS_PRECONDITION_NOT_MET = -3, + + // This means we could not connect to a remote host. + STATUS_NO_CONNECTION = -4, + + // The connection was lost. + STATUS_LOST_CONNECTION = -5, + + // The totoal process time has exceeded the timeout. + STATUS_EXPIRED = -6, + + // Keep track of the count of codes here. + STATUS_ERROR_COUNT = 6, + }; + + /** + * @brief Helper function to check status. + * + * When writing code to check status codes, if you do not + * specifically check a particular value, use this method for + * checking an error condition. + * @param status The status to check. + * @return Returns true if the code indicates an error occurred. + */ + inline static bool isError(EStatus status) + { + return ((S32)status < 0); + } + + /** + * @brief Helper function to check status. + * + * When writing code to check status codes, if you do not + * specifically check a particular value, use this method for + * checking an error condition. + * @param status The status to check. + * @return Returns true if the code indicates no error was generated. + */ + inline static bool isSuccess(EStatus status) + { + return ((S32)status >= 0); + } + + /** + * @brief Helper function to turn status into a string. + * + * @param status The status to check. + * @return Returns the name of the status code or empty string on failure. + */ + static std::string lookupStatusString(EStatus status); + + /** + * @brief Process the data in buffer. + * + * @param data The data processed + * @param eos True if this function call is the last because end of stream. + * @param pump The pump which is calling process. May be NULL. + * @param context Shared meta-data for the process. + * @return Returns a status code from the operation. + */ + EStatus process( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + + /** + * @brief Give this pipe a chance to handle a generated error + * + * If this pipe is in a chain being processed by a pump, and one + * of the pipes generates an error, the pump will rewind through + * the chain to see if any of the links can handle the error. For + * example, if a connection is refused in a socket connection, the + * socket client can try to find a new destination host. Return an + * error code if this pipe does not handle the error passed in. + * @param status The status code for the error + * @param pump The pump which was calling process before the error + * was generated. + * @return Returns a status code from the operation. Returns an + * error code if the error passed in was not handled. Returns + * STATUS_OK to indicate the error has been handled. + */ + virtual EStatus handleError(EStatus status, LLPumpIO* pump); + + /** + * @brief Base Destructor - do not call <code>delete</code> directly. + */ + virtual ~LLIOPipe(); + + virtual bool isValid() ; protected: - /** - * @brief Base Constructor. - */ - LLIOPipe(); - - /** - * @brief Process the data in buffer - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) = 0; + /** + * @brief Base Constructor. + */ + LLIOPipe(); + + /** + * @brief Process the data in buffer + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) = 0; private: - friend void intrusive_ptr_add_ref(LLIOPipe* p); - friend void intrusive_ptr_release(LLIOPipe* p); - U32 mReferenceCount; + friend void intrusive_ptr_add_ref(LLIOPipe* p); + friend void intrusive_ptr_release(LLIOPipe* p); + U32 mReferenceCount; }; inline void intrusive_ptr_add_ref(LLIOPipe* p) { - ++p->mReferenceCount; + ++p->mReferenceCount; } inline void intrusive_ptr_release(LLIOPipe* p) { - if(p && 0 == --p->mReferenceCount) - { - delete p; - } + if(p && 0 == --p->mReferenceCount) + { + delete p; + } } #endif // LL_LLIOPIPE_H diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 321d7286eb..a14d10fe5f 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliosocket.cpp * @author Phoenix * @date 2005-07-31 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -50,15 +50,15 @@ static const S32 LL_RECV_BUFFER_SIZE = 40000; //static const U16 LL_PORT_DISCOVERY_RANGE_MAX = 13050; // -// local methods +// local methods // bool is_addr_in_use(apr_status_t status) { #if LL_WINDOWS - return (WSAEADDRINUSE == APR_TO_OS_ERROR(status)); + return (WSAEADDRINUSE == APR_TO_OS_ERROR(status)); #else - return (EADDRINUSE == APR_TO_OS_ERROR(status)); + return (EADDRINUSE == APR_TO_OS_ERROR(status)); #endif } @@ -71,28 +71,28 @@ bool is_addr_in_use(apr_status_t status) #endif -// Quick function +// Quick function void ll_debug_socket(const char* msg, apr_socket_t* apr_sock) { #if LL_DEBUG_SOCKET_FILE_DESCRIPTORS - if(!apr_sock) - { - LL_DEBUGS("Socket") << "Socket -- " << (msg?msg:"") << ": no socket." << LL_ENDL; - return; - } - // *TODO: Why doesn't this work? - //apr_os_sock_t os_sock; - int os_sock; - if(APR_SUCCESS == apr_os_sock_get(&os_sock, apr_sock)) - { - LL_DEBUGS("Socket") << "Socket -- " << (msg?msg:"") << " on fd " << os_sock - << " at " << apr_sock << LL_ENDL; - } - else - { - LL_DEBUGS("Socket") << "Socket -- " << (msg?msg:"") << " no fd " - << " at " << apr_sock << LL_ENDL; - } + if(!apr_sock) + { + LL_DEBUGS("Socket") << "Socket -- " << (msg?msg:"") << ": no socket." << LL_ENDL; + return; + } + // *TODO: Why doesn't this work? + //apr_os_sock_t os_sock; + int os_sock; + if(APR_SUCCESS == apr_os_sock_get(&os_sock, apr_sock)) + { + LL_DEBUGS("Socket") << "Socket -- " << (msg?msg:"") << " on fd " << os_sock + << " at " << apr_sock << LL_ENDL; + } + else + { + LL_DEBUGS("Socket") << "Socket -- " << (msg?msg:"") << " no fd " + << " at " << apr_sock << LL_ENDL; + } #endif } @@ -103,162 +103,162 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock) // static LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port, const char *hostname) { - LLSocket::ptr_t rv; - apr_socket_t* socket = NULL; - apr_pool_t* new_pool = NULL; - apr_status_t status = APR_EGENERAL; - - // create a pool for the socket - status = apr_pool_create(&new_pool, pool); - if(ll_apr_warn_status(status)) - { - if(new_pool) apr_pool_destroy(new_pool); - return rv; - } - - if(STREAM_TCP == type) - { - status = apr_socket_create( - &socket, - APR_INET, - SOCK_STREAM, - APR_PROTO_TCP, - new_pool); - } - else if(DATAGRAM_UDP == type) - { - status = apr_socket_create( - &socket, - APR_INET, - SOCK_DGRAM, - APR_PROTO_UDP, - new_pool); - } - else - { - if(new_pool) apr_pool_destroy(new_pool); - return rv; - } - if(ll_apr_warn_status(status)) - { - if(new_pool) apr_pool_destroy(new_pool); - return rv; - } - // At this point, the new LLSocket instance takes ownership of new_pool, - // which is why no early return below this call explicitly destroys it: it - // is instead cleaned up by ~LLSocket(). - rv = ptr_t(new LLSocket(socket, new_pool)); - if(port > 0) - { - apr_sockaddr_t* sa = NULL; - status = apr_sockaddr_info_get( - &sa, - hostname, - APR_UNSPEC, - port, - 0, - new_pool); - if(ll_apr_warn_status(status)) - { - rv.reset(); - return rv; - } - // This allows us to reuse the address on quick down/up. This - // is unlikely to create problems. - ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); - status = apr_socket_bind(socket, sa); - if(ll_apr_warn_status(status)) - { - rv.reset(); - return rv; - } - LL_DEBUGS() << "Bound " << ((DATAGRAM_UDP == type) ? "udp" : "tcp") - << " socket to port: " << sa->port << LL_ENDL; - if(STREAM_TCP == type) - { - // If it's a stream based socket, we need to tell the OS - // to keep a queue of incoming connections for ACCEPT. - LL_DEBUGS() << "Setting listen state for socket." << LL_ENDL; - status = apr_socket_listen( - socket, - LL_DEFAULT_LISTEN_BACKLOG); - if(ll_apr_warn_status(status)) - { - rv.reset(); - return rv; - } - } - } - else // port <= 0 - { - // we need to indicate that we have an ephemeral port if the - // previous calls were successful. It will - port = PORT_EPHEMERAL; - } - rv->mPort = port; - rv->setNonBlocking(); - return rv; + LLSocket::ptr_t rv; + apr_socket_t* socket = NULL; + apr_pool_t* new_pool = NULL; + apr_status_t status = APR_EGENERAL; + + // create a pool for the socket + status = apr_pool_create(&new_pool, pool); + if(ll_apr_warn_status(status)) + { + if(new_pool) apr_pool_destroy(new_pool); + return rv; + } + + if(STREAM_TCP == type) + { + status = apr_socket_create( + &socket, + APR_INET, + SOCK_STREAM, + APR_PROTO_TCP, + new_pool); + } + else if(DATAGRAM_UDP == type) + { + status = apr_socket_create( + &socket, + APR_INET, + SOCK_DGRAM, + APR_PROTO_UDP, + new_pool); + } + else + { + if(new_pool) apr_pool_destroy(new_pool); + return rv; + } + if(ll_apr_warn_status(status)) + { + if(new_pool) apr_pool_destroy(new_pool); + return rv; + } + // At this point, the new LLSocket instance takes ownership of new_pool, + // which is why no early return below this call explicitly destroys it: it + // is instead cleaned up by ~LLSocket(). + rv = ptr_t(new LLSocket(socket, new_pool)); + if(port > 0) + { + apr_sockaddr_t* sa = NULL; + status = apr_sockaddr_info_get( + &sa, + hostname, + APR_UNSPEC, + port, + 0, + new_pool); + if(ll_apr_warn_status(status)) + { + rv.reset(); + return rv; + } + // This allows us to reuse the address on quick down/up. This + // is unlikely to create problems. + ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); + status = apr_socket_bind(socket, sa); + if(ll_apr_warn_status(status)) + { + rv.reset(); + return rv; + } + LL_DEBUGS() << "Bound " << ((DATAGRAM_UDP == type) ? "udp" : "tcp") + << " socket to port: " << sa->port << LL_ENDL; + if(STREAM_TCP == type) + { + // If it's a stream based socket, we need to tell the OS + // to keep a queue of incoming connections for ACCEPT. + LL_DEBUGS() << "Setting listen state for socket." << LL_ENDL; + status = apr_socket_listen( + socket, + LL_DEFAULT_LISTEN_BACKLOG); + if(ll_apr_warn_status(status)) + { + rv.reset(); + return rv; + } + } + } + else // port <= 0 + { + // we need to indicate that we have an ephemeral port if the + // previous calls were successful. It will + port = PORT_EPHEMERAL; + } + rv->mPort = port; + rv->setNonBlocking(); + return rv; } // static LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) { - LLSocket::ptr_t rv; - if(!socket) - { - return rv; - } - rv = ptr_t(new LLSocket(socket, pool)); - rv->mPort = PORT_EPHEMERAL; - rv->setNonBlocking(); - return rv; + LLSocket::ptr_t rv; + if(!socket) + { + return rv; + } + rv = ptr_t(new LLSocket(socket, pool)); + rv->mPort = PORT_EPHEMERAL; + rv->setNonBlocking(); + return rv; } bool LLSocket::blockingConnect(const LLHost& host) { - if(!mSocket) return false; - apr_sockaddr_t* sa = NULL; - std::string ip_address; - ip_address = host.getIPString(); - if(ll_apr_warn_status(apr_sockaddr_info_get( - &sa, - ip_address.c_str(), - APR_UNSPEC, - host.getPort(), - 0, - mPool))) - { - return false; - } - setBlocking(1000); - ll_debug_socket("Blocking connect", mSocket); - if(ll_apr_warn_status(apr_socket_connect(mSocket, sa))) return false; - setNonBlocking(); - return true; + if(!mSocket) return false; + apr_sockaddr_t* sa = NULL; + std::string ip_address; + ip_address = host.getIPString(); + if(ll_apr_warn_status(apr_sockaddr_info_get( + &sa, + ip_address.c_str(), + APR_UNSPEC, + host.getPort(), + 0, + mPool))) + { + return false; + } + setBlocking(1000); + ll_debug_socket("Blocking connect", mSocket); + if(ll_apr_warn_status(apr_socket_connect(mSocket, sa))) return false; + setNonBlocking(); + return true; } LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : - mSocket(socket), - mPool(pool), - mPort(PORT_INVALID) + mSocket(socket), + mPool(pool), + mPort(PORT_INVALID) { - ll_debug_socket("Constructing wholely formed socket", mSocket); + ll_debug_socket("Constructing wholely formed socket", mSocket); } LLSocket::~LLSocket() { - // *FIX: clean up memory we are holding. - if(mSocket) - { - ll_debug_socket("Destroying socket", mSocket); - apr_socket_close(mSocket); - mSocket = NULL; - } - if(mPool) - { - apr_pool_destroy(mPool); - } + // *FIX: clean up memory we are holding. + if(mSocket) + { + ll_debug_socket("Destroying socket", mSocket); + apr_socket_close(mSocket); + mSocket = NULL; + } + if(mPool) + { + apr_pool_destroy(mPool); + } } // See http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html#ss13.4 @@ -267,21 +267,21 @@ LLSocket::~LLSocket() void LLSocket::setBlocking(S32 timeout) { - // set up the socket options - ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); // Sets both receive and send timeout SO_RCVTIMEO, SO_SNDTIMEO - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); + // set up the socket options + ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); // Sets both receive and send timeout SO_RCVTIMEO, SO_SNDTIMEO + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); } void LLSocket::setNonBlocking() { - // set up the socket options - ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 1)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); + // set up the socket options + ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 1)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); } @@ -290,96 +290,96 @@ void LLSocket::setNonBlocking() /// LLIOSocketReader::LLIOSocketReader(LLSocket::ptr_t socket) : - mSource(socket), - mInitialized(false) + mSource(socket), + mInitialized(false) { } LLIOSocketReader::~LLIOSocketReader() { - //LL_DEBUGS() << "Destroying LLIOSocketReader" << LL_ENDL; + //LL_DEBUGS() << "Destroying LLIOSocketReader" << LL_ENDL; } // virtual LLIOPipe::EStatus LLIOSocketReader::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - if(!mSource) return STATUS_PRECONDITION_NOT_MET; - if(!mInitialized) - { - PUMP_DEBUG; - // Since the read will not block, it's ok to initialize and - // attempt to read off the descriptor immediately. - mInitialized = true; - if(pump) - { - PUMP_DEBUG; - LL_DEBUGS() << "Initializing poll descriptor for LLIOSocketReader." - << LL_ENDL; - apr_pollfd_t poll_fd; - poll_fd.p = NULL; - poll_fd.desc_type = APR_POLL_SOCKET; - poll_fd.reqevents = APR_POLLIN; - poll_fd.rtnevents = 0x0; - poll_fd.desc.s = mSource->getSocket(); - poll_fd.client_data = NULL; - pump->setConditional(this, &poll_fd); - } - } - //if(!buffer) - //{ - // buffer = new LLBufferArray; - //} - PUMP_DEBUG; - const apr_size_t READ_BUFFER_SIZE = 1024; - char read_buf[READ_BUFFER_SIZE]; /*Flawfinder: ignore*/ - apr_size_t len; - apr_status_t status = APR_SUCCESS; - do - { - PUMP_DEBUG; - len = READ_BUFFER_SIZE; - status = apr_socket_recv(mSource->getSocket(), read_buf, &len); - buffer->append(channels.out(), (U8*)read_buf, len); - } while((APR_SUCCESS == status) && (READ_BUFFER_SIZE == len)); - LL_DEBUGS() << "socket read status: " << status << LL_ENDL; - LLIOPipe::EStatus rv = STATUS_OK; - - PUMP_DEBUG; - // *FIX: Also need to check for broken pipe - if(APR_STATUS_IS_EOF(status)) - { - // *FIX: Should we shut down the socket read? - if(pump) - { - pump->setConditional(this, NULL); - } - rv = STATUS_DONE; - eos = true; - } - else if(APR_STATUS_IS_EAGAIN(status)) - { + PUMP_DEBUG; + if(!mSource) return STATUS_PRECONDITION_NOT_MET; + if(!mInitialized) + { + PUMP_DEBUG; + // Since the read will not block, it's ok to initialize and + // attempt to read off the descriptor immediately. + mInitialized = true; + if(pump) + { + PUMP_DEBUG; + LL_DEBUGS() << "Initializing poll descriptor for LLIOSocketReader." + << LL_ENDL; + apr_pollfd_t poll_fd; + poll_fd.p = NULL; + poll_fd.desc_type = APR_POLL_SOCKET; + poll_fd.reqevents = APR_POLLIN; + poll_fd.rtnevents = 0x0; + poll_fd.desc.s = mSource->getSocket(); + poll_fd.client_data = NULL; + pump->setConditional(this, &poll_fd); + } + } + //if(!buffer) + //{ + // buffer = new LLBufferArray; + //} + PUMP_DEBUG; + const apr_size_t READ_BUFFER_SIZE = 1024; + char read_buf[READ_BUFFER_SIZE]; /*Flawfinder: ignore*/ + apr_size_t len; + apr_status_t status = APR_SUCCESS; + do + { + PUMP_DEBUG; + len = READ_BUFFER_SIZE; + status = apr_socket_recv(mSource->getSocket(), read_buf, &len); + buffer->append(channels.out(), (U8*)read_buf, len); + } while((APR_SUCCESS == status) && (READ_BUFFER_SIZE == len)); + LL_DEBUGS() << "socket read status: " << status << LL_ENDL; + LLIOPipe::EStatus rv = STATUS_OK; + + PUMP_DEBUG; + // *FIX: Also need to check for broken pipe + if(APR_STATUS_IS_EOF(status)) + { + // *FIX: Should we shut down the socket read? + if(pump) + { + pump->setConditional(this, NULL); + } + rv = STATUS_DONE; + eos = true; + } + else if(APR_STATUS_IS_EAGAIN(status)) + { /*Commented out by Aura 9-9-8 for DEV-19961. - // everything is fine, but we can terminate this process pump. - - rv = STATUS_BREAK; + // everything is fine, but we can terminate this process pump. + + rv = STATUS_BREAK; */ - } - else - { - if(ll_apr_warn_status(status)) - { - rv = STATUS_ERROR; - } - } - PUMP_DEBUG; - return rv; + } + else + { + if(ll_apr_warn_status(status)) + { + rv = STATUS_ERROR; + } + } + PUMP_DEBUG; + return rv; } /// @@ -387,143 +387,143 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl( /// LLIOSocketWriter::LLIOSocketWriter(LLSocket::ptr_t socket) : - mDestination(socket), - mLastWritten(NULL), - mInitialized(false) + mDestination(socket), + mLastWritten(NULL), + mInitialized(false) { } LLIOSocketWriter::~LLIOSocketWriter() { - //LL_DEBUGS() << "Destroying LLIOSocketWriter" << LL_ENDL; + //LL_DEBUGS() << "Destroying LLIOSocketWriter" << LL_ENDL; } // virtual LLIOPipe::EStatus LLIOSocketWriter::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - if(!mDestination) return STATUS_PRECONDITION_NOT_MET; - if(!mInitialized) - { - PUMP_DEBUG; - // Since the write will not block, it's ok to initialize and - // attempt to write immediately. - mInitialized = true; - if(pump) - { - PUMP_DEBUG; - LL_DEBUGS() << "Initializing poll descriptor for LLIOSocketWriter." - << LL_ENDL; - apr_pollfd_t poll_fd; - poll_fd.p = NULL; - poll_fd.desc_type = APR_POLL_SOCKET; - poll_fd.reqevents = APR_POLLOUT; - poll_fd.rtnevents = 0x0; - poll_fd.desc.s = mDestination->getSocket(); - poll_fd.client_data = NULL; - pump->setConditional(this, &poll_fd); - } - } - - PUMP_DEBUG; - // *FIX: Some sort of writev implementation would be much more - // efficient - not only because writev() is better, but also - // because we won't have to do as much work to find the start - // address. - buffer->lock(); - LLBufferArray::segment_iterator_t it; - LLBufferArray::segment_iterator_t end = buffer->endSegment(); - LLSegment segment; - it = buffer->constructSegmentAfter(mLastWritten, segment); - /* - if(NULL == mLastWritten) - { - it = buffer->beginSegment(); - segment = (*it); - } - else - { - it = buffer->getSegment(mLastWritten); - segment = (*it); - S32 size = segment.size(); - U8* data = segment.data(); - if((data + size) == mLastWritten) - { - ++it; - segment = (*it); - } - else - { - // *FIX: check the math on this one - segment = LLSegment( - (*it).getChannelMask(), - mLastWritten + 1, - size - (mLastWritten - data)); - } - } - */ - - PUMP_DEBUG; - apr_size_t len; - bool done = false; - apr_status_t status = APR_SUCCESS; - while(it != end) - { - - PUMP_DEBUG; - if((*it).isOnChannel(channels.in())) - { - PUMP_DEBUG; - len = (apr_size_t)segment.size(); - status = apr_socket_send( - mDestination->getSocket(), - (const char*)segment.data(), - &len); - // We sometimes get a 'non-blocking socket operation could not be - // completed immediately' error from apr_socket_send. In this - // case we break and the data will be sent the next time the chain - // is pumped. - if(APR_STATUS_IS_EAGAIN(status)) - { - ll_apr_warn_status(status); - break; - } - - mLastWritten = segment.data() + len - 1; - - PUMP_DEBUG; - if((S32)len < segment.size()) - { - break; - } - - } - - ++it; - if(it != end) - { - segment = (*it); - } - else - { - done = true; - } - - } - buffer->unlock(); - - PUMP_DEBUG; - if(done && eos) - { - return STATUS_DONE; - } - return STATUS_OK; + PUMP_DEBUG; + if(!mDestination) return STATUS_PRECONDITION_NOT_MET; + if(!mInitialized) + { + PUMP_DEBUG; + // Since the write will not block, it's ok to initialize and + // attempt to write immediately. + mInitialized = true; + if(pump) + { + PUMP_DEBUG; + LL_DEBUGS() << "Initializing poll descriptor for LLIOSocketWriter." + << LL_ENDL; + apr_pollfd_t poll_fd; + poll_fd.p = NULL; + poll_fd.desc_type = APR_POLL_SOCKET; + poll_fd.reqevents = APR_POLLOUT; + poll_fd.rtnevents = 0x0; + poll_fd.desc.s = mDestination->getSocket(); + poll_fd.client_data = NULL; + pump->setConditional(this, &poll_fd); + } + } + + PUMP_DEBUG; + // *FIX: Some sort of writev implementation would be much more + // efficient - not only because writev() is better, but also + // because we won't have to do as much work to find the start + // address. + buffer->lock(); + LLBufferArray::segment_iterator_t it; + LLBufferArray::segment_iterator_t end = buffer->endSegment(); + LLSegment segment; + it = buffer->constructSegmentAfter(mLastWritten, segment); + /* + if(NULL == mLastWritten) + { + it = buffer->beginSegment(); + segment = (*it); + } + else + { + it = buffer->getSegment(mLastWritten); + segment = (*it); + S32 size = segment.size(); + U8* data = segment.data(); + if((data + size) == mLastWritten) + { + ++it; + segment = (*it); + } + else + { + // *FIX: check the math on this one + segment = LLSegment( + (*it).getChannelMask(), + mLastWritten + 1, + size - (mLastWritten - data)); + } + } + */ + + PUMP_DEBUG; + apr_size_t len; + bool done = false; + apr_status_t status = APR_SUCCESS; + while(it != end) + { + + PUMP_DEBUG; + if((*it).isOnChannel(channels.in())) + { + PUMP_DEBUG; + len = (apr_size_t)segment.size(); + status = apr_socket_send( + mDestination->getSocket(), + (const char*)segment.data(), + &len); + // We sometimes get a 'non-blocking socket operation could not be + // completed immediately' error from apr_socket_send. In this + // case we break and the data will be sent the next time the chain + // is pumped. + if(APR_STATUS_IS_EAGAIN(status)) + { + ll_apr_warn_status(status); + break; + } + + mLastWritten = segment.data() + len - 1; + + PUMP_DEBUG; + if((S32)len < segment.size()) + { + break; + } + + } + + ++it; + if(it != end) + { + segment = (*it); + } + else + { + done = true; + } + + } + buffer->unlock(); + + PUMP_DEBUG; + if(done && eos) + { + return STATUS_DONE; + } + return STATUS_OK; } @@ -532,166 +532,166 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( /// LLIOServerSocket::LLIOServerSocket( - apr_pool_t* pool, - LLIOServerSocket::socket_t listener, - factory_t factory) : - mPool(pool), - mListenSocket(listener), - mReactor(factory), - mInitialized(false), - mResponseTimeout(DEFAULT_CHAIN_EXPIRY_SECS) + apr_pool_t* pool, + LLIOServerSocket::socket_t listener, + factory_t factory) : + mPool(pool), + mListenSocket(listener), + mReactor(factory), + mInitialized(false), + mResponseTimeout(DEFAULT_CHAIN_EXPIRY_SECS) { } LLIOServerSocket::~LLIOServerSocket() { - //LL_DEBUGS() << "Destroying LLIOServerSocket" << LL_ENDL; + //LL_DEBUGS() << "Destroying LLIOServerSocket" << LL_ENDL; } void LLIOServerSocket::setResponseTimeout(F32 timeout_secs) { - mResponseTimeout = timeout_secs; + mResponseTimeout = timeout_secs; } // virtual LLIOPipe::EStatus LLIOServerSocket::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - PUMP_DEBUG; - if(!pump) - { - LL_WARNS() << "Need a pump for server socket." << LL_ENDL; - return STATUS_ERROR; - } - if(!mInitialized) - { - PUMP_DEBUG; - // This segment sets up the pump so that we do not call - // process again until we have an incoming read, aka connect() - // from a remote host. - LL_DEBUGS() << "Initializing poll descriptor for LLIOServerSocket." - << LL_ENDL; - apr_pollfd_t poll_fd; - poll_fd.p = NULL; - poll_fd.desc_type = APR_POLL_SOCKET; - poll_fd.reqevents = APR_POLLIN; - poll_fd.rtnevents = 0x0; - poll_fd.desc.s = mListenSocket->getSocket(); - poll_fd.client_data = NULL; - pump->setConditional(this, &poll_fd); - mInitialized = true; - return STATUS_OK; - } - - // we are initialized, and told to process, so we must have a - // socket waiting for a connection. - LL_DEBUGS() << "accepting socket" << LL_ENDL; - - PUMP_DEBUG; - apr_pool_t* new_pool = NULL; - apr_status_t status = apr_pool_create(&new_pool, mPool); - if(ll_apr_warn_status(status)) - { - if(new_pool) - { - apr_pool_destroy(new_pool); - } - return STATUS_ERROR; - } - - apr_socket_t* socket = NULL; - status = apr_socket_accept( - &socket, - mListenSocket->getSocket(), - new_pool); - LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool)); - //EStatus rv = STATUS_ERROR; - if(llsocket) - { - PUMP_DEBUG; - - apr_sockaddr_t* remote_addr; - apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); - - char* remote_host_string; - apr_sockaddr_ip_get(&remote_host_string, remote_addr); - - LLSD context; - context[CONTEXT_REMOTE_HOST] = remote_host_string; - context[CONTEXT_REMOTE_PORT] = remote_addr->port; - - LLPumpIO::chain_t chain; - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(llsocket))); - if(mReactor->build(chain, context)) - { - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); - pump->addChain(chain, mResponseTimeout); - status = STATUS_OK; - } - else - { - LL_WARNS() << "Unable to build reactor to socket." << LL_ENDL; - } - } - else - { - LL_WARNS() << "Unable to create linden socket." << LL_ENDL; - } - - PUMP_DEBUG; - // This needs to always return success, lest it get removed from - // the pump. - return STATUS_OK; + PUMP_DEBUG; + if(!pump) + { + LL_WARNS() << "Need a pump for server socket." << LL_ENDL; + return STATUS_ERROR; + } + if(!mInitialized) + { + PUMP_DEBUG; + // This segment sets up the pump so that we do not call + // process again until we have an incoming read, aka connect() + // from a remote host. + LL_DEBUGS() << "Initializing poll descriptor for LLIOServerSocket." + << LL_ENDL; + apr_pollfd_t poll_fd; + poll_fd.p = NULL; + poll_fd.desc_type = APR_POLL_SOCKET; + poll_fd.reqevents = APR_POLLIN; + poll_fd.rtnevents = 0x0; + poll_fd.desc.s = mListenSocket->getSocket(); + poll_fd.client_data = NULL; + pump->setConditional(this, &poll_fd); + mInitialized = true; + return STATUS_OK; + } + + // we are initialized, and told to process, so we must have a + // socket waiting for a connection. + LL_DEBUGS() << "accepting socket" << LL_ENDL; + + PUMP_DEBUG; + apr_pool_t* new_pool = NULL; + apr_status_t status = apr_pool_create(&new_pool, mPool); + if(ll_apr_warn_status(status)) + { + if(new_pool) + { + apr_pool_destroy(new_pool); + } + return STATUS_ERROR; + } + + apr_socket_t* socket = NULL; + status = apr_socket_accept( + &socket, + mListenSocket->getSocket(), + new_pool); + LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool)); + //EStatus rv = STATUS_ERROR; + if(llsocket) + { + PUMP_DEBUG; + + apr_sockaddr_t* remote_addr; + apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); + + char* remote_host_string; + apr_sockaddr_ip_get(&remote_host_string, remote_addr); + + LLSD context; + context[CONTEXT_REMOTE_HOST] = remote_host_string; + context[CONTEXT_REMOTE_PORT] = remote_addr->port; + + LLPumpIO::chain_t chain; + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(llsocket))); + if(mReactor->build(chain, context)) + { + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); + pump->addChain(chain, mResponseTimeout); + status = STATUS_OK; + } + else + { + LL_WARNS() << "Unable to build reactor to socket." << LL_ENDL; + } + } + else + { + LL_WARNS() << "Unable to create linden socket." << LL_ENDL; + } + + PUMP_DEBUG; + // This needs to always return success, lest it get removed from + // the pump. + return STATUS_OK; } #if 0 LLIODataSocket::LLIODataSocket( - U16 suggested_port, - U16 start_discovery_port, - apr_pool_t* pool) : - mSocket(NULL) + U16 suggested_port, + U16 start_discovery_port, + apr_pool_t* pool) : + mSocket(NULL) { - if(!pool || (PORT_INVALID == suggested_port)) return; - if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; - apr_sockaddr_t* sa = NULL; - if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; - apr_status_t status = apr_socket_bind(mSocket, sa); - if((start_discovery_port > 0) && is_addr_in_use(status)) - { - const U16 MAX_ATTEMPT_PORTS = 50; - for(U16 attempt_port = start_discovery_port; - attempt_port < (start_discovery_port + MAX_ATTEMPT_PORTS); - ++attempt_port) - { - sa->port = attempt_port; - sa->sa.sin.sin_port = htons(attempt_port); - status = apr_socket_bind(mSocket, sa); - if(APR_SUCCESS == status) break; - if(is_addr_in_use(status)) continue; - (void)ll_apr_warn_status(status); - } - } - if(ll_apr_warn_status(status)) return; - if(sa->port) - { - LL_DEBUGS() << "Bound datagram socket to port: " << sa->port << LL_ENDL; - mPort = sa->port; - } - else - { - mPort = LLIOSocket::PORT_EPHEMERAL; - } - - // set up the socket options options - ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); - ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); + if(!pool || (PORT_INVALID == suggested_port)) return; + if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; + apr_sockaddr_t* sa = NULL; + if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; + apr_status_t status = apr_socket_bind(mSocket, sa); + if((start_discovery_port > 0) && is_addr_in_use(status)) + { + const U16 MAX_ATTEMPT_PORTS = 50; + for(U16 attempt_port = start_discovery_port; + attempt_port < (start_discovery_port + MAX_ATTEMPT_PORTS); + ++attempt_port) + { + sa->port = attempt_port; + sa->sa.sin.sin_port = htons(attempt_port); + status = apr_socket_bind(mSocket, sa); + if(APR_SUCCESS == status) break; + if(is_addr_in_use(status)) continue; + (void)ll_apr_warn_status(status); + } + } + if(ll_apr_warn_status(status)) return; + if(sa->port) + { + LL_DEBUGS() << "Bound datagram socket to port: " << sa->port << LL_ENDL; + mPort = sa->port; + } + else + { + mPort = LLIOSocket::PORT_EPHEMERAL; + } + + // set up the socket options options + ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); + ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); } LLIODataSocket::~LLIODataSocket() diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h index a62b3c0204..0a3f2617e6 100644 --- a/indra/llmessage/lliosocket.h +++ b/indra/llmessage/lliosocket.h @@ -1,4 +1,4 @@ -/** +/** * @file lliosocket.h * @author Phoenix * @date 2005-07-31 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,7 +29,7 @@ #ifndef LL_LLIOSOCKET_H #define LL_LLIOSOCKET_H -/** +/** * The socket interface provided here is a simple wraper around apr * sockets, with a pipe source and sink to read and write off of the * socket. Every socket only performs non-blocking operations except @@ -48,7 +48,7 @@ extern const std::string CONTEXT_REMOTE_PORT; class LLHost; -/** +/** * @class LLSocket * @brief Implementation of a wrapper around a socket. * @@ -62,134 +62,134 @@ class LLHost; class LLSocket { public: - /** - * @brief Reference counted shared pointers to sockets. - */ - typedef std::shared_ptr<LLSocket> ptr_t; - - /** - * @brief Type of socket to create. - */ - enum EType - { - STREAM_TCP, - DATAGRAM_UDP, - }; - - /** - * @brief Anonymous enumeration to help identify ports - */ - enum - { - PORT_INVALID = (U16)-1, - PORT_EPHEMERAL = 0, - }; - - /** - * @brief Create a socket. - * - * This is the call you would use if you intend to create a listen - * socket. If you intend the socket to be known to external - * clients without prior port notification, do not use - * PORT_EPHEMERAL. - * @param pool The apr pool to use. A child pool will be created - * and associated with the socket. - * @param type The type of socket to create - * @param port The port for the socket - * @param hostname e.g. APR_ANYADDR to listen openly, or "127.0.0.1" - * @return A valid socket shared pointer if the call worked. - */ - static ptr_t create( - apr_pool_t* pool, - EType type, - U16 port = PORT_EPHEMERAL, - const char *hostname = APR_ANYADDR); - - /** - * @brief Create a LLSocket when you already have an apr socket. - * - * This method assumes an ephemeral port. This is typically used - * by calls which spawn a socket such as a call to - * <code>accept()</code> as in the server socket. This call should - * not fail if you have a valid apr socket. - * Because of the nature of how accept() works, you are expected - * to create a new pool for the socket, use that pool for the - * accept, and pass it in here where it will be bound with the - * socket and destroyed at the same time. - * @param socket The apr socket to use - * @param pool The pool used to create the socket. *NOTE: The pool - * passed in will be DESTROYED. - * @return A valid socket shared pointer if the call worked. - */ - static ptr_t create(apr_socket_t* socket, apr_pool_t* pool); - - /** - * @brief Perform a blocking connect to a host. Do not use in production. - * - * @param host The host to connect this socket to. - * @return Returns true if the connect was successful. - */ - bool blockingConnect(const LLHost& host); - - /** - * @brief Get the type of socket - */ - //EType getType() const { return mType; } - - /** - * @brief Get the port. - * - * This will return PORT_EPHEMERAL if bind was never called. - * @return Returns the port associated with this socket. - */ - U16 getPort() const { return mPort; } - - /** - * @brief Get the apr socket implementation. - * - * @return Returns the raw apr socket. - */ - apr_socket_t* getSocket() const { return mSocket; } - - /** - * @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us. - * @param timeout Number of microseconds to wait on this socket. Any - * negative number means block-forever. TIMEOUT OF 0 IS NON-PORTABLE. - */ - void setBlocking(S32 timeout); - - /** - * @brief Set default socket options, with SO_NONBLOCK = 1 and timeout = 0. - */ - void setNonBlocking(); + /** + * @brief Reference counted shared pointers to sockets. + */ + typedef std::shared_ptr<LLSocket> ptr_t; + + /** + * @brief Type of socket to create. + */ + enum EType + { + STREAM_TCP, + DATAGRAM_UDP, + }; + + /** + * @brief Anonymous enumeration to help identify ports + */ + enum + { + PORT_INVALID = (U16)-1, + PORT_EPHEMERAL = 0, + }; + + /** + * @brief Create a socket. + * + * This is the call you would use if you intend to create a listen + * socket. If you intend the socket to be known to external + * clients without prior port notification, do not use + * PORT_EPHEMERAL. + * @param pool The apr pool to use. A child pool will be created + * and associated with the socket. + * @param type The type of socket to create + * @param port The port for the socket + * @param hostname e.g. APR_ANYADDR to listen openly, or "127.0.0.1" + * @return A valid socket shared pointer if the call worked. + */ + static ptr_t create( + apr_pool_t* pool, + EType type, + U16 port = PORT_EPHEMERAL, + const char *hostname = APR_ANYADDR); + + /** + * @brief Create a LLSocket when you already have an apr socket. + * + * This method assumes an ephemeral port. This is typically used + * by calls which spawn a socket such as a call to + * <code>accept()</code> as in the server socket. This call should + * not fail if you have a valid apr socket. + * Because of the nature of how accept() works, you are expected + * to create a new pool for the socket, use that pool for the + * accept, and pass it in here where it will be bound with the + * socket and destroyed at the same time. + * @param socket The apr socket to use + * @param pool The pool used to create the socket. *NOTE: The pool + * passed in will be DESTROYED. + * @return A valid socket shared pointer if the call worked. + */ + static ptr_t create(apr_socket_t* socket, apr_pool_t* pool); + + /** + * @brief Perform a blocking connect to a host. Do not use in production. + * + * @param host The host to connect this socket to. + * @return Returns true if the connect was successful. + */ + bool blockingConnect(const LLHost& host); + + /** + * @brief Get the type of socket + */ + //EType getType() const { return mType; } + + /** + * @brief Get the port. + * + * This will return PORT_EPHEMERAL if bind was never called. + * @return Returns the port associated with this socket. + */ + U16 getPort() const { return mPort; } + + /** + * @brief Get the apr socket implementation. + * + * @return Returns the raw apr socket. + */ + apr_socket_t* getSocket() const { return mSocket; } + + /** + * @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us. + * @param timeout Number of microseconds to wait on this socket. Any + * negative number means block-forever. TIMEOUT OF 0 IS NON-PORTABLE. + */ + void setBlocking(S32 timeout); + + /** + * @brief Set default socket options, with SO_NONBLOCK = 1 and timeout = 0. + */ + void setNonBlocking(); protected: - /** - * @brief Protected constructor since should only make sockets - * with one of the two <code>create()</code> calls. - */ - LLSocket(apr_socket_t* socket, apr_pool_t* pool); + /** + * @brief Protected constructor since should only make sockets + * with one of the two <code>create()</code> calls. + */ + LLSocket(apr_socket_t* socket, apr_pool_t* pool); public: - /** - * @brief Do not call this directly. - */ - ~LLSocket(); + /** + * @brief Do not call this directly. + */ + ~LLSocket(); protected: - // The apr socket. - apr_socket_t* mSocket; + // The apr socket. + apr_socket_t* mSocket; - // our memory pool - apr_pool_t* mPool; + // our memory pool + apr_pool_t* mPool; - // The port if we know it. - U16 mPort; + // The port if we know it. + U16 mPort; - //EType mType; + //EType mType; }; -/** +/** * @class LLIOSocketReader * @brief An LLIOPipe implementation which reads from a socket. * @see LLIOPipe @@ -201,44 +201,44 @@ protected: class LLIOSocketReader : public LLIOPipe { public: - LLIOSocketReader(LLSocket::ptr_t socket); - ~LLIOSocketReader(); + LLIOSocketReader(LLSocket::ptr_t socket); + ~LLIOSocketReader(); protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Process the data coming in the socket. - * - * Since the socket and next pipe must exist for process to make - * any sense, this method will return STATUS_PRECONDITION_NOT_MET - * unless if they are not known. - * If a STATUS_STOP returned by the next link in the chain, this - * reader will turn of the socket polling. - * @param buffer Pointer to a buffer which needs processing. Probably NULL. - * @param bytes Number of bytes to in buffer to process. Probably 0. - * @param eos True if this function is the last. Almost always false. - * @param read Number of bytes actually processed. - * @param pump The pump which is calling process. May be NULL. - * @param context A data structure to pass structured data - * @return STATUS_OK unless the preconditions are not met. - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Process the data coming in the socket. + * + * Since the socket and next pipe must exist for process to make + * any sense, this method will return STATUS_PRECONDITION_NOT_MET + * unless if they are not known. + * If a STATUS_STOP returned by the next link in the chain, this + * reader will turn of the socket polling. + * @param buffer Pointer to a buffer which needs processing. Probably NULL. + * @param bytes Number of bytes to in buffer to process. Probably 0. + * @param eos True if this function is the last. Almost always false. + * @param read Number of bytes actually processed. + * @param pump The pump which is calling process. May be NULL. + * @param context A data structure to pass structured data + * @return STATUS_OK unless the preconditions are not met. + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - LLSocket::ptr_t mSource; - std::vector<U8> mBuffer; - bool mInitialized; + LLSocket::ptr_t mSource; + std::vector<U8> mBuffer; + bool mInitialized; }; -/** +/** * @class LLIOSocketWriter * @brief An LLIOPipe implementation which writes to a socket * @see LLIOPipe @@ -249,42 +249,42 @@ protected: class LLIOSocketWriter : public LLIOPipe { public: - LLIOSocketWriter(LLSocket::ptr_t socket); - ~LLIOSocketWriter(); + LLIOSocketWriter(LLSocket::ptr_t socket); + ~LLIOSocketWriter(); protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Write the data in buffer to the socket. - * - * Since the socket pipe must exist for process to make any sense, - * this method will return STATUS_PRECONDITION_NOT_MET if it is - * not known. - * @param buffer Pointer to a buffer which needs processing. - * @param bytes Number of bytes to in buffer to process. - * @param eos True if this function is the last. - * @param read Number of bytes actually processed. - * @param pump The pump which is calling process. May be NULL. - * @param context A data structure to pass structured data - * @return A return code for the write. - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Write the data in buffer to the socket. + * + * Since the socket pipe must exist for process to make any sense, + * this method will return STATUS_PRECONDITION_NOT_MET if it is + * not known. + * @param buffer Pointer to a buffer which needs processing. + * @param bytes Number of bytes to in buffer to process. + * @param eos True if this function is the last. + * @param read Number of bytes actually processed. + * @param pump The pump which is calling process. May be NULL. + * @param context A data structure to pass structured data + * @return A return code for the write. + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - LLSocket::ptr_t mDestination; - U8* mLastWritten; - bool mInitialized; + LLSocket::ptr_t mDestination; + U8* mLastWritten; + bool mInitialized; }; -/** +/** * @class LLIOServerSocket * @brief An IOPipe implementation which listens and spawns connected * sockets. @@ -304,49 +304,49 @@ protected: class LLIOServerSocket : public LLIOPipe { public: - typedef LLSocket::ptr_t socket_t; - typedef std::shared_ptr<LLChainIOFactory> factory_t; - LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor); - virtual ~LLIOServerSocket(); - - /** - * @brief Set the timeout for the generated chains. - * - * This value is passed directly to the LLPumpIO::addChain() - * method. The default on construction is set to - * DEFAULT_CHAIN_EXPIRY_SECS which is a reasonable value for most - * applications based on this library. Avoid passing in - * NEVER_CHAIN_EXPIRY_SECS unless you have another method of - * harvesting chains. - * @param timeout_secs The seconds before timeout for the response chain. - */ - void setResponseTimeout(F32 timeout_secs); - - /* @name LLIOPipe virtual implementations - */ - //@{ + typedef LLSocket::ptr_t socket_t; + typedef std::shared_ptr<LLChainIOFactory> factory_t; + LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor); + virtual ~LLIOServerSocket(); + + /** + * @brief Set the timeout for the generated chains. + * + * This value is passed directly to the LLPumpIO::addChain() + * method. The default on construction is set to + * DEFAULT_CHAIN_EXPIRY_SECS which is a reasonable value for most + * applications based on this library. Avoid passing in + * NEVER_CHAIN_EXPIRY_SECS unless you have another method of + * harvesting chains. + * @param timeout_secs The seconds before timeout for the response chain. + */ + void setResponseTimeout(F32 timeout_secs); + + /* @name LLIOPipe virtual implementations + */ + //@{ protected: - /** - * @brief Process the data in buffer - */ - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /** + * @brief Process the data in buffer + */ + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - apr_pool_t* mPool; - socket_t mListenSocket; - factory_t mReactor; - bool mInitialized; - F32 mResponseTimeout; + apr_pool_t* mPool; + socket_t mListenSocket; + factory_t mReactor; + bool mInitialized; + F32 mResponseTimeout; }; #if 0 -/** +/** * @class LLIODataSocket * @brief BRIEF_DESC * @@ -355,31 +355,31 @@ protected: class LLIODataSocket : public LLIOSocket { public: - /** - * @brief Construct a datagram socket. - * - * If you pass in LLIOSocket::PORT_EPHEMERAL as the suggested - * port, The socket will not be in a 'listen' mode, but can still - * read data sent back to it's port. When suggested_port is not - * ephemeral or invalid and bind fails, the port discovery - * algorithm will search through a limited set of ports to - * try to find an open port. If that process fails, getPort() will - * return LLIOSocket::PORT_INVALID - * @param suggested_port The port you would like to bind. Use - * LLIOSocket::PORT_EPHEMERAL for an unspecified port. - * @param start_discovery_port The start range for - * @param pool The pool to use for allocation. - */ - LLIODataSocket( - U16 suggested_port, - U16 start_discovery_port, - apr_pool_t* pool); - virtual ~LLIODataSocket(); + /** + * @brief Construct a datagram socket. + * + * If you pass in LLIOSocket::PORT_EPHEMERAL as the suggested + * port, The socket will not be in a 'listen' mode, but can still + * read data sent back to it's port. When suggested_port is not + * ephemeral or invalid and bind fails, the port discovery + * algorithm will search through a limited set of ports to + * try to find an open port. If that process fails, getPort() will + * return LLIOSocket::PORT_INVALID + * @param suggested_port The port you would like to bind. Use + * LLIOSocket::PORT_EPHEMERAL for an unspecified port. + * @param start_discovery_port The start range for + * @param pool The pool to use for allocation. + */ + LLIODataSocket( + U16 suggested_port, + U16 start_discovery_port, + apr_pool_t* pool); + virtual ~LLIODataSocket(); protected: private: - apr_socket_t* mSocket; + apr_socket_t* mSocket; }; #endif diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp index 850bc2a616..a1bf6332b4 100644 --- a/indra/llmessage/llioutil.cpp +++ b/indra/llmessage/llioutil.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llioutil.cpp * @author Phoenix * @date 2005-10-05 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,65 +34,65 @@ * LLIOFlush */ LLIOPipe::EStatus LLIOFlush::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - eos = true; - return STATUS_OK; + eos = true; + return STATUS_OK; } -/** +/** * @class LLIOSleep */ LLIOPipe::EStatus LLIOSleep::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - if(mSeconds > 0.0) - { - if(pump) pump->sleepChain(mSeconds); - mSeconds = 0.0; - return STATUS_BREAK; - } - return STATUS_DONE; + if(mSeconds > 0.0) + { + if(pump) pump->sleepChain(mSeconds); + mSeconds = 0.0; + return STATUS_BREAK; + } + return STATUS_DONE; } -/** +/** * @class LLIOAddChain */ LLIOPipe::EStatus LLIOAddChain::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { LL_PROFILE_ZONE_SCOPED; - pump->addChain(mChain, mTimeout); - return STATUS_DONE; + pump->addChain(mChain, mTimeout); + return STATUS_DONE; } /** * LLChangeChannel */ LLChangeChannel::LLChangeChannel(S32 is, S32 becomes) : - mIs(is), - mBecomes(becomes) + mIs(is), + mBecomes(becomes) { } void LLChangeChannel::operator()(LLSegment& segment) { - if(segment.isOnChannel(mIs)) - { - segment.setChannel(mBecomes); - } + if(segment.isOnChannel(mIs)) + { + segment.setChannel(mBecomes); + } } diff --git a/indra/llmessage/llioutil.h b/indra/llmessage/llioutil.h index c404a98bed..b6a4a9242f 100644 --- a/indra/llmessage/llioutil.h +++ b/indra/llmessage/llioutil.h @@ -1,4 +1,4 @@ -/** +/** * @file llioutil.h * @author Phoenix * @date 2005-10-05 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,7 +33,7 @@ #include "lliopipe.h" #include "llpumpio.h" -/** +/** * @class LLIOFlush * @brief This class is used as a mini chain head which drains the buffer. * @see LLIOPipe @@ -44,27 +44,27 @@ class LLIOFlush : public LLIOPipe { public: - LLIOFlush() {} - virtual ~LLIOFlush() {} + LLIOFlush() {} + virtual ~LLIOFlush() {} protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Process the data in buffer - */ - EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Process the data in buffer + */ + EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: }; -/** +/** * @class LLIOSleep * @brief This is a simple helper class which will hold a chain and * process it later using pump mechanisms @@ -73,28 +73,28 @@ protected: class LLIOSleep : public LLIOPipe { public: - LLIOSleep(F64 sleep_seconds) : mSeconds(sleep_seconds) {} - virtual ~LLIOSleep() {} + LLIOSleep(F64 sleep_seconds) : mSeconds(sleep_seconds) {} + virtual ~LLIOSleep() {} protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Process the data in buffer - */ - EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Process the data in buffer + */ + EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - F64 mSeconds; + F64 mSeconds; }; -/** +/** * @class LLIOAddChain * @brief Simple pipe that just adds a chain to a pump. * @see LLIOPipe @@ -102,33 +102,33 @@ protected: class LLIOAddChain : public LLIOPipe { public: - LLIOAddChain(const LLPumpIO::chain_t& chain, F32 timeout) : - mChain(chain), - mTimeout(timeout) - {} - virtual ~LLIOAddChain() {} + LLIOAddChain(const LLPumpIO::chain_t& chain, F32 timeout) : + mChain(chain), + mTimeout(timeout) + {} + virtual ~LLIOAddChain() {} protected: - /* @name LLIOPipe virtual implementations - */ - //@{ - /** - * @brief Process the data in buffer - */ - EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); - //@} + /* @name LLIOPipe virtual implementations + */ + //@{ + /** + * @brief Process the data in buffer + */ + EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); + //@} protected: - LLPumpIO::chain_t mChain; - F32 mTimeout; + LLPumpIO::chain_t mChain; + F32 mTimeout; }; -/** +/** * @class LLChangeChannel * @brief This class changes the channel of segments in the buffer * @see LLBufferArray @@ -150,22 +150,22 @@ protected: class LLChangeChannel { public: - /** - * @brief Constructor for iterating over a segment range to change channel. - * - * @param is The channel to match when looking at a segment. - * @param becomes The channel to set the segment when a match is found. - */ - LLChangeChannel(S32 is, S32 becomes); + /** + * @brief Constructor for iterating over a segment range to change channel. + * + * @param is The channel to match when looking at a segment. + * @param becomes The channel to set the segment when a match is found. + */ + LLChangeChannel(S32 is, S32 becomes); - /** - * @brief Do the work of changing the channel - */ - void operator()(LLSegment& segment); + /** + * @brief Do the work of changing the channel + */ + void operator()(LLSegment& segment); protected: - S32 mIs; - S32 mBecomes; + S32 mIs; + S32 mBecomes; }; diff --git a/indra/llmessage/llloginflags.h b/indra/llmessage/llloginflags.h index 45833fc914..a4d709888c 100644 --- a/indra/llmessage/llloginflags.h +++ b/indra/llmessage/llloginflags.h @@ -1,25 +1,25 @@ -/** +/** * @file llloginflags.h * @brief Login flag constants. * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,20 +28,20 @@ #define LL_LLLOGINFLAGS_H // Is this your first login to Second Life? -const U32 LOGIN_FLAG_FIRST_LOGIN = (1 << 0); +const U32 LOGIN_FLAG_FIRST_LOGIN = (1 << 0); // Is this a trial account? -const U32 LOGIN_FLAG_TRIAL = (1 << 1); +const U32 LOGIN_FLAG_TRIAL = (1 << 1); // Stipend paid since last login? -const U32 LOGIN_FLAG_STIPEND_SINCE_LOGIN = (1 << 2); +const U32 LOGIN_FLAG_STIPEND_SINCE_LOGIN = (1 << 2); // Is your account enabled? -const U32 LOGIN_FLAG_ENABLED = (1 << 3); +const U32 LOGIN_FLAG_ENABLED = (1 << 3); // Is the Pacific Time zone (aka the server time zone) // currently observing daylight savings time? -const U32 LOGIN_FLAG_PACIFIC_DAYLIGHT_TIME = (1 << 4); +const U32 LOGIN_FLAG_PACIFIC_DAYLIGHT_TIME = (1 << 4); // Does the avatar have wearables or not const U32 LOGIN_FLAG_GENDERED = (1 << 5); diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index 6414c2c016..ca027d7675 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmail.cpp * @brief smtp helper functions. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,7 +37,7 @@ #include "apr_network_io.h" #include "llapr.h" -#include "llbase32.h" // IM-to-email address +#include "llbase32.h" // IM-to-email address #include "llblowfishcipher.h" #include "llerror.h" #include "llhost.h" @@ -58,7 +58,7 @@ static apr_socket_t* gMailSocket; bool connect_smtp(); void disconnect_smtp(); - + //#if LL_WINDOWS //SOCKADDR_IN gMailDstAddr, gMailSrcAddr, gMailLclAddr; //#else @@ -70,327 +70,327 @@ void disconnect_smtp(); bool connect_smtp() { - // Prepare an soket to talk smtp - apr_status_t status; - status = apr_socket_create( - &gMailSocket, - gSockAddr->sa.sin.sin_family, - SOCK_STREAM, - APR_PROTO_TCP, - gMailPool); - if(ll_apr_warn_status(status)) return false; - status = apr_socket_connect(gMailSocket, gSockAddr); - if(ll_apr_warn_status(status)) - { - status = apr_socket_close(gMailSocket); - ll_apr_warn_status(status); - return false; - } - return true; + // Prepare an soket to talk smtp + apr_status_t status; + status = apr_socket_create( + &gMailSocket, + gSockAddr->sa.sin.sin_family, + SOCK_STREAM, + APR_PROTO_TCP, + gMailPool); + if(ll_apr_warn_status(status)) return false; + status = apr_socket_connect(gMailSocket, gSockAddr); + if(ll_apr_warn_status(status)) + { + status = apr_socket_close(gMailSocket); + ll_apr_warn_status(status); + return false; + } + return true; } void disconnect_smtp() { - if(gMailSocket) - { - apr_status_t status = apr_socket_close(gMailSocket); - ll_apr_warn_status(status); - gMailSocket = NULL; - } + if(gMailSocket) + { + apr_status_t status = apr_socket_close(gMailSocket); + ll_apr_warn_status(status); + gMailSocket = NULL; + } } // Returns true on success. // message should NOT be SMTP escaped. // static bool LLMail::send( - const char* from_name, - const char* from_address, - const char* to_name, - const char* to_address, - const char* subject, - const char* message, - const LLSD& headers) + const char* from_name, + const char* from_address, + const char* to_name, + const char* to_address, + const char* subject, + const char* message, + const LLSD& headers) { - std::string header = buildSMTPTransaction( - from_name, - from_address, - to_name, - to_address, - subject, - headers); - if(header.empty()) - { - return false; - } - - std::string message_str; - if(message) - { - message_str = message; - } - bool rv = send(header, message_str, to_address, from_address); - if(rv) return true; - return false; + std::string header = buildSMTPTransaction( + from_name, + from_address, + to_name, + to_address, + subject, + headers); + if(header.empty()) + { + return false; + } + + std::string message_str; + if(message) + { + message_str = message; + } + bool rv = send(header, message_str, to_address, from_address); + if(rv) return true; + return false; } // static void LLMail::init(const std::string& hostname, apr_pool_t* pool) { - gMailSocket = NULL; - if(hostname.empty() || !pool) - { - gMailPool = NULL; - gSockAddr = NULL; - } - else - { - gMailPool = pool; - - // collect all the information into a socaddr sturcture. the - // documentation is a bit unclear, but I either have to - // specify APR_UNSPEC or not specify any flags. I am not sure - // which option is better. - apr_status_t status = apr_sockaddr_info_get( - &gSockAddr, - hostname.c_str(), - APR_UNSPEC, - 25, - APR_IPV4_ADDR_OK, - gMailPool); - ll_apr_warn_status(status); - } + gMailSocket = NULL; + if(hostname.empty() || !pool) + { + gMailPool = NULL; + gSockAddr = NULL; + } + else + { + gMailPool = pool; + + // collect all the information into a socaddr sturcture. the + // documentation is a bit unclear, but I either have to + // specify APR_UNSPEC or not specify any flags. I am not sure + // which option is better. + apr_status_t status = apr_sockaddr_info_get( + &gSockAddr, + hostname.c_str(), + APR_UNSPEC, + 25, + APR_IPV4_ADDR_OK, + gMailPool); + ll_apr_warn_status(status); + } } // static void LLMail::enable(bool mail_enabled) { - gMailEnabled = mail_enabled; + gMailEnabled = mail_enabled; } // Test a subject line for RFC2822 compliance. static bool valid_subject_chars(const char *subject) { - for (; *subject != '\0'; subject++) - { - unsigned char c = *subject; + for (; *subject != '\0'; subject++) + { + unsigned char c = *subject; - if (c == '\xa' || c == '\xd' || c > '\x7f') - { - return false; - } - } + if (c == '\xa' || c == '\xd' || c > '\x7f') + { + return false; + } + } - return true; + return true; } // static std::string LLMail::buildSMTPTransaction( - const char* from_name, - const char* from_address, - const char* to_name, - const char* to_address, - const char* subject, - const LLSD& headers) + const char* from_name, + const char* from_address, + const char* to_name, + const char* to_address, + const char* subject, + const LLSD& headers) { - if(!from_address || !to_address) - { - LL_INFOS() << "send_mail build_smtp_transaction reject: missing to and/or" - << " from address." << LL_ENDL; - return std::string(); - } - if(!valid_subject_chars(subject)) - { - LL_INFOS() << "send_mail build_smtp_transaction reject: bad subject header: " - << "to=<" << to_address - << ">, from=<" << from_address << ">" - << LL_ENDL; - return std::string(); - } - std::ostringstream from_fmt; - if(from_name && from_name[0]) - { - // "My Name" <myaddress@example.com> - from_fmt << "\"" << from_name << "\" <" << from_address << ">"; - } - else - { - // <myaddress@example.com> - from_fmt << "<" << from_address << ">"; - } - std::ostringstream to_fmt; - if(to_name && to_name[0]) - { - to_fmt << "\"" << to_name << "\" <" << to_address << ">"; - } - else - { - to_fmt << "<" << to_address << ">"; - } - std::ostringstream header; - header - << "HELO lindenlab.com\r\n" - << "MAIL FROM:<" << from_address << ">\r\n" - << "RCPT TO:<" << to_address << ">\r\n" - << "DATA\r\n" - << "From: " << from_fmt.str() << "\r\n" - << "To: " << to_fmt.str() << "\r\n" - << "Subject: " << subject << "\r\n"; - - if(headers.isMap()) - { - LLSD::map_const_iterator iter = headers.beginMap(); - LLSD::map_const_iterator end = headers.endMap(); - for(; iter != end; ++iter) - { - header << (*iter).first << ": " << ((*iter).second).asString() - << "\r\n"; - } - } - - header << "\r\n"; - return header.str(); + if(!from_address || !to_address) + { + LL_INFOS() << "send_mail build_smtp_transaction reject: missing to and/or" + << " from address." << LL_ENDL; + return std::string(); + } + if(!valid_subject_chars(subject)) + { + LL_INFOS() << "send_mail build_smtp_transaction reject: bad subject header: " + << "to=<" << to_address + << ">, from=<" << from_address << ">" + << LL_ENDL; + return std::string(); + } + std::ostringstream from_fmt; + if(from_name && from_name[0]) + { + // "My Name" <myaddress@example.com> + from_fmt << "\"" << from_name << "\" <" << from_address << ">"; + } + else + { + // <myaddress@example.com> + from_fmt << "<" << from_address << ">"; + } + std::ostringstream to_fmt; + if(to_name && to_name[0]) + { + to_fmt << "\"" << to_name << "\" <" << to_address << ">"; + } + else + { + to_fmt << "<" << to_address << ">"; + } + std::ostringstream header; + header + << "HELO lindenlab.com\r\n" + << "MAIL FROM:<" << from_address << ">\r\n" + << "RCPT TO:<" << to_address << ">\r\n" + << "DATA\r\n" + << "From: " << from_fmt.str() << "\r\n" + << "To: " << to_fmt.str() << "\r\n" + << "Subject: " << subject << "\r\n"; + + if(headers.isMap()) + { + LLSD::map_const_iterator iter = headers.beginMap(); + LLSD::map_const_iterator end = headers.endMap(); + for(; iter != end; ++iter) + { + header << (*iter).first << ": " << ((*iter).second).asString() + << "\r\n"; + } + } + + header << "\r\n"; + return header.str(); } // static bool LLMail::send( - const std::string& header, - const std::string& raw_message, - const char* from_address, - const char* to_address) + const std::string& header, + const std::string& raw_message, + const char* from_address, + const char* to_address) { - if(!from_address || !to_address) - { - LL_INFOS() << "send_mail reject: missing to and/or from address." - << LL_ENDL; - return false; - } - - // remove any "." SMTP commands to prevent injection (DEV-35777) - // we don't need to worry about "\r\n.\r\n" because of the - // "\n" --> "\n\n" conversion going into rfc2822_msg below - std::string message = raw_message; - std::string bad_string = "\n.\n"; - std::string good_string = "\n..\n"; - while (1) - { - int index = message.find(bad_string); - if (index == std::string::npos) break; - message.replace(index, bad_string.size(), good_string); - } - - // convert all "\n" into "\r\n" - std::ostringstream rfc2822_msg; - for(U32 i = 0; i < message.size(); ++i) - { - switch(message[i]) - { - case '\0': - break; - case '\n': - // *NOTE: this is kinda busted if we're fed \r\n - rfc2822_msg << "\r\n"; - break; - default: - rfc2822_msg << message[i]; - break; - } - } - - if(!gMailEnabled) - { - LL_INFOS() << "send_mail reject: mail system is disabled: to=<" - << to_address << ">, from=<" << from_address - << ">" << LL_ENDL; - // Any future interface to SMTP should return this as an - // error. --mark - return true; - } - if(!gSockAddr) - { - LL_WARNS() << "send_mail reject: mail system not initialized: to=<" - << to_address << ">, from=<" << from_address - << ">" << LL_ENDL; - return false; - } - - if(!connect_smtp()) - { - LL_WARNS() << "send_mail reject: SMTP connect failure: to=<" - << to_address << ">, from=<" << from_address - << ">" << LL_ENDL; - return false; - } - - std::ostringstream smtp_fmt; - smtp_fmt << header << rfc2822_msg.str() << "\r\n" << ".\r\n" << "QUIT\r\n"; - std::string smtp_transaction = smtp_fmt.str(); - size_t original_size = smtp_transaction.size(); - apr_size_t send_size = original_size; - apr_status_t status = apr_socket_send( - gMailSocket, - smtp_transaction.c_str(), - (apr_size_t*)&send_size); - disconnect_smtp(); - if(ll_apr_warn_status(status)) - { - LL_WARNS() << "send_mail socket failure: unable to write " - << "to=<" << to_address - << ">, from=<" << from_address << ">" - << ", bytes=" << original_size - << ", sent=" << send_size << LL_ENDL; - return false; - } - if(send_size >= LL_MAX_KNOWN_GOOD_MAIL_SIZE) - { - LL_WARNS() << "send_mail message has been shown to fail in testing " - << "when sending messages larger than " << LL_MAX_KNOWN_GOOD_MAIL_SIZE - << " bytes. The next log about success is potentially a lie." << LL_ENDL; - } - LL_DEBUGS() << "send_mail success: " - << "to=<" << to_address - << ">, from=<" << from_address << ">" - << ", bytes=" << original_size - << ", sent=" << send_size << LL_ENDL; + if(!from_address || !to_address) + { + LL_INFOS() << "send_mail reject: missing to and/or from address." + << LL_ENDL; + return false; + } + + // remove any "." SMTP commands to prevent injection (DEV-35777) + // we don't need to worry about "\r\n.\r\n" because of the + // "\n" --> "\n\n" conversion going into rfc2822_msg below + std::string message = raw_message; + std::string bad_string = "\n.\n"; + std::string good_string = "\n..\n"; + while (1) + { + int index = message.find(bad_string); + if (index == std::string::npos) break; + message.replace(index, bad_string.size(), good_string); + } + + // convert all "\n" into "\r\n" + std::ostringstream rfc2822_msg; + for(U32 i = 0; i < message.size(); ++i) + { + switch(message[i]) + { + case '\0': + break; + case '\n': + // *NOTE: this is kinda busted if we're fed \r\n + rfc2822_msg << "\r\n"; + break; + default: + rfc2822_msg << message[i]; + break; + } + } + + if(!gMailEnabled) + { + LL_INFOS() << "send_mail reject: mail system is disabled: to=<" + << to_address << ">, from=<" << from_address + << ">" << LL_ENDL; + // Any future interface to SMTP should return this as an + // error. --mark + return true; + } + if(!gSockAddr) + { + LL_WARNS() << "send_mail reject: mail system not initialized: to=<" + << to_address << ">, from=<" << from_address + << ">" << LL_ENDL; + return false; + } + + if(!connect_smtp()) + { + LL_WARNS() << "send_mail reject: SMTP connect failure: to=<" + << to_address << ">, from=<" << from_address + << ">" << LL_ENDL; + return false; + } + + std::ostringstream smtp_fmt; + smtp_fmt << header << rfc2822_msg.str() << "\r\n" << ".\r\n" << "QUIT\r\n"; + std::string smtp_transaction = smtp_fmt.str(); + size_t original_size = smtp_transaction.size(); + apr_size_t send_size = original_size; + apr_status_t status = apr_socket_send( + gMailSocket, + smtp_transaction.c_str(), + (apr_size_t*)&send_size); + disconnect_smtp(); + if(ll_apr_warn_status(status)) + { + LL_WARNS() << "send_mail socket failure: unable to write " + << "to=<" << to_address + << ">, from=<" << from_address << ">" + << ", bytes=" << original_size + << ", sent=" << send_size << LL_ENDL; + return false; + } + if(send_size >= LL_MAX_KNOWN_GOOD_MAIL_SIZE) + { + LL_WARNS() << "send_mail message has been shown to fail in testing " + << "when sending messages larger than " << LL_MAX_KNOWN_GOOD_MAIL_SIZE + << " bytes. The next log about success is potentially a lie." << LL_ENDL; + } + LL_DEBUGS() << "send_mail success: " + << "to=<" << to_address + << ">, from=<" << from_address << ">" + << ", bytes=" << original_size + << ", sent=" << send_size << LL_ENDL; #if LL_LOG_ENTIRE_MAIL_MESSAGE_ON_SEND - LL_INFOS() << rfc2822_msg.str() << LL_ENDL; + LL_INFOS() << rfc2822_msg.str() << LL_ENDL; #endif - return true; + return true; } // static std::string LLMail::encryptIMEmailAddress(const LLUUID& from_agent_id, - const LLUUID& to_agent_id, - U32 time, - const U8* secret, - size_t secret_size) + const LLUUID& to_agent_id, + U32 time, + const U8* secret, + size_t secret_size) { #if LL_WINDOWS - return "blowfish-not-supported-on-windows"; + return "blowfish-not-supported-on-windows"; #else - size_t data_size = 4 + UUID_BYTES + UUID_BYTES; - // Convert input data into a binary blob - std::vector<U8> data; - data.resize(data_size); - // *NOTE: This may suffer from endian issues. Could be htolememcpy. - memcpy(&data[0], &time, 4); - memcpy(&data[4], &from_agent_id.mData[0], UUID_BYTES); - memcpy(&data[4 + UUID_BYTES], &to_agent_id.mData[0], UUID_BYTES); - - // Encrypt the blob - LLBlowfishCipher cipher(secret, secret_size); - size_t encrypted_size = cipher.requiredEncryptionSpace(data.size()); - U8* encrypted = new U8[encrypted_size]; - cipher.encrypt(&data[0], data_size, encrypted, encrypted_size); - - std::string address = LLBase32::encode(encrypted, encrypted_size); - - // Make it more pretty for humans. - LLStringUtil::toLower(address); - - delete [] encrypted; - - return address; + size_t data_size = 4 + UUID_BYTES + UUID_BYTES; + // Convert input data into a binary blob + std::vector<U8> data; + data.resize(data_size); + // *NOTE: This may suffer from endian issues. Could be htolememcpy. + memcpy(&data[0], &time, 4); + memcpy(&data[4], &from_agent_id.mData[0], UUID_BYTES); + memcpy(&data[4 + UUID_BYTES], &to_agent_id.mData[0], UUID_BYTES); + + // Encrypt the blob + LLBlowfishCipher cipher(secret, secret_size); + size_t encrypted_size = cipher.requiredEncryptionSpace(data.size()); + U8* encrypted = new U8[encrypted_size]; + cipher.encrypt(&data[0], data_size, encrypted, encrypted_size); + + std::string address = LLBase32::encode(encrypted, encrypted_size); + + // Make it more pretty for humans. + LLStringUtil::toLower(address); + + delete [] encrypted; + + return address; #endif } diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h index f97a443c47..d67b89d1ea 100644 --- a/indra/llmessage/llmail.h +++ b/indra/llmessage/llmail.h @@ -1,25 +1,25 @@ -/** +/** * @file llmail.h * @brief smtp helper functions. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,95 +34,95 @@ typedef struct apr_pool_t apr_pool_t; class LLMail { public: - // if hostname is NULL, then the host is resolved as 'mail' - static void init(const std::string& hostname, apr_pool_t* pool); + // if hostname is NULL, then the host is resolved as 'mail' + static void init(const std::string& hostname, apr_pool_t* pool); - // Allow all email transmission to be disabled/enabled. - static void enable(bool mail_enabled); + // Allow all email transmission to be disabled/enabled. + static void enable(bool mail_enabled); - /** - * @brief send an email - * @param from_name The name of the email sender - * @param from_address The email address for the sender - * @param to_name The name of the email recipient - * @param to_address The email recipient address - * @param subject The subject of the email - * @param headers optional X-Foo headers in an llsd map. - * @return Returns true if the call succeeds, false otherwise. - * - * Results in: - * From: "from_name" <from_address> - * To: "to_name" <to_address> - * Subject: subject - * - * message - */ - static bool send( - const char* from_name, - const char* from_address, - const char* to_name, - const char* to_address, - const char* subject, - const char* message, - const LLSD& headers = LLSD()); + /** + * @brief send an email + * @param from_name The name of the email sender + * @param from_address The email address for the sender + * @param to_name The name of the email recipient + * @param to_address The email recipient address + * @param subject The subject of the email + * @param headers optional X-Foo headers in an llsd map. + * @return Returns true if the call succeeds, false otherwise. + * + * Results in: + * From: "from_name" <from_address> + * To: "to_name" <to_address> + * Subject: subject + * + * message + */ + static bool send( + const char* from_name, + const char* from_address, + const char* to_name, + const char* to_address, + const char* subject, + const char* message, + const LLSD& headers = LLSD()); - /** - * @brief build the complete smtp transaction & header for use in an - * mail. - * - * @param from_name The name of the email sender - * @param from_address The email address for the sender - * @param to_name The name of the email recipient - * @param to_address The email recipient address - * @param subject The subject of the email - * @param headers optional X-Foo headers in an llsd map. - * @return Returns the complete SMTP transaction mail header. - */ - static std::string buildSMTPTransaction( - const char* from_name, - const char* from_address, - const char* to_name, - const char* to_address, - const char* subject, - const LLSD& headers = LLSD()); + /** + * @brief build the complete smtp transaction & header for use in an + * mail. + * + * @param from_name The name of the email sender + * @param from_address The email address for the sender + * @param to_name The name of the email recipient + * @param to_address The email recipient address + * @param subject The subject of the email + * @param headers optional X-Foo headers in an llsd map. + * @return Returns the complete SMTP transaction mail header. + */ + static std::string buildSMTPTransaction( + const char* from_name, + const char* from_address, + const char* to_name, + const char* to_address, + const char* subject, + const LLSD& headers = LLSD()); - /** - * @brief send an email with header and body. - * - * @param header The email header. Use build_mail_header(). - * @param message The unescaped email message. - * @param from_address Used for debugging - * @param to_address Used for debugging - * @return Returns true if the message could be sent. - */ - static bool send( - const std::string& header, - const std::string& message, - const char* from_address, - const char* to_address); + /** + * @brief send an email with header and body. + * + * @param header The email header. Use build_mail_header(). + * @param message The unescaped email message. + * @param from_address Used for debugging + * @param to_address Used for debugging + * @return Returns true if the message could be sent. + */ + static bool send( + const std::string& header, + const std::string& message, + const char* from_address, + const char* to_address); - // IM-to-email sessions use a "session id" based on an encrypted - // combination of from agent_id, to agent_id, and timestamp. When - // a user replies to an email we use the from_id to determine the - // sender's name and the to_id to route the message. The address - // is encrypted to prevent users from building addresses to spoof - // IMs from other users. The timestamps allow the "sessions" to - // expire, in case one of the sessions is stolen/hijacked. - // - // indra/tools/mailglue is responsible for parsing the inbound mail. - // - // secret: binary blob passed to blowfish, max length 56 bytes - // secret_size: length of blob, in bytes - // - // Returns: "base64" encoded email local-part, with _ and - as the - // non-alphanumeric characters. This allows better compatibility - // with email systems than the default / and + extra chars. JC - static std::string encryptIMEmailAddress( - const LLUUID& from_agent_id, - const LLUUID& to_agent_id, - U32 time, - const U8* secret, - size_t secret_size); + // IM-to-email sessions use a "session id" based on an encrypted + // combination of from agent_id, to agent_id, and timestamp. When + // a user replies to an email we use the from_id to determine the + // sender's name and the to_id to route the message. The address + // is encrypted to prevent users from building addresses to spoof + // IMs from other users. The timestamps allow the "sessions" to + // expire, in case one of the sessions is stolen/hijacked. + // + // indra/tools/mailglue is responsible for parsing the inbound mail. + // + // secret: binary blob passed to blowfish, max length 56 bytes + // secret_size: length of blob, in bytes + // + // Returns: "base64" encoded email local-part, with _ and - as the + // non-alphanumeric characters. This allows better compatibility + // with email systems than the default / and + extra chars. JC + static std::string encryptIMEmailAddress( + const LLUUID& from_agent_id, + const LLUUID& to_agent_id, + U32 time, + const U8* secret, + size_t secret_size); }; extern const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE; diff --git a/indra/llmessage/llmessagebuilder.cpp b/indra/llmessage/llmessagebuilder.cpp index e2ed968a57..2bac3bffee 100644 --- a/indra/llmessage/llmessagebuilder.cpp +++ b/indra/llmessage/llmessagebuilder.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmessagebuilder.cpp * @brief LLMessageBuilder class implementation * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,6 +31,6 @@ //virtual LLMessageBuilder::~LLMessageBuilder() { - // even abstract base classes need a concrete destructor + // even abstract base classes need a concrete destructor } diff --git a/indra/llmessage/llmessagebuilder.h b/indra/llmessage/llmessagebuilder.h index 75bd5f5cc7..3f04857945 100644 --- a/indra/llmessage/llmessagebuilder.h +++ b/indra/llmessage/llmessagebuilder.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessagebuilder.h * @brief Declaration of LLMessageBuilder class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,59 +43,59 @@ class LLMessageBuilder { public: - //CLASS_LOG_TYPE(LLMessageBuilder); - - virtual ~LLMessageBuilder(); - virtual void newMessage(const char* name) = 0; + //CLASS_LOG_TYPE(LLMessageBuilder); + + virtual ~LLMessageBuilder(); + virtual void newMessage(const char* name) = 0; - virtual void nextBlock(const char* blockname) = 0; - virtual bool removeLastBlock() = 0; // TODO: babbage: remove this horror + virtual void nextBlock(const char* blockname) = 0; + virtual bool removeLastBlock() = 0; // TODO: babbage: remove this horror - /** All add* methods expect pointers to canonical strings. */ - virtual void addBinaryData( - const char* varname, - const void* data, - S32 size) = 0; - virtual void addBOOL(const char* varname, bool b) = 0; - virtual void addS8(const char* varname, S8 s) = 0; - virtual void addU8(const char* varname, U8 u) = 0; - virtual void addS16(const char* varname, S16 i) = 0; - virtual void addU16(const char* varname, U16 i) = 0; - virtual void addF32(const char* varname, F32 f) = 0; - virtual void addS32(const char* varname, S32 s) = 0; - virtual void addU32(const char* varname, U32 u) = 0; - virtual void addU64(const char* varname, U64 lu) = 0; - virtual void addF64(const char* varname, F64 d) = 0; - virtual void addVector3(const char* varname, const LLVector3& vec) = 0; - virtual void addVector4(const char* varname, const LLVector4& vec) = 0; - virtual void addVector3d(const char* varname, const LLVector3d& vec) = 0; - virtual void addQuat(const char* varname, const LLQuaternion& quat) = 0; - virtual void addUUID(const char* varname, const LLUUID& uuid) = 0; - virtual void addIPAddr(const char* varname, const U32 ip) = 0; - virtual void addIPPort(const char* varname, const U16 port) = 0; - virtual void addString(const char* varname, const char* s) = 0; - virtual void addString(const char* varname, const std::string& s) = 0; + /** All add* methods expect pointers to canonical strings. */ + virtual void addBinaryData( + const char* varname, + const void* data, + S32 size) = 0; + virtual void addBOOL(const char* varname, bool b) = 0; + virtual void addS8(const char* varname, S8 s) = 0; + virtual void addU8(const char* varname, U8 u) = 0; + virtual void addS16(const char* varname, S16 i) = 0; + virtual void addU16(const char* varname, U16 i) = 0; + virtual void addF32(const char* varname, F32 f) = 0; + virtual void addS32(const char* varname, S32 s) = 0; + virtual void addU32(const char* varname, U32 u) = 0; + virtual void addU64(const char* varname, U64 lu) = 0; + virtual void addF64(const char* varname, F64 d) = 0; + virtual void addVector3(const char* varname, const LLVector3& vec) = 0; + virtual void addVector4(const char* varname, const LLVector4& vec) = 0; + virtual void addVector3d(const char* varname, const LLVector3d& vec) = 0; + virtual void addQuat(const char* varname, const LLQuaternion& quat) = 0; + virtual void addUUID(const char* varname, const LLUUID& uuid) = 0; + virtual void addIPAddr(const char* varname, const U32 ip) = 0; + virtual void addIPPort(const char* varname, const U16 port) = 0; + virtual void addString(const char* varname, const char* s) = 0; + virtual void addString(const char* varname, const std::string& s) = 0; - virtual bool isMessageFull(const char* blockname) const = 0; - virtual void compressMessage(U8*& buf_ptr, U32& buffer_length) = 0; - virtual S32 getMessageSize() = 0; + virtual bool isMessageFull(const char* blockname) const = 0; + virtual void compressMessage(U8*& buf_ptr, U32& buffer_length) = 0; + virtual S32 getMessageSize() = 0; - virtual bool isBuilt() const = 0; - virtual bool isClear() const = 0; - virtual U32 buildMessage( - U8* buffer, - U32 buffer_size, - U8 offset_to_data) = 0; + virtual bool isBuilt() const = 0; + virtual bool isClear() const = 0; + virtual U32 buildMessage( + U8* buffer, + U32 buffer_size, + U8 offset_to_data) = 0; /**< Return built message size */ - virtual void clearMessage() = 0; + virtual void clearMessage() = 0; - // TODO: babbage: remove this horror - virtual void setBuilt(bool b) = 0; + // TODO: babbage: remove this horror + virtual void setBuilt(bool b) = 0; - virtual const char* getMessageName() const = 0; + virtual const char* getMessageName() const = 0; - virtual void copyFromMessageData(const LLMsgData& data) = 0; - virtual void copyFromLLSD(const LLSD& data) = 0; + virtual void copyFromMessageData(const LLMsgData& data) = 0; + virtual void copyFromLLSD(const LLSD& data) = 0; }; #endif // LL_LLMESSAGEBUILDER_H diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp index 64e79d6767..e611688155 100644 --- a/indra/llmessage/llmessageconfig.cpp +++ b/indra/llmessage/llmessageconfig.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmessageconfig.cpp * @brief Live file handling for messaging * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,107 +47,107 @@ static LLSD sMessages; class LLMessageConfigFile : public LLLiveFile { public: - LLMessageConfigFile() : - LLLiveFile(filename(), messageConfigRefreshRate), - mMaxQueuedEvents(0) + LLMessageConfigFile() : + LLLiveFile(filename(), messageConfigRefreshRate), + mMaxQueuedEvents(0) { } - static std::string filename(); + static std::string filename(); + + LLSD mMessages; + std::string mServerDefault; - LLSD mMessages; - std::string mServerDefault; - - static LLMessageConfigFile& instance(); - // return the singleton configuration file + static LLMessageConfigFile& instance(); + // return the singleton configuration file - /* virtual */ bool loadFile(); - void loadServerDefaults(const LLSD& data); - void loadMaxQueuedEvents(const LLSD& data); - void loadMessages(const LLSD& data); - void loadCapBans(const LLSD& blacklist); - void loadMessageBans(const LLSD& blacklist); - bool isCapBanned(const std::string& cap_name) const; + /* virtual */ bool loadFile(); + void loadServerDefaults(const LLSD& data); + void loadMaxQueuedEvents(const LLSD& data); + void loadMessages(const LLSD& data); + void loadCapBans(const LLSD& blacklist); + void loadMessageBans(const LLSD& blacklist); + bool isCapBanned(const std::string& cap_name) const; public: - LLSD mCapBans; - S32 mMaxQueuedEvents; + LLSD mCapBans; + S32 mMaxQueuedEvents; private: - static const S32 DEFAULT_MAX_QUEUED_EVENTS = 100; + static const S32 DEFAULT_MAX_QUEUED_EVENTS = 100; }; std::string LLMessageConfigFile::filename() { std::ostringstream ostr; - ostr << sConfigDir//gAppSimp->getOption("configdir").asString() - << "/" << messageConfigFileName; - return ostr.str(); + ostr << sConfigDir//gAppSimp->getOption("configdir").asString() + << "/" << messageConfigFileName; + return ostr.str(); } LLMessageConfigFile& LLMessageConfigFile::instance() { - static LLMessageConfigFile the_file; - the_file.checkAndReload(); - return the_file; + static LLMessageConfigFile the_file; + the_file.checkAndReload(); + return the_file; } // virtual bool LLMessageConfigFile::loadFile() { - LLSD data; + LLSD data; { llifstream file(filename().c_str()); - + if (file.is_open()) { - LL_DEBUGS("AppInit") << "Loading message.xml file at " << filename() << LL_ENDL; + LL_DEBUGS("AppInit") << "Loading message.xml file at " << filename() << LL_ENDL; LLSDSerialize::fromXML(data, file); } if (data.isUndefined()) { LL_INFOS("AppInit") << "LLMessageConfigFile::loadFile: file missing," - " ill-formed, or simply undefined; not changing the" - " file" << LL_ENDL; + " ill-formed, or simply undefined; not changing the" + " file" << LL_ENDL; return false; } } - loadServerDefaults(data); - loadMaxQueuedEvents(data); - loadMessages(data); - loadCapBans(data); - loadMessageBans(data); - return true; + loadServerDefaults(data); + loadMaxQueuedEvents(data); + loadMessages(data); + loadCapBans(data); + loadMessageBans(data); + return true; } void LLMessageConfigFile::loadServerDefaults(const LLSD& data) { - mServerDefault = data["serverDefaults"][sServerName].asString(); + mServerDefault = data["serverDefaults"][sServerName].asString(); } void LLMessageConfigFile::loadMaxQueuedEvents(const LLSD& data) { - if (data.has("maxQueuedEvents")) - { - mMaxQueuedEvents = data["maxQueuedEvents"].asInteger(); - } - else - { - mMaxQueuedEvents = DEFAULT_MAX_QUEUED_EVENTS; - } + if (data.has("maxQueuedEvents")) + { + mMaxQueuedEvents = data["maxQueuedEvents"].asInteger(); + } + else + { + mMaxQueuedEvents = DEFAULT_MAX_QUEUED_EVENTS; + } } void LLMessageConfigFile::loadMessages(const LLSD& data) { - mMessages = data["messages"]; + mMessages = data["messages"]; #ifdef DEBUG - std::ostringstream out; - LLSDXMLFormatter *formatter = new LLSDXMLFormatter; - formatter->format(mMessages, out); - LL_INFOS() << "loading ... " << out.str() - << " LLMessageConfigFile::loadMessages loaded " - << mMessages.size() << " messages" << LL_ENDL; + std::ostringstream out; + LLSDXMLFormatter *formatter = new LLSDXMLFormatter; + formatter->format(mMessages, out); + LL_INFOS() << "loading ... " << out.str() + << " LLMessageConfigFile::loadMessages loaded " + << mMessages.size() << " messages" << LL_ENDL; #endif } @@ -160,9 +160,9 @@ void LLMessageConfigFile::loadCapBans(const LLSD& data) << LL_ENDL; return; } - - mCapBans = bans; - + + mCapBans = bans; + LL_DEBUGS("AppInit") << "LLMessageConfigFile::loadCapBans: " << bans.size() << " ban tests" << LL_ENDL; } @@ -176,13 +176,13 @@ void LLMessageConfigFile::loadMessageBans(const LLSD& data) << LL_ENDL; return; } - - gMessageSystem->setMessageBans(bans["trusted"], bans["untrusted"]); + + gMessageSystem->setMessageBans(bans["trusted"], bans["untrusted"]); } bool LLMessageConfigFile::isCapBanned(const std::string& cap_name) const { - LL_DEBUGS() << "mCapBans is " << LLSDNotationStreamer(mCapBans) << LL_ENDL; + LL_DEBUGS() << "mCapBans is " << LLSDNotationStreamer(mCapBans) << LL_ENDL; return mCapBans[cap_name]; } @@ -192,99 +192,99 @@ bool LLMessageConfigFile::isCapBanned(const std::string& cap_name) const //static void LLMessageConfig::initClass(const std::string& server_name, - const std::string& config_dir) + const std::string& config_dir) { - sServerName = server_name; - sConfigDir = config_dir; - (void) LLMessageConfigFile::instance(); - LL_DEBUGS("AppInit") << "LLMessageConfig::initClass config file " - << config_dir << "/" << messageConfigFileName << LL_ENDL; + sServerName = server_name; + sConfigDir = config_dir; + (void) LLMessageConfigFile::instance(); + LL_DEBUGS("AppInit") << "LLMessageConfig::initClass config file " + << config_dir << "/" << messageConfigFileName << LL_ENDL; } //static void LLMessageConfig::useConfig(const LLSD& config) { - LLMessageConfigFile &the_file = LLMessageConfigFile::instance(); - the_file.loadServerDefaults(config); - the_file.loadMaxQueuedEvents(config); - the_file.loadMessages(config); - the_file.loadCapBans(config); - the_file.loadMessageBans(config); + LLMessageConfigFile &the_file = LLMessageConfigFile::instance(); + the_file.loadServerDefaults(config); + the_file.loadMaxQueuedEvents(config); + the_file.loadMessages(config); + the_file.loadCapBans(config); + the_file.loadMessageBans(config); } //static LLMessageConfig::Flavor LLMessageConfig::getServerDefaultFlavor() { - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - if (file.mServerDefault == "llsd") - { - return LLSD_FLAVOR; - } - if (file.mServerDefault == "template") - { - return TEMPLATE_FLAVOR; - } - return NO_FLAVOR; + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + if (file.mServerDefault == "llsd") + { + return LLSD_FLAVOR; + } + if (file.mServerDefault == "template") + { + return TEMPLATE_FLAVOR; + } + return NO_FLAVOR; } //static S32 LLMessageConfig::getMaxQueuedEvents() { - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - return file.mMaxQueuedEvents; + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + return file.mMaxQueuedEvents; } //static LLMessageConfig::Flavor LLMessageConfig::getMessageFlavor(const std::string& msg_name) { - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - LLSD config = file.mMessages[msg_name]; - if (config["flavor"].asString() == "llsd") - { - return LLSD_FLAVOR; - } - if (config["flavor"].asString() == "template") - { - return TEMPLATE_FLAVOR; - } - return NO_FLAVOR; + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + LLSD config = file.mMessages[msg_name]; + if (config["flavor"].asString() == "llsd") + { + return LLSD_FLAVOR; + } + if (config["flavor"].asString() == "template") + { + return TEMPLATE_FLAVOR; + } + return NO_FLAVOR; } //static LLMessageConfig::SenderTrust LLMessageConfig::getSenderTrustedness( - const std::string& msg_name) + const std::string& msg_name) { - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - LLSD config = file.mMessages[msg_name]; - if (config.has("trusted-sender")) - { - return config["trusted-sender"].asBoolean() ? TRUSTED : UNTRUSTED; - } - return NOT_SET; + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + LLSD config = file.mMessages[msg_name]; + if (config.has("trusted-sender")) + { + return config["trusted-sender"].asBoolean() ? TRUSTED : UNTRUSTED; + } + return NOT_SET; } //static bool LLMessageConfig::isValidMessage(const std::string& msg_name) { - if (sServerName.empty()) - { - LL_ERRS() << "LLMessageConfig::initClass() not called" << LL_ENDL; - } - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - return file.mMessages.has(msg_name); + if (sServerName.empty()) + { + LL_ERRS() << "LLMessageConfig::initClass() not called" << LL_ENDL; + } + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + return file.mMessages.has(msg_name); } //static bool LLMessageConfig::onlySendLatest(const std::string& msg_name) { - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - LLSD config = file.mMessages[msg_name]; - return config["only-send-latest"].asBoolean(); + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + LLSD config = file.mMessages[msg_name]; + return config["only-send-latest"].asBoolean(); } bool LLMessageConfig::isCapBanned(const std::string& cap_name) { - return LLMessageConfigFile::instance().isCapBanned(cap_name); + return LLMessageConfigFile::instance().isCapBanned(cap_name); } // return the web-service path to use for a given @@ -292,13 +292,13 @@ bool LLMessageConfig::isCapBanned(const std::string& cap_name) // in simulator.xml! LLSD LLMessageConfig::getConfigForMessage(const std::string& msg_name) { - if (sServerName.empty()) - { - LL_ERRS() << "LLMessageConfig::isMessageTrusted(name) before" - << " LLMessageConfig::initClass()" << LL_ENDL; - } - LLMessageConfigFile& file = LLMessageConfigFile::instance(); - // LLSD for the CamelCase message name - LLSD config = file.mMessages[msg_name]; - return config; + if (sServerName.empty()) + { + LL_ERRS() << "LLMessageConfig::isMessageTrusted(name) before" + << " LLMessageConfig::initClass()" << LL_ENDL; + } + LLMessageConfigFile& file = LLMessageConfigFile::instance(); + // LLSD for the CamelCase message name + LLSD config = file.mMessages[msg_name]; + return config; } diff --git a/indra/llmessage/llmessageconfig.h b/indra/llmessage/llmessageconfig.h index 1b39c386ca..ce308faa1b 100644 --- a/indra/llmessage/llmessageconfig.h +++ b/indra/llmessage/llmessageconfig.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessageconfig.h * @brief Live file handling for messaging * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,22 +35,22 @@ class LLSD; class LLMessageConfig { public: - enum Flavor { NO_FLAVOR=0, LLSD_FLAVOR=1, TEMPLATE_FLAVOR=2 }; - enum SenderTrust { NOT_SET=0, UNTRUSTED=1, TRUSTED=2 }; - - static void initClass(const std::string& server_name, - const std::string& config_dir); - static void useConfig(const LLSD& config); + enum Flavor { NO_FLAVOR=0, LLSD_FLAVOR=1, TEMPLATE_FLAVOR=2 }; + enum SenderTrust { NOT_SET=0, UNTRUSTED=1, TRUSTED=2 }; + + static void initClass(const std::string& server_name, + const std::string& config_dir); + static void useConfig(const LLSD& config); - static Flavor getServerDefaultFlavor(); - static S32 getMaxQueuedEvents(); + static Flavor getServerDefaultFlavor(); + static S32 getMaxQueuedEvents(); - // For individual messages - static Flavor getMessageFlavor(const std::string& msg_name); - static SenderTrust getSenderTrustedness(const std::string& msg_name); - static bool isValidMessage(const std::string& msg_name); - static bool onlySendLatest(const std::string& msg_name); - static bool isCapBanned(const std::string& cap_name); - static LLSD getConfigForMessage(const std::string& msg_name); + // For individual messages + static Flavor getMessageFlavor(const std::string& msg_name); + static SenderTrust getSenderTrustedness(const std::string& msg_name); + static bool isValidMessage(const std::string& msg_name); + static bool onlySendLatest(const std::string& msg_name); + static bool isCapBanned(const std::string& cap_name); + static LLSD getConfigForMessage(const std::string& msg_name); }; #endif // LL_MESSAGECONFIG_H diff --git a/indra/llmessage/llmessagereader.cpp b/indra/llmessage/llmessagereader.cpp index 4a6f5145b3..4d4bf679ed 100644 --- a/indra/llmessage/llmessagereader.cpp +++ b/indra/llmessage/llmessagereader.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmessagereader.cpp * @brief LLMessageReader class implementation * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,29 +34,29 @@ static F32 sTimeDecodesSpamThreshold = 0.05f; //virtual LLMessageReader::~LLMessageReader() { - // even abstract base classes need a concrete destructor + // even abstract base classes need a concrete destructor } -//static +//static void LLMessageReader::setTimeDecodes(bool b) { - sTimeDecodes = b; + sTimeDecodes = b; } -//static +//static void LLMessageReader::setTimeDecodesSpamThreshold(F32 seconds) { - sTimeDecodesSpamThreshold = seconds; + sTimeDecodesSpamThreshold = seconds; } //static bool LLMessageReader::getTimeDecodes() { - return sTimeDecodes; + return sTimeDecodes; } -//static +//static F32 LLMessageReader::getTimeDecodesSpamThreshold() { - return sTimeDecodesSpamThreshold; + return sTimeDecodesSpamThreshold; } diff --git a/indra/llmessage/llmessagereader.h b/indra/llmessage/llmessagereader.h index 2f64371f63..5bc9aea5e4 100644 --- a/indra/llmessage/llmessagereader.h +++ b/indra/llmessage/llmessagereader.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessagereader.h * @brief Declaration of LLMessageReader class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,47 +48,47 @@ class LLMessageReader { public: - virtual ~LLMessageReader(); + virtual ~LLMessageReader(); + + /** All get* methods expect pointers to canonical strings. */ + virtual void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX) = 0; + virtual void getBOOL(const char *block, const char *var, bool &data, S32 blocknum = 0) = 0; + virtual void getS8(const char *block, const char *var, S8 &data, S32 blocknum = 0) = 0; + virtual void getU8(const char *block, const char *var, U8 &data, S32 blocknum = 0) = 0; + virtual void getS16(const char *block, const char *var, S16 &data, S32 blocknum = 0) = 0; + virtual void getU16(const char *block, const char *var, U16 &data, S32 blocknum = 0) = 0; + virtual void getS32(const char *block, const char *var, S32 &data, S32 blocknum = 0) = 0; + virtual void getF32(const char *block, const char *var, F32 &data, S32 blocknum = 0) = 0; + virtual void getU32(const char *block, const char *var, U32 &data, S32 blocknum = 0) = 0; + virtual void getU64(const char *block, const char *var, U64 &data, S32 blocknum = 0) = 0; + virtual void getF64(const char *block, const char *var, F64 &data, S32 blocknum = 0) = 0; + virtual void getVector3(const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0) = 0; + virtual void getVector4(const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0) = 0; + virtual void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0) = 0; + virtual void getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0) = 0; + virtual void getUUID(const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0) = 0; + virtual void getIPAddr(const char *block, const char *var, U32 &ip, S32 blocknum = 0) = 0; + virtual void getIPPort(const char *block, const char *var, U16 &port, S32 blocknum = 0) = 0; + virtual void getString(const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0) = 0; + virtual void getString(const char *block, const char *var, std::string& outstr, S32 blocknum = 0) = 0; - /** All get* methods expect pointers to canonical strings. */ - virtual void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX) = 0; - virtual void getBOOL(const char *block, const char *var, bool &data, S32 blocknum = 0) = 0; - virtual void getS8(const char *block, const char *var, S8 &data, S32 blocknum = 0) = 0; - virtual void getU8(const char *block, const char *var, U8 &data, S32 blocknum = 0) = 0; - virtual void getS16(const char *block, const char *var, S16 &data, S32 blocknum = 0) = 0; - virtual void getU16(const char *block, const char *var, U16 &data, S32 blocknum = 0) = 0; - virtual void getS32(const char *block, const char *var, S32 &data, S32 blocknum = 0) = 0; - virtual void getF32(const char *block, const char *var, F32 &data, S32 blocknum = 0) = 0; - virtual void getU32(const char *block, const char *var, U32 &data, S32 blocknum = 0) = 0; - virtual void getU64(const char *block, const char *var, U64 &data, S32 blocknum = 0) = 0; - virtual void getF64(const char *block, const char *var, F64 &data, S32 blocknum = 0) = 0; - virtual void getVector3(const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0) = 0; - virtual void getVector4(const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0) = 0; - virtual void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0) = 0; - virtual void getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0) = 0; - virtual void getUUID(const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0) = 0; - virtual void getIPAddr(const char *block, const char *var, U32 &ip, S32 blocknum = 0) = 0; - virtual void getIPPort(const char *block, const char *var, U16 &port, S32 blocknum = 0) = 0; - virtual void getString(const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0) = 0; - virtual void getString(const char *block, const char *var, std::string& outstr, S32 blocknum = 0) = 0; + virtual S32 getNumberOfBlocks(const char *blockname) = 0; + virtual S32 getSize(const char *blockname, const char *varname) = 0; + virtual S32 getSize(const char *blockname, S32 blocknum, const char *varname) = 0; - virtual S32 getNumberOfBlocks(const char *blockname) = 0; - virtual S32 getSize(const char *blockname, const char *varname) = 0; - virtual S32 getSize(const char *blockname, S32 blocknum, const char *varname) = 0; + virtual void clearMessage() = 0; - virtual void clearMessage() = 0; + /** Returns pointer to canonical (prehashed) string. */ + virtual const char* getMessageName() const = 0; + virtual S32 getMessageSize() const = 0; - /** Returns pointer to canonical (prehashed) string. */ - virtual const char* getMessageName() const = 0; - virtual S32 getMessageSize() const = 0; + virtual void copyToBuilder(LLMessageBuilder&) const = 0; - virtual void copyToBuilder(LLMessageBuilder&) const = 0; - - static void setTimeDecodes(bool b); - static bool getTimeDecodes(); - static void setTimeDecodesSpamThreshold(F32 seconds); - static F32 getTimeDecodesSpamThreshold(); + static void setTimeDecodes(bool b); + static bool getTimeDecodes(); + static void setTimeDecodesSpamThreshold(F32 seconds); + static F32 getTimeDecodesSpamThreshold(); }; #endif // LL_LLMESSAGEREADER_H diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h index ac0f9f7edb..51f03841c3 100644 --- a/indra/llmessage/llmessagesenderinterface.h +++ b/indra/llmessage/llmessagesenderinterface.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessagesenderinterface.h - * @brief + * @brief * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,8 +35,8 @@ class LLSD; class LLMessageSenderInterface { public: - virtual ~LLMessageSenderInterface() {} - virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message) = 0; + virtual ~LLMessageSenderInterface() {} + virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message) = 0; }; diff --git a/indra/llmessage/llmessagetemplate.cpp b/indra/llmessage/llmessagetemplate.cpp index e70e259436..8d2c1bf87a 100644 --- a/indra/llmessage/llmessagetemplate.cpp +++ b/indra/llmessage/llmessagetemplate.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmessagetemplate.cpp * @brief Implementation of message template classes. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,161 +32,161 @@ void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size) { - mSize = size; - mDataSize = data_size; - if ( (type != MVT_VARIABLE) && (type != MVT_FIXED) - && (mType != MVT_VARIABLE) && (mType != MVT_FIXED)) - { - if (mType != type) - { - LL_WARNS() << "Type mismatch in LLMsgVarData::addData for " << mName - << LL_ENDL; - } - } - if(size) - { - delete[] mData; // Delete it if it already exists - mData = new U8[size]; - htolememcpy(mData, data, mType, size); - } + mSize = size; + mDataSize = data_size; + if ( (type != MVT_VARIABLE) && (type != MVT_FIXED) + && (mType != MVT_VARIABLE) && (mType != MVT_FIXED)) + { + if (mType != type) + { + LL_WARNS() << "Type mismatch in LLMsgVarData::addData for " << mName + << LL_ENDL; + } + } + if(size) + { + delete[] mData; // Delete it if it already exists + mData = new U8[size]; + htolememcpy(mData, data, mType, size); + } } void LLMsgData::addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size) { - // remember that if the blocknumber is > 0 then the number is appended to the name - char *namep = (char *)blockname; - LLMsgBlkData* block_data = mMemberBlocks[namep]; - if (block_data->mBlockNumber) - { - namep += block_data->mBlockNumber; - block_data->addData(varname, data, size, type, data_size); - } - else - { - block_data->addData(varname, data, size, type, data_size); - } + // remember that if the blocknumber is > 0 then the number is appended to the name + char *namep = (char *)blockname; + LLMsgBlkData* block_data = mMemberBlocks[namep]; + if (block_data->mBlockNumber) + { + namep += block_data->mBlockNumber; + block_data->addData(varname, data, size, type, data_size); + } + else + { + block_data->addData(varname, data, size, type, data_size); + } } // LLMessageVariable functions and friends std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg) { - s << "\t\t" << msg.mName << " ("; - switch (msg.mType) - { - case MVT_FIXED: - s << "Fixed, " << msg.mSize << " bytes total)\n"; - break; - case MVT_VARIABLE: - s << "Variable, " << msg.mSize << " bytes of size info)\n"; - break; - default: - s << "Unknown\n"; - break; - } - return s; + s << "\t\t" << msg.mName << " ("; + switch (msg.mType) + { + case MVT_FIXED: + s << "Fixed, " << msg.mSize << " bytes total)\n"; + break; + case MVT_VARIABLE: + s << "Variable, " << msg.mSize << " bytes of size info)\n"; + break; + default: + s << "Unknown\n"; + break; + } + return s; } // LLMessageBlock functions and friends std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg) { - s << "\t" << msg.mName << " ("; - switch (msg.mType) - { - case MBT_SINGLE: - s << "Fixed"; - break; - case MBT_MULTIPLE: - s << "Multiple - " << msg.mNumber << " copies"; - break; - case MBT_VARIABLE: - s << "Variable"; - break; - default: - s << "Unknown"; - break; - } - if (msg.mTotalSize != -1) - { - s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n"; - } - else - { - s << ")\n"; - } - - - for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin(); - iter != msg.mMemberVariables.end(); iter++) - { - LLMessageVariable& ci = *(*iter); - s << ci; - } - - return s; + s << "\t" << msg.mName << " ("; + switch (msg.mType) + { + case MBT_SINGLE: + s << "Fixed"; + break; + case MBT_MULTIPLE: + s << "Multiple - " << msg.mNumber << " copies"; + break; + case MBT_VARIABLE: + s << "Variable"; + break; + default: + s << "Unknown"; + break; + } + if (msg.mTotalSize != -1) + { + s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n"; + } + else + { + s << ")\n"; + } + + + for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin(); + iter != msg.mMemberVariables.end(); iter++) + { + LLMessageVariable& ci = *(*iter); + s << ci; + } + + return s; } // LLMessageTemplate functions and friends std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg) { - switch (msg.mFrequency) - { - case MFT_HIGH: - s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " ("; - s << "High"; - break; - case MFT_MEDIUM: - s << "========================================\n" << "Message #"; - s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " ("; - s << "Medium"; - break; - case MFT_LOW: - s << "========================================\n" << "Message #"; - s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " ("; - s << "Low"; - break; - default: - s << "Unknown"; - break; - } - - if (msg.mTotalSize != -1) - { - s << ", " << msg.mTotalSize << " bytes total)\n"; - } - else - { - s << ")\n"; - } - - for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin(); - iter != msg.mMemberBlocks.end(); iter++) - { - LLMessageBlock* ci = *iter; - s << *ci; - } - - return s; + switch (msg.mFrequency) + { + case MFT_HIGH: + s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " ("; + s << "High"; + break; + case MFT_MEDIUM: + s << "========================================\n" << "Message #"; + s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " ("; + s << "Medium"; + break; + case MFT_LOW: + s << "========================================\n" << "Message #"; + s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " ("; + s << "Low"; + break; + default: + s << "Unknown"; + break; + } + + if (msg.mTotalSize != -1) + { + s << ", " << msg.mTotalSize << " bytes total)\n"; + } + else + { + s << ")\n"; + } + + for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin(); + iter != msg.mMemberBlocks.end(); iter++) + { + LLMessageBlock* ci = *iter; + s << *ci; + } + + return s; } void LLMessageTemplate::banUdp() { - static const char* deprecation[] = { - "NotDeprecated", - "Deprecated", - "UDPDeprecated", - "UDPBlackListed" - }; - if (mDeprecation != MD_DEPRECATED) - { - LL_INFOS() << "Setting " << mName << " to UDPBlackListed was " << deprecation[mDeprecation] << LL_ENDL; - mDeprecation = MD_UDPBLACKLISTED; - } - else - { - LL_INFOS() << mName << " is already more deprecated than UDPBlackListed" << LL_ENDL; - } + static const char* deprecation[] = { + "NotDeprecated", + "Deprecated", + "UDPDeprecated", + "UDPBlackListed" + }; + if (mDeprecation != MD_DEPRECATED) + { + LL_INFOS() << "Setting " << mName << " to UDPBlackListed was " << deprecation[mDeprecation] << LL_ENDL; + mDeprecation = MD_UDPBLACKLISTED; + } + else + { + LL_INFOS() << mName << " is already more deprecated than UDPBlackListed" << LL_ENDL; + } } diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h index 41aca4ab91..e91d4346b6 100644 --- a/indra/llmessage/llmessagetemplate.h +++ b/indra/llmessage/llmessagetemplate.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessagetemplate.h * @brief Declaration of the message template classes. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,388 +34,388 @@ class LLMsgVarData { public: - LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8) - { - } - - LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type) - { - mName = (char *)name; - } - - ~LLMsgVarData() - { - // copy constructor just copies the mData pointer, so only delete mData explicitly - } - - void deleteData() - { - delete[] mData; - mData = NULL; - } - - void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1); - - char *getName() const { return mName; } - S32 getSize() const { return mSize; } - void *getData() { return (void*)mData; } - const void *getData() const { return (const void*)mData; } - S32 getDataSize() const { return mDataSize; } - EMsgVariableType getType() const { return mType; } + LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8) + { + } + + LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type) + { + mName = (char *)name; + } + + ~LLMsgVarData() + { + // copy constructor just copies the mData pointer, so only delete mData explicitly + } + + void deleteData() + { + delete[] mData; + mData = NULL; + } + + void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1); + + char *getName() const { return mName; } + S32 getSize() const { return mSize; } + void *getData() { return (void*)mData; } + const void *getData() const { return (const void*)mData; } + S32 getDataSize() const { return mDataSize; } + EMsgVariableType getType() const { return mType; } protected: - char *mName; - S32 mSize; - S32 mDataSize; + char *mName; + S32 mSize; + S32 mDataSize; - U8 *mData; - EMsgVariableType mType; + U8 *mData; + EMsgVariableType mType; }; class LLMsgBlkData { public: - LLMsgBlkData(const char *name, S32 blocknum) : mBlockNumber(blocknum), mTotalSize(-1) - { - mName = (char *)name; - } - - ~LLMsgBlkData() - { - for (msg_var_data_map_t::iterator iter = mMemberVarData.begin(); - iter != mMemberVarData.end(); iter++) - { - iter->deleteData(); - } - } - - void addVariable(const char *name, EMsgVariableType type) - { - LLMsgVarData tmp(name,type); - mMemberVarData[name] = tmp; - } - - void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1) - { - LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist - temp->addData(data, size, type, data_size); - } - - S32 mBlockNumber; - typedef LLIndexedVector<LLMsgVarData, const char *, 8> msg_var_data_map_t; - msg_var_data_map_t mMemberVarData; - char *mName; - S32 mTotalSize; + LLMsgBlkData(const char *name, S32 blocknum) : mBlockNumber(blocknum), mTotalSize(-1) + { + mName = (char *)name; + } + + ~LLMsgBlkData() + { + for (msg_var_data_map_t::iterator iter = mMemberVarData.begin(); + iter != mMemberVarData.end(); iter++) + { + iter->deleteData(); + } + } + + void addVariable(const char *name, EMsgVariableType type) + { + LLMsgVarData tmp(name,type); + mMemberVarData[name] = tmp; + } + + void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1) + { + LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist + temp->addData(data, size, type, data_size); + } + + S32 mBlockNumber; + typedef LLIndexedVector<LLMsgVarData, const char *, 8> msg_var_data_map_t; + msg_var_data_map_t mMemberVarData; + char *mName; + S32 mTotalSize; }; class LLMsgData { public: - LLMsgData(const char *name) : mTotalSize(-1) - { - mName = (char *)name; - } - ~LLMsgData() - { - for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); - mMemberBlocks.clear(); - } - - void addBlock(LLMsgBlkData *blockp) - { - mMemberBlocks[blockp->mName] = blockp; - } - - void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1); + LLMsgData(const char *name) : mTotalSize(-1) + { + mName = (char *)name; + } + ~LLMsgData() + { + for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); + mMemberBlocks.clear(); + } + + void addBlock(LLMsgBlkData *blockp) + { + mMemberBlocks[blockp->mName] = blockp; + } + + void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1); public: - typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t; - msg_blk_data_map_t mMemberBlocks; - char *mName; - S32 mTotalSize; + typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t; + msg_blk_data_map_t mMemberBlocks; + char *mName; + S32 mTotalSize; }; // LLMessage* classes store the template of messages class LLMessageVariable { public: - LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1) - { - } - - LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1) - { - mName = name; - } - - LLMessageVariable(const char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size) - { - mName = LLMessageStringTable::getInstance()->getString(name); - } - - ~LLMessageVariable() {} - - friend std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg); - - EMsgVariableType getType() const { return mType; } - S32 getSize() const { return mSize; } - char *getName() const { return mName; } + LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1) + { + } + + LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1) + { + mName = name; + } + + LLMessageVariable(const char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size) + { + mName = LLMessageStringTable::getInstance()->getString(name); + } + + ~LLMessageVariable() {} + + friend std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg); + + EMsgVariableType getType() const { return mType; } + S32 getSize() const { return mSize; } + char *getName() const { return mName; } protected: - char *mName; - EMsgVariableType mType; - S32 mSize; + char *mName; + EMsgVariableType mType; + S32 mSize; }; typedef enum e_message_block_type { - MBT_NULL, - MBT_SINGLE, - MBT_MULTIPLE, - MBT_VARIABLE, - MBT_EOF + MBT_NULL, + MBT_SINGLE, + MBT_MULTIPLE, + MBT_VARIABLE, + MBT_EOF } EMsgBlockType; class LLMessageBlock { public: - LLMessageBlock(const char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0) - { - mName = LLMessageStringTable::getInstance()->getString(name); - } - - ~LLMessageBlock() - { - for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePointer()); - } - - void addVariable(char *name, const EMsgVariableType type, const S32 size) - { - LLMessageVariable** varp = &mMemberVariables[name]; - if (*varp != NULL) - { - LL_ERRS() << name << " has already been used as a variable name!" << LL_ENDL; - } - *varp = new LLMessageVariable(name, type, size); - if (((*varp)->getType() != MVT_VARIABLE) - &&(mTotalSize != -1)) - { - mTotalSize += (*varp)->getSize(); - } - else - { - mTotalSize = -1; - } - } - - EMsgVariableType getVariableType(char *name) - { - return (mMemberVariables[name])->getType(); - } - - S32 getVariableSize(char *name) - { - return (mMemberVariables[name])->getSize(); - } - - const LLMessageVariable* getVariable(char* name) const - { - message_variable_map_t::const_iterator iter = mMemberVariables.find(name); - return iter != mMemberVariables.end()? *iter : NULL; - } - - friend std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg); - - typedef LLIndexedVector<LLMessageVariable*, const char *, 8> message_variable_map_t; - message_variable_map_t mMemberVariables; - char *mName; - EMsgBlockType mType; - S32 mNumber; - S32 mTotalSize; + LLMessageBlock(const char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0) + { + mName = LLMessageStringTable::getInstance()->getString(name); + } + + ~LLMessageBlock() + { + for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePointer()); + } + + void addVariable(char *name, const EMsgVariableType type, const S32 size) + { + LLMessageVariable** varp = &mMemberVariables[name]; + if (*varp != NULL) + { + LL_ERRS() << name << " has already been used as a variable name!" << LL_ENDL; + } + *varp = new LLMessageVariable(name, type, size); + if (((*varp)->getType() != MVT_VARIABLE) + &&(mTotalSize != -1)) + { + mTotalSize += (*varp)->getSize(); + } + else + { + mTotalSize = -1; + } + } + + EMsgVariableType getVariableType(char *name) + { + return (mMemberVariables[name])->getType(); + } + + S32 getVariableSize(char *name) + { + return (mMemberVariables[name])->getSize(); + } + + const LLMessageVariable* getVariable(char* name) const + { + message_variable_map_t::const_iterator iter = mMemberVariables.find(name); + return iter != mMemberVariables.end()? *iter : NULL; + } + + friend std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg); + + typedef LLIndexedVector<LLMessageVariable*, const char *, 8> message_variable_map_t; + message_variable_map_t mMemberVariables; + char *mName; + EMsgBlockType mType; + S32 mNumber; + S32 mTotalSize; }; enum EMsgFrequency { - MFT_NULL = 0, // value is size of message number in bytes - MFT_HIGH = 1, - MFT_MEDIUM = 2, - MFT_LOW = 4 + MFT_NULL = 0, // value is size of message number in bytes + MFT_HIGH = 1, + MFT_MEDIUM = 2, + MFT_LOW = 4 }; typedef enum e_message_trust { - MT_TRUST, - MT_NOTRUST + MT_TRUST, + MT_NOTRUST } EMsgTrust; enum EMsgEncoding { - ME_UNENCODED, - ME_ZEROCODED + ME_UNENCODED, + ME_ZEROCODED }; enum EMsgDeprecation { - MD_NOTDEPRECATED, - MD_UDPDEPRECATED, - MD_UDPBLACKLISTED, - MD_DEPRECATED + MD_NOTDEPRECATED, + MD_UDPDEPRECATED, + MD_UDPBLACKLISTED, + MD_DEPRECATED }; class LLMessageTemplate { public: - LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq) - : - //mMemberBlocks(), - mName(NULL), - mFrequency(freq), - mTrust(MT_NOTRUST), - mEncoding(ME_ZEROCODED), - mDeprecation(MD_NOTDEPRECATED), - mMessageNumber(message_number), - mTotalSize(0), - mReceiveCount(0), - mReceiveBytes(0), - mReceiveInvalid(0), - mDecodeTimeThisFrame(0.f), - mTotalDecoded(0), - mTotalDecodeTime(0.f), - mMaxDecodeTimePerMsg(0.f), - mBanFromTrusted(false), - mBanFromUntrusted(false), - mHandlerFunc(NULL), - mUserData(NULL) - { - mName = LLMessageStringTable::getInstance()->getString(name); - } - - ~LLMessageTemplate() - { - for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePointer()); - } - - void addBlock(LLMessageBlock *blockp) - { - LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName]; - if (*member_blockp != NULL) - { - LL_ERRS() << "Block " << blockp->mName - << "has already been used as a block name!" << LL_ENDL; - } - *member_blockp = blockp; - if ( (mTotalSize != -1) - &&(blockp->mTotalSize != -1) - &&( (blockp->mType == MBT_SINGLE) - ||(blockp->mType == MBT_MULTIPLE))) - { - mTotalSize += blockp->mNumber*blockp->mTotalSize; - } - else - { - mTotalSize = -1; - } - } - - LLMessageBlock *getBlock(char *name) - { - return mMemberBlocks[name]; - } - - // Trusted messages can only be recieved on trusted circuits. - void setTrust(EMsgTrust t) - { - mTrust = t; - } - - EMsgTrust getTrust(void) const - { - return mTrust; - } - - // controls for how the message should be encoded - void setEncoding(EMsgEncoding e) - { - mEncoding = e; - } - EMsgEncoding getEncoding() const - { - return mEncoding; - } - - void setDeprecation(EMsgDeprecation d) - { - mDeprecation = d; - } - - EMsgDeprecation getDeprecation() const - { - return mDeprecation; - } - - void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) - { - mHandlerFunc = handler_func; - mUserData = user_data; - } - - bool callHandlerFunc(LLMessageSystem *msgsystem) const - { - if (mHandlerFunc) - { - mHandlerFunc(msgsystem, mUserData); - return true; - } - return false; - } - - bool isUdpBanned() const - { - return mDeprecation == MD_UDPBLACKLISTED; - } - - void banUdp(); - - bool isBanned(bool trustedSource) const - { - return trustedSource ? mBanFromTrusted : mBanFromUntrusted; - } - - friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg); - - const LLMessageBlock* getBlock(char* name) const - { - message_block_map_t::const_iterator iter = mMemberBlocks.find(name); - return iter != mMemberBlocks.end()? *iter : NULL; - } + LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq) + : + //mMemberBlocks(), + mName(NULL), + mFrequency(freq), + mTrust(MT_NOTRUST), + mEncoding(ME_ZEROCODED), + mDeprecation(MD_NOTDEPRECATED), + mMessageNumber(message_number), + mTotalSize(0), + mReceiveCount(0), + mReceiveBytes(0), + mReceiveInvalid(0), + mDecodeTimeThisFrame(0.f), + mTotalDecoded(0), + mTotalDecodeTime(0.f), + mMaxDecodeTimePerMsg(0.f), + mBanFromTrusted(false), + mBanFromUntrusted(false), + mHandlerFunc(NULL), + mUserData(NULL) + { + mName = LLMessageStringTable::getInstance()->getString(name); + } + + ~LLMessageTemplate() + { + for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePointer()); + } + + void addBlock(LLMessageBlock *blockp) + { + LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName]; + if (*member_blockp != NULL) + { + LL_ERRS() << "Block " << blockp->mName + << "has already been used as a block name!" << LL_ENDL; + } + *member_blockp = blockp; + if ( (mTotalSize != -1) + &&(blockp->mTotalSize != -1) + &&( (blockp->mType == MBT_SINGLE) + ||(blockp->mType == MBT_MULTIPLE))) + { + mTotalSize += blockp->mNumber*blockp->mTotalSize; + } + else + { + mTotalSize = -1; + } + } + + LLMessageBlock *getBlock(char *name) + { + return mMemberBlocks[name]; + } + + // Trusted messages can only be recieved on trusted circuits. + void setTrust(EMsgTrust t) + { + mTrust = t; + } + + EMsgTrust getTrust(void) const + { + return mTrust; + } + + // controls for how the message should be encoded + void setEncoding(EMsgEncoding e) + { + mEncoding = e; + } + EMsgEncoding getEncoding() const + { + return mEncoding; + } + + void setDeprecation(EMsgDeprecation d) + { + mDeprecation = d; + } + + EMsgDeprecation getDeprecation() const + { + return mDeprecation; + } + + void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) + { + mHandlerFunc = handler_func; + mUserData = user_data; + } + + bool callHandlerFunc(LLMessageSystem *msgsystem) const + { + if (mHandlerFunc) + { + mHandlerFunc(msgsystem, mUserData); + return true; + } + return false; + } + + bool isUdpBanned() const + { + return mDeprecation == MD_UDPBLACKLISTED; + } + + void banUdp(); + + bool isBanned(bool trustedSource) const + { + return trustedSource ? mBanFromTrusted : mBanFromUntrusted; + } + + friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg); + + const LLMessageBlock* getBlock(char* name) const + { + message_block_map_t::const_iterator iter = mMemberBlocks.find(name); + return iter != mMemberBlocks.end()? *iter : NULL; + } public: - typedef LLIndexedVector<LLMessageBlock*, char*, 8> message_block_map_t; - message_block_map_t mMemberBlocks; - char *mName; - EMsgFrequency mFrequency; - EMsgTrust mTrust; - EMsgEncoding mEncoding; - EMsgDeprecation mDeprecation; - U32 mMessageNumber; - S32 mTotalSize; - U32 mReceiveCount; // how many of this template have been received since last reset - U32 mReceiveBytes; // How many bytes received - U32 mReceiveInvalid; // How many "invalid" packets - F32 mDecodeTimeThisFrame; // Total seconds spent decoding this frame - U32 mTotalDecoded; // Total messages successfully decoded - F32 mTotalDecodeTime; // Total time successfully decoding messages - F32 mMaxDecodeTimePerMsg; - - bool mBanFromTrusted; - bool mBanFromUntrusted; + typedef LLIndexedVector<LLMessageBlock*, char*, 8> message_block_map_t; + message_block_map_t mMemberBlocks; + char *mName; + EMsgFrequency mFrequency; + EMsgTrust mTrust; + EMsgEncoding mEncoding; + EMsgDeprecation mDeprecation; + U32 mMessageNumber; + S32 mTotalSize; + U32 mReceiveCount; // how many of this template have been received since last reset + U32 mReceiveBytes; // How many bytes received + U32 mReceiveInvalid; // How many "invalid" packets + F32 mDecodeTimeThisFrame; // Total seconds spent decoding this frame + U32 mTotalDecoded; // Total messages successfully decoded + F32 mTotalDecodeTime; // Total time successfully decoding messages + F32 mMaxDecodeTimePerMsg; + + bool mBanFromTrusted; + bool mBanFromUntrusted; private: - // message handler function (this is set by each application) - void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data); - void **mUserData; + // message handler function (this is set by each application) + void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data); + void **mUserData; }; #endif // LL_LLMESSAGETEMPLATE_H diff --git a/indra/llmessage/llmessagetemplateparser.cpp b/indra/llmessage/llmessagetemplateparser.cpp index 4b61272454..cf1f49116e 100644 --- a/indra/llmessage/llmessagetemplateparser.cpp +++ b/indra/llmessage/llmessagetemplateparser.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmessagetemplateparser.cpp * @brief LLMessageTemplateParser implementation * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,729 +33,729 @@ // Lets support a small subset of regular expressions here // Syntax is a string made up of: -// a - checks against alphanumeric ([A-Za-z0-9]) -// c - checks against character ([A-Za-z]) -// f - checks against first variable character ([A-Za-z_]) -// v - checks against variable ([A-Za-z0-9_]) -// s - checks against sign of integer ([-0-9]) -// d - checks against integer digit ([0-9]) -// * - repeat last check +// a - checks against alphanumeric ([A-Za-z0-9]) +// c - checks against character ([A-Za-z]) +// f - checks against first variable character ([A-Za-z_]) +// v - checks against variable ([A-Za-z0-9_]) +// s - checks against sign of integer ([-0-9]) +// d - checks against integer digit ([0-9]) +// * - repeat last check // checks 'a' -bool b_return_alphanumeric_ok(char c) +bool b_return_alphanumeric_ok(char c) { - if ( ( (c < 'A') - ||(c > 'Z')) - &&( (c < 'a') - ||(c > 'z')) - &&( (c < '0') - ||(c > '9'))) - { - return false; - } - return true; + if ( ( (c < 'A') + ||(c > 'Z')) + &&( (c < 'a') + ||(c > 'z')) + &&( (c < '0') + ||(c > '9'))) + { + return false; + } + return true; } // checks 'c' -bool b_return_character_ok(char c) +bool b_return_character_ok(char c) { - if ( ( (c < 'A') - ||(c > 'Z')) - &&( (c < 'a') - ||(c > 'z'))) - { - return false; - } - return true; + if ( ( (c < 'A') + ||(c > 'Z')) + &&( (c < 'a') + ||(c > 'z'))) + { + return false; + } + return true; } // checks 'f' -bool b_return_first_variable_ok(char c) +bool b_return_first_variable_ok(char c) { - if ( ( (c < 'A') - ||(c > 'Z')) - &&( (c < 'a') - ||(c > 'z')) - &&(c != '_')) - { - return false; - } - return true; + if ( ( (c < 'A') + ||(c > 'Z')) + &&( (c < 'a') + ||(c > 'z')) + &&(c != '_')) + { + return false; + } + return true; } // checks 'v' -bool b_return_variable_ok(char c) +bool b_return_variable_ok(char c) { - if ( ( (c < 'A') - ||(c > 'Z')) - &&( (c < 'a') - ||(c > 'z')) - &&( (c < '0') - ||(c > '9')) - &&(c != '_')) - { - return false; - } - return true; + if ( ( (c < 'A') + ||(c > 'Z')) + &&( (c < 'a') + ||(c > 'z')) + &&( (c < '0') + ||(c > '9')) + &&(c != '_')) + { + return false; + } + return true; } // checks 's' -bool b_return_signed_integer_ok(char c) +bool b_return_signed_integer_ok(char c) { - if ( ( (c < '0') - ||(c > '9')) - &&(c != '-')) - { - return false; - } - return true; + if ( ( (c < '0') + ||(c > '9')) + &&(c != '-')) + { + return false; + } + return true; } // checks 'd' -bool b_return_integer_ok(char c) +bool b_return_integer_ok(char c) { - if ( (c < '0') - ||(c > '9')) - { - return false; - } - return true; + if ( (c < '0') + ||(c > '9')) + { + return false; + } + return true; } -bool (*gParseCheckCharacters[])(char c) = +bool (*gParseCheckCharacters[])(char c) = { - b_return_alphanumeric_ok, - b_return_character_ok, - b_return_first_variable_ok, - b_return_variable_ok, - b_return_signed_integer_ok, - b_return_integer_ok + b_return_alphanumeric_ok, + b_return_character_ok, + b_return_first_variable_ok, + b_return_variable_ok, + b_return_signed_integer_ok, + b_return_integer_ok }; S32 get_checker_number(char checker) { - switch(checker) - { - case 'a': - return 0; - case 'c': - return 1; - case 'f': - return 2; - case 'v': - return 3; - case 's': - return 4; - case 'd': - return 5; - case '*': - return 9999; - default: - return -1; - } + switch(checker) + { + case 'a': + return 0; + case 'c': + return 1; + case 'f': + return 2; + case 'v': + return 3; + case 's': + return 4; + case 'd': + return 5; + case '*': + return 9999; + default: + return -1; + } } // check token based on passed simplified regular expression -bool b_check_token(const char *token, const char *regexp) +bool b_check_token(const char *token, const char *regexp) { - S32 tptr, rptr = 0; - S32 current_checker, next_checker = 0; - - current_checker = get_checker_number(regexp[rptr++]); - - if (current_checker == -1) - { - LL_ERRS() << "Invalid regular expression value!" << LL_ENDL; - return false; - } - - if (current_checker == 9999) - { - LL_ERRS() << "Regular expression can't start with *!" << LL_ENDL; - return false; - } - - for (tptr = 0; token[tptr]; tptr++) - { - if (current_checker == -1) - { - LL_ERRS() << "Input exceeds regular expression!\nDid you forget a *?" << LL_ENDL; - return false; - } - - if (!gParseCheckCharacters[current_checker](token[tptr])) - { - return false; - } - if (next_checker != 9999) - { - next_checker = get_checker_number(regexp[rptr++]); - if (next_checker != 9999) - { - current_checker = next_checker; - } - } - } - return true; + S32 tptr, rptr = 0; + S32 current_checker, next_checker = 0; + + current_checker = get_checker_number(regexp[rptr++]); + + if (current_checker == -1) + { + LL_ERRS() << "Invalid regular expression value!" << LL_ENDL; + return false; + } + + if (current_checker == 9999) + { + LL_ERRS() << "Regular expression can't start with *!" << LL_ENDL; + return false; + } + + for (tptr = 0; token[tptr]; tptr++) + { + if (current_checker == -1) + { + LL_ERRS() << "Input exceeds regular expression!\nDid you forget a *?" << LL_ENDL; + return false; + } + + if (!gParseCheckCharacters[current_checker](token[tptr])) + { + return false; + } + if (next_checker != 9999) + { + next_checker = get_checker_number(regexp[rptr++]); + if (next_checker != 9999) + { + current_checker = next_checker; + } + } + } + return true; } // C variable can be made up of upper or lower case letters, underscores, or numbers, but can't start with a number -bool b_variable_ok(const char *token) +bool b_variable_ok(const char *token) { - if (!b_check_token(token, "fv*")) - { - LL_WARNS() << "Token '" << token << "' isn't a variable!" << LL_ENDL; - return false; - } - return true; + if (!b_check_token(token, "fv*")) + { + LL_WARNS() << "Token '" << token << "' isn't a variable!" << LL_ENDL; + return false; + } + return true; } // An integer is made up of the digits 0-9 and may be preceded by a '-' -bool b_integer_ok(const char *token) +bool b_integer_ok(const char *token) { - if (!b_check_token(token, "sd*")) - { - LL_WARNS() << "Token isn't an integer!" << LL_ENDL; - return false; - } - return true; + if (!b_check_token(token, "sd*")) + { + LL_WARNS() << "Token isn't an integer!" << LL_ENDL; + return false; + } + return true; } // An integer is made up of the digits 0-9 -bool b_positive_integer_ok(const char *token) +bool b_positive_integer_ok(const char *token) { - if (!b_check_token(token, "d*")) - { - LL_WARNS() << "Token isn't an integer!" << LL_ENDL; - return false; - } - return true; + if (!b_check_token(token, "d*")) + { + LL_WARNS() << "Token isn't an integer!" << LL_ENDL; + return false; + } + return true; } // Done with C functions, here's the tokenizer. -typedef boost::tokenizer< boost::char_separator<char> > tokenizer; +typedef boost::tokenizer< boost::char_separator<char> > tokenizer; LLTemplateTokenizer::LLTemplateTokenizer(const std::string & contents) : mStarted(false), mTokens() { - boost::char_separator<char> newline("\r\n", "", boost::keep_empty_tokens); - boost::char_separator<char> spaces(" \t"); - U32 line_counter = 1; - - tokenizer line_tokens(contents, newline); - for(tokenizer::iterator line_iter = line_tokens.begin(); - line_iter != line_tokens.end(); - ++line_iter, ++line_counter) - { - tokenizer word_tokens(*line_iter, spaces); - for(tokenizer::iterator word_iter = word_tokens.begin(); - word_iter != word_tokens.end(); - ++word_iter) - { - if((*word_iter)[0] == '/') - { - break; // skip to end of line on comments - } - positioned_token pt;// = new positioned_token(); - pt.str = std::string(*word_iter); - pt.line = line_counter; - mTokens.push_back(pt); - } - } - mCurrent = mTokens.begin(); + boost::char_separator<char> newline("\r\n", "", boost::keep_empty_tokens); + boost::char_separator<char> spaces(" \t"); + U32 line_counter = 1; + + tokenizer line_tokens(contents, newline); + for(tokenizer::iterator line_iter = line_tokens.begin(); + line_iter != line_tokens.end(); + ++line_iter, ++line_counter) + { + tokenizer word_tokens(*line_iter, spaces); + for(tokenizer::iterator word_iter = word_tokens.begin(); + word_iter != word_tokens.end(); + ++word_iter) + { + if((*word_iter)[0] == '/') + { + break; // skip to end of line on comments + } + positioned_token pt;// = new positioned_token(); + pt.str = std::string(*word_iter); + pt.line = line_counter; + mTokens.push_back(pt); + } + } + mCurrent = mTokens.begin(); } void LLTemplateTokenizer::inc() { - if(atEOF()) - { - error("trying to increment token of EOF"); - } - else if(mStarted) - { - ++mCurrent; - } - else - { - mStarted = true; - mCurrent = mTokens.begin(); - } + if(atEOF()) + { + error("trying to increment token of EOF"); + } + else if(mStarted) + { + ++mCurrent; + } + else + { + mStarted = true; + mCurrent = mTokens.begin(); + } } void LLTemplateTokenizer::dec() { - if(mCurrent == mTokens.begin()) - { - if(mStarted) - { - mStarted = false; - } - else - { - error("trying to decrement past beginning of file"); - } - } - else - { - mCurrent--; - } + if(mCurrent == mTokens.begin()) + { + if(mStarted) + { + mStarted = false; + } + else + { + error("trying to decrement past beginning of file"); + } + } + else + { + mCurrent--; + } } std::string LLTemplateTokenizer::get() const { - if(atEOF()) - { - error("trying to get EOF"); - } - return mCurrent->str; + if(atEOF()) + { + error("trying to get EOF"); + } + return mCurrent->str; } U32 LLTemplateTokenizer::line() const { - if(atEOF()) - { - return 0; - } - return mCurrent->line; + if(atEOF()) + { + return 0; + } + return mCurrent->line; } bool LLTemplateTokenizer::atEOF() const { - return mCurrent == mTokens.end(); + return mCurrent == mTokens.end(); } std::string LLTemplateTokenizer::next() { - inc(); - return get(); + inc(); + return get(); } bool LLTemplateTokenizer::want(const std::string & token) { - if(atEOF()) return false; - inc(); - if(atEOF()) return false; - if(get() != token) - { - dec(); // back up a step - return false; - } - return true; + if(atEOF()) return false; + inc(); + if(atEOF()) return false; + if(get() != token) + { + dec(); // back up a step + return false; + } + return true; } bool LLTemplateTokenizer::wantEOF() { - // see if the next token is EOF - if(atEOF()) return true; - inc(); - if(!atEOF()) - { - dec(); // back up a step - return false; - } - return true; + // see if the next token is EOF + if(atEOF()) return true; + inc(); + if(!atEOF()) + { + dec(); // back up a step + return false; + } + return true; } void LLTemplateTokenizer::error(std::string message) const { - if(atEOF()) - { - LL_ERRS() << "Unexpected end of file: " << message << LL_ENDL; - } - else - { - LL_ERRS() << "Problem parsing message template at line " - << line() << ", with token '" << get() << "' : " - << message << LL_ENDL; - } + if(atEOF()) + { + LL_ERRS() << "Unexpected end of file: " << message << LL_ENDL; + } + else + { + LL_ERRS() << "Problem parsing message template at line " + << line() << ", with token '" << get() << "' : " + << message << LL_ENDL; + } } // Done with tokenizer, next is the parser. LLTemplateParser::LLTemplateParser(LLTemplateTokenizer & tokens): - mVersion(0.f), - mMessages() + mVersion(0.f), + mMessages() { - // the version number should be the first thing in the file - if (tokens.want("version")) - { - // version number - std::string vers_string = tokens.next(); - mVersion = (F32)atof(vers_string.c_str()); - - LL_INFOS() << "### Message template version " << mVersion << " ###" << LL_ENDL; - } - else - { - LL_ERRS() << "Version must be first in the message template, found " - << tokens.next() << LL_ENDL; - } - - while(LLMessageTemplate * templatep = parseMessage(tokens)) - { - if (templatep->getDeprecation() != MD_DEPRECATED) - { - mMessages.push_back(templatep); - } - else - { - delete templatep; - } - } - - if(!tokens.wantEOF()) - { - LL_ERRS() << "Expected end of template or a message, instead found: " - << tokens.next() << " at " << tokens.line() << LL_ENDL; - } + // the version number should be the first thing in the file + if (tokens.want("version")) + { + // version number + std::string vers_string = tokens.next(); + mVersion = (F32)atof(vers_string.c_str()); + + LL_INFOS() << "### Message template version " << mVersion << " ###" << LL_ENDL; + } + else + { + LL_ERRS() << "Version must be first in the message template, found " + << tokens.next() << LL_ENDL; + } + + while(LLMessageTemplate * templatep = parseMessage(tokens)) + { + if (templatep->getDeprecation() != MD_DEPRECATED) + { + mMessages.push_back(templatep); + } + else + { + delete templatep; + } + } + + if(!tokens.wantEOF()) + { + LL_ERRS() << "Expected end of template or a message, instead found: " + << tokens.next() << " at " << tokens.line() << LL_ENDL; + } } F32 LLTemplateParser::getVersion() const { - return mVersion; + return mVersion; } LLTemplateParser::message_iterator LLTemplateParser::getMessagesBegin() const { - return mMessages.begin(); + return mMessages.begin(); } LLTemplateParser::message_iterator LLTemplateParser::getMessagesEnd() const { - return mMessages.end(); + return mMessages.end(); } // static LLMessageTemplate * LLTemplateParser::parseMessage(LLTemplateTokenizer & tokens) { - LLMessageTemplate *templatep = NULL; - if(!tokens.want("{")) - { - return NULL; - } - - // name first - std::string template_name = tokens.next(); - - // is name a legit C variable name - if (!b_variable_ok(template_name.c_str())) - { - LL_ERRS() << "Not legit variable name: " << template_name << " at " << tokens.line() << LL_ENDL; - } - - // ok, now get Frequency ("High", "Medium", or "Low") - EMsgFrequency frequency = MFT_LOW; - std::string freq_string = tokens.next(); - if (freq_string == "High") - { - frequency = MFT_HIGH; - } - else if (freq_string == "Medium") - { - frequency = MFT_MEDIUM; - } - else if (freq_string == "Low" || freq_string == "Fixed") - { - frequency = MFT_LOW; - } - else - { - LL_ERRS() << "Expected frequency, got " << freq_string << " at " << tokens.line() << LL_ENDL; - } - - // TODO more explicit checking here pls - U32 message_number = strtoul(tokens.next().c_str(),NULL,0); - - switch (frequency) { - case MFT_HIGH: - break; - case MFT_MEDIUM: - message_number = (255 << 8) | message_number; - break; - case MFT_LOW: - message_number = (255 << 24) | (255 << 16) | message_number; - break; - default: - LL_ERRS() << "Unknown frequency enum: " << frequency << LL_ENDL; - } - - templatep = new LLMessageTemplate( - template_name.c_str(), - message_number, - frequency); - - // Now get trust ("Trusted", "NotTrusted") - std::string trust = tokens.next(); - if (trust == "Trusted") - { - templatep->setTrust(MT_TRUST); - } - else if (trust == "NotTrusted") - { - templatep->setTrust(MT_NOTRUST); - } - else - { - LL_ERRS() << "Bad trust " << trust << " at " << tokens.line() << LL_ENDL; - } - - // get encoding - std::string encoding = tokens.next(); - if(encoding == "Unencoded") - { - templatep->setEncoding(ME_UNENCODED); - } - else if(encoding == "Zerocoded") - { - templatep->setEncoding(ME_ZEROCODED); - } - else - { - LL_ERRS() << "Bad encoding " << encoding << " at " << tokens.line() << LL_ENDL; - } - - // get deprecation - if(tokens.want("Deprecated")) - { - templatep->setDeprecation(MD_DEPRECATED); - } - else if (tokens.want("UDPDeprecated")) - { - templatep->setDeprecation(MD_UDPDEPRECATED); - } - else if (tokens.want("UDPBlackListed")) - { - templatep->setDeprecation(MD_UDPBLACKLISTED); - } - else if (tokens.want("NotDeprecated")) - { - // this is the default value, but it can't hurt to set it twice - templatep->setDeprecation(MD_NOTDEPRECATED); - } - else { - // It's probably a brace, let's just start block processing - } - - while(LLMessageBlock * blockp = parseBlock(tokens)) - { - templatep->addBlock(blockp); - } - - if(!tokens.want("}")) - { - LL_ERRS() << "Expecting closing } for message " << template_name - << " at " << tokens.line() << LL_ENDL; - } - return templatep; + LLMessageTemplate *templatep = NULL; + if(!tokens.want("{")) + { + return NULL; + } + + // name first + std::string template_name = tokens.next(); + + // is name a legit C variable name + if (!b_variable_ok(template_name.c_str())) + { + LL_ERRS() << "Not legit variable name: " << template_name << " at " << tokens.line() << LL_ENDL; + } + + // ok, now get Frequency ("High", "Medium", or "Low") + EMsgFrequency frequency = MFT_LOW; + std::string freq_string = tokens.next(); + if (freq_string == "High") + { + frequency = MFT_HIGH; + } + else if (freq_string == "Medium") + { + frequency = MFT_MEDIUM; + } + else if (freq_string == "Low" || freq_string == "Fixed") + { + frequency = MFT_LOW; + } + else + { + LL_ERRS() << "Expected frequency, got " << freq_string << " at " << tokens.line() << LL_ENDL; + } + + // TODO more explicit checking here pls + U32 message_number = strtoul(tokens.next().c_str(),NULL,0); + + switch (frequency) { + case MFT_HIGH: + break; + case MFT_MEDIUM: + message_number = (255 << 8) | message_number; + break; + case MFT_LOW: + message_number = (255 << 24) | (255 << 16) | message_number; + break; + default: + LL_ERRS() << "Unknown frequency enum: " << frequency << LL_ENDL; + } + + templatep = new LLMessageTemplate( + template_name.c_str(), + message_number, + frequency); + + // Now get trust ("Trusted", "NotTrusted") + std::string trust = tokens.next(); + if (trust == "Trusted") + { + templatep->setTrust(MT_TRUST); + } + else if (trust == "NotTrusted") + { + templatep->setTrust(MT_NOTRUST); + } + else + { + LL_ERRS() << "Bad trust " << trust << " at " << tokens.line() << LL_ENDL; + } + + // get encoding + std::string encoding = tokens.next(); + if(encoding == "Unencoded") + { + templatep->setEncoding(ME_UNENCODED); + } + else if(encoding == "Zerocoded") + { + templatep->setEncoding(ME_ZEROCODED); + } + else + { + LL_ERRS() << "Bad encoding " << encoding << " at " << tokens.line() << LL_ENDL; + } + + // get deprecation + if(tokens.want("Deprecated")) + { + templatep->setDeprecation(MD_DEPRECATED); + } + else if (tokens.want("UDPDeprecated")) + { + templatep->setDeprecation(MD_UDPDEPRECATED); + } + else if (tokens.want("UDPBlackListed")) + { + templatep->setDeprecation(MD_UDPBLACKLISTED); + } + else if (tokens.want("NotDeprecated")) + { + // this is the default value, but it can't hurt to set it twice + templatep->setDeprecation(MD_NOTDEPRECATED); + } + else { + // It's probably a brace, let's just start block processing + } + + while(LLMessageBlock * blockp = parseBlock(tokens)) + { + templatep->addBlock(blockp); + } + + if(!tokens.want("}")) + { + LL_ERRS() << "Expecting closing } for message " << template_name + << " at " << tokens.line() << LL_ENDL; + } + return templatep; } // static LLMessageBlock * LLTemplateParser::parseBlock(LLTemplateTokenizer & tokens) { - LLMessageBlock * blockp = NULL; - - if(!tokens.want("{")) - { - return NULL; - } - - // name first - std::string block_name = tokens.next(); - - // is name a legit C variable name - if (!b_variable_ok(block_name.c_str())) - { - LL_ERRS() << "not a legal block name: " << block_name - << " at " << tokens.line() << LL_ENDL; - } - - // now, block type ("Single", "Multiple", or "Variable") - std::string block_type = tokens.next(); - // which one is it? - if (block_type == "Single") - { - // ok, we can create a block - blockp = new LLMessageBlock(block_name.c_str(), MBT_SINGLE); - } - else if (block_type == "Multiple") - { - // need to get the number of repeats - std::string repeats = tokens.next(); - - // is it a legal integer - if (!b_positive_integer_ok(repeats.c_str())) - { - LL_ERRS() << "not a legal integer for block multiple count: " - << repeats << " at " << tokens.line() << LL_ENDL; - } - - // ok, we can create a block - blockp = new LLMessageBlock(block_name.c_str(), - MBT_MULTIPLE, - atoi(repeats.c_str())); - } - else if (block_type == "Variable") - { - // ok, we can create a block - blockp = new LLMessageBlock(block_name.c_str(), MBT_VARIABLE); - } - else - { - LL_ERRS() << "bad block type: " << block_type - << " at " << tokens.line() << LL_ENDL; - } - - - while(LLMessageVariable * varp = parseVariable(tokens)) - { - blockp->addVariable(varp->getName(), - varp->getType(), - varp->getSize()); - delete varp; - } - - if(!tokens.want("}")) - { - LL_ERRS() << "Expecting closing } for block " << block_name - << " at " << tokens.line() << LL_ENDL; - } - return blockp; - + LLMessageBlock * blockp = NULL; + + if(!tokens.want("{")) + { + return NULL; + } + + // name first + std::string block_name = tokens.next(); + + // is name a legit C variable name + if (!b_variable_ok(block_name.c_str())) + { + LL_ERRS() << "not a legal block name: " << block_name + << " at " << tokens.line() << LL_ENDL; + } + + // now, block type ("Single", "Multiple", or "Variable") + std::string block_type = tokens.next(); + // which one is it? + if (block_type == "Single") + { + // ok, we can create a block + blockp = new LLMessageBlock(block_name.c_str(), MBT_SINGLE); + } + else if (block_type == "Multiple") + { + // need to get the number of repeats + std::string repeats = tokens.next(); + + // is it a legal integer + if (!b_positive_integer_ok(repeats.c_str())) + { + LL_ERRS() << "not a legal integer for block multiple count: " + << repeats << " at " << tokens.line() << LL_ENDL; + } + + // ok, we can create a block + blockp = new LLMessageBlock(block_name.c_str(), + MBT_MULTIPLE, + atoi(repeats.c_str())); + } + else if (block_type == "Variable") + { + // ok, we can create a block + blockp = new LLMessageBlock(block_name.c_str(), MBT_VARIABLE); + } + else + { + LL_ERRS() << "bad block type: " << block_type + << " at " << tokens.line() << LL_ENDL; + } + + + while(LLMessageVariable * varp = parseVariable(tokens)) + { + blockp->addVariable(varp->getName(), + varp->getType(), + varp->getSize()); + delete varp; + } + + if(!tokens.want("}")) + { + LL_ERRS() << "Expecting closing } for block " << block_name + << " at " << tokens.line() << LL_ENDL; + } + return blockp; + } // static LLMessageVariable * LLTemplateParser::parseVariable(LLTemplateTokenizer & tokens) { - LLMessageVariable * varp = NULL; - if(!tokens.want("{")) - { - return NULL; - } - - std::string var_name = tokens.next(); - - if (!b_variable_ok(var_name.c_str())) - { - LL_ERRS() << "Not a legit variable name: " << var_name - << " at " << tokens.line() << LL_ENDL; - } - - std::string var_type = tokens.next(); - - if (var_type == "U8") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_U8, 1); - } - else if (var_type == "U16") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_U16, 2); - } - else if (var_type == "U32") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_U32, 4); - } - else if (var_type == "U64") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_U64, 8); - } - else if (var_type == "S8") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_S8, 1); - } - else if (var_type == "S16") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_S16, 2); - } - else if (var_type == "S32") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_S32, 4); - } - else if (var_type == "S64") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_S64, 8); - } - else if (var_type == "F32") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_F32, 4); - } - else if (var_type == "F64") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_F64, 8); - } - else if (var_type == "LLVector3") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_LLVector3, 12); - } - else if (var_type == "LLVector3d") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_LLVector3d, 24); - } - else if (var_type == "LLVector4") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_LLVector4, 16); - } - else if (var_type == "LLQuaternion") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_LLQuaternion, 12); - } - else if (var_type == "LLUUID") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_LLUUID, 16); - } - else if (var_type == "BOOL") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_BOOL, 1); - } - else if (var_type == "IPADDR") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_IP_ADDR, 4); - } - else if (var_type == "IPPORT") - { - varp = new LLMessageVariable(var_name.c_str(), MVT_IP_PORT, 2); - } - else if (var_type == "Fixed" || var_type == "Variable") - { - std::string variable_size = tokens.next(); - - if (!b_positive_integer_ok(variable_size.c_str())) - { - LL_ERRS() << "not a legal integer variable size: " << variable_size - << " at " << tokens.line() << LL_ENDL; - } - - EMsgVariableType type_enum; - if(var_type == "Variable") - { - type_enum = MVT_VARIABLE; - } - else if(var_type == "Fixed") - { - type_enum = MVT_FIXED; - } - else - { - type_enum = MVT_FIXED; // removes a warning - LL_ERRS() << "bad variable type: " << var_type - << " at " << tokens.line() << LL_ENDL; - } - - varp = new LLMessageVariable( - var_name.c_str(), - type_enum, - atoi(variable_size.c_str())); - } - else - { - LL_ERRS() << "bad variable type:" << var_type - << " at " << tokens.line() << LL_ENDL; - } - - if(!tokens.want("}")) - { - LL_ERRS() << "Expecting closing } for variable " << var_name - << " at " << tokens.line() << LL_ENDL; - } - return varp; + LLMessageVariable * varp = NULL; + if(!tokens.want("{")) + { + return NULL; + } + + std::string var_name = tokens.next(); + + if (!b_variable_ok(var_name.c_str())) + { + LL_ERRS() << "Not a legit variable name: " << var_name + << " at " << tokens.line() << LL_ENDL; + } + + std::string var_type = tokens.next(); + + if (var_type == "U8") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_U8, 1); + } + else if (var_type == "U16") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_U16, 2); + } + else if (var_type == "U32") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_U32, 4); + } + else if (var_type == "U64") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_U64, 8); + } + else if (var_type == "S8") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_S8, 1); + } + else if (var_type == "S16") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_S16, 2); + } + else if (var_type == "S32") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_S32, 4); + } + else if (var_type == "S64") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_S64, 8); + } + else if (var_type == "F32") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_F32, 4); + } + else if (var_type == "F64") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_F64, 8); + } + else if (var_type == "LLVector3") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_LLVector3, 12); + } + else if (var_type == "LLVector3d") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_LLVector3d, 24); + } + else if (var_type == "LLVector4") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_LLVector4, 16); + } + else if (var_type == "LLQuaternion") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_LLQuaternion, 12); + } + else if (var_type == "LLUUID") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_LLUUID, 16); + } + else if (var_type == "BOOL") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_BOOL, 1); + } + else if (var_type == "IPADDR") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_IP_ADDR, 4); + } + else if (var_type == "IPPORT") + { + varp = new LLMessageVariable(var_name.c_str(), MVT_IP_PORT, 2); + } + else if (var_type == "Fixed" || var_type == "Variable") + { + std::string variable_size = tokens.next(); + + if (!b_positive_integer_ok(variable_size.c_str())) + { + LL_ERRS() << "not a legal integer variable size: " << variable_size + << " at " << tokens.line() << LL_ENDL; + } + + EMsgVariableType type_enum; + if(var_type == "Variable") + { + type_enum = MVT_VARIABLE; + } + else if(var_type == "Fixed") + { + type_enum = MVT_FIXED; + } + else + { + type_enum = MVT_FIXED; // removes a warning + LL_ERRS() << "bad variable type: " << var_type + << " at " << tokens.line() << LL_ENDL; + } + + varp = new LLMessageVariable( + var_name.c_str(), + type_enum, + atoi(variable_size.c_str())); + } + else + { + LL_ERRS() << "bad variable type:" << var_type + << " at " << tokens.line() << LL_ENDL; + } + + if(!tokens.want("}")) + { + LL_ERRS() << "Expecting closing } for variable " << var_name + << " at " << tokens.line() << LL_ENDL; + } + return varp; } diff --git a/indra/llmessage/llmessagetemplateparser.h b/indra/llmessage/llmessagetemplateparser.h index 372a2b292d..83ed608429 100644 --- a/indra/llmessage/llmessagetemplateparser.h +++ b/indra/llmessage/llmessagetemplateparser.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessagetemplateparser.h * @brief Classes to parse message template. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,48 +33,48 @@ class LLTemplateTokenizer { public: - LLTemplateTokenizer(const std::string & contents); + LLTemplateTokenizer(const std::string & contents); - U32 line() const; - bool atEOF() const; - std::string next(); + U32 line() const; + bool atEOF() const; + std::string next(); - bool want(const std::string & token); - bool wantEOF(); + bool want(const std::string & token); + bool wantEOF(); private: - void inc(); - void dec(); - std::string get() const; - void error(std::string message = "generic") const; + void inc(); + void dec(); + std::string get() const; + void error(std::string message = "generic") const; - struct positioned_token - { - std::string str; - U32 line; - }; - - bool mStarted; - std::list<positioned_token> mTokens; - std::list<positioned_token>::const_iterator mCurrent; + struct positioned_token + { + std::string str; + U32 line; + }; + + bool mStarted; + std::list<positioned_token> mTokens; + std::list<positioned_token>::const_iterator mCurrent; }; class LLTemplateParser { public: - typedef std::list<LLMessageTemplate *>::const_iterator message_iterator; - - static LLMessageTemplate * parseMessage(LLTemplateTokenizer & tokens); - static LLMessageBlock * parseBlock(LLTemplateTokenizer & tokens); - static LLMessageVariable * parseVariable(LLTemplateTokenizer & tokens); + typedef std::list<LLMessageTemplate *>::const_iterator message_iterator; + + static LLMessageTemplate * parseMessage(LLTemplateTokenizer & tokens); + static LLMessageBlock * parseBlock(LLTemplateTokenizer & tokens); + static LLMessageVariable * parseVariable(LLTemplateTokenizer & tokens); + + LLTemplateParser(LLTemplateTokenizer & tokens); + message_iterator getMessagesBegin() const; + message_iterator getMessagesEnd() const; + F32 getVersion() const; - LLTemplateParser(LLTemplateTokenizer & tokens); - message_iterator getMessagesBegin() const; - message_iterator getMessagesEnd() const; - F32 getVersion() const; - private: - F32 mVersion; - std::list<LLMessageTemplate *> mMessages; + F32 mVersion; + std::list<LLMessageTemplate *> mMessages; }; #endif diff --git a/indra/llmessage/llmessagethrottle.cpp b/indra/llmessage/llmessagethrottle.cpp index bddb9e14d6..abcb1085ba 100644 --- a/indra/llmessage/llmessagethrottle.cpp +++ b/indra/llmessage/llmessagethrottle.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmessagethrottle.cpp * @brief LLMessageThrottle class used for throttling messages. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,15 +33,15 @@ // This is used for the stl search_n function. bool eq_message_throttle_entry(LLMessageThrottleEntry a, LLMessageThrottleEntry b) - { return a.getHash() == b.getHash(); } + { return a.getHash() == b.getHash(); } const U64 SEC_TO_USEC = 1000000; - + // How long (in microseconds) each type of message stays in its throttle list. const U64 MAX_MESSAGE_AGE[MTC_EOF] = { - 10 * SEC_TO_USEC, // MTC_VIEWER_ALERT - 10 * SEC_TO_USEC // MTC_AGENT_ALERT + 10 * SEC_TO_USEC, // MTC_VIEWER_ALERT + 10 * SEC_TO_USEC // MTC_AGENT_ALERT }; LLMessageThrottle::LLMessageThrottle() @@ -54,100 +54,100 @@ LLMessageThrottle::~LLMessageThrottle() void LLMessageThrottle::pruneEntries() { - // Go through each message category, and prune entries older than max age. - S32 cat; - for (cat = 0; cat < MTC_EOF; cat++) - { - message_list_t* message_list = &(mMessageList[cat]); - - // Use a reverse iterator, since entries on the back will be the oldest. - message_list_reverse_iterator_t r_iterator = message_list->rbegin(); - message_list_reverse_iterator_t r_last = message_list->rend(); - - // Look for the first entry younger than the maximum age. - F32 max_age = (F32)MAX_MESSAGE_AGE[cat]; - bool found = false; - while (r_iterator != r_last && !found) - { - if ( LLFrameTimer::getTotalTime() - (*r_iterator).getEntryTime() < max_age ) - { - // We found a young enough entry. - found = true; - - // Did we find at least one entry to remove? - if (r_iterator != message_list->rbegin()) - { - // Yes, remove it. - message_list->erase(r_iterator.base(), message_list->end()); - } - } - else - { - r_iterator++; - } - } - - // If we didn't find any entries young enough to keep, remove them all. - if (!found) - { - message_list->clear(); - } - } + // Go through each message category, and prune entries older than max age. + S32 cat; + for (cat = 0; cat < MTC_EOF; cat++) + { + message_list_t* message_list = &(mMessageList[cat]); + + // Use a reverse iterator, since entries on the back will be the oldest. + message_list_reverse_iterator_t r_iterator = message_list->rbegin(); + message_list_reverse_iterator_t r_last = message_list->rend(); + + // Look for the first entry younger than the maximum age. + F32 max_age = (F32)MAX_MESSAGE_AGE[cat]; + bool found = false; + while (r_iterator != r_last && !found) + { + if ( LLFrameTimer::getTotalTime() - (*r_iterator).getEntryTime() < max_age ) + { + // We found a young enough entry. + found = true; + + // Did we find at least one entry to remove? + if (r_iterator != message_list->rbegin()) + { + // Yes, remove it. + message_list->erase(r_iterator.base(), message_list->end()); + } + } + else + { + r_iterator++; + } + } + + // If we didn't find any entries young enough to keep, remove them all. + if (!found) + { + message_list->clear(); + } + } } bool LLMessageThrottle::addViewerAlert(const LLUUID& to, const std::string& mesg) { - message_list_t* message_list = &(mMessageList[MTC_VIEWER_ALERT]); - - // Concatenate from,to,mesg into one string. - std::ostringstream full_mesg; - full_mesg << to << mesg; - - // Create an entry for this message. - size_t hash = llhash(full_mesg.str().c_str()); - LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime()); - - // Check if this message is already in the list. - message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(), - 1, entry, eq_message_throttle_entry); - if (found == message_list->end()) - { - // This message was not found. Add it to the list. - message_list->push_front(entry); - return true; - } - else - { - // This message was already in the list. - return false; - } + message_list_t* message_list = &(mMessageList[MTC_VIEWER_ALERT]); + + // Concatenate from,to,mesg into one string. + std::ostringstream full_mesg; + full_mesg << to << mesg; + + // Create an entry for this message. + size_t hash = llhash(full_mesg.str().c_str()); + LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime()); + + // Check if this message is already in the list. + message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(), + 1, entry, eq_message_throttle_entry); + if (found == message_list->end()) + { + // This message was not found. Add it to the list. + message_list->push_front(entry); + return true; + } + else + { + // This message was already in the list. + return false; + } } bool LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, const std::string& mesg) { - message_list_t* message_list = &(mMessageList[MTC_AGENT_ALERT]); - - // Concatenate from,to,mesg into one string. - std::ostringstream full_mesg; - full_mesg << agent << task << mesg; - - // Create an entry for this message. - size_t hash = llhash(full_mesg.str().c_str()); - LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime()); - - // Check if this message is already in the list. - message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(), - 1, entry, eq_message_throttle_entry); - if (found == message_list->end()) - { - // This message was not found. Add it to the list. - message_list->push_front(entry); - return true; - } - else - { - // This message was already in the list. - return false; - } + message_list_t* message_list = &(mMessageList[MTC_AGENT_ALERT]); + + // Concatenate from,to,mesg into one string. + std::ostringstream full_mesg; + full_mesg << agent << task << mesg; + + // Create an entry for this message. + size_t hash = llhash(full_mesg.str().c_str()); + LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime()); + + // Check if this message is already in the list. + message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(), + 1, entry, eq_message_throttle_entry); + if (found == message_list->end()) + { + // This message was not found. Add it to the list. + message_list->push_front(entry); + return true; + } + else + { + // This message was already in the list. + return false; + } } diff --git a/indra/llmessage/llmessagethrottle.h b/indra/llmessage/llmessagethrottle.h index ae62b43920..295bddbd8c 100644 --- a/indra/llmessage/llmessagethrottle.h +++ b/indra/llmessage/llmessagethrottle.h @@ -1,25 +1,25 @@ -/** +/** * @file llmessagethrottle.h * @brief LLMessageThrottle class used for throttling messages. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,43 +34,43 @@ typedef enum e_message_throttle_categories { - MTC_VIEWER_ALERT, - MTC_AGENT_ALERT, - MTC_EOF + MTC_VIEWER_ALERT, + MTC_AGENT_ALERT, + MTC_EOF } EMessageThrottleCats; class LLMessageThrottleEntry { public: - LLMessageThrottleEntry(const size_t hash, const U64 entry_time) - : mHash(hash), mEntryTime(entry_time) {} + LLMessageThrottleEntry(const size_t hash, const U64 entry_time) + : mHash(hash), mEntryTime(entry_time) {} - size_t getHash() const { return mHash; } - U64 getEntryTime() const { return mEntryTime; } + size_t getHash() const { return mHash; } + U64 getEntryTime() const { return mEntryTime; } protected: - size_t mHash; - U64 mEntryTime; + size_t mHash; + U64 mEntryTime; }; class LLMessageThrottle { public: - LLMessageThrottle(); - ~LLMessageThrottle(); + LLMessageThrottle(); + ~LLMessageThrottle(); - bool addViewerAlert (const LLUUID& to, const std::string& mesg); - bool addAgentAlert (const LLUUID& agent, const LLUUID& task, const std::string& mesg); + bool addViewerAlert (const LLUUID& to, const std::string& mesg); + bool addAgentAlert (const LLUUID& agent, const LLUUID& task, const std::string& mesg); - void pruneEntries(); + void pruneEntries(); protected: - typedef std::deque<LLMessageThrottleEntry> message_list_t; - typedef std::deque<LLMessageThrottleEntry>::iterator message_list_iterator_t; - typedef std::deque<LLMessageThrottleEntry>::reverse_iterator message_list_reverse_iterator_t; - typedef std::deque<LLMessageThrottleEntry>::const_iterator message_list_const_iterator_t; - typedef std::deque<LLMessageThrottleEntry>::const_reverse_iterator message_list_const_reverse_iterator_t; - message_list_t mMessageList[MTC_EOF]; + typedef std::deque<LLMessageThrottleEntry> message_list_t; + typedef std::deque<LLMessageThrottleEntry>::iterator message_list_iterator_t; + typedef std::deque<LLMessageThrottleEntry>::reverse_iterator message_list_reverse_iterator_t; + typedef std::deque<LLMessageThrottleEntry>::const_iterator message_list_const_iterator_t; + typedef std::deque<LLMessageThrottleEntry>::const_reverse_iterator message_list_const_reverse_iterator_t; + message_list_t mMessageList[MTC_EOF]; }; extern LLMessageThrottle gMessageThrottle; diff --git a/indra/llmessage/llmsgvariabletype.h b/indra/llmessage/llmsgvariabletype.h index c4de822b46..74575f3a53 100644 --- a/indra/llmessage/llmsgvariabletype.h +++ b/indra/llmessage/llmsgvariabletype.h @@ -1,25 +1,25 @@ -/** +/** * @file llmsgvariabletype.h * @brief Declaration of the EMsgVariableType enumeration. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,31 +29,31 @@ typedef enum e_message_variable_type { - MVT_NULL, - MVT_FIXED, - MVT_VARIABLE, - MVT_U8, - MVT_U16, - MVT_U32, - MVT_U64, - MVT_S8, - MVT_S16, - MVT_S32, - MVT_S64, - MVT_F32, - MVT_F64, - MVT_LLVector3, - MVT_LLVector3d, - MVT_LLVector4, - MVT_LLQuaternion, - MVT_LLUUID, - MVT_BOOL, - MVT_IP_ADDR, - MVT_IP_PORT, - MVT_U16Vec3, - MVT_U16Quat, - MVT_S16Array, - MVT_EOL + MVT_NULL, + MVT_FIXED, + MVT_VARIABLE, + MVT_U8, + MVT_U16, + MVT_U32, + MVT_U64, + MVT_S8, + MVT_S16, + MVT_S32, + MVT_S64, + MVT_F32, + MVT_F64, + MVT_LLVector3, + MVT_LLVector3d, + MVT_LLVector4, + MVT_LLQuaternion, + MVT_LLUUID, + MVT_BOOL, + MVT_IP_ADDR, + MVT_IP_PORT, + MVT_U16Vec3, + MVT_U16Quat, + MVT_S16Array, + MVT_EOL } EMsgVariableType; #endif // LL_LLMSGVARIABLETYPE_H diff --git a/indra/llmessage/llnamevalue.cpp b/indra/llmessage/llnamevalue.cpp index 761e990c76..853ae7df82 100644 --- a/indra/llmessage/llnamevalue.cpp +++ b/indra/llmessage/llnamevalue.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llnamevalue.cpp * @brief class for defining name value pairs. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,40 +41,40 @@ // you change U64_BUFFER_LEN. enum { - NV_BUFFER_LEN = 2048, - U64_BUFFER_LEN = 64 + NV_BUFFER_LEN = 2048, + U64_BUFFER_LEN = 64 }; -LLStringTable gNVNameTable(256); +LLStringTable gNVNameTable(256); char NameValueTypeStrings[NVT_EOF][NAME_VALUE_TYPE_STRING_LENGTH] = /*Flawfinder: Ignore*/ { - "NULL", - "STRING", - "F32", - "S32", - "VEC3", - "U32", - "CAMERA", // Deprecated, but leaving in case removing completely would cause problems - "ASSET", - "U64" -}; + "NULL", + "STRING", + "F32", + "S32", + "VEC3", + "U32", + "CAMERA", // Deprecated, but leaving in case removing completely would cause problems + "ASSET", + "U64" +}; char NameValueClassStrings[NVC_EOF][NAME_VALUE_CLASS_STRING_LENGTH] = /*Flawfinder: Ignore*/ { - "NULL", - "R", // read only - "RW" // read write -}; + "NULL", + "R", // read only + "RW" // read write +}; char NameValueSendtoStrings[NVS_EOF][NAME_VALUE_SENDTO_STRING_LENGTH] = /*Flawfinder: Ignore*/ { - "NULL", - "S", // "Sim", formerly SIM - "DS", // "Data Sim" formerly SIM_SPACE - "SV", // "Sim Viewer" formerly SIM_VIEWER - "DSV" // "Data Sim Viewer", formerly SIM_SPACE_VIEWER -}; /*Flawfinder: Ignore*/ + "NULL", + "S", // "Sim", formerly SIM + "DS", // "Data Sim" formerly SIM_SPACE + "SV", // "Sim Viewer" formerly SIM_VIEWER + "DSV" // "Data Sim Viewer", formerly SIM_SPACE_VIEWER +}; /*Flawfinder: Ignore*/ // @@ -83,205 +83,205 @@ char NameValueSendtoStrings[NVS_EOF][NAME_VALUE_SENDTO_STRING_LENGTH] = /*Flawfi LLNameValue::LLNameValue() { - baseInit(); + baseInit(); } void LLNameValue::baseInit() { - mNVNameTable = &gNVNameTable; + mNVNameTable = &gNVNameTable; + + mName = NULL; + mNameValueReference.string = NULL; + + mType = NVT_NULL; + mStringType = NameValueTypeStrings[NVT_NULL]; - mName = NULL; - mNameValueReference.string = NULL; + mClass = NVC_NULL; + mStringClass = NameValueClassStrings[NVC_NULL]; - mType = NVT_NULL; - mStringType = NameValueTypeStrings[NVT_NULL]; - - mClass = NVC_NULL; - mStringClass = NameValueClassStrings[NVC_NULL]; - - mSendto = NVS_NULL; - mStringSendto = NameValueSendtoStrings[NVS_NULL]; + mSendto = NVS_NULL; + mStringSendto = NameValueSendtoStrings[NVS_NULL]; } void LLNameValue::init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto) { - mNVNameTable = &gNVNameTable; - - mName = mNVNameTable->addString(name); - - // Nota Bene: Whatever global structure manages this should have these in the name table already! - mStringType = mNVNameTable->addString(type); - if (!strcmp(mStringType, "STRING")) - { - S32 string_length = (S32)strlen(data); /*Flawfinder: Ignore*/ - mType = NVT_STRING; - - delete[] mNameValueReference.string; - - // two options here. . . data can either look like foo or "foo" - // WRONG! - this is a poorly implemented and incomplete escape - // mechanism. For example, using this scheme, there is no way - // to tell an intentional double quotes from a zero length - // string. This needs to excised. Phoenix - //if (strchr(data, '\"')) - //{ - // string_length -= 2; - // mNameValueReference.string = new char[string_length + 1];; - // strncpy(mNameValueReference.string, data + 1, string_length); - //} - //else - //{ - mNameValueReference.string = new char[string_length + 1];; - strncpy(mNameValueReference.string, data, string_length); /*Flawfinder: Ignore*/ - //} - mNameValueReference.string[string_length] = 0; - } - else if (!strcmp(mStringType, "F32")) - { - mType = NVT_F32; - mNameValueReference.f32 = new F32((F32)atof(data)); - } - else if (!strcmp(mStringType, "S32")) - { - mType = NVT_S32; - mNameValueReference.s32 = new S32(atoi(data)); - } - else if (!strcmp(mStringType, "U64")) - { - mType = NVT_U64; - mNameValueReference.u64 = new U64(str_to_U64(ll_safe_string(data))); - } - else if (!strcmp(mStringType, "VEC3")) - { - mType = NVT_VEC3; - F32 t1, t2, t3; - - // two options here. . . data can either look like 0, 1, 2 or <0, 1, 2> - - if (strchr(data, '<')) - { - sscanf(data, "<%f, %f, %f>", &t1, &t2, &t3); - } - else - { - sscanf(data, "%f, %f, %f", &t1, &t2, &t3); - } - - // finite checks - if (!llfinite(t1) || !llfinite(t2) || !llfinite(t3)) - { - t1 = 0.f; - t2 = 0.f; - t3 = 0.f; - } - - mNameValueReference.vec3 = new LLVector3(t1, t2, t3); - } - else if (!strcmp(mStringType, "U32")) - { - mType = NVT_U32; - mNameValueReference.u32 = new U32(atoi(data)); - } - else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET])) - { - // assets are treated like strings, except that the name has - // meaning to an LLAssetInfo object - S32 string_length = (S32)strlen(data); /*Flawfinder: Ignore*/ - mType = NVT_ASSET; - - // two options here. . . data can either look like foo or "foo" - // WRONG! - this is a poorly implemented and incomplete escape - // mechanism. For example, using this scheme, there is no way - // to tell an intentional double quotes from a zero length - // string. This needs to excised. Phoenix - //if (strchr(data, '\"')) - //{ - // string_length -= 2; - // mNameValueReference.string = new char[string_length + 1];; - // strncpy(mNameValueReference.string, data + 1, string_length); - //} - //else - //{ - mNameValueReference.string = new char[string_length + 1];; - strncpy(mNameValueReference.string, data, string_length); /*Flawfinder: Ignore*/ - //} - mNameValueReference.string[string_length] = 0; - } - else - { - LL_WARNS() << "Unknown name value type string " << mStringType << " for " << mName << LL_ENDL; - mType = NVT_NULL; - } - - - // Nota Bene: Whatever global structure manages this should have these in the name table already! - if (!strcmp(nvclass, "R") || - !strcmp(nvclass, "READ_ONLY")) // legacy - { - mClass = NVC_READ_ONLY; - mStringClass = mNVNameTable->addString("R"); - } - else if (!strcmp(nvclass, "RW") || - !strcmp(nvclass, "READ_WRITE")) // legacy - { - mClass = NVC_READ_WRITE; - mStringClass = mNVNameTable->addString("RW"); - } - else - { - // assume it's bad - mClass = NVC_NULL; - mStringClass = mNVNameTable->addString(nvclass); - } - - // Initialize the sendto variable - if (!strcmp(nvsendto, "S") || - !strcmp(nvsendto, "SIM")) // legacy - { - mSendto = NVS_SIM; - mStringSendto = mNVNameTable->addString("S"); - } - else if (!strcmp(nvsendto, "DS") || - !strcmp(nvsendto, "SIM_SPACE")) // legacy - { - mSendto = NVS_DATA_SIM; - mStringSendto = mNVNameTable->addString("DS"); - } - else if (!strcmp(nvsendto, "SV") || - !strcmp(nvsendto, "SIM_VIEWER")) // legacy - { - mSendto = NVS_SIM_VIEWER; - mStringSendto = mNVNameTable->addString("SV"); - } - else if (!strcmp(nvsendto, "DSV") || - !strcmp(nvsendto, "SIM_SPACE_VIEWER")) // legacy - { - mSendto = NVS_DATA_SIM_VIEWER; - mStringSendto = mNVNameTable->addString("DSV"); - } - else - { - LL_WARNS() << "LLNameValue::init() - unknown sendto field " - << nvsendto << " for NV " << mName << LL_ENDL; - mSendto = NVS_NULL; - mStringSendto = mNVNameTable->addString("S"); - } + mNVNameTable = &gNVNameTable; + + mName = mNVNameTable->addString(name); + + // Nota Bene: Whatever global structure manages this should have these in the name table already! + mStringType = mNVNameTable->addString(type); + if (!strcmp(mStringType, "STRING")) + { + S32 string_length = (S32)strlen(data); /*Flawfinder: Ignore*/ + mType = NVT_STRING; + + delete[] mNameValueReference.string; + + // two options here. . . data can either look like foo or "foo" + // WRONG! - this is a poorly implemented and incomplete escape + // mechanism. For example, using this scheme, there is no way + // to tell an intentional double quotes from a zero length + // string. This needs to excised. Phoenix + //if (strchr(data, '\"')) + //{ + // string_length -= 2; + // mNameValueReference.string = new char[string_length + 1];; + // strncpy(mNameValueReference.string, data + 1, string_length); + //} + //else + //{ + mNameValueReference.string = new char[string_length + 1];; + strncpy(mNameValueReference.string, data, string_length); /*Flawfinder: Ignore*/ + //} + mNameValueReference.string[string_length] = 0; + } + else if (!strcmp(mStringType, "F32")) + { + mType = NVT_F32; + mNameValueReference.f32 = new F32((F32)atof(data)); + } + else if (!strcmp(mStringType, "S32")) + { + mType = NVT_S32; + mNameValueReference.s32 = new S32(atoi(data)); + } + else if (!strcmp(mStringType, "U64")) + { + mType = NVT_U64; + mNameValueReference.u64 = new U64(str_to_U64(ll_safe_string(data))); + } + else if (!strcmp(mStringType, "VEC3")) + { + mType = NVT_VEC3; + F32 t1, t2, t3; + + // two options here. . . data can either look like 0, 1, 2 or <0, 1, 2> + + if (strchr(data, '<')) + { + sscanf(data, "<%f, %f, %f>", &t1, &t2, &t3); + } + else + { + sscanf(data, "%f, %f, %f", &t1, &t2, &t3); + } + + // finite checks + if (!llfinite(t1) || !llfinite(t2) || !llfinite(t3)) + { + t1 = 0.f; + t2 = 0.f; + t3 = 0.f; + } + + mNameValueReference.vec3 = new LLVector3(t1, t2, t3); + } + else if (!strcmp(mStringType, "U32")) + { + mType = NVT_U32; + mNameValueReference.u32 = new U32(atoi(data)); + } + else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET])) + { + // assets are treated like strings, except that the name has + // meaning to an LLAssetInfo object + S32 string_length = (S32)strlen(data); /*Flawfinder: Ignore*/ + mType = NVT_ASSET; + + // two options here. . . data can either look like foo or "foo" + // WRONG! - this is a poorly implemented and incomplete escape + // mechanism. For example, using this scheme, there is no way + // to tell an intentional double quotes from a zero length + // string. This needs to excised. Phoenix + //if (strchr(data, '\"')) + //{ + // string_length -= 2; + // mNameValueReference.string = new char[string_length + 1];; + // strncpy(mNameValueReference.string, data + 1, string_length); + //} + //else + //{ + mNameValueReference.string = new char[string_length + 1];; + strncpy(mNameValueReference.string, data, string_length); /*Flawfinder: Ignore*/ + //} + mNameValueReference.string[string_length] = 0; + } + else + { + LL_WARNS() << "Unknown name value type string " << mStringType << " for " << mName << LL_ENDL; + mType = NVT_NULL; + } + + + // Nota Bene: Whatever global structure manages this should have these in the name table already! + if (!strcmp(nvclass, "R") || + !strcmp(nvclass, "READ_ONLY")) // legacy + { + mClass = NVC_READ_ONLY; + mStringClass = mNVNameTable->addString("R"); + } + else if (!strcmp(nvclass, "RW") || + !strcmp(nvclass, "READ_WRITE")) // legacy + { + mClass = NVC_READ_WRITE; + mStringClass = mNVNameTable->addString("RW"); + } + else + { + // assume it's bad + mClass = NVC_NULL; + mStringClass = mNVNameTable->addString(nvclass); + } + + // Initialize the sendto variable + if (!strcmp(nvsendto, "S") || + !strcmp(nvsendto, "SIM")) // legacy + { + mSendto = NVS_SIM; + mStringSendto = mNVNameTable->addString("S"); + } + else if (!strcmp(nvsendto, "DS") || + !strcmp(nvsendto, "SIM_SPACE")) // legacy + { + mSendto = NVS_DATA_SIM; + mStringSendto = mNVNameTable->addString("DS"); + } + else if (!strcmp(nvsendto, "SV") || + !strcmp(nvsendto, "SIM_VIEWER")) // legacy + { + mSendto = NVS_SIM_VIEWER; + mStringSendto = mNVNameTable->addString("SV"); + } + else if (!strcmp(nvsendto, "DSV") || + !strcmp(nvsendto, "SIM_SPACE_VIEWER")) // legacy + { + mSendto = NVS_DATA_SIM_VIEWER; + mStringSendto = mNVNameTable->addString("DSV"); + } + else + { + LL_WARNS() << "LLNameValue::init() - unknown sendto field " + << nvsendto << " for NV " << mName << LL_ENDL; + mSendto = NVS_NULL; + mStringSendto = mNVNameTable->addString("S"); + } } LLNameValue::LLNameValue(const char *name, const char *data, const char *type, const char *nvclass) { - baseInit(); - // if not specified, send to simulator only - init(name, data, type, nvclass, "SIM"); + baseInit(); + // if not specified, send to simulator only + init(name, data, type, nvclass, "SIM"); } LLNameValue::LLNameValue(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto) { - baseInit(); - init(name, data, type, nvclass, nvsendto); + baseInit(); + init(name, data, type, nvclass, nvsendto); } @@ -289,682 +289,682 @@ LLNameValue::LLNameValue(const char *name, const char *data, const char *type, c // Initialize without any initial data. LLNameValue::LLNameValue(const char *name, const char *type, const char *nvclass) { - baseInit(); - mName = mNVNameTable->addString(name); - - // Nota Bene: Whatever global structure manages this should have these in the name table already! - mStringType = mNVNameTable->addString(type); - if (!strcmp(mStringType, "STRING")) - { - mType = NVT_STRING; - mNameValueReference.string = NULL; - } - else if (!strcmp(mStringType, "F32")) - { - mType = NVT_F32; - mNameValueReference.f32 = NULL; - } - else if (!strcmp(mStringType, "S32")) - { - mType = NVT_S32; - mNameValueReference.s32 = NULL; - } - else if (!strcmp(mStringType, "VEC3")) - { - mType = NVT_VEC3; - mNameValueReference.vec3 = NULL; - } - else if (!strcmp(mStringType, "U32")) - { - mType = NVT_U32; - mNameValueReference.u32 = NULL; - } - else if (!strcmp(mStringType, "U64")) - { - mType = NVT_U64; - mNameValueReference.u64 = NULL; - } - else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET])) - { - mType = NVT_ASSET; - mNameValueReference.string = NULL; - } - else - { - mType = NVT_NULL; - LL_INFOS() << "Unknown name-value type " << mStringType << LL_ENDL; - } - - // Nota Bene: Whatever global structure manages this should have these in the name table already! - mStringClass = mNVNameTable->addString(nvclass); - if (!strcmp(mStringClass, "READ_ONLY")) - { - mClass = NVC_READ_ONLY; - } - else if (!strcmp(mStringClass, "READ_WRITE")) - { - mClass = NVC_READ_WRITE; - } - else - { - mClass = NVC_NULL; - } - - // Initialize the sendto variable - mStringSendto = mNVNameTable->addString("SIM"); - mSendto = NVS_SIM; + baseInit(); + mName = mNVNameTable->addString(name); + + // Nota Bene: Whatever global structure manages this should have these in the name table already! + mStringType = mNVNameTable->addString(type); + if (!strcmp(mStringType, "STRING")) + { + mType = NVT_STRING; + mNameValueReference.string = NULL; + } + else if (!strcmp(mStringType, "F32")) + { + mType = NVT_F32; + mNameValueReference.f32 = NULL; + } + else if (!strcmp(mStringType, "S32")) + { + mType = NVT_S32; + mNameValueReference.s32 = NULL; + } + else if (!strcmp(mStringType, "VEC3")) + { + mType = NVT_VEC3; + mNameValueReference.vec3 = NULL; + } + else if (!strcmp(mStringType, "U32")) + { + mType = NVT_U32; + mNameValueReference.u32 = NULL; + } + else if (!strcmp(mStringType, "U64")) + { + mType = NVT_U64; + mNameValueReference.u64 = NULL; + } + else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET])) + { + mType = NVT_ASSET; + mNameValueReference.string = NULL; + } + else + { + mType = NVT_NULL; + LL_INFOS() << "Unknown name-value type " << mStringType << LL_ENDL; + } + + // Nota Bene: Whatever global structure manages this should have these in the name table already! + mStringClass = mNVNameTable->addString(nvclass); + if (!strcmp(mStringClass, "READ_ONLY")) + { + mClass = NVC_READ_ONLY; + } + else if (!strcmp(mStringClass, "READ_WRITE")) + { + mClass = NVC_READ_WRITE; + } + else + { + mClass = NVC_NULL; + } + + // Initialize the sendto variable + mStringSendto = mNVNameTable->addString("SIM"); + mSendto = NVS_SIM; } // data is in the format: -// "NameValueName Type Class Data" +// "NameValueName Type Class Data" LLNameValue::LLNameValue(const char *data) { - baseInit(); - static char name[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ - static char type[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ - static char nvclass[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ - static char nvsendto[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ - static char nvdata[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ - - S32 i; - - S32 character_count = 0; - S32 length = 0; - - // go to first non-whitespace character - while (1) - { - if ( (*(data + character_count) == ' ') - ||(*(data + character_count) == '\n') - ||(*(data + character_count) == '\t') - ||(*(data + character_count) == '\r')) - { - character_count++; - } - else - { - break; - } - } - - // read in the name - sscanf((data + character_count), "%2047s", name); /*Flawfinder: ignore*/ - - // bump past it and add null terminator - length = (S32)strlen(name); /* Flawfinder: ignore */ - name[length] = 0; - character_count += length; - - // go to the next non-whitespace character - while (1) - { - if ( (*(data + character_count) == ' ') - ||(*(data + character_count) == '\n') - ||(*(data + character_count) == '\t') - ||(*(data + character_count) == '\r')) - { - character_count++; - } - else - { - break; - } - } - - // read in the type - sscanf((data + character_count), "%2047s", type); /*Flawfinder: ignore*/ - - // bump past it and add null terminator - length = (S32)strlen(type); /* Flawfinder: ignore */ - type[length] = 0; - character_count += length; - - // go to the next non-whitespace character - while (1) - { - if ( (*(data + character_count) == ' ') - ||(*(data + character_count) == '\n') - ||(*(data + character_count) == '\t') - ||(*(data + character_count) == '\r')) - { - character_count++; - } - else - { - break; - } - } - - // do we have a type argument? - for (i = NVC_READ_ONLY; i < NVC_EOF; i++) - { - if (!strncmp(NameValueClassStrings[i], data + character_count, strlen(NameValueClassStrings[i]))) /* Flawfinder: ignore */ - { - break; - } - } - - if (i != NVC_EOF) - { - // yes we do! - // read in the class - sscanf((data + character_count), "%2047s", nvclass); /*Flawfinder: ignore*/ - - // bump past it and add null terminator - length = (S32)strlen(nvclass); /* Flawfinder: ignore */ - nvclass[length] = 0; - character_count += length; - - // go to the next non-whitespace character - while (1) - { - if ( (*(data + character_count) == ' ') - ||(*(data + character_count) == '\n') - ||(*(data + character_count) == '\t') - ||(*(data + character_count) == '\r')) - { - character_count++; - } - else - { - break; - } - } - } - else - { - // no type argument given, default to read-write - strncpy(nvclass, "READ_WRITE", sizeof(nvclass) -1); /* Flawfinder: ignore */ - nvclass[sizeof(nvclass) -1] = '\0'; - } - - // Do we have a sendto argument? - for (i = NVS_SIM; i < NVS_EOF; i++) - { - if (!strncmp(NameValueSendtoStrings[i], data + character_count, strlen(NameValueSendtoStrings[i]))) /* Flawfinder: ignore */ - { - break; - } - } - - if (i != NVS_EOF) - { - // found a sendto argument - sscanf((data + character_count), "%2047s", nvsendto); /*Flawfinder: ignore*/ - - // add null terminator - length = (S32)strlen(nvsendto); /* Flawfinder: ignore */ - nvsendto[length] = 0; - character_count += length; - - // seek to next non-whitespace characer - while (1) - { - if ( (*(data + character_count) == ' ') - ||(*(data + character_count) == '\n') - ||(*(data + character_count) == '\t') - ||(*(data + character_count) == '\r')) - { - character_count++; - } - else - { - break; - } - } - } - else - { - // no sendto argument given, default to sim only - strncpy(nvsendto, "SIM", sizeof(nvsendto) -1); /* Flawfinder: ignore */ - nvsendto[sizeof(nvsendto) -1] ='\0'; - } - - - // copy the rest character by character into data - length = 0; - - while ( (*(nvdata + length++) = *(data + character_count++)) ) - ; - - init(name, nvdata, type, nvclass, nvsendto); + baseInit(); + static char name[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ + static char type[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ + static char nvclass[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ + static char nvsendto[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ + static char nvdata[NV_BUFFER_LEN]; /*Flawfinder: ignore*/ + + S32 i; + + S32 character_count = 0; + S32 length = 0; + + // go to first non-whitespace character + while (1) + { + if ( (*(data + character_count) == ' ') + ||(*(data + character_count) == '\n') + ||(*(data + character_count) == '\t') + ||(*(data + character_count) == '\r')) + { + character_count++; + } + else + { + break; + } + } + + // read in the name + sscanf((data + character_count), "%2047s", name); /*Flawfinder: ignore*/ + + // bump past it and add null terminator + length = (S32)strlen(name); /* Flawfinder: ignore */ + name[length] = 0; + character_count += length; + + // go to the next non-whitespace character + while (1) + { + if ( (*(data + character_count) == ' ') + ||(*(data + character_count) == '\n') + ||(*(data + character_count) == '\t') + ||(*(data + character_count) == '\r')) + { + character_count++; + } + else + { + break; + } + } + + // read in the type + sscanf((data + character_count), "%2047s", type); /*Flawfinder: ignore*/ + + // bump past it and add null terminator + length = (S32)strlen(type); /* Flawfinder: ignore */ + type[length] = 0; + character_count += length; + + // go to the next non-whitespace character + while (1) + { + if ( (*(data + character_count) == ' ') + ||(*(data + character_count) == '\n') + ||(*(data + character_count) == '\t') + ||(*(data + character_count) == '\r')) + { + character_count++; + } + else + { + break; + } + } + + // do we have a type argument? + for (i = NVC_READ_ONLY; i < NVC_EOF; i++) + { + if (!strncmp(NameValueClassStrings[i], data + character_count, strlen(NameValueClassStrings[i]))) /* Flawfinder: ignore */ + { + break; + } + } + + if (i != NVC_EOF) + { + // yes we do! + // read in the class + sscanf((data + character_count), "%2047s", nvclass); /*Flawfinder: ignore*/ + + // bump past it and add null terminator + length = (S32)strlen(nvclass); /* Flawfinder: ignore */ + nvclass[length] = 0; + character_count += length; + + // go to the next non-whitespace character + while (1) + { + if ( (*(data + character_count) == ' ') + ||(*(data + character_count) == '\n') + ||(*(data + character_count) == '\t') + ||(*(data + character_count) == '\r')) + { + character_count++; + } + else + { + break; + } + } + } + else + { + // no type argument given, default to read-write + strncpy(nvclass, "READ_WRITE", sizeof(nvclass) -1); /* Flawfinder: ignore */ + nvclass[sizeof(nvclass) -1] = '\0'; + } + + // Do we have a sendto argument? + for (i = NVS_SIM; i < NVS_EOF; i++) + { + if (!strncmp(NameValueSendtoStrings[i], data + character_count, strlen(NameValueSendtoStrings[i]))) /* Flawfinder: ignore */ + { + break; + } + } + + if (i != NVS_EOF) + { + // found a sendto argument + sscanf((data + character_count), "%2047s", nvsendto); /*Flawfinder: ignore*/ + + // add null terminator + length = (S32)strlen(nvsendto); /* Flawfinder: ignore */ + nvsendto[length] = 0; + character_count += length; + + // seek to next non-whitespace characer + while (1) + { + if ( (*(data + character_count) == ' ') + ||(*(data + character_count) == '\n') + ||(*(data + character_count) == '\t') + ||(*(data + character_count) == '\r')) + { + character_count++; + } + else + { + break; + } + } + } + else + { + // no sendto argument given, default to sim only + strncpy(nvsendto, "SIM", sizeof(nvsendto) -1); /* Flawfinder: ignore */ + nvsendto[sizeof(nvsendto) -1] ='\0'; + } + + + // copy the rest character by character into data + length = 0; + + while ( (*(nvdata + length++) = *(data + character_count++)) ) + ; + + init(name, nvdata, type, nvclass, nvsendto); } LLNameValue::~LLNameValue() { - mNVNameTable->removeString(mName); - mName = NULL; - - switch(mType) - { - case NVT_STRING: - case NVT_ASSET: - delete [] mNameValueReference.string; - mNameValueReference.string = NULL; - break; - case NVT_F32: - delete mNameValueReference.f32; - mNameValueReference.string = NULL; - break; - case NVT_S32: - delete mNameValueReference.s32; - mNameValueReference.string = NULL; - break; - case NVT_VEC3: - delete mNameValueReference.vec3; - mNameValueReference.string = NULL; - break; - case NVT_U32: - delete mNameValueReference.u32; - mNameValueReference.u32 = NULL; - break; - case NVT_U64: - delete mNameValueReference.u64; - mNameValueReference.u64 = NULL; - break; - default: - break; - } - - delete[] mNameValueReference.string; - mNameValueReference.string = NULL; + mNVNameTable->removeString(mName); + mName = NULL; + + switch(mType) + { + case NVT_STRING: + case NVT_ASSET: + delete [] mNameValueReference.string; + mNameValueReference.string = NULL; + break; + case NVT_F32: + delete mNameValueReference.f32; + mNameValueReference.string = NULL; + break; + case NVT_S32: + delete mNameValueReference.s32; + mNameValueReference.string = NULL; + break; + case NVT_VEC3: + delete mNameValueReference.vec3; + mNameValueReference.string = NULL; + break; + case NVT_U32: + delete mNameValueReference.u32; + mNameValueReference.u32 = NULL; + break; + case NVT_U64: + delete mNameValueReference.u64; + mNameValueReference.u64 = NULL; + break; + default: + break; + } + + delete[] mNameValueReference.string; + mNameValueReference.string = NULL; } -char *LLNameValue::getString() -{ - if (mType == NVT_STRING) - { - return mNameValueReference.string; - } - else - { - LL_ERRS() << mName << " not a string!" << LL_ENDL; - return NULL; - } +char *LLNameValue::getString() +{ + if (mType == NVT_STRING) + { + return mNameValueReference.string; + } + else + { + LL_ERRS() << mName << " not a string!" << LL_ENDL; + return NULL; + } } const char *LLNameValue::getAsset() const { - if (mType == NVT_ASSET) - { - return mNameValueReference.string; - } - else - { - LL_ERRS() << mName << " not an asset!" << LL_ENDL; - return NULL; - } + if (mType == NVT_ASSET) + { + return mNameValueReference.string; + } + else + { + LL_ERRS() << mName << " not an asset!" << LL_ENDL; + return NULL; + } } -F32 *LLNameValue::getF32() -{ - if (mType == NVT_F32) - { - return mNameValueReference.f32; - } - else - { - LL_ERRS() << mName << " not a F32!" << LL_ENDL; - return NULL; - } +F32 *LLNameValue::getF32() +{ + if (mType == NVT_F32) + { + return mNameValueReference.f32; + } + else + { + LL_ERRS() << mName << " not a F32!" << LL_ENDL; + return NULL; + } } -S32 *LLNameValue::getS32() -{ - if (mType == NVT_S32) - { - return mNameValueReference.s32; - } - else - { - LL_ERRS() << mName << " not a S32!" << LL_ENDL; - return NULL; - } +S32 *LLNameValue::getS32() +{ + if (mType == NVT_S32) + { + return mNameValueReference.s32; + } + else + { + LL_ERRS() << mName << " not a S32!" << LL_ENDL; + return NULL; + } } -U32 *LLNameValue::getU32() -{ - if (mType == NVT_U32) - { - return mNameValueReference.u32; - } - else - { - LL_ERRS() << mName << " not a U32!" << LL_ENDL; - return NULL; - } +U32 *LLNameValue::getU32() +{ + if (mType == NVT_U32) + { + return mNameValueReference.u32; + } + else + { + LL_ERRS() << mName << " not a U32!" << LL_ENDL; + return NULL; + } } -U64 *LLNameValue::getU64() -{ - if (mType == NVT_U64) - { - return mNameValueReference.u64; - } - else - { - LL_ERRS() << mName << " not a U64!" << LL_ENDL; - return NULL; - } +U64 *LLNameValue::getU64() +{ + if (mType == NVT_U64) + { + return mNameValueReference.u64; + } + else + { + LL_ERRS() << mName << " not a U64!" << LL_ENDL; + return NULL; + } } -void LLNameValue::getVec3(LLVector3 &vec) +void LLNameValue::getVec3(LLVector3 &vec) { - if (mType == NVT_VEC3) - { - vec = *mNameValueReference.vec3; - } - else - { - LL_ERRS() << mName << " not a Vec3!" << LL_ENDL; - } + if (mType == NVT_VEC3) + { + vec = *mNameValueReference.vec3; + } + else + { + LL_ERRS() << mName << " not a Vec3!" << LL_ENDL; + } } -LLVector3 *LLNameValue::getVec3() -{ - if (mType == NVT_VEC3) - { - return (mNameValueReference.vec3); - } - else - { - LL_ERRS() << mName << " not a Vec3!" << LL_ENDL; - return NULL; - } +LLVector3 *LLNameValue::getVec3() +{ + if (mType == NVT_VEC3) + { + return (mNameValueReference.vec3); + } + else + { + LL_ERRS() << mName << " not a Vec3!" << LL_ENDL; + return NULL; + } } bool LLNameValue::sendToData() const { - return (mSendto == NVS_DATA_SIM || mSendto == NVS_DATA_SIM_VIEWER); + return (mSendto == NVS_DATA_SIM || mSendto == NVS_DATA_SIM_VIEWER); } bool LLNameValue::sendToViewer() const { - return (mSendto == NVS_SIM_VIEWER || mSendto == NVS_DATA_SIM_VIEWER); + return (mSendto == NVS_SIM_VIEWER || mSendto == NVS_DATA_SIM_VIEWER); } LLNameValue &LLNameValue::operator=(const LLNameValue &a) { - if (mType != a.mType) - { - return *this; - } - if (mClass == NVC_READ_ONLY) - return *this; - - switch(a.mType) - { - case NVT_STRING: - case NVT_ASSET: - if (mNameValueReference.string) - delete [] mNameValueReference.string; - - mNameValueReference.string = new char [strlen(a.mNameValueReference.string) + 1]; /* Flawfinder: ignore */ - if(mNameValueReference.string != NULL) - { - strcpy(mNameValueReference.string, a.mNameValueReference.string); /* Flawfinder: ignore */ - } - break; - case NVT_F32: - *mNameValueReference.f32 = *a.mNameValueReference.f32; - break; - case NVT_S32: - *mNameValueReference.s32 = *a.mNameValueReference.s32; - break; - case NVT_VEC3: - *mNameValueReference.vec3 = *a.mNameValueReference.vec3; - break; - case NVT_U32: - *mNameValueReference.u32 = *a.mNameValueReference.u32; - break; - case NVT_U64: - *mNameValueReference.u64 = *a.mNameValueReference.u64; - break; - default: - LL_ERRS() << "Unknown Name value type " << (U32)a.mType << LL_ENDL; - break; - } - - return *this; + if (mType != a.mType) + { + return *this; + } + if (mClass == NVC_READ_ONLY) + return *this; + + switch(a.mType) + { + case NVT_STRING: + case NVT_ASSET: + if (mNameValueReference.string) + delete [] mNameValueReference.string; + + mNameValueReference.string = new char [strlen(a.mNameValueReference.string) + 1]; /* Flawfinder: ignore */ + if(mNameValueReference.string != NULL) + { + strcpy(mNameValueReference.string, a.mNameValueReference.string); /* Flawfinder: ignore */ + } + break; + case NVT_F32: + *mNameValueReference.f32 = *a.mNameValueReference.f32; + break; + case NVT_S32: + *mNameValueReference.s32 = *a.mNameValueReference.s32; + break; + case NVT_VEC3: + *mNameValueReference.vec3 = *a.mNameValueReference.vec3; + break; + case NVT_U32: + *mNameValueReference.u32 = *a.mNameValueReference.u32; + break; + case NVT_U64: + *mNameValueReference.u64 = *a.mNameValueReference.u64; + break; + default: + LL_ERRS() << "Unknown Name value type " << (U32)a.mType << LL_ENDL; + break; + } + + return *this; } void LLNameValue::setString(const char *a) { - if (mClass == NVC_READ_ONLY) - return; - - switch(mType) - { - case NVT_STRING: - if (a) - { - if (mNameValueReference.string) - { - delete [] mNameValueReference.string; - } - - mNameValueReference.string = new char [strlen(a) + 1]; /* Flawfinder: ignore */ - if(mNameValueReference.string != NULL) - { - strcpy(mNameValueReference.string, a); /* Flawfinder: ignore */ - } - } - else - { - if (mNameValueReference.string) - delete [] mNameValueReference.string; - - mNameValueReference.string = new char [1]; - mNameValueReference.string[0] = 0; - } - break; - default: - break; - } - - return; + if (mClass == NVC_READ_ONLY) + return; + + switch(mType) + { + case NVT_STRING: + if (a) + { + if (mNameValueReference.string) + { + delete [] mNameValueReference.string; + } + + mNameValueReference.string = new char [strlen(a) + 1]; /* Flawfinder: ignore */ + if(mNameValueReference.string != NULL) + { + strcpy(mNameValueReference.string, a); /* Flawfinder: ignore */ + } + } + else + { + if (mNameValueReference.string) + delete [] mNameValueReference.string; + + mNameValueReference.string = new char [1]; + mNameValueReference.string[0] = 0; + } + break; + default: + break; + } + + return; } void LLNameValue::setAsset(const char *a) { - if (mClass == NVC_READ_ONLY) - return; - - switch(mType) - { - case NVT_ASSET: - if (a) - { - if (mNameValueReference.string) - { - delete [] mNameValueReference.string; - } - mNameValueReference.string = new char [strlen(a) + 1]; /* Flawfinder: ignore */ - if(mNameValueReference.string != NULL) - { - strcpy(mNameValueReference.string, a); /* Flawfinder: ignore */ - } - } - else - { - if (mNameValueReference.string) - delete [] mNameValueReference.string; - - mNameValueReference.string = new char [1]; - mNameValueReference.string[0] = 0; - } - break; - default: - break; - } + if (mClass == NVC_READ_ONLY) + return; + + switch(mType) + { + case NVT_ASSET: + if (a) + { + if (mNameValueReference.string) + { + delete [] mNameValueReference.string; + } + mNameValueReference.string = new char [strlen(a) + 1]; /* Flawfinder: ignore */ + if(mNameValueReference.string != NULL) + { + strcpy(mNameValueReference.string, a); /* Flawfinder: ignore */ + } + } + else + { + if (mNameValueReference.string) + delete [] mNameValueReference.string; + + mNameValueReference.string = new char [1]; + mNameValueReference.string[0] = 0; + } + break; + default: + break; + } } void LLNameValue::setF32(const F32 a) { - if (mClass == NVC_READ_ONLY) - return; + if (mClass == NVC_READ_ONLY) + return; - switch(mType) - { - case NVT_F32: - *mNameValueReference.f32 = a; - break; - default: - break; - } + switch(mType) + { + case NVT_F32: + *mNameValueReference.f32 = a; + break; + default: + break; + } - return; + return; } void LLNameValue::setS32(const S32 a) { - if (mClass == NVC_READ_ONLY) - return; - - switch(mType) - { - case NVT_S32: - *mNameValueReference.s32 = a; - break; - case NVT_U32: - *mNameValueReference.u32 = a; - break; - case NVT_F32: - *mNameValueReference.f32 = (F32)a; - break; - default: - break; - } - - return; + if (mClass == NVC_READ_ONLY) + return; + + switch(mType) + { + case NVT_S32: + *mNameValueReference.s32 = a; + break; + case NVT_U32: + *mNameValueReference.u32 = a; + break; + case NVT_F32: + *mNameValueReference.f32 = (F32)a; + break; + default: + break; + } + + return; } void LLNameValue::setU32(const U32 a) { - if (mClass == NVC_READ_ONLY) - return; - - switch(mType) - { - case NVT_S32: - *mNameValueReference.s32 = a; - break; - case NVT_U32: - *mNameValueReference.u32 = a; - break; - case NVT_F32: - *mNameValueReference.f32 = (F32)a; - break; - default: - LL_ERRS() << "NameValue: Trying to set U32 into a " << mStringType << ", unknown conversion" << LL_ENDL; - break; - } - return; + if (mClass == NVC_READ_ONLY) + return; + + switch(mType) + { + case NVT_S32: + *mNameValueReference.s32 = a; + break; + case NVT_U32: + *mNameValueReference.u32 = a; + break; + case NVT_F32: + *mNameValueReference.f32 = (F32)a; + break; + default: + LL_ERRS() << "NameValue: Trying to set U32 into a " << mStringType << ", unknown conversion" << LL_ENDL; + break; + } + return; } void LLNameValue::setVec3(const LLVector3 &a) { - if (mClass == NVC_READ_ONLY) - return; - - switch(mType) - { - case NVT_VEC3: - *mNameValueReference.vec3 = a; - break; - default: - LL_ERRS() << "NameValue: Trying to set LLVector3 into a " << mStringType << ", unknown conversion" << LL_ENDL; - break; - } - return; + if (mClass == NVC_READ_ONLY) + return; + + switch(mType) + { + case NVT_VEC3: + *mNameValueReference.vec3 = a; + break; + default: + LL_ERRS() << "NameValue: Trying to set LLVector3 into a " << mStringType << ", unknown conversion" << LL_ENDL; + break; + } + return; } std::string LLNameValue::printNameValue() const { - std::string buffer; - buffer = llformat("%s %s %s %s ", mName, mStringType, mStringClass, mStringSendto); - buffer += printData(); -// LL_INFOS() << "Name Value Length: " << buffer.size() + 1 << LL_ENDL; - return buffer; + std::string buffer; + buffer = llformat("%s %s %s %s ", mName, mStringType, mStringClass, mStringSendto); + buffer += printData(); +// LL_INFOS() << "Name Value Length: " << buffer.size() + 1 << LL_ENDL; + return buffer; } std::string LLNameValue::printData() const { - std::string buffer; - switch(mType) - { - case NVT_STRING: - case NVT_ASSET: - buffer = mNameValueReference.string; - break; - case NVT_F32: - buffer = llformat("%f", *mNameValueReference.f32); - break; - case NVT_S32: - buffer = llformat("%d", *mNameValueReference.s32); - break; - case NVT_U32: - buffer = llformat("%u", *mNameValueReference.u32); - break; - case NVT_U64: - { - char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ - U64_to_str(*mNameValueReference.u64, u64_string, sizeof(u64_string)); - buffer = u64_string; - } - break; - case NVT_VEC3: - buffer = llformat( "%f, %f, %f", mNameValueReference.vec3->mV[VX], mNameValueReference.vec3->mV[VY], mNameValueReference.vec3->mV[VZ]); - break; - default: - LL_ERRS() << "Trying to print unknown NameValue type " << mStringType << LL_ENDL; - break; - } - return buffer; + std::string buffer; + switch(mType) + { + case NVT_STRING: + case NVT_ASSET: + buffer = mNameValueReference.string; + break; + case NVT_F32: + buffer = llformat("%f", *mNameValueReference.f32); + break; + case NVT_S32: + buffer = llformat("%d", *mNameValueReference.s32); + break; + case NVT_U32: + buffer = llformat("%u", *mNameValueReference.u32); + break; + case NVT_U64: + { + char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ + U64_to_str(*mNameValueReference.u64, u64_string, sizeof(u64_string)); + buffer = u64_string; + } + break; + case NVT_VEC3: + buffer = llformat( "%f, %f, %f", mNameValueReference.vec3->mV[VX], mNameValueReference.vec3->mV[VY], mNameValueReference.vec3->mV[VZ]); + break; + default: + LL_ERRS() << "Trying to print unknown NameValue type " << mStringType << LL_ENDL; + break; + } + return buffer; } -std::ostream& operator<<(std::ostream& s, const LLNameValue &a) -{ - switch(a.mType) - { - case NVT_STRING: - case NVT_ASSET: - s << a.mNameValueReference.string; - break; - case NVT_F32: - s << (*a.mNameValueReference.f32); - break; - case NVT_S32: - s << *(a.mNameValueReference.s32); - break; - case NVT_U32: - s << *(a.mNameValueReference.u32); - break; - case NVT_U64: - { - char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ - U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string)); - s << u64_string; - } - break; - case NVT_VEC3: - s << *(a.mNameValueReference.vec3); - break; - default: - LL_ERRS() << "Trying to print unknown NameValue type " << a.mStringType << LL_ENDL; - break; - } - return s; +std::ostream& operator<<(std::ostream& s, const LLNameValue &a) +{ + switch(a.mType) + { + case NVT_STRING: + case NVT_ASSET: + s << a.mNameValueReference.string; + break; + case NVT_F32: + s << (*a.mNameValueReference.f32); + break; + case NVT_S32: + s << *(a.mNameValueReference.s32); + break; + case NVT_U32: + s << *(a.mNameValueReference.u32); + break; + case NVT_U64: + { + char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ + U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string)); + s << u64_string; + } + break; + case NVT_VEC3: + s << *(a.mNameValueReference.vec3); + break; + default: + LL_ERRS() << "Trying to print unknown NameValue type " << a.mStringType << LL_ENDL; + break; + } + return s; } diff --git a/indra/llmessage/llnamevalue.h b/indra/llmessage/llnamevalue.h index 92b20284ef..3c442df009 100644 --- a/indra/llmessage/llnamevalue.h +++ b/indra/llmessage/llnamevalue.h @@ -1,25 +1,25 @@ -/** +/** * @file llnamevalue.h * @brief class for defining name value pairs. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -51,34 +51,34 @@ class LLStringTable; typedef enum e_name_value_types { - NVT_NULL, - NVT_STRING, - NVT_F32, - NVT_S32, - NVT_VEC3, - NVT_U32, - NVT_CAMERA, // Deprecated, but leaving in case removing this will cause problems - NVT_ASSET, - NVT_U64, - NVT_EOF + NVT_NULL, + NVT_STRING, + NVT_F32, + NVT_S32, + NVT_VEC3, + NVT_U32, + NVT_CAMERA, // Deprecated, but leaving in case removing this will cause problems + NVT_ASSET, + NVT_U64, + NVT_EOF } ENameValueType; typedef enum e_name_value_class { - NVC_NULL, - NVC_READ_ONLY, - NVC_READ_WRITE, - NVC_EOF + NVC_NULL, + NVC_READ_ONLY, + NVC_READ_WRITE, + NVC_EOF } ENameValueClass; typedef enum e_name_value_sento { - NVS_NULL, - NVS_SIM, - NVS_DATA_SIM, - NVS_SIM_VIEWER, - NVS_DATA_SIM_VIEWER, - NVS_EOF + NVS_NULL, + NVS_SIM, + NVS_DATA_SIM, + NVS_SIM_VIEWER, + NVS_DATA_SIM_VIEWER, + NVS_EOF } ENameValueSendto; @@ -89,95 +89,95 @@ const U32 NAME_VALUE_BUF_SIZE = 1024; const U32 NAME_VALUE_TYPE_STRING_LENGTH = 8; const U32 NAME_VALUE_CLASS_STRING_LENGTH = 16; const U32 NAME_VALUE_SENDTO_STRING_LENGTH = 18; -const U32 NAME_VALUE_DATA_SIZE = - NAME_VALUE_BUF_SIZE - - ( DB_NV_NAME_BUF_SIZE + - NAME_VALUE_TYPE_STRING_LENGTH + - NAME_VALUE_CLASS_STRING_LENGTH + - NAME_VALUE_SENDTO_STRING_LENGTH ); +const U32 NAME_VALUE_DATA_SIZE = + NAME_VALUE_BUF_SIZE - + ( DB_NV_NAME_BUF_SIZE + + NAME_VALUE_TYPE_STRING_LENGTH + + NAME_VALUE_CLASS_STRING_LENGTH + + NAME_VALUE_SENDTO_STRING_LENGTH ); -extern char NameValueTypeStrings[NVT_EOF][NAME_VALUE_TYPE_STRING_LENGTH]; /* Flawfinder: Ignore */ -extern char NameValueClassStrings[NVC_EOF][NAME_VALUE_CLASS_STRING_LENGTH]; /* Flawfinder: Ignore */ -extern char NameValueSendtoStrings[NVS_EOF][NAME_VALUE_SENDTO_STRING_LENGTH]; /* Flawfinder: Ignore */ +extern char NameValueTypeStrings[NVT_EOF][NAME_VALUE_TYPE_STRING_LENGTH]; /* Flawfinder: Ignore */ +extern char NameValueClassStrings[NVC_EOF][NAME_VALUE_CLASS_STRING_LENGTH]; /* Flawfinder: Ignore */ +extern char NameValueSendtoStrings[NVS_EOF][NAME_VALUE_SENDTO_STRING_LENGTH]; /* Flawfinder: Ignore */ typedef union u_name_value_reference { - char *string; - F32 *f32; - S32 *s32; - LLVector3 *vec3; - U32 *u32; - U64 *u64; + char *string; + F32 *f32; + S32 *s32; + LLVector3 *vec3; + U32 *u32; + U64 *u64; } UNameValueReference; class LLNameValue { public: - void baseInit(); - void init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto ); - - LLNameValue(); - LLNameValue(const char *data); - LLNameValue(const char *name, const char *type, const char *nvclass ); - LLNameValue(const char *name, const char *data, const char *type, const char *nvclass ); - LLNameValue(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto ); - - ~LLNameValue(); - - char *getString(); - const char *getAsset() const; - F32 *getF32(); - S32 *getS32(); - void getVec3(LLVector3 &vec); - LLVector3 *getVec3(); - U32 *getU32(); - U64 *getU64(); - - const char *getType() const { return mStringType; } - const char *getClass() const { return mStringClass; } - const char *getSendto() const { return mStringSendto; } - - bool sendToData() const; - bool sendToViewer() const; - - void callCallback(); - std::string printNameValue() const; - std::string printData() const; - - ENameValueType getTypeEnum() const { return mType; } - ENameValueClass getClassEnum() const { return mClass; } - ENameValueSendto getSendtoEnum() const { return mSendto; } - - LLNameValue &operator=(const LLNameValue &a); - void setString(const char *a); - void setAsset(const char *a); - void setF32(const F32 a); - void setS32(const S32 a); - void setVec3(const LLVector3 &a); - void setU32(const U32 a); - - friend std::ostream& operator<<(std::ostream& s, const LLNameValue &a); + void baseInit(); + void init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto ); + + LLNameValue(); + LLNameValue(const char *data); + LLNameValue(const char *name, const char *type, const char *nvclass ); + LLNameValue(const char *name, const char *data, const char *type, const char *nvclass ); + LLNameValue(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto ); + + ~LLNameValue(); + + char *getString(); + const char *getAsset() const; + F32 *getF32(); + S32 *getS32(); + void getVec3(LLVector3 &vec); + LLVector3 *getVec3(); + U32 *getU32(); + U64 *getU64(); + + const char *getType() const { return mStringType; } + const char *getClass() const { return mStringClass; } + const char *getSendto() const { return mStringSendto; } + + bool sendToData() const; + bool sendToViewer() const; + + void callCallback(); + std::string printNameValue() const; + std::string printData() const; + + ENameValueType getTypeEnum() const { return mType; } + ENameValueClass getClassEnum() const { return mClass; } + ENameValueSendto getSendtoEnum() const { return mSendto; } + + LLNameValue &operator=(const LLNameValue &a); + void setString(const char *a); + void setAsset(const char *a); + void setF32(const F32 a); + void setS32(const S32 a); + void setVec3(const LLVector3 &a); + void setU32(const U32 a); + + friend std::ostream& operator<<(std::ostream& s, const LLNameValue &a); private: - void printNameValue(std::ostream& s); - + void printNameValue(std::ostream& s); + public: - char *mName; + char *mName; - char *mStringType; - ENameValueType mType; - char *mStringClass; - ENameValueClass mClass; - char *mStringSendto; - ENameValueSendto mSendto; + char *mStringType; + ENameValueType mType; + char *mStringClass; + ENameValueClass mClass; + char *mStringSendto; + ENameValueSendto mSendto; - UNameValueReference mNameValueReference; - LLStringTable *mNVNameTable; + UNameValueReference mNameValueReference; + LLStringTable *mNVNameTable; }; -extern LLStringTable gNVNameTable; +extern LLStringTable gNVNameTable; #endif diff --git a/indra/llmessage/llnullcipher.cpp b/indra/llmessage/llnullcipher.cpp index b32e7e6fa6..47230f58d4 100644 --- a/indra/llmessage/llnullcipher.cpp +++ b/indra/llmessage/llnullcipher.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llnullcipher.cpp * @brief Implementation of a cipher which does not encrypt. * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,25 +34,25 @@ U32 LLNullCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) { - if((src_len == dst_len) && src && dst) - { - memmove(dst, src, src_len); - return src_len; - } - return 0; + if((src_len == dst_len) && src && dst) + { + memmove(dst, src, src_len); + return src_len; + } + return 0; } U32 LLNullCipher::decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) { - if((src_len == dst_len) && src && dst) - { - memmove(dst, src, src_len); - return src_len; - } - return 0; + if((src_len == dst_len) && src && dst) + { + memmove(dst, src, src_len); + return src_len; + } + return 0; } U32 LLNullCipher::requiredEncryptionSpace(U32 len) const { - return len; + return len; } diff --git a/indra/llmessage/llnullcipher.h b/indra/llmessage/llnullcipher.h index a9f9a1ce03..8b397d46cf 100644 --- a/indra/llmessage/llnullcipher.h +++ b/indra/llmessage/llnullcipher.h @@ -1,24 +1,24 @@ -/** +/** * @file llnullcipher.h * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,11 +38,11 @@ class LLNullCipher : public LLCipher { public: - LLNullCipher() {} - virtual ~LLNullCipher() {} - virtual U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); - virtual U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); - virtual U32 requiredEncryptionSpace(U32 src_len) const; + LLNullCipher() {} + virtual ~LLNullCipher() {} + virtual U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); + virtual U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len); + virtual U32 requiredEncryptionSpace(U32 src_len) const; }; #endif diff --git a/indra/llmessage/llpacketack.cpp b/indra/llmessage/llpacketack.cpp index 8e04934286..e66e8b0285 100644 --- a/indra/llmessage/llpacketack.cpp +++ b/indra/llmessage/llpacketack.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpacketack.cpp * @author Phoenix * @date 2007-05-09 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,45 +38,45 @@ #include "message.h" LLReliablePacket::LLReliablePacket( - S32 socket, - U8* buf_ptr, - S32 buf_len, - LLReliablePacketParams* params) : - mBuffer(NULL), - mBufferLength(0) + S32 socket, + U8* buf_ptr, + S32 buf_len, + LLReliablePacketParams* params) : + mBuffer(NULL), + mBufferLength(0) { - if (params) - { - mHost = params->mHost; - mRetries = params->mRetries; - mPingBasedRetry = params->mPingBasedRetry; - mTimeout = F32Seconds(params->mTimeout); - mCallback = params->mCallback; - mCallbackData = params->mCallbackData; - mMessageName = params->mMessageName; - } - else - { - mRetries = 0; - mPingBasedRetry = true; - mTimeout = F32Seconds(0.f); - mCallback = NULL; - mCallbackData = NULL; - mMessageName = NULL; - } + if (params) + { + mHost = params->mHost; + mRetries = params->mRetries; + mPingBasedRetry = params->mPingBasedRetry; + mTimeout = F32Seconds(params->mTimeout); + mCallback = params->mCallback; + mCallbackData = params->mCallbackData; + mMessageName = params->mMessageName; + } + else + { + mRetries = 0; + mPingBasedRetry = true; + mTimeout = F32Seconds(0.f); + mCallback = NULL; + mCallbackData = NULL; + mMessageName = NULL; + } + + mExpirationTime = (F64Seconds)totalTime() + mTimeout; + mPacketID = ntohl(*((U32*)(&buf_ptr[PHL_PACKET_ID]))); - mExpirationTime = (F64Seconds)totalTime() + mTimeout; - mPacketID = ntohl(*((U32*)(&buf_ptr[PHL_PACKET_ID]))); + mSocket = socket; + if (mRetries) + { + mBuffer = new U8[buf_len]; + if (mBuffer != NULL) + { + memcpy(mBuffer,buf_ptr,buf_len); /*Flawfinder: ignore*/ + mBufferLength = buf_len; + } - mSocket = socket; - if (mRetries) - { - mBuffer = new U8[buf_len]; - if (mBuffer != NULL) - { - memcpy(mBuffer,buf_ptr,buf_len); /*Flawfinder: ignore*/ - mBufferLength = buf_len; - } - - } + } } diff --git a/indra/llmessage/llpacketack.h b/indra/llmessage/llpacketack.h index 76e2e43acb..0903c01e14 100644 --- a/indra/llmessage/llpacketack.h +++ b/indra/llmessage/llpacketack.h @@ -1,25 +1,25 @@ -/** +/** * @file llpacketack.h * @brief Reliable UDP helpers for the message system. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,83 +33,83 @@ class LLReliablePacketParams { public: - LLHost mHost; - S32 mRetries; - bool mPingBasedRetry; - F32Seconds mTimeout; - void (*mCallback)(void **,S32); - void** mCallbackData; - char* mMessageName; + LLHost mHost; + S32 mRetries; + bool mPingBasedRetry; + F32Seconds mTimeout; + void (*mCallback)(void **,S32); + void** mCallbackData; + char* mMessageName; public: - LLReliablePacketParams() - { - clear(); - }; + LLReliablePacketParams() + { + clear(); + }; - ~LLReliablePacketParams() { }; + ~LLReliablePacketParams() { }; - void clear() - { - mHost.invalidate(); - mRetries = 0; - mPingBasedRetry = true; - mTimeout = F32Seconds(0.f); - mCallback = NULL; - mCallbackData = NULL; - mMessageName = NULL; - }; + void clear() + { + mHost.invalidate(); + mRetries = 0; + mPingBasedRetry = true; + mTimeout = F32Seconds(0.f); + mCallback = NULL; + mCallbackData = NULL; + mMessageName = NULL; + }; - void set( - const LLHost& host, - S32 retries, - bool ping_based_retry, - F32Seconds timeout, - void (*callback)(void**,S32), - void** callback_data, char* name) - { - mHost = host; - mRetries = retries; - mPingBasedRetry = ping_based_retry; - mTimeout = timeout; - mCallback = callback; - mCallbackData = callback_data; - mMessageName = name; - }; + void set( + const LLHost& host, + S32 retries, + bool ping_based_retry, + F32Seconds timeout, + void (*callback)(void**,S32), + void** callback_data, char* name) + { + mHost = host; + mRetries = retries; + mPingBasedRetry = ping_based_retry; + mTimeout = timeout; + mCallback = callback; + mCallbackData = callback_data; + mMessageName = name; + }; }; class LLReliablePacket { public: - LLReliablePacket( - S32 socket, - U8* buf_ptr, - S32 buf_len, - LLReliablePacketParams* params); - ~LLReliablePacket() - { - mCallback = NULL; - delete [] mBuffer; - mBuffer = NULL; - }; + LLReliablePacket( + S32 socket, + U8* buf_ptr, + S32 buf_len, + LLReliablePacketParams* params); + ~LLReliablePacket() + { + mCallback = NULL; + delete [] mBuffer; + mBuffer = NULL; + }; - friend class LLCircuitData; + friend class LLCircuitData; protected: - S32 mSocket; - LLHost mHost; - S32 mRetries; - bool mPingBasedRetry; - F32Seconds mTimeout; - void (*mCallback)(void**,S32); - void** mCallbackData; - char* mMessageName; + S32 mSocket; + LLHost mHost; + S32 mRetries; + bool mPingBasedRetry; + F32Seconds mTimeout; + void (*mCallback)(void**,S32); + void** mCallbackData; + char* mMessageName; - U8* mBuffer; - S32 mBufferLength; + U8* mBuffer; + S32 mBufferLength; - TPACKETID mPacketID; + TPACKETID mPacketID; - F64Seconds mExpirationTime; + F64Seconds mExpirationTime; }; #endif diff --git a/indra/llmessage/llpacketbuffer.cpp b/indra/llmessage/llpacketbuffer.cpp index ccf991b1a7..dc5c7a73cb 100644 --- a/indra/llmessage/llpacketbuffer.cpp +++ b/indra/llmessage/llpacketbuffer.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpacketbuffer.cpp * @brief implementation of LLPacketBuffer class for a packet. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,27 +36,27 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host) { - mSize = 0; - mData[0] = '!'; + mSize = 0; + mData[0] = '!'; + + if (size > NET_BUFFER_SIZE) + { + LL_ERRS() << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << LL_ENDL; + } + else + { + if (datap != NULL) + { + memcpy(mData, datap, size); + mSize = size; + } + } - if (size > NET_BUFFER_SIZE) - { - LL_ERRS() << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << LL_ENDL; - } - else - { - if (datap != NULL) - { - memcpy(mData, datap, size); - mSize = size; - } - } - } LLPacketBuffer::LLPacketBuffer (S32 hSocket) { - init(hSocket); + init(hSocket); } /////////////////////////////////////////////////////////// @@ -69,8 +69,8 @@ LLPacketBuffer::~LLPacketBuffer () void LLPacketBuffer::init (S32 hSocket) { - mSize = receive_packet(hSocket, mData); - mHost = ::get_sender(); - mReceivingIF = ::get_receiving_interface(); + mSize = receive_packet(hSocket, mData); + mHost = ::get_sender(); + mReceivingIF = ::get_receiving_interface(); } diff --git a/indra/llmessage/llpacketbuffer.h b/indra/llmessage/llpacketbuffer.h index 14b6f9d5d2..a2d2973fb0 100644 --- a/indra/llmessage/llpacketbuffer.h +++ b/indra/llmessage/llpacketbuffer.h @@ -1,4 +1,4 @@ -/** +/** * @file llpacketbuffer.h * @brief definition of LLPacketBuffer class for implementing a * resend, drop, or delay in packet transmissions. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,27 +28,27 @@ #ifndef LL_LLPACKETBUFFER_H #define LL_LLPACKETBUFFER_H -#include "net.h" // for NET_BUFFER_SIZE +#include "net.h" // for NET_BUFFER_SIZE #include "llhost.h" class LLPacketBuffer { public: - LLPacketBuffer(const LLHost &host, const char *datap, const S32 size); - LLPacketBuffer(S32 hSocket); // receive a packet - ~LLPacketBuffer(); + LLPacketBuffer(const LLHost &host, const char *datap, const S32 size); + LLPacketBuffer(S32 hSocket); // receive a packet + ~LLPacketBuffer(); - S32 getSize() const { return mSize; } - const char *getData() const { return mData; } - LLHost getHost() const { return mHost; } - LLHost getReceivingInterface() const { return mReceivingIF; } - void init(S32 hSocket); + S32 getSize() const { return mSize; } + const char *getData() const { return mData; } + LLHost getHost() const { return mHost; } + LLHost getReceivingInterface() const { return mReceivingIF; } + void init(S32 hSocket); protected: - char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */ - S32 mSize; // size of buffer in bytes - LLHost mHost; // source/dest IP and port - LLHost mReceivingIF; // source/dest IP and port + char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */ + S32 mSize; // size of buffer in bytes + LLHost mHost; // source/dest IP and port + LLHost mReceivingIF; // source/dest IP and port }; #endif diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp index 8e098bfc8c..be838770a8 100644 --- a/indra/llmessage/llpacketring.cpp +++ b/indra/llmessage/llpacketring.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpacketring.cpp * @brief implementation of LLPacketRing class for a packet. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,10 +29,10 @@ #include "llpacketring.h" #if LL_WINDOWS - #include <winsock2.h> + #include <winsock2.h> #else - #include <sys/socket.h> - #include <netinet/in.h> + #include <sys/socket.h> + #include <netinet/in.h> #endif // linden library includes @@ -45,327 +45,327 @@ /////////////////////////////////////////////////////////// LLPacketRing::LLPacketRing () : - mUseInThrottle(false), - mUseOutThrottle(false), - mInThrottle(256000.f), - mOutThrottle(64000.f), - mActualBitsIn(0), - mActualBitsOut(0), - mMaxBufferLength(64000), - mInBufferLength(0), - mOutBufferLength(0), - mDropPercentage(0.0f), - mPacketsToDrop(0x0) + mUseInThrottle(false), + mUseOutThrottle(false), + mInThrottle(256000.f), + mOutThrottle(64000.f), + mActualBitsIn(0), + mActualBitsOut(0), + mMaxBufferLength(64000), + mInBufferLength(0), + mOutBufferLength(0), + mDropPercentage(0.0f), + mPacketsToDrop(0x0) { } /////////////////////////////////////////////////////////// LLPacketRing::~LLPacketRing () { - cleanup(); + cleanup(); } - + /////////////////////////////////////////////////////////// void LLPacketRing::cleanup () { - LLPacketBuffer *packetp; - - while (!mReceiveQueue.empty()) - { - packetp = mReceiveQueue.front(); - delete packetp; - mReceiveQueue.pop(); - } - - while (!mSendQueue.empty()) - { - packetp = mSendQueue.front(); - delete packetp; - mSendQueue.pop(); - } + LLPacketBuffer *packetp; + + while (!mReceiveQueue.empty()) + { + packetp = mReceiveQueue.front(); + delete packetp; + mReceiveQueue.pop(); + } + + while (!mSendQueue.empty()) + { + packetp = mSendQueue.front(); + delete packetp; + mSendQueue.pop(); + } } /////////////////////////////////////////////////////////// void LLPacketRing::dropPackets (U32 num_to_drop) { - mPacketsToDrop += num_to_drop; + mPacketsToDrop += num_to_drop; } /////////////////////////////////////////////////////////// void LLPacketRing::setDropPercentage (F32 percent_to_drop) { - mDropPercentage = percent_to_drop; + mDropPercentage = percent_to_drop; } void LLPacketRing::setUseInThrottle(const bool use_throttle) { - mUseInThrottle = use_throttle; + mUseInThrottle = use_throttle; } void LLPacketRing::setUseOutThrottle(const bool use_throttle) { - mUseOutThrottle = use_throttle; + mUseOutThrottle = use_throttle; } void LLPacketRing::setInBandwidth(const F32 bps) { - mInThrottle.setRate(bps); + mInThrottle.setRate(bps); } void LLPacketRing::setOutBandwidth(const F32 bps) { - mOutThrottle.setRate(bps); + mOutThrottle.setRate(bps); } /////////////////////////////////////////////////////////// S32 LLPacketRing::receiveFromRing (S32 socket, char *datap) { - if (mInThrottle.checkOverflow(0)) - { - // We don't have enough bandwidth, don't give them a packet. - return 0; - } - - LLPacketBuffer *packetp = NULL; - if (mReceiveQueue.empty()) - { - // No packets on the queue, don't give them any. - return 0; - } - - S32 packet_size = 0; - packetp = mReceiveQueue.front(); - mReceiveQueue.pop(); - packet_size = packetp->getSize(); - if (packetp->getData() != NULL) - { - memcpy(datap, packetp->getData(), packet_size); /*Flawfinder: ignore*/ - } - // need to set sender IP/port!! - mLastSender = packetp->getHost(); - mLastReceivingIF = packetp->getReceivingInterface(); - delete packetp; - - this->mInBufferLength -= packet_size; - - // Adjust the throttle - mInThrottle.throttleOverflow(packet_size * 8.f); - return packet_size; + if (mInThrottle.checkOverflow(0)) + { + // We don't have enough bandwidth, don't give them a packet. + return 0; + } + + LLPacketBuffer *packetp = NULL; + if (mReceiveQueue.empty()) + { + // No packets on the queue, don't give them any. + return 0; + } + + S32 packet_size = 0; + packetp = mReceiveQueue.front(); + mReceiveQueue.pop(); + packet_size = packetp->getSize(); + if (packetp->getData() != NULL) + { + memcpy(datap, packetp->getData(), packet_size); /*Flawfinder: ignore*/ + } + // need to set sender IP/port!! + mLastSender = packetp->getHost(); + mLastReceivingIF = packetp->getReceivingInterface(); + delete packetp; + + this->mInBufferLength -= packet_size; + + // Adjust the throttle + mInThrottle.throttleOverflow(packet_size * 8.f); + return packet_size; } /////////////////////////////////////////////////////////// S32 LLPacketRing::receivePacket (S32 socket, char *datap) { - S32 packet_size = 0; - - // If using the throttle, simulate a limited size input buffer. - if (mUseInThrottle) - { - bool done = false; - - // push any current net packet (if any) onto delay ring - while (!done) - { - LLPacketBuffer *packetp; - packetp = new LLPacketBuffer(socket); - - if (packetp->getSize()) - { - mActualBitsIn += packetp->getSize() * 8; - - // Fake packet loss - if (mDropPercentage && (ll_frand(100.f) < mDropPercentage)) - { - mPacketsToDrop++; - } - - if (mPacketsToDrop) - { - delete packetp; - packetp = NULL; - packet_size = 0; - mPacketsToDrop--; - } - } - - // If we faked packet loss, then we don't have a packet - // to use for buffer overflow testing - if (packetp) - { - if (mInBufferLength + packetp->getSize() > mMaxBufferLength) - { - // Toss it. - LL_WARNS() << "Throwing away packet, overflowing buffer" << LL_ENDL; - delete packetp; - packetp = NULL; - } - else if (packetp->getSize()) - { - mReceiveQueue.push(packetp); - mInBufferLength += packetp->getSize(); - } - else - { - delete packetp; - packetp = NULL; - done = true; - } - } - else - { - // No packetp, keep going? - no packetp == faked packet loss - } - } - - // Now, grab data off of the receive queue according to our - // throttled bandwidth settings. - packet_size = receiveFromRing(socket, datap); - } - else - { - // no delay, pull straight from net - if (LLProxy::isSOCKSProxyEnabled()) - { - U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; - packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer))); - - if (packet_size > SOCKS_HEADER_SIZE) - { - // *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6) - memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE); - proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer)); - mLastSender.setAddress(header->addr); - mLastSender.setPort(ntohs(header->port)); - - packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size - } - else - { - packet_size = 0; - } - } - else - { - packet_size = receive_packet(socket, datap); - mLastSender = ::get_sender(); - } - - mLastReceivingIF = ::get_receiving_interface(); - - if (packet_size) // did we actually get a packet? - { - if (mDropPercentage && (ll_frand(100.f) < mDropPercentage)) - { - mPacketsToDrop++; - } - - if (mPacketsToDrop) - { - packet_size = 0; - mPacketsToDrop--; - } - } - } - - return packet_size; + S32 packet_size = 0; + + // If using the throttle, simulate a limited size input buffer. + if (mUseInThrottle) + { + bool done = false; + + // push any current net packet (if any) onto delay ring + while (!done) + { + LLPacketBuffer *packetp; + packetp = new LLPacketBuffer(socket); + + if (packetp->getSize()) + { + mActualBitsIn += packetp->getSize() * 8; + + // Fake packet loss + if (mDropPercentage && (ll_frand(100.f) < mDropPercentage)) + { + mPacketsToDrop++; + } + + if (mPacketsToDrop) + { + delete packetp; + packetp = NULL; + packet_size = 0; + mPacketsToDrop--; + } + } + + // If we faked packet loss, then we don't have a packet + // to use for buffer overflow testing + if (packetp) + { + if (mInBufferLength + packetp->getSize() > mMaxBufferLength) + { + // Toss it. + LL_WARNS() << "Throwing away packet, overflowing buffer" << LL_ENDL; + delete packetp; + packetp = NULL; + } + else if (packetp->getSize()) + { + mReceiveQueue.push(packetp); + mInBufferLength += packetp->getSize(); + } + else + { + delete packetp; + packetp = NULL; + done = true; + } + } + else + { + // No packetp, keep going? - no packetp == faked packet loss + } + } + + // Now, grab data off of the receive queue according to our + // throttled bandwidth settings. + packet_size = receiveFromRing(socket, datap); + } + else + { + // no delay, pull straight from net + if (LLProxy::isSOCKSProxyEnabled()) + { + U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; + packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer))); + + if (packet_size > SOCKS_HEADER_SIZE) + { + // *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6) + memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE); + proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer)); + mLastSender.setAddress(header->addr); + mLastSender.setPort(ntohs(header->port)); + + packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size + } + else + { + packet_size = 0; + } + } + else + { + packet_size = receive_packet(socket, datap); + mLastSender = ::get_sender(); + } + + mLastReceivingIF = ::get_receiving_interface(); + + if (packet_size) // did we actually get a packet? + { + if (mDropPercentage && (ll_frand(100.f) < mDropPercentage)) + { + mPacketsToDrop++; + } + + if (mPacketsToDrop) + { + packet_size = 0; + mPacketsToDrop--; + } + } + } + + return packet_size; } bool LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host) { - bool status = true; - if (!mUseOutThrottle) - { - return sendPacketImpl(h_socket, send_buffer, buf_size, host ); - } - else - { - mActualBitsOut += buf_size * 8; - LLPacketBuffer *packetp = NULL; - // See if we've got enough throttle to send a packet. - while (!mOutThrottle.checkOverflow(0.f)) - { - // While we have enough bandwidth, send a packet from the queue or the current packet - - S32 packet_size = 0; - if (!mSendQueue.empty()) - { - // Send a packet off of the queue - LLPacketBuffer *packetp = mSendQueue.front(); - mSendQueue.pop(); - - mOutBufferLength -= packetp->getSize(); - packet_size = packetp->getSize(); - - status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost()); - - delete packetp; - // Update the throttle - mOutThrottle.throttleOverflow(packet_size * 8.f); - } - else - { - // If the queue's empty, we can just send this packet right away. - status = sendPacketImpl(h_socket, send_buffer, buf_size, host ); - packet_size = buf_size; - - // Update the throttle - mOutThrottle.throttleOverflow(packet_size * 8.f); - - // This was the packet we're sending now, there are no other packets - // that we need to send - return status; - } - - } - - // We haven't sent the incoming packet, add it to the queue - if (mOutBufferLength + buf_size > mMaxBufferLength) - { - // Nuke this packet, we overflowed the buffer. - // Toss it. - LL_WARNS() << "Throwing away outbound packet, overflowing buffer" << LL_ENDL; - } - else - { - static LLTimer queue_timer; - if ((mOutBufferLength > 4192) && queue_timer.getElapsedTimeF32() > 1.f) - { - // Add it to the queue - LL_INFOS() << "Outbound packet queue " << mOutBufferLength << " bytes" << LL_ENDL; - queue_timer.reset(); - } - packetp = new LLPacketBuffer(host, send_buffer, buf_size); - - mOutBufferLength += packetp->getSize(); - mSendQueue.push(packetp); - } - } - - return status; + bool status = true; + if (!mUseOutThrottle) + { + return sendPacketImpl(h_socket, send_buffer, buf_size, host ); + } + else + { + mActualBitsOut += buf_size * 8; + LLPacketBuffer *packetp = NULL; + // See if we've got enough throttle to send a packet. + while (!mOutThrottle.checkOverflow(0.f)) + { + // While we have enough bandwidth, send a packet from the queue or the current packet + + S32 packet_size = 0; + if (!mSendQueue.empty()) + { + // Send a packet off of the queue + LLPacketBuffer *packetp = mSendQueue.front(); + mSendQueue.pop(); + + mOutBufferLength -= packetp->getSize(); + packet_size = packetp->getSize(); + + status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost()); + + delete packetp; + // Update the throttle + mOutThrottle.throttleOverflow(packet_size * 8.f); + } + else + { + // If the queue's empty, we can just send this packet right away. + status = sendPacketImpl(h_socket, send_buffer, buf_size, host ); + packet_size = buf_size; + + // Update the throttle + mOutThrottle.throttleOverflow(packet_size * 8.f); + + // This was the packet we're sending now, there are no other packets + // that we need to send + return status; + } + + } + + // We haven't sent the incoming packet, add it to the queue + if (mOutBufferLength + buf_size > mMaxBufferLength) + { + // Nuke this packet, we overflowed the buffer. + // Toss it. + LL_WARNS() << "Throwing away outbound packet, overflowing buffer" << LL_ENDL; + } + else + { + static LLTimer queue_timer; + if ((mOutBufferLength > 4192) && queue_timer.getElapsedTimeF32() > 1.f) + { + // Add it to the queue + LL_INFOS() << "Outbound packet queue " << mOutBufferLength << " bytes" << LL_ENDL; + queue_timer.reset(); + } + packetp = new LLPacketBuffer(host, send_buffer, buf_size); + + mOutBufferLength += packetp->getSize(); + mSendQueue.push(packetp); + } + } + + return status; } bool LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host) { - - if (!LLProxy::isSOCKSProxyEnabled()) - { - return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort()); - } - - char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; - - proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer)); - socks_header->rsv = 0; - socks_header->addr = host.getAddress(); - socks_header->port = htons(host.getPort()); - socks_header->atype = ADDRESS_IPV4; - socks_header->frag = 0; - - memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size); - - return send_packet( h_socket, - headered_send_buffer, - buf_size + SOCKS_HEADER_SIZE, - LLProxy::getInstance()->getUDPProxy().getAddress(), - LLProxy::getInstance()->getUDPProxy().getPort()); + + if (!LLProxy::isSOCKSProxyEnabled()) + { + return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort()); + } + + char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; + + proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer)); + socks_header->rsv = 0; + socks_header->addr = host.getAddress(); + socks_header->port = htons(host.getPort()); + socks_header->atype = ADDRESS_IPV4; + socks_header->frag = 0; + + memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size); + + return send_packet( h_socket, + headered_send_buffer, + buf_size + SOCKS_HEADER_SIZE, + LLProxy::getInstance()->getUDPProxy().getAddress(), + LLProxy::getInstance()->getUDPProxy().getPort()); } diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h index 888ee927b5..f0e95f8524 100644 --- a/indra/llmessage/llpacketring.h +++ b/indra/llmessage/llpacketring.h @@ -1,4 +1,4 @@ -/** +/** * @file llpacketring.h * @brief definition of LLPacketRing class for implementing a resend, * drop, or delay in packet transmissions @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,63 +39,63 @@ class LLPacketRing { public: - LLPacketRing(); + LLPacketRing(); ~LLPacketRing(); - void cleanup(); + void cleanup(); - void dropPackets(U32); - void setDropPercentage (F32 percent_to_drop); - void setUseInThrottle(const bool use_throttle); - void setUseOutThrottle(const bool use_throttle); - void setInBandwidth(const F32 bps); - void setOutBandwidth(const F32 bps); - S32 receivePacket (S32 socket, char *datap); - S32 receiveFromRing (S32 socket, char *datap); + void dropPackets(U32); + void setDropPercentage (F32 percent_to_drop); + void setUseInThrottle(const bool use_throttle); + void setUseOutThrottle(const bool use_throttle); + void setInBandwidth(const F32 bps); + void setOutBandwidth(const F32 bps); + S32 receivePacket (S32 socket, char *datap); + S32 receiveFromRing (S32 socket, char *datap); - bool sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host); + bool sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host); - inline LLHost getLastSender(); - inline LLHost getLastReceivingInterface(); + inline LLHost getLastSender(); + inline LLHost getLastReceivingInterface(); - S32 getAndResetActualInBits() { S32 bits = mActualBitsIn; mActualBitsIn = 0; return bits;} - S32 getAndResetActualOutBits() { S32 bits = mActualBitsOut; mActualBitsOut = 0; return bits;} + S32 getAndResetActualInBits() { S32 bits = mActualBitsIn; mActualBitsIn = 0; return bits;} + S32 getAndResetActualOutBits() { S32 bits = mActualBitsOut; mActualBitsOut = 0; return bits;} protected: - bool mUseInThrottle; - bool mUseOutThrottle; - - // For simulating a lower-bandwidth connection - BPS - LLThrottle mInThrottle; - LLThrottle mOutThrottle; + bool mUseInThrottle; + bool mUseOutThrottle; + + // For simulating a lower-bandwidth connection - BPS + LLThrottle mInThrottle; + LLThrottle mOutThrottle; - S32 mActualBitsIn; - S32 mActualBitsOut; - S32 mMaxBufferLength; // How much data can we queue up before dropping data. - S32 mInBufferLength; // Current incoming buffer length - S32 mOutBufferLength; // Current outgoing buffer length + S32 mActualBitsIn; + S32 mActualBitsOut; + S32 mMaxBufferLength; // How much data can we queue up before dropping data. + S32 mInBufferLength; // Current incoming buffer length + S32 mOutBufferLength; // Current outgoing buffer length - F32 mDropPercentage; // % of packets to drop - U32 mPacketsToDrop; // drop next n packets + F32 mDropPercentage; // % of packets to drop + U32 mPacketsToDrop; // drop next n packets - std::queue<LLPacketBuffer *> mReceiveQueue; - std::queue<LLPacketBuffer *> mSendQueue; + std::queue<LLPacketBuffer *> mReceiveQueue; + std::queue<LLPacketBuffer *> mSendQueue; - LLHost mLastSender; - LLHost mLastReceivingIF; + LLHost mLastSender; + LLHost mLastReceivingIF; private: - bool sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host); + bool sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host); }; inline LLHost LLPacketRing::getLastSender() { - return mLastSender; + return mLastSender; } inline LLHost LLPacketRing::getLastReceivingInterface() { - return mLastReceivingIF; + return mLastReceivingIF; } #endif diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index a4852cefba..296f4b5464 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpartdata.cpp * @brief Particle system data packing * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,10 +42,10 @@ const S32 PS_PART_DATA_BLEND_SIZE = 2; const S32 PS_LEGACY_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; //18 const S32 PS_SYS_DATA_BLOCK_SIZE = 68; const S32 PS_MAX_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE+ - PS_LEGACY_PART_DATA_BLOCK_SIZE + - PS_PART_DATA_BLEND_SIZE + - PS_PART_DATA_GLOW_SIZE+ - 8; //two S32 size fields + PS_LEGACY_PART_DATA_BLOCK_SIZE + + PS_PART_DATA_BLEND_SIZE + + PS_PART_DATA_GLOW_SIZE+ + 8; //two S32 size fields const S32 PS_LEGACY_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE + PS_LEGACY_PART_DATA_BLOCK_SIZE; @@ -53,367 +53,367 @@ const F32 MAX_PART_SCALE = 4.f; bool LLPartData::hasGlow() const { - return mStartGlow > 0.f || mEndGlow > 0.f; + return mStartGlow > 0.f || mEndGlow > 0.f; } bool LLPartData::hasBlendFunc() const { - return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; + return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; } S32 LLPartData::getSize() const { - S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE; - if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE; - if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE; + S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE; + if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE; + if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE; - return size; + return size; } bool LLPartData::unpackLegacy(LLDataPacker &dp) { - LLColor4U coloru; - - dp.unpackU32(mFlags, "pdflags"); - dp.unpackFixed(mMaxAge, "pdmaxage", false, 8, 8); - - dp.unpackColor4U(coloru, "pdstartcolor"); - mStartColor.setVec(coloru); - dp.unpackColor4U(coloru, "pdendcolor"); - mEndColor.setVec(coloru); - dp.unpackFixed(mStartScale.mV[0], "pdstartscalex", false, 3, 5); - dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", false, 3, 5); - dp.unpackFixed(mEndScale.mV[0], "pdendscalex", false, 3, 5); - dp.unpackFixed(mEndScale.mV[1], "pdendscaley", false, 3, 5); - - mStartGlow = 0.f; - mEndGlow = 0.f; - mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; - mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; - - return true; + LLColor4U coloru; + + dp.unpackU32(mFlags, "pdflags"); + dp.unpackFixed(mMaxAge, "pdmaxage", false, 8, 8); + + dp.unpackColor4U(coloru, "pdstartcolor"); + mStartColor.setVec(coloru); + dp.unpackColor4U(coloru, "pdendcolor"); + mEndColor.setVec(coloru); + dp.unpackFixed(mStartScale.mV[0], "pdstartscalex", false, 3, 5); + dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", false, 3, 5); + dp.unpackFixed(mEndScale.mV[0], "pdendscalex", false, 3, 5); + dp.unpackFixed(mEndScale.mV[1], "pdendscaley", false, 3, 5); + + mStartGlow = 0.f; + mEndGlow = 0.f; + mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; + mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; + + return true; } bool LLPartData::unpack(LLDataPacker &dp) { - S32 size = 0; - dp.unpackS32(size, "partsize"); - - unpackLegacy(dp); - size -= PS_LEGACY_PART_DATA_BLOCK_SIZE; - - if (mFlags & LL_PART_DATA_GLOW) - { - if (size < PS_PART_DATA_GLOW_SIZE) return false; - - U8 tmp_glow = 0; - dp.unpackU8(tmp_glow,"pdstartglow"); - mStartGlow = tmp_glow / 255.f; - dp.unpackU8(tmp_glow,"pdendglow"); - mEndGlow = tmp_glow / 255.f; - - size -= PS_PART_DATA_GLOW_SIZE; - } - else - { - mStartGlow = 0.f; - mEndGlow = 0.f; - } - - if (mFlags & LL_PART_DATA_BLEND) - { - if (size < PS_PART_DATA_BLEND_SIZE) return false; - dp.unpackU8(mBlendFuncSource,"pdblendsource"); - dp.unpackU8(mBlendFuncDest,"pdblenddest"); - size -= PS_PART_DATA_BLEND_SIZE; - } - else - { - mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; - mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; - } - - if (size > 0) - { //leftover bytes, unrecognized parameters - U8 feh = 0; - while (size > 0) - { //read remaining bytes in block - dp.unpackU8(feh, "whippang"); - size--; - } - - //this particle system won't display properly, better to not show anything - return false; - } - - - return true; + S32 size = 0; + dp.unpackS32(size, "partsize"); + + unpackLegacy(dp); + size -= PS_LEGACY_PART_DATA_BLOCK_SIZE; + + if (mFlags & LL_PART_DATA_GLOW) + { + if (size < PS_PART_DATA_GLOW_SIZE) return false; + + U8 tmp_glow = 0; + dp.unpackU8(tmp_glow,"pdstartglow"); + mStartGlow = tmp_glow / 255.f; + dp.unpackU8(tmp_glow,"pdendglow"); + mEndGlow = tmp_glow / 255.f; + + size -= PS_PART_DATA_GLOW_SIZE; + } + else + { + mStartGlow = 0.f; + mEndGlow = 0.f; + } + + if (mFlags & LL_PART_DATA_BLEND) + { + if (size < PS_PART_DATA_BLEND_SIZE) return false; + dp.unpackU8(mBlendFuncSource,"pdblendsource"); + dp.unpackU8(mBlendFuncDest,"pdblenddest"); + size -= PS_PART_DATA_BLEND_SIZE; + } + else + { + mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; + mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; + } + + if (size > 0) + { //leftover bytes, unrecognized parameters + U8 feh = 0; + while (size > 0) + { //read remaining bytes in block + dp.unpackU8(feh, "whippang"); + size--; + } + + //this particle system won't display properly, better to not show anything + return false; + } + + + return true; } void LLPartData::setFlags(const U32 flags) { - mFlags = flags; + mFlags = flags; } void LLPartData::setMaxAge(const F32 max_age) { - mMaxAge = llclamp(max_age, 0.f, 30.f); + mMaxAge = llclamp(max_age, 0.f, 30.f); } void LLPartData::setStartScale(const F32 xs, const F32 ys) { - mStartScale.mV[VX] = llmin(xs, MAX_PART_SCALE); - mStartScale.mV[VY] = llmin(ys, MAX_PART_SCALE); + mStartScale.mV[VX] = llmin(xs, MAX_PART_SCALE); + mStartScale.mV[VY] = llmin(ys, MAX_PART_SCALE); } void LLPartData::setEndScale(const F32 xs, const F32 ys) { - mEndScale.mV[VX] = llmin(xs, MAX_PART_SCALE); - mEndScale.mV[VY] = llmin(ys, MAX_PART_SCALE); + mEndScale.mV[VX] = llmin(xs, MAX_PART_SCALE); + mEndScale.mV[VY] = llmin(ys, MAX_PART_SCALE); } void LLPartData::setStartColor(const LLVector3 &rgb) { - mStartColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]); + mStartColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]); } void LLPartData::setEndColor(const LLVector3 &rgb) { - mEndColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]); + mEndColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]); } void LLPartData::setStartAlpha(const F32 alpha) { - mStartColor.mV[3] = alpha; + mStartColor.mV[3] = alpha; } void LLPartData::setEndAlpha(const F32 alpha) { - mEndColor.mV[3] = alpha; + mEndColor.mV[3] = alpha; } // static bool LLPartData::validBlendFunc(S32 func) { - if (func >= 0 - && func < LL_PART_BF_COUNT - && func != UNSUPPORTED_DEST_ALPHA - && func != UNSUPPORTED_ONE_MINUS_DEST_ALPHA) - { - return true; - } - return false; + if (func >= 0 + && func < LL_PART_BF_COUNT + && func != UNSUPPORTED_DEST_ALPHA + && func != UNSUPPORTED_ONE_MINUS_DEST_ALPHA) + { + return true; + } + return false; } LLPartSysData::LLPartSysData() { - mCRC = 0; - mFlags = 0; - - mPartData.mFlags = 0; - mPartData.mStartColor = LLColor4(1.f, 1.f, 1.f, 1.f); - mPartData.mEndColor = LLColor4(1.f, 1.f, 1.f, 1.f); - mPartData.mStartScale = LLVector2(1.f, 1.f); - mPartData.mEndScale = LLVector2(1.f, 1.f); - mPartData.mMaxAge = 10.0; - mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; - mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; - mPartData.mStartGlow = 0.f; - mPartData.mEndGlow = 0.f; - - mMaxAge = 0.0; - mStartAge = 0.0; - mPattern = LL_PART_SRC_PATTERN_DROP; // Pattern for particle velocity - mInnerAngle = 0.0; // Inner angle of PATTERN_ANGLE_* - mOuterAngle = 0.0; // Outer angle of PATTERN_ANGLE_* - mBurstRate = 0.1f; // How often to do a burst of particles - mBurstPartCount = 1; // How many particles in a burst - mBurstSpeedMin = 1.f; // Minimum particle velocity - mBurstSpeedMax = 1.f; // Maximum particle velocity - mBurstRadius = 0.f; - - mNumParticles = 0; + mCRC = 0; + mFlags = 0; + + mPartData.mFlags = 0; + mPartData.mStartColor = LLColor4(1.f, 1.f, 1.f, 1.f); + mPartData.mEndColor = LLColor4(1.f, 1.f, 1.f, 1.f); + mPartData.mStartScale = LLVector2(1.f, 1.f); + mPartData.mEndScale = LLVector2(1.f, 1.f); + mPartData.mMaxAge = 10.0; + mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; + mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; + mPartData.mStartGlow = 0.f; + mPartData.mEndGlow = 0.f; + + mMaxAge = 0.0; + mStartAge = 0.0; + mPattern = LL_PART_SRC_PATTERN_DROP; // Pattern for particle velocity + mInnerAngle = 0.0; // Inner angle of PATTERN_ANGLE_* + mOuterAngle = 0.0; // Outer angle of PATTERN_ANGLE_* + mBurstRate = 0.1f; // How often to do a burst of particles + mBurstPartCount = 1; // How many particles in a burst + mBurstSpeedMin = 1.f; // Minimum particle velocity + mBurstSpeedMax = 1.f; // Maximum particle velocity + mBurstRadius = 0.f; + + mNumParticles = 0; } bool LLPartSysData::unpackSystem(LLDataPacker &dp) { - dp.unpackU32(mCRC, "pscrc"); - dp.unpackU32(mFlags, "psflags"); - dp.unpackU8(mPattern, "pspattern"); - dp.unpackFixed(mMaxAge, "psmaxage", false, 8, 8); - dp.unpackFixed(mStartAge, "psstartage", false, 8, 8); - dp.unpackFixed(mInnerAngle, "psinnerangle", false, 3, 5); - dp.unpackFixed(mOuterAngle, "psouterangle", false, 3, 5); - dp.unpackFixed(mBurstRate, "psburstrate", false, 8, 8); - mBurstRate = llmax(0.01f, mBurstRate); - dp.unpackFixed(mBurstRadius, "psburstradius", false, 8, 8); - dp.unpackFixed(mBurstSpeedMin, "psburstspeedmin", false, 8, 8); - dp.unpackFixed(mBurstSpeedMax, "psburstspeedmax", false, 8, 8); - dp.unpackU8(mBurstPartCount, "psburstpartcount"); - - dp.unpackFixed(mAngularVelocity.mV[0], "psangvelx", true, 8, 7); - dp.unpackFixed(mAngularVelocity.mV[1], "psangvely", true, 8, 7); - dp.unpackFixed(mAngularVelocity.mV[2], "psangvelz", true, 8, 7); - - dp.unpackFixed(mPartAccel.mV[0], "psaccelx", true, 8, 7); - dp.unpackFixed(mPartAccel.mV[1], "psaccely", true, 8, 7); - dp.unpackFixed(mPartAccel.mV[2], "psaccelz", true, 8, 7); - - dp.unpackUUID(mPartImageID, "psuuid"); - dp.unpackUUID(mTargetUUID, "pstargetuuid"); - return true; + dp.unpackU32(mCRC, "pscrc"); + dp.unpackU32(mFlags, "psflags"); + dp.unpackU8(mPattern, "pspattern"); + dp.unpackFixed(mMaxAge, "psmaxage", false, 8, 8); + dp.unpackFixed(mStartAge, "psstartage", false, 8, 8); + dp.unpackFixed(mInnerAngle, "psinnerangle", false, 3, 5); + dp.unpackFixed(mOuterAngle, "psouterangle", false, 3, 5); + dp.unpackFixed(mBurstRate, "psburstrate", false, 8, 8); + mBurstRate = llmax(0.01f, mBurstRate); + dp.unpackFixed(mBurstRadius, "psburstradius", false, 8, 8); + dp.unpackFixed(mBurstSpeedMin, "psburstspeedmin", false, 8, 8); + dp.unpackFixed(mBurstSpeedMax, "psburstspeedmax", false, 8, 8); + dp.unpackU8(mBurstPartCount, "psburstpartcount"); + + dp.unpackFixed(mAngularVelocity.mV[0], "psangvelx", true, 8, 7); + dp.unpackFixed(mAngularVelocity.mV[1], "psangvely", true, 8, 7); + dp.unpackFixed(mAngularVelocity.mV[2], "psangvelz", true, 8, 7); + + dp.unpackFixed(mPartAccel.mV[0], "psaccelx", true, 8, 7); + dp.unpackFixed(mPartAccel.mV[1], "psaccely", true, 8, 7); + dp.unpackFixed(mPartAccel.mV[2], "psaccelz", true, 8, 7); + + dp.unpackUUID(mPartImageID, "psuuid"); + dp.unpackUUID(mTargetUUID, "pstargetuuid"); + return true; } bool LLPartSysData::unpackLegacy(LLDataPacker &dp) { - unpackSystem(dp); - mPartData.unpackLegacy(dp); + unpackSystem(dp); + mPartData.unpackLegacy(dp); - return true; + return true; } bool LLPartSysData::unpack(LLDataPacker &dp) { - // syssize is currently unused. Adding now when modifying the 'version to make extensible in the future - S32 size = 0; - dp.unpackS32(size, "syssize"); - - if (size != PS_SYS_DATA_BLOCK_SIZE) - { //unexpected size, this viewer doesn't know how to parse this particle system - - //skip to LLPartData block - U8 feh = 0; - - for (U32 i = 0; i < size; ++i) - { - dp.unpackU8(feh, "whippang"); - } - - dp.unpackS32(size, "partsize"); - //skip LLPartData block - for (U32 i = 0; i < size; ++i) - { - dp.unpackU8(feh, "whippang"); - } - return false; - } - - unpackSystem(dp); - - return mPartData.unpack(dp); + // syssize is currently unused. Adding now when modifying the 'version to make extensible in the future + S32 size = 0; + dp.unpackS32(size, "syssize"); + + if (size != PS_SYS_DATA_BLOCK_SIZE) + { //unexpected size, this viewer doesn't know how to parse this particle system + + //skip to LLPartData block + U8 feh = 0; + + for (U32 i = 0; i < size; ++i) + { + dp.unpackU8(feh, "whippang"); + } + + dp.unpackS32(size, "partsize"); + //skip LLPartData block + for (U32 i = 0; i < size; ++i) + { + dp.unpackU8(feh, "whippang"); + } + return false; + } + + unpackSystem(dp); + + return mPartData.unpack(dp); } std::ostream& operator<<(std::ostream& s, const LLPartSysData &data) { - s << "Flags: " << std::hex << data.mFlags; - s << "Pattern: " << std::hex << (U32) data.mPattern << "\n"; - s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Flags: " << std::hex << data.mFlags; + s << "Pattern: " << std::hex << (U32) data.mPattern << "\n"; + s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; s << "Particle Age: " << data.mPartData.mMaxAge << "\n"; - s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n"; - s << "Burst Rate: " << data.mBurstRate << "\n"; - s << "Burst Radius: " << data.mBurstRadius << "\n"; - s << "Burst Speed: [" << data.mBurstSpeedMin << ", " << data.mBurstSpeedMax << "]\n"; - s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << "\n"; - s << "Angular Velocity: " << data.mAngularVelocity << "\n"; - s << "Accel: " << data.mPartAccel; - return s; + s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n"; + s << "Burst Rate: " << data.mBurstRate << "\n"; + s << "Burst Radius: " << data.mBurstRadius << "\n"; + s << "Burst Speed: [" << data.mBurstSpeedMin << ", " << data.mBurstSpeedMax << "]\n"; + s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << "\n"; + s << "Angular Velocity: " << data.mAngularVelocity << "\n"; + s << "Accel: " << data.mPartAccel; + return s; } bool LLPartSysData::isNullPS(const S32 block_num) { - U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE]; - U32 crc; - - S32 size; - // Check size of block - size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); - - if (!size) - { - return true; - } - - if (size > PS_MAX_DATA_BLOCK_SIZE) - { - //size is too big, newer particle version unsupported - return true; - } - - gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); - - LLDataPackerBinaryBuffer dp(ps_data_block, size); - if (size > PS_LEGACY_DATA_BLOCK_SIZE) - { - // non legacy systems pack a size before the CRC - S32 tmp = 0; - dp.unpackS32(tmp, "syssize"); - - if (tmp > PS_SYS_DATA_BLOCK_SIZE) - { //unknown system data block size, don't know how to parse it, treat as NULL - return true; - } - } - - dp.unpackU32(crc, "crc"); - - if (crc == 0) - { - return true; - } - return false; + U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE]; + U32 crc; + + S32 size; + // Check size of block + size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); + + if (!size) + { + return true; + } + + if (size > PS_MAX_DATA_BLOCK_SIZE) + { + //size is too big, newer particle version unsupported + return true; + } + + gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); + + LLDataPackerBinaryBuffer dp(ps_data_block, size); + if (size > PS_LEGACY_DATA_BLOCK_SIZE) + { + // non legacy systems pack a size before the CRC + S32 tmp = 0; + dp.unpackS32(tmp, "syssize"); + + if (tmp > PS_SYS_DATA_BLOCK_SIZE) + { //unknown system data block size, don't know how to parse it, treat as NULL + return true; + } + } + + dp.unpackU32(crc, "crc"); + + if (crc == 0) + { + return true; + } + return false; } bool LLPartSysData::unpackBlock(const S32 block_num) { - U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE]; - - // Check size of block - S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); - - if (size > PS_MAX_DATA_BLOCK_SIZE) - { - // Larger packets are newer and unsupported - return false; - } - - // Get from message - gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); - - LLDataPackerBinaryBuffer dp(ps_data_block, size); - - if (size == PS_LEGACY_DATA_BLOCK_SIZE) - { - return unpackLegacy(dp); - } - else - { - return unpack(dp); - } + U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE]; + + // Check size of block + S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); + + if (size > PS_MAX_DATA_BLOCK_SIZE) + { + // Larger packets are newer and unsupported + return false; + } + + // Get from message + gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); + + LLDataPackerBinaryBuffer dp(ps_data_block, size); + + if (size == PS_LEGACY_DATA_BLOCK_SIZE) + { + return unpackLegacy(dp); + } + else + { + return unpack(dp); + } } bool LLPartSysData::isLegacyCompatible() const { - return !mPartData.hasGlow() && !mPartData.hasBlendFunc(); + return !mPartData.hasGlow() && !mPartData.hasBlendFunc(); } void LLPartSysData::clampSourceParticleRate() { - F32 particle_rate = 0; - particle_rate = mBurstPartCount/mBurstRate; - if (particle_rate > 256.f) - { - mBurstPartCount = llfloor(((F32)mBurstPartCount)*(256.f/particle_rate)); - } + F32 particle_rate = 0; + particle_rate = mBurstPartCount/mBurstRate; + if (particle_rate > 256.f) + { + mBurstPartCount = llfloor(((F32)mBurstPartCount)*(256.f/particle_rate)); + } } void LLPartSysData::setPartAccel(const LLVector3 &accel) { - mPartAccel.mV[VX] = llclamp(accel.mV[VX], -100.f, 100.f); - mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f); - mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f); + mPartAccel.mV[VX] = llclamp(accel.mV[VX], -100.f, 100.f); + mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f); + mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f); } diff --git a/indra/llmessage/llpartdata.h b/indra/llmessage/llpartdata.h index c61e411a23..49b9e51a3d 100644 --- a/indra/llmessage/llpartdata.h +++ b/indra/llmessage/llpartdata.h @@ -1,25 +1,25 @@ -/** +/** * @file llpartdata.h * @brief Particle system data packing * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,236 +44,236 @@ const S32 PS_CUR_VERSION = 18; enum LLPSScriptFlags { - // Flags for the different parameters of individual particles - LLPS_PART_FLAGS, - LLPS_PART_START_COLOR, - LLPS_PART_START_ALPHA, - LLPS_PART_END_COLOR, - LLPS_PART_END_ALPHA, - LLPS_PART_START_SCALE, - LLPS_PART_END_SCALE, - LLPS_PART_MAX_AGE, - - // Flags for the different parameters of the particle source - LLPS_SRC_ACCEL, - LLPS_SRC_PATTERN, - LLPS_SRC_INNERANGLE, - LLPS_SRC_OUTERANGLE, - LLPS_SRC_TEXTURE, - LLPS_SRC_BURST_RATE, - LLPS_SRC_BURST_DURATION, - LLPS_SRC_BURST_PART_COUNT, - LLPS_SRC_BURST_RADIUS, - LLPS_SRC_BURST_SPEED_MIN, - LLPS_SRC_BURST_SPEED_MAX, - LLPS_SRC_MAX_AGE, - LLPS_SRC_TARGET_UUID, - LLPS_SRC_OMEGA, - LLPS_SRC_ANGLE_BEGIN, - LLPS_SRC_ANGLE_END, - - LLPS_PART_BLEND_FUNC_SOURCE, - LLPS_PART_BLEND_FUNC_DEST, - LLPS_PART_START_GLOW, - LLPS_PART_END_GLOW + // Flags for the different parameters of individual particles + LLPS_PART_FLAGS, + LLPS_PART_START_COLOR, + LLPS_PART_START_ALPHA, + LLPS_PART_END_COLOR, + LLPS_PART_END_ALPHA, + LLPS_PART_START_SCALE, + LLPS_PART_END_SCALE, + LLPS_PART_MAX_AGE, + + // Flags for the different parameters of the particle source + LLPS_SRC_ACCEL, + LLPS_SRC_PATTERN, + LLPS_SRC_INNERANGLE, + LLPS_SRC_OUTERANGLE, + LLPS_SRC_TEXTURE, + LLPS_SRC_BURST_RATE, + LLPS_SRC_BURST_DURATION, + LLPS_SRC_BURST_PART_COUNT, + LLPS_SRC_BURST_RADIUS, + LLPS_SRC_BURST_SPEED_MIN, + LLPS_SRC_BURST_SPEED_MAX, + LLPS_SRC_MAX_AGE, + LLPS_SRC_TARGET_UUID, + LLPS_SRC_OMEGA, + LLPS_SRC_ANGLE_BEGIN, + LLPS_SRC_ANGLE_END, + + LLPS_PART_BLEND_FUNC_SOURCE, + LLPS_PART_BLEND_FUNC_DEST, + LLPS_PART_START_GLOW, + LLPS_PART_END_GLOW }; class LLPartData { public: - LLPartData() : - mFlags(0), - mMaxAge(0.f), - mParameter(0.f) - { - } - bool unpackLegacy(LLDataPacker &dp); - bool unpack(LLDataPacker &dp); - - bool pack(LLDataPacker &dp); - - bool hasGlow() const; - bool hasBlendFunc() const; - - // Masks for the different particle flags - enum - { - LL_PART_INTERP_COLOR_MASK = 0x01, - LL_PART_INTERP_SCALE_MASK = 0x02, - LL_PART_BOUNCE_MASK = 0x04, - LL_PART_WIND_MASK = 0x08, - LL_PART_FOLLOW_SRC_MASK = 0x10, // Follows source, no rotation following (expensive!) - LL_PART_FOLLOW_VELOCITY_MASK = 0x20, // Particles orient themselves with velocity - LL_PART_TARGET_POS_MASK = 0x40, - LL_PART_TARGET_LINEAR_MASK = 0x80, // Particle uses a direct linear interpolation - LL_PART_EMISSIVE_MASK = 0x100, // Particle is "emissive", instead of being lit - LL_PART_BEAM_MASK = 0x200, // Particle is a "beam" connecting source and target - LL_PART_RIBBON_MASK = 0x400, // Particles are joined together into one continuous triangle strip - - // Not implemented yet! - //LL_PART_RANDOM_ACCEL_MASK = 0x100, // Particles have random acceleration - //LL_PART_RANDOM_VEL_MASK = 0x200, // Particles have random velocity shifts" - //LL_PART_TRAIL_MASK = 0x400, // Particles have historical "trails" - - //sYSTEM SET FLAGS - LL_PART_DATA_GLOW = 0x10000, - LL_PART_DATA_BLEND = 0x20000, - - // Viewer side use only! - LL_PART_HUD = 0x40000000, - LL_PART_DEAD_MASK = 0x80000000, - }; - - enum - { - LL_PART_BF_ONE = 0, - LL_PART_BF_ZERO = 1, - LL_PART_BF_DEST_COLOR = 2, - LL_PART_BF_SOURCE_COLOR = 3, - LL_PART_BF_ONE_MINUS_DEST_COLOR = 4, - LL_PART_BF_ONE_MINUS_SOURCE_COLOR = 5, - UNSUPPORTED_DEST_ALPHA = 6, - LL_PART_BF_SOURCE_ALPHA = 7, - UNSUPPORTED_ONE_MINUS_DEST_ALPHA = 8, - LL_PART_BF_ONE_MINUS_SOURCE_ALPHA = 9, - LL_PART_BF_COUNT = 10 - }; - - static bool validBlendFunc(S32 func); - - void setFlags(const U32 flags); - void setMaxAge(const F32 max_age); - void setStartScale(const F32 xs, F32 ys); - void setEndScale(const F32 xs, F32 ys); - void setStartColor(const LLVector3 &rgb); - void setEndColor(const LLVector3 &rgb); - void setStartAlpha(const F32 alpha); - void setEndAlpha(const F32 alpha); - - - friend class LLPartSysData; - friend class LLViewerPartSourceScript; + LLPartData() : + mFlags(0), + mMaxAge(0.f), + mParameter(0.f) + { + } + bool unpackLegacy(LLDataPacker &dp); + bool unpack(LLDataPacker &dp); + + bool pack(LLDataPacker &dp); + + bool hasGlow() const; + bool hasBlendFunc() const; + + // Masks for the different particle flags + enum + { + LL_PART_INTERP_COLOR_MASK = 0x01, + LL_PART_INTERP_SCALE_MASK = 0x02, + LL_PART_BOUNCE_MASK = 0x04, + LL_PART_WIND_MASK = 0x08, + LL_PART_FOLLOW_SRC_MASK = 0x10, // Follows source, no rotation following (expensive!) + LL_PART_FOLLOW_VELOCITY_MASK = 0x20, // Particles orient themselves with velocity + LL_PART_TARGET_POS_MASK = 0x40, + LL_PART_TARGET_LINEAR_MASK = 0x80, // Particle uses a direct linear interpolation + LL_PART_EMISSIVE_MASK = 0x100, // Particle is "emissive", instead of being lit + LL_PART_BEAM_MASK = 0x200, // Particle is a "beam" connecting source and target + LL_PART_RIBBON_MASK = 0x400, // Particles are joined together into one continuous triangle strip + + // Not implemented yet! + //LL_PART_RANDOM_ACCEL_MASK = 0x100, // Particles have random acceleration + //LL_PART_RANDOM_VEL_MASK = 0x200, // Particles have random velocity shifts" + //LL_PART_TRAIL_MASK = 0x400, // Particles have historical "trails" + + //sYSTEM SET FLAGS + LL_PART_DATA_GLOW = 0x10000, + LL_PART_DATA_BLEND = 0x20000, + + // Viewer side use only! + LL_PART_HUD = 0x40000000, + LL_PART_DEAD_MASK = 0x80000000, + }; + + enum + { + LL_PART_BF_ONE = 0, + LL_PART_BF_ZERO = 1, + LL_PART_BF_DEST_COLOR = 2, + LL_PART_BF_SOURCE_COLOR = 3, + LL_PART_BF_ONE_MINUS_DEST_COLOR = 4, + LL_PART_BF_ONE_MINUS_SOURCE_COLOR = 5, + UNSUPPORTED_DEST_ALPHA = 6, + LL_PART_BF_SOURCE_ALPHA = 7, + UNSUPPORTED_ONE_MINUS_DEST_ALPHA = 8, + LL_PART_BF_ONE_MINUS_SOURCE_ALPHA = 9, + LL_PART_BF_COUNT = 10 + }; + + static bool validBlendFunc(S32 func); + + void setFlags(const U32 flags); + void setMaxAge(const F32 max_age); + void setStartScale(const F32 xs, F32 ys); + void setEndScale(const F32 xs, F32 ys); + void setStartColor(const LLVector3 &rgb); + void setEndColor(const LLVector3 &rgb); + void setStartAlpha(const F32 alpha); + void setEndAlpha(const F32 alpha); + + + friend class LLPartSysData; + friend class LLViewerPartSourceScript; private: - S32 getSize() const; + S32 getSize() const; - // These are public because I'm really lazy... + // These are public because I'm really lazy... public: - U32 mFlags; // Particle state/interpolators in effect - F32 mMaxAge; // Maximum age of the particle - LLColor4 mStartColor; // Start color - LLColor4 mEndColor; // End color - LLVector2 mStartScale; // Start scale - LLVector2 mEndScale; // End scale - - LLVector3 mPosOffset; // Offset from source if using FOLLOW_SOURCE - F32 mParameter; // A single floating point parameter - - F32 mStartGlow; - F32 mEndGlow; - - U8 mBlendFuncSource; - U8 mBlendFuncDest; + U32 mFlags; // Particle state/interpolators in effect + F32 mMaxAge; // Maximum age of the particle + LLColor4 mStartColor; // Start color + LLColor4 mEndColor; // End color + LLVector2 mStartScale; // Start scale + LLVector2 mEndScale; // End scale + + LLVector3 mPosOffset; // Offset from source if using FOLLOW_SOURCE + F32 mParameter; // A single floating point parameter + + F32 mStartGlow; + F32 mEndGlow; + + U8 mBlendFuncSource; + U8 mBlendFuncDest; }; class LLPartSysData { public: - LLPartSysData(); - - bool unpack(LLDataPacker &dp); - bool unpackLegacy(LLDataPacker &dp); - bool unpackBlock(const S32 block_num); - - static bool isNullPS(const S32 block_num); // Returns false if this is a "NULL" particle system (i.e. no system) - - bool isLegacyCompatible() const; - - // Different masks for effects on the source - enum - { - LL_PART_SRC_OBJ_REL_MASK = 0x01, // Accel and velocity for particles relative object rotation - LL_PART_USE_NEW_ANGLE = 0x02, // Particles uses new 'correct' angle parameters. - }; - - // The different patterns for how particles are created - enum - { - LL_PART_SRC_PATTERN_DROP = 0x01, - LL_PART_SRC_PATTERN_EXPLODE = 0x02, - // Not implemented fully yet - LL_PART_SRC_PATTERN_ANGLE = 0x04, - LL_PART_SRC_PATTERN_ANGLE_CONE = 0x08, - LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY = 0x10, - }; - - - void setBurstSpeedMin(const F32 spd) { mBurstSpeedMin = llclamp(spd, -100.f, 100.f); } - void setBurstSpeedMax(const F32 spd) { mBurstSpeedMax = llclamp(spd, -100.f, 100.f); } - void setBurstRadius(const F32 rad) { mBurstRadius = llclamp(rad, 0.f, 50.f); } - void setPartAccel(const LLVector3 &accel); - void setUseNewAngle() { mFlags |= LL_PART_USE_NEW_ANGLE; } - void unsetUseNewAngle() { mFlags &= ~LL_PART_USE_NEW_ANGLE; } - - // Since the actual particle creation rate is - // a combination of multiple parameters, we - // need to clamp it using a separate method instead of an accessor. - void clampSourceParticleRate(); - - friend std::ostream& operator<<(std::ostream& s, const LLPartSysData &data); // Stream a - - S32 getdataBlockSize() const; - + LLPartSysData(); + + bool unpack(LLDataPacker &dp); + bool unpackLegacy(LLDataPacker &dp); + bool unpackBlock(const S32 block_num); + + static bool isNullPS(const S32 block_num); // Returns false if this is a "NULL" particle system (i.e. no system) + + bool isLegacyCompatible() const; + + // Different masks for effects on the source + enum + { + LL_PART_SRC_OBJ_REL_MASK = 0x01, // Accel and velocity for particles relative object rotation + LL_PART_USE_NEW_ANGLE = 0x02, // Particles uses new 'correct' angle parameters. + }; + + // The different patterns for how particles are created + enum + { + LL_PART_SRC_PATTERN_DROP = 0x01, + LL_PART_SRC_PATTERN_EXPLODE = 0x02, + // Not implemented fully yet + LL_PART_SRC_PATTERN_ANGLE = 0x04, + LL_PART_SRC_PATTERN_ANGLE_CONE = 0x08, + LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY = 0x10, + }; + + + void setBurstSpeedMin(const F32 spd) { mBurstSpeedMin = llclamp(spd, -100.f, 100.f); } + void setBurstSpeedMax(const F32 spd) { mBurstSpeedMax = llclamp(spd, -100.f, 100.f); } + void setBurstRadius(const F32 rad) { mBurstRadius = llclamp(rad, 0.f, 50.f); } + void setPartAccel(const LLVector3 &accel); + void setUseNewAngle() { mFlags |= LL_PART_USE_NEW_ANGLE; } + void unsetUseNewAngle() { mFlags &= ~LL_PART_USE_NEW_ANGLE; } + + // Since the actual particle creation rate is + // a combination of multiple parameters, we + // need to clamp it using a separate method instead of an accessor. + void clampSourceParticleRate(); + + friend std::ostream& operator<<(std::ostream& s, const LLPartSysData &data); // Stream a + + S32 getdataBlockSize() const; + private: - bool unpackSystem(LLDataPacker &dp); + bool unpackSystem(LLDataPacker &dp); public: - // Public because I'm lazy.... + // Public because I'm lazy.... - // - // There are two kinds of data for the particle system - // 1. Parameters which specify parameters of the source (mSource*) - // 2. Parameters which specify parameters of the particles generated by the source (mPart*) - // + // + // There are two kinds of data for the particle system + // 1. Parameters which specify parameters of the source (mSource*) + // 2. Parameters which specify parameters of the particles generated by the source (mPart*) + // - U32 mCRC; - U32 mFlags; + U32 mCRC; + U32 mFlags; - U8 mPattern; // Pattern for particle velocity/output - F32 mInnerAngle; // Inner angle for PATTERN_ANGLE - F32 mOuterAngle; // Outer angle for PATTERN_ANGLE - LLVector3 mAngularVelocity; // Angular velocity for emission axis (for PATTERN_ANGLE) + U8 mPattern; // Pattern for particle velocity/output + F32 mInnerAngle; // Inner angle for PATTERN_ANGLE + F32 mOuterAngle; // Outer angle for PATTERN_ANGLE + LLVector3 mAngularVelocity; // Angular velocity for emission axis (for PATTERN_ANGLE) - F32 mBurstRate; // How often to do a burst of particles - U8 mBurstPartCount; // How many particles in a burst - F32 mBurstRadius; - F32 mBurstSpeedMin; // Minimum particle velocity - F32 mBurstSpeedMax; // Maximum particle velocity + F32 mBurstRate; // How often to do a burst of particles + U8 mBurstPartCount; // How many particles in a burst + F32 mBurstRadius; + F32 mBurstSpeedMin; // Minimum particle velocity + F32 mBurstSpeedMax; // Maximum particle velocity - F32 mMaxAge; // Maximum lifetime of this particle source + F32 mMaxAge; // Maximum lifetime of this particle source - LLUUID mTargetUUID; // Target UUID for the particle system + LLUUID mTargetUUID; // Target UUID for the particle system - F32 mStartAge; // Age at which to start the particle system (for an update after the - // particle system has started) + F32 mStartAge; // Age at which to start the particle system (for an update after the + // particle system has started) - // - // These are actually particle properties, but can be mutated by the source, - // so are stored here instead - // - LLVector3 mPartAccel; - LLUUID mPartImageID; + // + // These are actually particle properties, but can be mutated by the source, + // so are stored here instead + // + LLVector3 mPartAccel; + LLUUID mPartImageID; - // - // The "template" partdata where we actually store the non-mutable particle parameters - // - LLPartData mPartData; + // + // The "template" partdata where we actually store the non-mutable particle parameters + // + LLPartData mPartData; protected: - S32 mNumParticles; // Number of particles generated + S32 mNumParticles; // Number of particles generated }; #endif // LL_LLPARTDATA_H diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 749e599c66..3e1e5daa02 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,15 +48,15 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel LLProxy::LLProxy(): - mHTTPProxyEnabled(false), - mProxyMutex(), - mUDPProxy(), - mTCPProxy(), - mHTTPProxy(), - mProxyType(LLPROXY_SOCKS), - mAuthMethodSelected(METHOD_NOAUTH), - mSocksUsername(), - mSocksPassword() + mHTTPProxyEnabled(false), + mProxyMutex(), + mUDPProxy(), + mTCPProxy(), + mHTTPProxy(), + mProxyType(LLPROXY_SOCKS), + mAuthMethodSelected(METHOD_NOAUTH), + mSocksUsername(), + mSocksPassword() {} LLProxy::~LLProxy() @@ -88,112 +88,112 @@ void LLProxy::initSingleton() */ S32 LLProxy::proxyHandshake(LLHost proxy) { - S32 result; - - /* SOCKS 5 Auth request */ - socks_auth_request_t socks_auth_request; - socks_auth_response_t socks_auth_response; - - socks_auth_request.version = SOCKS_VERSION; // SOCKS version 5 - socks_auth_request.num_methods = 1; // Sending 1 method. - socks_auth_request.methods = getSelectedAuthMethod(); // Send only the selected method. - - result = tcp_blocking_handshake(mProxyControlChannel, - static_cast<char*>(static_cast<void*>(&socks_auth_request)), - sizeof(socks_auth_request), - static_cast<char*>(static_cast<void*>(&socks_auth_response)), - sizeof(socks_auth_response)); - if (result != APR_SUCCESS) - { - LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_CONNECT_ERROR; - } - - if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE) - { - LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_NOT_ACCEPTABLE; - } - - /* SOCKS 5 USERNAME/PASSWORD authentication */ - if (socks_auth_response.method == METHOD_PASSWORD) - { - // The server has requested a username/password combination - std::string socks_username(getSocksUser()); - std::string socks_password(getSocksPwd()); - U32 request_size = socks_username.size() + socks_password.size() + 3; - char * password_auth = new char[request_size]; - password_auth[0] = 0x01; - password_auth[1] = (char)(socks_username.size()); - memcpy(&password_auth[2], socks_username.c_str(), socks_username.size()); - password_auth[socks_username.size() + 2] = (char)(socks_password.size()); - memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size()); - - authmethod_password_reply_t password_reply; - - result = tcp_blocking_handshake(mProxyControlChannel, - password_auth, - request_size, - static_cast<char*>(static_cast<void*>(&password_reply)), - sizeof(password_reply)); - delete[] password_auth; - - if (result != APR_SUCCESS) - { - LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_CONNECT_ERROR; - } - - if (password_reply.status != AUTH_SUCCESS) - { - LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_AUTH_FAIL; - } - } - - /* SOCKS5 connect request */ - - socks_command_request_t connect_request; - socks_command_response_t connect_reply; - - connect_request.version = SOCKS_VERSION; // SOCKS V5 - connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP - connect_request.reserved = FIELD_RESERVED; - connect_request.atype = ADDRESS_IPV4; - connect_request.address = htonl(0); // 0.0.0.0 - connect_request.port = htons(0); // 0 - // "If the client is not in possession of the information at the time of the UDP ASSOCIATE, - // the client MUST use a port number and address of all zeros. RFC 1928" - - result = tcp_blocking_handshake(mProxyControlChannel, - static_cast<char*>(static_cast<void*>(&connect_request)), - sizeof(connect_request), - static_cast<char*>(static_cast<void*>(&connect_reply)), - sizeof(connect_reply)); - if (result != APR_SUCCESS) - { - LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_CONNECT_ERROR; - } - - if (connect_reply.reply != REPLY_REQUEST_GRANTED) - { - LL_WARNS("Proxy") << "Connection to SOCKS 5 server failed, UDP forward request not granted" << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_UDP_FWD_NOT_GRANTED; - } - - mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order - mUDPProxy.setAddress(proxy.getAddress()); - // The connection was successful. We now have the UDP port to send requests that need forwarding to. - LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL; - - return SOCKS_OK; + S32 result; + + /* SOCKS 5 Auth request */ + socks_auth_request_t socks_auth_request; + socks_auth_response_t socks_auth_response; + + socks_auth_request.version = SOCKS_VERSION; // SOCKS version 5 + socks_auth_request.num_methods = 1; // Sending 1 method. + socks_auth_request.methods = getSelectedAuthMethod(); // Send only the selected method. + + result = tcp_blocking_handshake(mProxyControlChannel, + static_cast<char*>(static_cast<void*>(&socks_auth_request)), + sizeof(socks_auth_request), + static_cast<char*>(static_cast<void*>(&socks_auth_response)), + sizeof(socks_auth_response)); + if (result != APR_SUCCESS) + { + LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_CONNECT_ERROR; + } + + if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE) + { + LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_NOT_ACCEPTABLE; + } + + /* SOCKS 5 USERNAME/PASSWORD authentication */ + if (socks_auth_response.method == METHOD_PASSWORD) + { + // The server has requested a username/password combination + std::string socks_username(getSocksUser()); + std::string socks_password(getSocksPwd()); + U32 request_size = socks_username.size() + socks_password.size() + 3; + char * password_auth = new char[request_size]; + password_auth[0] = 0x01; + password_auth[1] = (char)(socks_username.size()); + memcpy(&password_auth[2], socks_username.c_str(), socks_username.size()); + password_auth[socks_username.size() + 2] = (char)(socks_password.size()); + memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size()); + + authmethod_password_reply_t password_reply; + + result = tcp_blocking_handshake(mProxyControlChannel, + password_auth, + request_size, + static_cast<char*>(static_cast<void*>(&password_reply)), + sizeof(password_reply)); + delete[] password_auth; + + if (result != APR_SUCCESS) + { + LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_CONNECT_ERROR; + } + + if (password_reply.status != AUTH_SUCCESS) + { + LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_AUTH_FAIL; + } + } + + /* SOCKS5 connect request */ + + socks_command_request_t connect_request; + socks_command_response_t connect_reply; + + connect_request.version = SOCKS_VERSION; // SOCKS V5 + connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP + connect_request.reserved = FIELD_RESERVED; + connect_request.atype = ADDRESS_IPV4; + connect_request.address = htonl(0); // 0.0.0.0 + connect_request.port = htons(0); // 0 + // "If the client is not in possession of the information at the time of the UDP ASSOCIATE, + // the client MUST use a port number and address of all zeros. RFC 1928" + + result = tcp_blocking_handshake(mProxyControlChannel, + static_cast<char*>(static_cast<void*>(&connect_request)), + sizeof(connect_request), + static_cast<char*>(static_cast<void*>(&connect_reply)), + sizeof(connect_reply)); + if (result != APR_SUCCESS) + { + LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_CONNECT_ERROR; + } + + if (connect_reply.reply != REPLY_REQUEST_GRANTED) + { + LL_WARNS("Proxy") << "Connection to SOCKS 5 server failed, UDP forward request not granted" << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_UDP_FWD_NOT_GRANTED; + } + + mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order + mUDPProxy.setAddress(proxy.getAddress()); + // The connection was successful. We now have the UDP port to send requests that need forwarding to. + LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL; + + return SOCKS_OK; } /** @@ -209,38 +209,38 @@ S32 LLProxy::proxyHandshake(LLHost proxy) */ S32 LLProxy::startSOCKSProxy(LLHost host) { - if (host.isOk()) - { - mTCPProxy = host; - } - else - { - return SOCKS_INVALID_HOST; - } - - // Close any running SOCKS connection. - stopSOCKSProxy(); - - mProxyControlChannel = tcp_open_channel(mTCPProxy); - if (!mProxyControlChannel) - { - return SOCKS_HOST_CONNECT_FAILED; - } - - S32 status = proxyHandshake(mTCPProxy); - - if (status != SOCKS_OK) - { - // Shut down the proxy if any of the above steps failed. - stopSOCKSProxy(); - } - else - { - // Connection was successful. - sUDPProxyEnabled = true; - } - - return status; + if (host.isOk()) + { + mTCPProxy = host; + } + else + { + return SOCKS_INVALID_HOST; + } + + // Close any running SOCKS connection. + stopSOCKSProxy(); + + mProxyControlChannel = tcp_open_channel(mTCPProxy); + if (!mProxyControlChannel) + { + return SOCKS_HOST_CONNECT_FAILED; + } + + S32 status = proxyHandshake(mTCPProxy); + + if (status != SOCKS_OK) + { + // Shut down the proxy if any of the above steps failed. + stopSOCKSProxy(); + } + else + { + // Connection was successful. + sUDPProxyEnabled = true; + } + + return status; } /** @@ -252,21 +252,21 @@ S32 LLProxy::startSOCKSProxy(LLHost host) */ void LLProxy::stopSOCKSProxy() { - sUDPProxyEnabled = false; + sUDPProxyEnabled = false; - // If the SOCKS proxy is requested to stop and we are using that for HTTP as well - // then we must shut down any HTTP proxy operations. But it is allowable if web - // proxy is being used to continue proxying HTTP. + // If the SOCKS proxy is requested to stop and we are using that for HTTP as well + // then we must shut down any HTTP proxy operations. But it is allowable if web + // proxy is being used to continue proxying HTTP. - if (LLPROXY_SOCKS == getHTTPProxyType()) - { - disableHTTPProxy(); - } + if (LLPROXY_SOCKS == getHTTPProxyType()) + { + disableHTTPProxy(); + } - if (mProxyControlChannel) - { - tcp_close_channel(&mProxyControlChannel); - } + if (mProxyControlChannel) + { + tcp_close_channel(&mProxyControlChannel); + } } /** @@ -274,9 +274,9 @@ void LLProxy::stopSOCKSProxy() */ void LLProxy::setAuthNone() { - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mAuthMethodSelected = METHOD_NOAUTH; + mAuthMethodSelected = METHOD_NOAUTH; } /** @@ -286,27 +286,27 @@ void LLProxy::setAuthNone() * and password conform to the lengths allowed by the * SOCKS protocol. * - * @param username The SOCKS username to send. - * @param password The SOCKS password to send. + * @param username The SOCKS username to send. + * @param password The SOCKS password to send. * @return Return true if applying the settings was successful. No changes are made if false. * */ bool LLProxy::setAuthPassword(const std::string &username, const std::string &password) { - if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN || - username.length() < SOCKSMINUSERNAMELEN || password.length() < SOCKSMINPASSWORDLEN) - { - LL_WARNS("Proxy") << "Invalid SOCKS 5 password or username length." << LL_ENDL; - return false; - } + if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN || + username.length() < SOCKSMINUSERNAMELEN || password.length() < SOCKSMINPASSWORDLEN) + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 password or username length." << LL_ENDL; + return false; + } - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mAuthMethodSelected = METHOD_PASSWORD; - mSocksUsername = username; - mSocksPassword = password; + mAuthMethodSelected = METHOD_PASSWORD; + mSocksUsername = username; + mSocksPassword = password; - return true; + return true; } /** @@ -320,20 +320,20 @@ bool LLProxy::setAuthPassword(const std::string &username, const std::string &pa */ bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) { - if (!httpHost.isOk()) - { - LL_WARNS("Proxy") << "Invalid SOCKS 5 Server" << LL_ENDL; - return false; - } + if (!httpHost.isOk()) + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 Server" << LL_ENDL; + return false; + } - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mHTTPProxy = httpHost; - mProxyType = type; + mHTTPProxy = httpHost; + mProxyType = type; - mHTTPProxyEnabled = true; + mHTTPProxyEnabled = true; - return true; + return true; } /** @@ -345,17 +345,17 @@ bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) */ bool LLProxy::enableHTTPProxy() { - bool ok; + bool ok; - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - ok = (mHTTPProxy.isOk()); - if (ok) - { - mHTTPProxyEnabled = true; - } + ok = (mHTTPProxy.isOk()); + if (ok) + { + mHTTPProxyEnabled = true; + } - return ok; + return ok; } /** @@ -363,9 +363,9 @@ bool LLProxy::enableHTTPProxy() */ void LLProxy::disableHTTPProxy() { - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mHTTPProxyEnabled = false; + mHTTPProxyEnabled = false; } /** @@ -373,8 +373,8 @@ void LLProxy::disableHTTPProxy() */ LLHttpProxyType LLProxy::getHTTPProxyType() const { - LLMutexLock lock(&mProxyMutex); - return mProxyType; + LLMutexLock lock(&mProxyMutex); + return mProxyType; } /** @@ -382,8 +382,8 @@ LLHttpProxyType LLProxy::getHTTPProxyType() const */ std::string LLProxy::getSocksPwd() const { - LLMutexLock lock(&mProxyMutex); - return mSocksPassword; + LLMutexLock lock(&mProxyMutex); + return mSocksPassword; } /** @@ -391,8 +391,8 @@ std::string LLProxy::getSocksPwd() const */ std::string LLProxy::getSocksUser() const { - LLMutexLock lock(&mProxyMutex); - return mSocksUsername; + LLMutexLock lock(&mProxyMutex); + return mSocksUsername; } /** @@ -402,8 +402,8 @@ std::string LLProxy::getSocksUser() const */ LLSocks5AuthType LLProxy::getSelectedAuthMethod() const { - LLMutexLock lock(&mProxyMutex); - return mAuthMethodSelected; + LLMutexLock lock(&mProxyMutex); + return mAuthMethodSelected; } /** @@ -434,32 +434,32 @@ void LLProxy::cleanupClass() */ void LLProxy::applyProxySettings(CURL* handle) { - // Do a faster unlocked check to see if we are supposed to proxy. - if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled) - { - // We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex - LLMutexLock lock(&sProxyInstance->mProxyMutex); - // Now test again to verify that the proxy wasn't disabled between the first check and the lock. - if (sProxyInstance->mHTTPProxyEnabled) - { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY); - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT); - - if (sProxyInstance->mProxyType == LLPROXY_SOCKS) - { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE); - if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD) - { - std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword; - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD); - } - } - else - { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE); - } - } - } + // Do a faster unlocked check to see if we are supposed to proxy. + if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled) + { + // We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex + LLMutexLock lock(&sProxyInstance->mProxyMutex); + // Now test again to verify that the proxy wasn't disabled between the first check and the lock. + if (sProxyInstance->mHTTPProxyEnabled) + { + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY); + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT); + + if (sProxyInstance->mProxyType == LLPROXY_SOCKS) + { + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE); + if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD) + { + std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword; + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD); + } + } + else + { + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE); + } + } + } } /** @@ -468,59 +468,59 @@ void LLProxy::applyProxySettings(CURL* handle) * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking * operation would impact the operation of the viewer. * - * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. - * @param dataout Data to send. - * @param outlen Length of dataout. - * @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS. - * @param maxinlen Maximum possible length of received data. Short reads are allowed. - * @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received. + * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. + * @param dataout Data to send. + * @param outlen Length of dataout. + * @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS. + * @param maxinlen Maximum possible length of received data. Short reads are allowed. + * @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received. */ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen) { - apr_socket_t* apr_socket = handle->getSocket(); - apr_status_t rv = APR_SUCCESS; - - apr_size_t expected_len = outlen; - - handle->setBlocking(1000); - - rv = apr_socket_send(apr_socket, dataout, &outlen); - if (APR_SUCCESS != rv) - { - char buf[MAX_STRING]; - LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; - ll_apr_warn_status(rv); - } - else if (expected_len != outlen) - { - LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len << - " Sent: " << outlen << LL_ENDL; - rv = -1; - } - - ms_sleep(1); - - if (APR_SUCCESS == rv) - { - expected_len = maxinlen; - rv = apr_socket_recv(apr_socket, datain, &maxinlen); - if (rv != APR_SUCCESS) - { - char buf[MAX_STRING]; - LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; - ll_apr_warn_status(rv); - } - else if (expected_len < maxinlen) - { - LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len << - " Received: " << maxinlen << LL_ENDL; - rv = -1; - } - } - - handle->setNonBlocking(); - - return rv; + apr_socket_t* apr_socket = handle->getSocket(); + apr_status_t rv = APR_SUCCESS; + + apr_size_t expected_len = outlen; + + handle->setBlocking(1000); + + rv = apr_socket_send(apr_socket, dataout, &outlen); + if (APR_SUCCESS != rv) + { + char buf[MAX_STRING]; + LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; + ll_apr_warn_status(rv); + } + else if (expected_len != outlen) + { + LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len << + " Sent: " << outlen << LL_ENDL; + rv = -1; + } + + ms_sleep(1); + + if (APR_SUCCESS == rv) + { + expected_len = maxinlen; + rv = apr_socket_recv(apr_socket, datain, &maxinlen); + if (rv != APR_SUCCESS) + { + char buf[MAX_STRING]; + LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; + ll_apr_warn_status(rv); + } + else if (expected_len < maxinlen) + { + LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len << + " Received: " << maxinlen << LL_ENDL; + rv = -1; + } + } + + handle->setNonBlocking(); + + return rv; } /** @@ -528,19 +528,19 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou * * Checks for a successful connection, and makes sure the connection is closed if it fails. * - * @param host The host to open the connection to. - * @return The created socket. Will evaluate as NULL if the connection is unsuccessful. + * @param host The host to open the connection to. + * @return The created socket. Will evaluate as NULL if the connection is unsuccessful. */ static LLSocket::ptr_t tcp_open_channel(LLHost host) { - LLSocket::ptr_t socket = LLSocket::create(NULL, LLSocket::STREAM_TCP); - bool connected = socket->blockingConnect(host); - if (!connected) - { - tcp_close_channel(&socket); - } - - return socket; + LLSocket::ptr_t socket = LLSocket::create(NULL, LLSocket::STREAM_TCP); + bool connected = socket->blockingConnect(host); + if (!connected) + { + tcp_close_channel(&socket); + } + + return socket; } /** @@ -550,6 +550,6 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host) */ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr) { - LL_DEBUGS("Proxy") << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << LL_ENDL; - handle_ptr->reset(); + LL_DEBUGS("Proxy") << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << LL_ENDL; + handle_ptr->reset(); } diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 8a64cdbfaa..10d4911c60 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,7 +47,7 @@ #define SOCKS_INVALID_HOST (-7) #ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */ +#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */ #endif #define SOCKSMAXUSERNAMELEN 255 @@ -68,8 +68,8 @@ // Lets just use our own ipv4 struct rather than dragging in system // specific headers union ipv4_address_t { - U8 octets[4]; - U32 addr32; + U8 octets[4]; + U32 addr32; }; // SOCKS 5 control channel commands @@ -98,22 +98,22 @@ union ipv4_address_t { // SOCKS 5 command packet struct socks_command_request_t { - U8 version; - U8 command; - U8 reserved; - U8 atype; - U32 address; - U16 port; + U8 version; + U8 command; + U8 reserved; + U8 atype; + U32 address; + U16 port; }; // Standard SOCKS 5 reply packet struct socks_command_response_t { - U8 version; - U8 reply; - U8 reserved; - U8 atype; - U8 add_bytes[4]; - U16 port; + U8 version; + U8 reply; + U8 reserved; + U8 atype; + U8 add_bytes[4]; + U16 port; }; #define AUTH_NOT_ACCEPTABLE 0xFF // reply if preferred methods are not available @@ -121,30 +121,30 @@ struct socks_command_response_t { // SOCKS 5 authentication request, stating which methods the client supports struct socks_auth_request_t { - U8 version; - U8 num_methods; - U8 methods; // We are only using a single method currently + U8 version; + U8 num_methods; + U8 methods; // We are only using a single method currently }; // SOCKS 5 authentication response packet, stating server preferred method struct socks_auth_response_t { - U8 version; - U8 method; + U8 version; + U8 method; }; // SOCKS 5 password reply packet struct authmethod_password_reply_t { - U8 version; - U8 status; + U8 version; + U8 status; }; // SOCKS 5 UDP packet header struct proxywrap_t { - U16 rsv; - U8 frag; - U8 atype; - U32 addr; - U16 port; + U16 rsv; + U8 frag; + U8 atype; + U32 addr; + U16 port; }; #pragma pack(pop) /* restore original alignment from stack */ @@ -153,16 +153,16 @@ struct proxywrap_t { // Currently selected HTTP proxy type enum LLHttpProxyType { - LLPROXY_SOCKS = 0, - LLPROXY_HTTP = 1 + LLPROXY_SOCKS = 0, + LLPROXY_HTTP = 1 }; // Auth types enum LLSocks5AuthType { - METHOD_NOAUTH = 0x00, // Client supports no auth - METHOD_GSSAPI = 0x01, // Client supports GSSAPI (Not currently supported) - METHOD_PASSWORD = 0x02 // Client supports username/password + METHOD_NOAUTH = 0x00, // Client supports no auth + METHOD_GSSAPI = 0x01, // Client supports GSSAPI (Not currently supported) + METHOD_PASSWORD = 0x02 // Client supports username/password }; /** @@ -213,139 +213,139 @@ enum LLSocks5AuthType * * To ensure thread safety, all LLProxy members that relate to the HTTP * proxy require the LLProxyMutex to be locked before accessing. - * + * * *TODO$: This should be moved into the LLCore::Http space. - * + * */ class LLProxy: public LLSingleton<LLProxy> { - /*########################################################################################### - METHODS THAT DO NOT LOCK mProxyMutex! - ###########################################################################################*/ - // Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only. - LLSINGLETON(LLProxy); - LOG_CLASS(LLProxy); + /*########################################################################################### + METHODS THAT DO NOT LOCK mProxyMutex! + ###########################################################################################*/ + // Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only. + LLSINGLETON(LLProxy); + LOG_CLASS(LLProxy); /*virtual*/ void initSingleton() override; public: - // Static check for enabled status for UDP packets. Call from main thread only. - static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } + // Static check for enabled status for UDP packets. Call from main thread only. + static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } - // Get the UDP proxy address and port. Call from main thread only. - LLHost getUDPProxy() const { return mUDPProxy; } + // Get the UDP proxy address and port. Call from main thread only. + LLHost getUDPProxy() const { return mUDPProxy; } - /*########################################################################################### - END OF NON-LOCKING METHODS - ###########################################################################################*/ + /*########################################################################################### + END OF NON-LOCKING METHODS + ###########################################################################################*/ - /*########################################################################################### - METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! - ###########################################################################################*/ + /*########################################################################################### + METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! + ###########################################################################################*/ private: - // Destructor, closes open connections. Do not call directly, use cleanupClass(). - ~LLProxy(); + // Destructor, closes open connections. Do not call directly, use cleanupClass(). + ~LLProxy(); public: - // Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be - // destroyed before the call to apr_terminate. Call from main thread only. - static void cleanupClass(); + // Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be + // destroyed before the call to apr_terminate. Call from main thread only. + static void cleanupClass(); - // Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false. - // Safe to call from any thread. - static void applyProxySettings(CURL* handle); - // Start a connection to the SOCKS 5 proxy. Call from main thread only. - S32 startSOCKSProxy(LLHost host); + // Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false. + // Safe to call from any thread. + static void applyProxySettings(CURL* handle); + // Start a connection to the SOCKS 5 proxy. Call from main thread only. + S32 startSOCKSProxy(LLHost host); - // Disconnect and clean up any connection to the SOCKS 5 proxy. Call from main thread only. - void stopSOCKSProxy(); + // Disconnect and clean up any connection to the SOCKS 5 proxy. Call from main thread only. + void stopSOCKSProxy(); - // Use Password auth when connecting to the SOCKS proxy. Call from main thread only. - bool setAuthPassword(const std::string &username, const std::string &password); + // Use Password auth when connecting to the SOCKS proxy. Call from main thread only. + bool setAuthPassword(const std::string &username, const std::string &password); - // Disable authentication when connecting to the SOCKS proxy. Call from main thread only. - void setAuthNone(); + // Disable authentication when connecting to the SOCKS proxy. Call from main thread only. + void setAuthNone(); - // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy. - // as specified in type. Call from main thread only. - bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); - bool enableHTTPProxy(); + // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy. + // as specified in type. Call from main thread only. + bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); + bool enableHTTPProxy(); - // Stop proxying HTTP packets. Call from main thread only. - void disableHTTPProxy(); + // Stop proxying HTTP packets. Call from main thread only. + void disableHTTPProxy(); - /*########################################################################################### - END OF LOCKING METHODS - ###########################################################################################*/ + /*########################################################################################### + END OF LOCKING METHODS + ###########################################################################################*/ private: - /*########################################################################################### - METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! - ###########################################################################################*/ + /*########################################################################################### + METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! + ###########################################################################################*/ - // Perform a SOCKS 5 authentication and UDP association with the proxy server. - S32 proxyHandshake(LLHost proxy); + // Perform a SOCKS 5 authentication and UDP association with the proxy server. + S32 proxyHandshake(LLHost proxy); - // Get the currently selected auth method. - LLSocks5AuthType getSelectedAuthMethod() const; + // Get the currently selected auth method. + LLSocks5AuthType getSelectedAuthMethod() const; - // Get the currently selected HTTP proxy type - LLHttpProxyType getHTTPProxyType() const; + // Get the currently selected HTTP proxy type + LLHttpProxyType getHTTPProxyType() const; - std::string getSocksPwd() const; - std::string getSocksUser() const; + std::string getSocksPwd() const; + std::string getSocksUser() const; - /*########################################################################################### - END OF LOCKING METHODS - ###########################################################################################*/ + /*########################################################################################### + END OF LOCKING METHODS + ###########################################################################################*/ private: - // Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly. - // Instead use enableHTTPProxy() and disableHTTPProxy() instead. - mutable LLAtomicBool mHTTPProxyEnabled; + // Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly. + // Instead use enableHTTPProxy() and disableHTTPProxy() instead. + mutable LLAtomicBool mHTTPProxyEnabled; - // Mutex to protect shared members in non-main thread calls to applyProxySettings(). - mutable LLMutex mProxyMutex; + // Mutex to protect shared members in non-main thread calls to applyProxySettings(). + mutable LLMutex mProxyMutex; - /*########################################################################################### - MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE! - ###########################################################################################*/ + /*########################################################################################### + MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE! + ###########################################################################################*/ - // Is the UDP proxy enabled? - static bool sUDPProxyEnabled; + // Is the UDP proxy enabled? + static bool sUDPProxyEnabled; - // UDP proxy address and port - LLHost mUDPProxy; - // TCP proxy control channel address and port - LLHost mTCPProxy; + // UDP proxy address and port + LLHost mUDPProxy; + // TCP proxy control channel address and port + LLHost mTCPProxy; - // socket handle to proxy TCP control channel - LLSocket::ptr_t mProxyControlChannel; + // socket handle to proxy TCP control channel + LLSocket::ptr_t mProxyControlChannel; - /*########################################################################################### - END OF UNSHARED MEMBERS - ###########################################################################################*/ + /*########################################################################################### + END OF UNSHARED MEMBERS + ###########################################################################################*/ - /*########################################################################################### - MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex! - ###########################################################################################*/ + /*########################################################################################### + MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex! + ###########################################################################################*/ - // HTTP proxy address and port - LLHost mHTTPProxy; + // HTTP proxy address and port + LLHost mHTTPProxy; - // Currently selected HTTP proxy type. Can be web or socks. - LLHttpProxyType mProxyType; + // Currently selected HTTP proxy type. Can be web or socks. + LLHttpProxyType mProxyType; - // SOCKS 5 selected authentication method. - LLSocks5AuthType mAuthMethodSelected; + // SOCKS 5 selected authentication method. + LLSocks5AuthType mAuthMethodSelected; - // SOCKS 5 username - std::string mSocksUsername; - // SOCKS 5 password - std::string mSocksPassword; + // SOCKS 5 username + std::string mSocksUsername; + // SOCKS 5 password + std::string mSocksPassword; - /*########################################################################################### - END OF SHARED MEMBERS - ###########################################################################################*/ + /*########################################################################################### + END OF SHARED MEMBERS + ###########################################################################################*/ // A hack to get arround getInstance() and capture_dependency() which are unsafe to use inside threads // set/reset on init/cleanup, strictly for use in applyProxySettings diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 52e6be6f98..d3b75cf86b 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpumpio.cpp * @author Phoenix * @date 2004-11-21 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -76,43 +76,43 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS = 0.0f; void ll_debug_poll_fd(const char* msg, const apr_pollfd_t* poll) { #if LL_DEBUG_POLL_FILE_DESCRIPTORS - if(!poll) - { - LL_DEBUGS() << "Poll -- " << (msg?msg:"") << ": no pollfd." << LL_ENDL; - return; - } - if(poll->desc.s) - { - apr_os_sock_t os_sock; - if(APR_SUCCESS == apr_os_sock_get(&os_sock, poll->desc.s)) - { - LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " on fd " << os_sock - << " at " << poll->desc.s << LL_ENDL; - } - else - { - LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " no fd " - << " at " << poll->desc.s << LL_ENDL; - } - } - else if(poll->desc.f) - { - apr_os_file_t os_file; - if(APR_SUCCESS == apr_os_file_get(&os_file, poll->desc.f)) - { - LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " on fd " << os_file - << " at " << poll->desc.f << LL_ENDL; - } - else - { - LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " no fd " - << " at " << poll->desc.f << LL_ENDL; - } - } - else - { - LL_DEBUGS() << "Poll -- " << (msg?msg:"") << ": no descriptor." << LL_ENDL; - } + if(!poll) + { + LL_DEBUGS() << "Poll -- " << (msg?msg:"") << ": no pollfd." << LL_ENDL; + return; + } + if(poll->desc.s) + { + apr_os_sock_t os_sock; + if(APR_SUCCESS == apr_os_sock_get(&os_sock, poll->desc.s)) + { + LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " on fd " << os_sock + << " at " << poll->desc.s << LL_ENDL; + } + else + { + LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " no fd " + << " at " << poll->desc.s << LL_ENDL; + } + } + else if(poll->desc.f) + { + apr_os_file_t os_file; + if(APR_SUCCESS == apr_os_file_get(&os_file, poll->desc.f)) + { + LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " on fd " << os_file + << " at " << poll->desc.f << LL_ENDL; + } + else + { + LL_DEBUGS() << "Poll -- " << (msg?msg:"") << " no fd " + << " at " << poll->desc.f << LL_ENDL; + } + } + else + { + LL_DEBUGS() << "Poll -- " << (msg?msg:"") << ": no descriptor." << LL_ENDL; + } #endif } @@ -122,20 +122,20 @@ void ll_debug_poll_fd(const char* msg, const apr_pollfd_t* poll) class LLChainSleeper : public LLRunnable { public: - static LLRunner::run_ptr_t build(LLPumpIO* pump, S32 key) - { - return LLRunner::run_ptr_t(new LLChainSleeper(pump, key)); - } - - virtual void run(LLRunner* runner, S64 handle) - { - mPump->clearLock(mKey); - } + static LLRunner::run_ptr_t build(LLPumpIO* pump, S32 key) + { + return LLRunner::run_ptr_t(new LLChainSleeper(pump, key)); + } + + virtual void run(LLRunner* runner, S64 handle) + { + mPump->clearLock(mKey); + } protected: - LLChainSleeper(LLPumpIO* pump, S32 key) : mPump(pump), mKey(key) {} - LLPumpIO* mPump; - S32 mKey; + LLChainSleeper(LLPumpIO* pump, S32 key) : mPump(pump), mKey(key) {} + LLPumpIO* mPump; + S32 mKey; }; @@ -145,971 +145,971 @@ protected: */ struct ll_delete_apr_pollset_fd_client_data { - typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; - void operator()(const pipe_conditional_t& conditional) - { - S32* client_id = (S32*)conditional.second.client_data; - delete client_id; - } + typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; + void operator()(const pipe_conditional_t& conditional) + { + S32* client_id = (S32*)conditional.second.client_data; + delete client_id; + } }; /** * LLPumpIO */ LLPumpIO::LLPumpIO(apr_pool_t* pool) : - mState(LLPumpIO::NORMAL), - mRebuildPollset(false), - mPollset(NULL), - mPollsetClientID(0), - mNextLock(0), - mPool(NULL), - mCurrentPool(NULL), - mCurrentPoolReallocCount(0), - mCurrentChain(mRunningChains.end()) + mState(LLPumpIO::NORMAL), + mRebuildPollset(false), + mPollset(NULL), + mPollsetClientID(0), + mNextLock(0), + mPool(NULL), + mCurrentPool(NULL), + mCurrentPoolReallocCount(0), + mCurrentChain(mRunningChains.end()) { - mCurrentChain = mRunningChains.end(); + mCurrentChain = mRunningChains.end(); - initialize(pool); + initialize(pool); } LLPumpIO::~LLPumpIO() { - cleanup(); + cleanup(); } bool LLPumpIO::prime(apr_pool_t* pool) { - cleanup(); - initialize(pool); - return pool != nullptr; + cleanup(); + initialize(pool); + return pool != nullptr; } bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request) { - if (chain.empty()) - return false; - - LLChainInfo info; - info.mHasCurlRequest = has_curl_request; - info.setTimeoutSeconds(timeout); - info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray); - info.mData->setThreaded(has_curl_request); - LLLinkInfo link; + if (chain.empty()) + return false; + + LLChainInfo info; + info.mHasCurlRequest = has_curl_request; + info.setTimeoutSeconds(timeout); + info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray); + info.mData->setThreaded(has_curl_request); + LLLinkInfo link; #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_DEBUGS() << "LLPumpIO::addChain() " << chain[0] << " '" - << typeid(*(chain[0])).name() << "'" << LL_ENDL; + LL_DEBUGS() << "LLPumpIO::addChain() " << chain[0] << " '" + << typeid(*(chain[0])).name() << "'" << LL_ENDL; #else - LL_DEBUGS() << "LLPumpIO::addChain() " << chain[0] <<LL_ENDL; + LL_DEBUGS() << "LLPumpIO::addChain() " << chain[0] <<LL_ENDL; #endif - chain_t::const_iterator it = chain.begin(); - chain_t::const_iterator end = chain.end(); - for(; it != end; ++it) - { - link.mPipe = (*it); - link.mChannels = info.mData->nextChannel(); - info.mChainLinks.push_back(link); - } - mPendingChains.push_back(info); - return true; + chain_t::const_iterator it = chain.begin(); + chain_t::const_iterator end = chain.end(); + for(; it != end; ++it) + { + link.mPipe = (*it); + link.mChannels = info.mData->nextChannel(); + info.mChainLinks.push_back(link); + } + mPendingChains.push_back(info); + return true; } bool LLPumpIO::addChain( - const LLPumpIO::links_t& links, - LLIOPipe::buffer_ptr_t data, - LLSD context, - F32 timeout) + const LLPumpIO::links_t& links, + LLIOPipe::buffer_ptr_t data, + LLSD context, + F32 timeout) { - // remember that if the caller is providing a full link - // description, we need to have that description matched to a - // particular buffer. - if (!data) - return false; - if (links.empty()) - return false; + // remember that if the caller is providing a full link + // description, we need to have that description matched to a + // particular buffer. + if (!data) + return false; + if (links.empty()) + return false; #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_DEBUGS() << "LLPumpIO::addChain() " << links[0].mPipe << " '" - << typeid(*(links[0].mPipe)).name() << "'" << LL_ENDL; + LL_DEBUGS() << "LLPumpIO::addChain() " << links[0].mPipe << " '" + << typeid(*(links[0].mPipe)).name() << "'" << LL_ENDL; #else - LL_DEBUGS() << "LLPumpIO::addChain() " << links[0].mPipe << LL_ENDL; + LL_DEBUGS() << "LLPumpIO::addChain() " << links[0].mPipe << LL_ENDL; #endif - LLChainInfo info; - info.setTimeoutSeconds(timeout); - info.mChainLinks = links; - info.mData = data; - info.mContext = context; - mPendingChains.push_back(info); - return true; + LLChainInfo info; + info.setTimeoutSeconds(timeout); + info.mChainLinks = links; + info.mData = data; + info.mContext = context; + mPendingChains.push_back(info); + return true; } bool LLPumpIO::setTimeoutSeconds(F32 timeout) { - // If no chain is running, return failure. - if (mRunningChains.end() == mCurrentChain) - { - return false; - } - - (*mCurrentChain).setTimeoutSeconds(timeout); - return true; + // If no chain is running, return failure. + if (mRunningChains.end() == mCurrentChain) + { + return false; + } + + (*mCurrentChain).setTimeoutSeconds(timeout); + return true; } void LLPumpIO::adjustTimeoutSeconds(F32 delta) { - // Ensure a chain is running - if (mRunningChains.end() != mCurrentChain) - { - (*mCurrentChain).adjustTimeoutSeconds(delta); - } + // Ensure a chain is running + if (mRunningChains.end() != mCurrentChain) + { + (*mCurrentChain).adjustTimeoutSeconds(delta); + } } static std::string events_2_string(apr_int16_t events) { - std::ostringstream ostr; - if (events & APR_POLLIN) - { - ostr << "read,"; - } - if (events & APR_POLLPRI) - { - ostr << "priority,"; - } - if (events & APR_POLLOUT) - { - ostr << "write,"; - } - if (events & APR_POLLERR) - { - ostr << "error,"; - } - if (events & APR_POLLHUP) - { - ostr << "hangup,"; - } - if (events & APR_POLLNVAL) - { - ostr << "invalid,"; - } - return chop_tail_copy(ostr.str(), 1); + std::ostringstream ostr; + if (events & APR_POLLIN) + { + ostr << "read,"; + } + if (events & APR_POLLPRI) + { + ostr << "priority,"; + } + if (events & APR_POLLOUT) + { + ostr << "write,"; + } + if (events & APR_POLLERR) + { + ostr << "error,"; + } + if (events & APR_POLLHUP) + { + ostr << "hangup,"; + } + if (events & APR_POLLNVAL) + { + ostr << "invalid,"; + } + return chop_tail_copy(ostr.str(), 1); } bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll) { - if (!pipe) - return false; - ll_debug_poll_fd("Set conditional", poll); + if (!pipe) + return false; + ll_debug_poll_fd("Set conditional", poll); - LL_DEBUGS() << "Setting conditionals (" << (poll ? events_2_string(poll->reqevents) :"null") - << ") " + LL_DEBUGS() << "Setting conditionals (" << (poll ? events_2_string(poll->reqevents) :"null") + << ") " #if LL_DEBUG_PIPE_TYPE_IN_PUMP - << "on pipe " << typeid(*pipe).name() + << "on pipe " << typeid(*pipe).name() #endif - << " at " << pipe << LL_ENDL; - - // remove any matching poll file descriptors for this pipe. - LLIOPipe::ptr_t pipe_ptr(pipe); - LLChainInfo::conditionals_t::iterator it; - it = (*mCurrentChain).mDescriptors.begin(); - while(it != (*mCurrentChain).mDescriptors.end()) - { - LLChainInfo::pipe_conditional_t& value = (*it); - if(pipe_ptr == value.first) - { - ll_delete_apr_pollset_fd_client_data()(value); - it = (*mCurrentChain).mDescriptors.erase(it); - mRebuildPollset = true; - } - else - { - ++it; - } - } - - if(!poll) - { - mRebuildPollset = true; - return true; - } - LLChainInfo::pipe_conditional_t value; - value.first = pipe_ptr; - value.second = *poll; - value.second.rtnevents = 0; - if(!poll->p) - { - // each fd needs a pool to work with, so if one was - // not specified, use this pool. - // *FIX: Should it always be this pool? - value.second.p = mPool; - } - value.second.client_data = new S32(++mPollsetClientID); - (*mCurrentChain).mDescriptors.push_back(value); - mRebuildPollset = true; - return true; + << " at " << pipe << LL_ENDL; + + // remove any matching poll file descriptors for this pipe. + LLIOPipe::ptr_t pipe_ptr(pipe); + LLChainInfo::conditionals_t::iterator it; + it = (*mCurrentChain).mDescriptors.begin(); + while(it != (*mCurrentChain).mDescriptors.end()) + { + LLChainInfo::pipe_conditional_t& value = (*it); + if(pipe_ptr == value.first) + { + ll_delete_apr_pollset_fd_client_data()(value); + it = (*mCurrentChain).mDescriptors.erase(it); + mRebuildPollset = true; + } + else + { + ++it; + } + } + + if(!poll) + { + mRebuildPollset = true; + return true; + } + LLChainInfo::pipe_conditional_t value; + value.first = pipe_ptr; + value.second = *poll; + value.second.rtnevents = 0; + if(!poll->p) + { + // each fd needs a pool to work with, so if one was + // not specified, use this pool. + // *FIX: Should it always be this pool? + value.second.p = mPool; + } + value.second.client_data = new S32(++mPollsetClientID); + (*mCurrentChain).mDescriptors.push_back(value); + mRebuildPollset = true; + return true; } S32 LLPumpIO::setLock() { - // *NOTE: I do not think it is necessary to acquire a mutex here - // since this should only be called during the pump(), and should - // only change the running chain. Any other use of this method is - // incorrect usage. If it becomes necessary to acquire a lock - // here, be sure to lock here and call a protected method to get - // the lock, and sleepChain() should probably acquire the same - // lock while and calling the same protected implementation to - // lock the runner at the same time. - - // If no chain is running, return failure. - if(mRunningChains.end() == mCurrentChain) - { - return 0; - } - - // deal with wrap. - if(++mNextLock <= 0) - { - mNextLock = 1; - } - - // set the lock - (*mCurrentChain).mLock = mNextLock; - return mNextLock; + // *NOTE: I do not think it is necessary to acquire a mutex here + // since this should only be called during the pump(), and should + // only change the running chain. Any other use of this method is + // incorrect usage. If it becomes necessary to acquire a lock + // here, be sure to lock here and call a protected method to get + // the lock, and sleepChain() should probably acquire the same + // lock while and calling the same protected implementation to + // lock the runner at the same time. + + // If no chain is running, return failure. + if(mRunningChains.end() == mCurrentChain) + { + return 0; + } + + // deal with wrap. + if(++mNextLock <= 0) + { + mNextLock = 1; + } + + // set the lock + (*mCurrentChain).mLock = mNextLock; + return mNextLock; } void LLPumpIO::clearLock(S32 key) { - // We need to lock it here since we do not want to be iterating - // over the chains twice. We can safely call process() while this - // is happening since we should not be erasing a locked pipe, and - // therefore won't be treading into deleted memory. I think we can - // also clear the lock on the chain safely since the pump only - // reads that value. - mClearLocks.insert(key); + // We need to lock it here since we do not want to be iterating + // over the chains twice. We can safely call process() while this + // is happening since we should not be erasing a locked pipe, and + // therefore won't be treading into deleted memory. I think we can + // also clear the lock on the chain safely since the pump only + // reads that value. + mClearLocks.insert(key); } bool LLPumpIO::sleepChain(F64 seconds) { - // Much like the call to setLock(), this should only be called - // from one chain during processing, so there is no need to - // acquire a mutex. - if(seconds <= 0.0) return false; - S32 key = setLock(); - if(!key) return false; - LLRunner::run_handle_t handle = mRunner.addRunnable( - LLChainSleeper::build(this, key), - LLRunner::RUN_IN, - seconds); - if(0 == handle) return false; - return true; + // Much like the call to setLock(), this should only be called + // from one chain during processing, so there is no need to + // acquire a mutex. + if(seconds <= 0.0) return false; + S32 key = setLock(); + if(!key) return false; + LLRunner::run_handle_t handle = mRunner.addRunnable( + LLChainSleeper::build(this, key), + LLRunner::RUN_IN, + seconds); + if(0 == handle) return false; + return true; } bool LLPumpIO::copyCurrentLinkInfo(links_t& links) const { - if(mRunningChains.end() == mCurrentChain) - { - return false; - } - std::copy( - (*mCurrentChain).mChainLinks.begin(), - (*mCurrentChain).mChainLinks.end(), - std::back_insert_iterator<links_t>(links)); - return true; + if(mRunningChains.end() == mCurrentChain) + { + return false; + } + std::copy( + (*mCurrentChain).mChainLinks.begin(), + (*mCurrentChain).mChainLinks.end(), + std::back_insert_iterator<links_t>(links)); + return true; } void LLPumpIO::pump() { - pump(DEFAULT_POLL_TIMEOUT); + pump(DEFAULT_POLL_TIMEOUT); } -LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain) +LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain) { - std::for_each( - (*run_chain).mDescriptors.begin(), - (*run_chain).mDescriptors.end(), - ll_delete_apr_pollset_fd_client_data()); - return mRunningChains.erase(run_chain); + std::for_each( + (*run_chain).mDescriptors.begin(), + (*run_chain).mDescriptors.end(), + ll_delete_apr_pollset_fd_client_data()); + return mRunningChains.erase(run_chain); } //timeout is in microseconds void LLPumpIO::pump(const S32& poll_timeout) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - //LL_INFOS() << "LLPumpIO::pump()" << LL_ENDL; - - // Run any pending runners. - mRunner.run(); - - // We need to move all of the pending heads over to the running - // chains. - PUMP_DEBUG; - if(true) - { - // bail if this pump is paused. - if(PAUSING == mState) - { - mState = PAUSED; - } - if(PAUSED == mState) - { - return; - } - - PUMP_DEBUG; - // Move the pending chains over to the running chaings - if(!mPendingChains.empty()) - { - PUMP_DEBUG; - //LL_DEBUGS() << "Pushing " << mPendingChains.size() << "." << LL_ENDL; - std::copy( - mPendingChains.begin(), - mPendingChains.end(), - std::back_insert_iterator<running_chains_t>(mRunningChains)); - mPendingChains.clear(); - PUMP_DEBUG; - } - - // Clear any locks. This needs to be done here so that we do - // not clash during a call to clearLock(). - if(!mClearLocks.empty()) - { - PUMP_DEBUG; - running_chains_t::iterator it = mRunningChains.begin(); - running_chains_t::iterator end = mRunningChains.end(); - std::set<S32>::iterator not_cleared = mClearLocks.end(); - for(; it != end; ++it) - { - if((*it).mLock && mClearLocks.find((*it).mLock) != not_cleared) - { - (*it).mLock = 0; - } - } - PUMP_DEBUG; - mClearLocks.clear(); - } - } - - PUMP_DEBUG; - // rebuild the pollset if necessary - if(mRebuildPollset) - { - PUMP_DEBUG; - rebuildPollset(); - mRebuildPollset = false; - } - - // Poll based on the last known pollset - // *TODO: may want to pass in a poll timeout so it works correctly - // in single and multi threaded processes. - PUMP_DEBUG; - typedef std::map<S32, S32> signal_client_t; - signal_client_t signalled_client; - const apr_pollfd_t* poll_fd = NULL; - if(mPollset) - { - PUMP_DEBUG; - //LL_INFOS() << "polling" << LL_ENDL; - S32 count = 0; - S32 client_id = 0; + //LL_INFOS() << "LLPumpIO::pump()" << LL_ENDL; + + // Run any pending runners. + mRunner.run(); + + // We need to move all of the pending heads over to the running + // chains. + PUMP_DEBUG; + if(true) + { + // bail if this pump is paused. + if(PAUSING == mState) + { + mState = PAUSED; + } + if(PAUSED == mState) + { + return; + } + + PUMP_DEBUG; + // Move the pending chains over to the running chaings + if(!mPendingChains.empty()) + { + PUMP_DEBUG; + //LL_DEBUGS() << "Pushing " << mPendingChains.size() << "." << LL_ENDL; + std::copy( + mPendingChains.begin(), + mPendingChains.end(), + std::back_insert_iterator<running_chains_t>(mRunningChains)); + mPendingChains.clear(); + PUMP_DEBUG; + } + + // Clear any locks. This needs to be done here so that we do + // not clash during a call to clearLock(). + if(!mClearLocks.empty()) + { + PUMP_DEBUG; + running_chains_t::iterator it = mRunningChains.begin(); + running_chains_t::iterator end = mRunningChains.end(); + std::set<S32>::iterator not_cleared = mClearLocks.end(); + for(; it != end; ++it) + { + if((*it).mLock && mClearLocks.find((*it).mLock) != not_cleared) + { + (*it).mLock = 0; + } + } + PUMP_DEBUG; + mClearLocks.clear(); + } + } + + PUMP_DEBUG; + // rebuild the pollset if necessary + if(mRebuildPollset) + { + PUMP_DEBUG; + rebuildPollset(); + mRebuildPollset = false; + } + + // Poll based on the last known pollset + // *TODO: may want to pass in a poll timeout so it works correctly + // in single and multi threaded processes. + PUMP_DEBUG; + typedef std::map<S32, S32> signal_client_t; + signal_client_t signalled_client; + const apr_pollfd_t* poll_fd = NULL; + if(mPollset) + { + PUMP_DEBUG; + //LL_INFOS() << "polling" << LL_ENDL; + S32 count = 0; + S32 client_id = 0; { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd); } - PUMP_DEBUG; - for(S32 ii = 0; ii < count; ++ii) - { - ll_debug_poll_fd("Signalled pipe", &poll_fd[ii]); - client_id = *((S32*)poll_fd[ii].client_data); - signalled_client[client_id] = ii; - } - PUMP_DEBUG; - } - - PUMP_DEBUG; - // set up for a check to see if each one was signalled - signal_client_t::iterator not_signalled = signalled_client.end(); - - // Process everything as appropriate - //LL_DEBUGS() << "Running chain count: " << mRunningChains.size() << LL_ENDL; - running_chains_t::iterator run_chain = mRunningChains.begin(); - bool process_this_chain = false; - while( run_chain != mRunningChains.end() ) - { - PUMP_DEBUG; - if((*run_chain).mInit - && (*run_chain).mTimer.getStarted() - && (*run_chain).mTimer.hasExpired()) - { - PUMP_DEBUG; - if(handleChainError(*run_chain, LLIOPipe::STATUS_EXPIRED)) - { - // the pipe probably handled the error. If the handler - // forgot to reset the expiration then we need to do - // that here. - if((*run_chain).mTimer.getStarted() - && (*run_chain).mTimer.hasExpired()) - { - PUMP_DEBUG; - LL_INFOS() << "Error handler forgot to reset timeout. " - << "Resetting to " << DEFAULT_CHAIN_EXPIRY_SECS - << " seconds." << LL_ENDL; - (*run_chain).setTimeoutSeconds(DEFAULT_CHAIN_EXPIRY_SECS); - } - } - else - { - PUMP_DEBUG; - // it timed out and no one handled it, so we need to - // retire the chain + PUMP_DEBUG; + for(S32 ii = 0; ii < count; ++ii) + { + ll_debug_poll_fd("Signalled pipe", &poll_fd[ii]); + client_id = *((S32*)poll_fd[ii].client_data); + signalled_client[client_id] = ii; + } + PUMP_DEBUG; + } + + PUMP_DEBUG; + // set up for a check to see if each one was signalled + signal_client_t::iterator not_signalled = signalled_client.end(); + + // Process everything as appropriate + //LL_DEBUGS() << "Running chain count: " << mRunningChains.size() << LL_ENDL; + running_chains_t::iterator run_chain = mRunningChains.begin(); + bool process_this_chain = false; + while( run_chain != mRunningChains.end() ) + { + PUMP_DEBUG; + if((*run_chain).mInit + && (*run_chain).mTimer.getStarted() + && (*run_chain).mTimer.hasExpired()) + { + PUMP_DEBUG; + if(handleChainError(*run_chain, LLIOPipe::STATUS_EXPIRED)) + { + // the pipe probably handled the error. If the handler + // forgot to reset the expiration then we need to do + // that here. + if((*run_chain).mTimer.getStarted() + && (*run_chain).mTimer.hasExpired()) + { + PUMP_DEBUG; + LL_INFOS() << "Error handler forgot to reset timeout. " + << "Resetting to " << DEFAULT_CHAIN_EXPIRY_SECS + << " seconds." << LL_ENDL; + (*run_chain).setTimeoutSeconds(DEFAULT_CHAIN_EXPIRY_SECS); + } + } + else + { + PUMP_DEBUG; + // it timed out and no one handled it, so we need to + // retire the chain #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_DEBUGS() << "Removing chain " - << (*run_chain).mChainLinks[0].mPipe - << " '" - << typeid(*((*run_chain).mChainLinks[0].mPipe)).name() - << "' because it timed out." << LL_ENDL; + LL_DEBUGS() << "Removing chain " + << (*run_chain).mChainLinks[0].mPipe + << " '" + << typeid(*((*run_chain).mChainLinks[0].mPipe)).name() + << "' because it timed out." << LL_ENDL; #else -// LL_DEBUGS() << "Removing chain " -// << (*run_chain).mChainLinks[0].mPipe -// << " because we reached the end." << LL_ENDL; +// LL_DEBUGS() << "Removing chain " +// << (*run_chain).mChainLinks[0].mPipe +// << " because we reached the end." << LL_ENDL; #endif - run_chain = removeRunningChain(run_chain); - continue; - } - } - else if(isChainExpired(*run_chain)) - { - run_chain = removeRunningChain(run_chain); - continue; - } - - PUMP_DEBUG; - if((*run_chain).mLock) - { - ++run_chain; - continue; - } - PUMP_DEBUG; - mCurrentChain = run_chain; - - if((*run_chain).mDescriptors.empty()) - { - // if there are no conditionals, just process this chain. - process_this_chain = true; - //LL_DEBUGS() << "no conditionals - processing" << LL_ENDL; - } - else - { - PUMP_DEBUG; - //LL_DEBUGS() << "checking conditionals" << LL_ENDL; - // Check if this run chain was signalled. If any file - // descriptor is ready for something, then go ahead and - // process this chian. - process_this_chain = false; - if(!signalled_client.empty()) - { - PUMP_DEBUG; - LLChainInfo::conditionals_t::iterator it; - it = (*run_chain).mDescriptors.begin(); - LLChainInfo::conditionals_t::iterator end; - end = (*run_chain).mDescriptors.end(); - S32 client_id = 0; - signal_client_t::iterator signal; - for(; it != end; ++it) - { - PUMP_DEBUG; - client_id = *((S32*)((*it).second.client_data)); - signal = signalled_client.find(client_id); - if (signal == not_signalled) continue; - static const apr_int16_t POLL_CHAIN_ERROR = - APR_POLLHUP | APR_POLLNVAL | APR_POLLERR; - const apr_pollfd_t* poll = &(poll_fd[(*signal).second]); - if(poll->rtnevents & POLL_CHAIN_ERROR) - { - // Potential eror condition has been - // returned. If HUP was one of them, we pass - // that as the error even though there may be - // more. If there are in fact more errors, - // we'll just wait for that detection until - // the next pump() cycle to catch it so that - // the logic here gets no more strained than - // it already is. - LLIOPipe::EStatus error_status; - if(poll->rtnevents & APR_POLLHUP) - error_status = LLIOPipe::STATUS_LOST_CONNECTION; - else - error_status = LLIOPipe::STATUS_ERROR; - if(handleChainError(*run_chain, error_status)) break; - ll_debug_poll_fd("Removing pipe", poll); - LL_WARNS() << "Removing pipe " - << (*run_chain).mChainLinks[0].mPipe - << " '" + run_chain = removeRunningChain(run_chain); + continue; + } + } + else if(isChainExpired(*run_chain)) + { + run_chain = removeRunningChain(run_chain); + continue; + } + + PUMP_DEBUG; + if((*run_chain).mLock) + { + ++run_chain; + continue; + } + PUMP_DEBUG; + mCurrentChain = run_chain; + + if((*run_chain).mDescriptors.empty()) + { + // if there are no conditionals, just process this chain. + process_this_chain = true; + //LL_DEBUGS() << "no conditionals - processing" << LL_ENDL; + } + else + { + PUMP_DEBUG; + //LL_DEBUGS() << "checking conditionals" << LL_ENDL; + // Check if this run chain was signalled. If any file + // descriptor is ready for something, then go ahead and + // process this chian. + process_this_chain = false; + if(!signalled_client.empty()) + { + PUMP_DEBUG; + LLChainInfo::conditionals_t::iterator it; + it = (*run_chain).mDescriptors.begin(); + LLChainInfo::conditionals_t::iterator end; + end = (*run_chain).mDescriptors.end(); + S32 client_id = 0; + signal_client_t::iterator signal; + for(; it != end; ++it) + { + PUMP_DEBUG; + client_id = *((S32*)((*it).second.client_data)); + signal = signalled_client.find(client_id); + if (signal == not_signalled) continue; + static const apr_int16_t POLL_CHAIN_ERROR = + APR_POLLHUP | APR_POLLNVAL | APR_POLLERR; + const apr_pollfd_t* poll = &(poll_fd[(*signal).second]); + if(poll->rtnevents & POLL_CHAIN_ERROR) + { + // Potential eror condition has been + // returned. If HUP was one of them, we pass + // that as the error even though there may be + // more. If there are in fact more errors, + // we'll just wait for that detection until + // the next pump() cycle to catch it so that + // the logic here gets no more strained than + // it already is. + LLIOPipe::EStatus error_status; + if(poll->rtnevents & APR_POLLHUP) + error_status = LLIOPipe::STATUS_LOST_CONNECTION; + else + error_status = LLIOPipe::STATUS_ERROR; + if(handleChainError(*run_chain, error_status)) break; + ll_debug_poll_fd("Removing pipe", poll); + LL_WARNS() << "Removing pipe " + << (*run_chain).mChainLinks[0].mPipe + << " '" #if LL_DEBUG_PIPE_TYPE_IN_PUMP - << typeid( - *((*run_chain).mChainLinks[0].mPipe)).name() + << typeid( + *((*run_chain).mChainLinks[0].mPipe)).name() #endif - << "' because: " - << events_2_string(poll->rtnevents) - << LL_ENDL; - (*run_chain).mHead = (*run_chain).mChainLinks.end(); - break; - } - - // at least 1 fd got signalled, and there were no - // errors. That means we process this chain. - process_this_chain = true; - break; - } - } - } - if(process_this_chain) - { - PUMP_DEBUG; - if(!((*run_chain).mInit)) - { - (*run_chain).mHead = (*run_chain).mChainLinks.begin(); - (*run_chain).mInit = true; - } - PUMP_DEBUG; - processChain(*run_chain); - } - - PUMP_DEBUG; - if((*run_chain).mHead == (*run_chain).mChainLinks.end()) - { + << "' because: " + << events_2_string(poll->rtnevents) + << LL_ENDL; + (*run_chain).mHead = (*run_chain).mChainLinks.end(); + break; + } + + // at least 1 fd got signalled, and there were no + // errors. That means we process this chain. + process_this_chain = true; + break; + } + } + } + if(process_this_chain) + { + PUMP_DEBUG; + if(!((*run_chain).mInit)) + { + (*run_chain).mHead = (*run_chain).mChainLinks.begin(); + (*run_chain).mInit = true; + } + PUMP_DEBUG; + processChain(*run_chain); + } + + PUMP_DEBUG; + if((*run_chain).mHead == (*run_chain).mChainLinks.end()) + { #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_DEBUGS() << "Removing chain " << (*run_chain).mChainLinks[0].mPipe - << " '" - << typeid(*((*run_chain).mChainLinks[0].mPipe)).name() - << "' because we reached the end." << LL_ENDL; + LL_DEBUGS() << "Removing chain " << (*run_chain).mChainLinks[0].mPipe + << " '" + << typeid(*((*run_chain).mChainLinks[0].mPipe)).name() + << "' because we reached the end." << LL_ENDL; #else -// LL_DEBUGS() << "Removing chain " << (*run_chain).mChainLinks[0].mPipe -// << " because we reached the end." << LL_ENDL; +// LL_DEBUGS() << "Removing chain " << (*run_chain).mChainLinks[0].mPipe +// << " because we reached the end." << LL_ENDL; #endif - PUMP_DEBUG; - // This chain is done. Clean up any allocated memory and - // erase the chain info. - run_chain = removeRunningChain(run_chain); - - // *NOTE: may not always need to rebuild the pollset. - mRebuildPollset = true; - } - else - { - PUMP_DEBUG; - // this chain needs more processing - just go to the next - // chain. - ++run_chain; - } - } - - PUMP_DEBUG; - // null out the chain - mCurrentChain = mRunningChains.end(); - END_PUMP_DEBUG; + PUMP_DEBUG; + // This chain is done. Clean up any allocated memory and + // erase the chain info. + run_chain = removeRunningChain(run_chain); + + // *NOTE: may not always need to rebuild the pollset. + mRebuildPollset = true; + } + else + { + PUMP_DEBUG; + // this chain needs more processing - just go to the next + // chain. + ++run_chain; + } + } + + PUMP_DEBUG; + // null out the chain + mCurrentChain = mRunningChains.end(); + END_PUMP_DEBUG; } bool LLPumpIO::respond(LLIOPipe* pipe) { - if(NULL == pipe) return false; - - LLChainInfo info; - LLLinkInfo link; - link.mPipe = pipe; - info.mChainLinks.push_back(link); - mPendingCallbacks.push_back(info); - return true; + if(NULL == pipe) return false; + + LLChainInfo info; + LLLinkInfo link; + link.mPipe = pipe; + info.mChainLinks.push_back(link); + mPendingCallbacks.push_back(info); + return true; } bool LLPumpIO::respond( - const links_t& links, - LLIOPipe::buffer_ptr_t data, - LLSD context) + const links_t& links, + LLIOPipe::buffer_ptr_t data, + LLSD context) { - // if the caller is providing a full link description, we need to - // have that description matched to a particular buffer. - if(!data) return false; - if(links.empty()) return false; - - // Add the callback response - LLChainInfo info; - info.mChainLinks = links; - info.mData = data; - info.mContext = context; - mPendingCallbacks.push_back(info); - return true; + // if the caller is providing a full link description, we need to + // have that description matched to a particular buffer. + if(!data) return false; + if(links.empty()) return false; + + // Add the callback response + LLChainInfo info; + info.mChainLinks = links; + info.mData = data; + info.mContext = context; + mPendingCallbacks.push_back(info); + return true; } void LLPumpIO::callback() { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - //LL_INFOS() << "LLPumpIO::callback()" << LL_ENDL; - if(true) - { - std::copy( - mPendingCallbacks.begin(), - mPendingCallbacks.end(), - std::back_insert_iterator<callbacks_t>(mCallbacks)); - mPendingCallbacks.clear(); - } - if(!mCallbacks.empty()) - { - callbacks_t::iterator it = mCallbacks.begin(); - callbacks_t::iterator end = mCallbacks.end(); - for(; it != end; ++it) - { - // it's always the first and last time for respone chains - (*it).mHead = (*it).mChainLinks.begin(); - (*it).mInit = true; - (*it).mEOS = true; - processChain(*it); - } - mCallbacks.clear(); - } + //LL_INFOS() << "LLPumpIO::callback()" << LL_ENDL; + if(true) + { + std::copy( + mPendingCallbacks.begin(), + mPendingCallbacks.end(), + std::back_insert_iterator<callbacks_t>(mCallbacks)); + mPendingCallbacks.clear(); + } + if(!mCallbacks.empty()) + { + callbacks_t::iterator it = mCallbacks.begin(); + callbacks_t::iterator end = mCallbacks.end(); + for(; it != end; ++it) + { + // it's always the first and last time for respone chains + (*it).mHead = (*it).mChainLinks.begin(); + (*it).mInit = true; + (*it).mEOS = true; + processChain(*it); + } + mCallbacks.clear(); + } } void LLPumpIO::control(LLPumpIO::EControl op) { - switch(op) - { - case PAUSE: - mState = PAUSING; - break; - case RESUME: - mState = NORMAL; - break; - default: - // no-op - break; - } + switch(op) + { + case PAUSE: + mState = PAUSING; + break; + case RESUME: + mState = NORMAL; + break; + default: + // no-op + break; + } } void LLPumpIO::initialize(apr_pool_t* pool) { - if(!pool) return; - mPool = pool; + if(!pool) return; + mPool = pool; } void LLPumpIO::cleanup() { - if(mPollset) - { -// LL_DEBUGS() << "cleaning up pollset" << LL_ENDL; - apr_pollset_destroy(mPollset); - mPollset = NULL; - } - if(mCurrentPool) - { - apr_pool_destroy(mCurrentPool); - mCurrentPool = NULL; - } - mPool = NULL; + if(mPollset) + { +// LL_DEBUGS() << "cleaning up pollset" << LL_ENDL; + apr_pollset_destroy(mPollset); + mPollset = NULL; + } + if(mCurrentPool) + { + apr_pool_destroy(mCurrentPool); + mCurrentPool = NULL; + } + mPool = NULL; } void LLPumpIO::rebuildPollset() { -// LL_DEBUGS() << "LLPumpIO::rebuildPollset()" << LL_ENDL; - if(mPollset) - { - //LL_DEBUGS() << "destroying pollset" << LL_ENDL; - apr_pollset_destroy(mPollset); - mPollset = NULL; - } - U32 size = 0; - running_chains_t::iterator run_it = mRunningChains.begin(); - running_chains_t::iterator run_end = mRunningChains.end(); - for(; run_it != run_end; ++run_it) - { - size += (*run_it).mDescriptors.size(); - } - //LL_DEBUGS() << "found " << size << " descriptors." << LL_ENDL; - if(size) - { - // Recycle the memory pool - const S32 POLLSET_POOL_RECYCLE_COUNT = 100; - if(mCurrentPool - && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) - { - apr_pool_destroy(mCurrentPool); - mCurrentPool = NULL; - mCurrentPoolReallocCount = 0; - } - if(!mCurrentPool) - { - apr_status_t status = apr_pool_create(&mCurrentPool, mPool); - (void)ll_apr_warn_status(status); - } - - // add all of the file descriptors - run_it = mRunningChains.begin(); - LLChainInfo::conditionals_t::iterator fd_it; - LLChainInfo::conditionals_t::iterator fd_end; - apr_pollset_create(&mPollset, size, mCurrentPool, 0); - for(; run_it != run_end; ++run_it) - { - fd_it = (*run_it).mDescriptors.begin(); - fd_end = (*run_it).mDescriptors.end(); - for(; fd_it != fd_end; ++fd_it) - { - apr_pollset_add(mPollset, &((*fd_it).second)); - } - } - } +// LL_DEBUGS() << "LLPumpIO::rebuildPollset()" << LL_ENDL; + if(mPollset) + { + //LL_DEBUGS() << "destroying pollset" << LL_ENDL; + apr_pollset_destroy(mPollset); + mPollset = NULL; + } + U32 size = 0; + running_chains_t::iterator run_it = mRunningChains.begin(); + running_chains_t::iterator run_end = mRunningChains.end(); + for(; run_it != run_end; ++run_it) + { + size += (*run_it).mDescriptors.size(); + } + //LL_DEBUGS() << "found " << size << " descriptors." << LL_ENDL; + if(size) + { + // Recycle the memory pool + const S32 POLLSET_POOL_RECYCLE_COUNT = 100; + if(mCurrentPool + && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) + { + apr_pool_destroy(mCurrentPool); + mCurrentPool = NULL; + mCurrentPoolReallocCount = 0; + } + if(!mCurrentPool) + { + apr_status_t status = apr_pool_create(&mCurrentPool, mPool); + (void)ll_apr_warn_status(status); + } + + // add all of the file descriptors + run_it = mRunningChains.begin(); + LLChainInfo::conditionals_t::iterator fd_it; + LLChainInfo::conditionals_t::iterator fd_end; + apr_pollset_create(&mPollset, size, mCurrentPool, 0); + for(; run_it != run_end; ++run_it) + { + fd_it = (*run_it).mDescriptors.begin(); + fd_end = (*run_it).mDescriptors.end(); + for(; fd_it != fd_end; ++fd_it) + { + apr_pollset_add(mPollset, &((*fd_it).second)); + } + } + } } void LLPumpIO::processChain(LLChainInfo& chain) { - PUMP_DEBUG; - LLIOPipe::EStatus status = LLIOPipe::STATUS_OK; - links_t::iterator it = chain.mHead; - links_t::iterator end = chain.mChainLinks.end(); - bool need_process_signaled = false; - bool keep_going = true; - do - { + PUMP_DEBUG; + LLIOPipe::EStatus status = LLIOPipe::STATUS_OK; + links_t::iterator it = chain.mHead; + links_t::iterator end = chain.mChainLinks.end(); + bool need_process_signaled = false; + bool keep_going = true; + do + { #if LL_DEBUG_PROCESS_LINK #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_INFOS() << "Processing " << typeid(*((*it).mPipe)).name() << "." - << LL_ENDL; + LL_INFOS() << "Processing " << typeid(*((*it).mPipe)).name() << "." + << LL_ENDL; #else - LL_INFOS() << "Processing link " << (*it).mPipe << "." << LL_ENDL; + LL_INFOS() << "Processing link " << (*it).mPipe << "." << LL_ENDL; #endif #endif #if LL_DEBUG_SPEW_BUFFER_CHANNEL_IN - if(chain.mData) - { - char* buf = NULL; - S32 bytes = chain.mData->countAfter((*it).mChannels.in(), NULL); - if(bytes) - { - buf = new char[bytes + 1]; - chain.mData->readAfter( - (*it).mChannels.in(), - NULL, - (U8*)buf, - bytes); - buf[bytes] = '\0'; - LL_INFOS() << "CHANNEL IN(" << (*it).mChannels.in() << "): " - << buf << LL_ENDL; - delete[] buf; - buf = NULL; - } - else - { - LL_INFOS() << "CHANNEL IN(" << (*it).mChannels.in()<< "): (null)" - << LL_ENDL; - } - } + if(chain.mData) + { + char* buf = NULL; + S32 bytes = chain.mData->countAfter((*it).mChannels.in(), NULL); + if(bytes) + { + buf = new char[bytes + 1]; + chain.mData->readAfter( + (*it).mChannels.in(), + NULL, + (U8*)buf, + bytes); + buf[bytes] = '\0'; + LL_INFOS() << "CHANNEL IN(" << (*it).mChannels.in() << "): " + << buf << LL_ENDL; + delete[] buf; + buf = NULL; + } + else + { + LL_INFOS() << "CHANNEL IN(" << (*it).mChannels.in()<< "): (null)" + << LL_ENDL; + } + } #endif - PUMP_DEBUG; - status = (*it).mPipe->process( - (*it).mChannels, - chain.mData, - chain.mEOS, - chain.mContext, - this); + PUMP_DEBUG; + status = (*it).mPipe->process( + (*it).mChannels, + chain.mData, + chain.mEOS, + chain.mContext, + this); #if LL_DEBUG_SPEW_BUFFER_CHANNEL_OUT - if(chain.mData) - { - char* buf = NULL; - S32 bytes = chain.mData->countAfter((*it).mChannels.out(), NULL); - if(bytes) - { - buf = new char[bytes + 1]; - chain.mData->readAfter( - (*it).mChannels.out(), - NULL, - (U8*)buf, - bytes); - buf[bytes] = '\0'; - LL_INFOS() << "CHANNEL OUT(" << (*it).mChannels.out()<< "): " - << buf << LL_ENDL; - delete[] buf; - buf = NULL; - } - else - { - LL_INFOS() << "CHANNEL OUT(" << (*it).mChannels.out()<< "): (null)" - << LL_ENDL; - } - } + if(chain.mData) + { + char* buf = NULL; + S32 bytes = chain.mData->countAfter((*it).mChannels.out(), NULL); + if(bytes) + { + buf = new char[bytes + 1]; + chain.mData->readAfter( + (*it).mChannels.out(), + NULL, + (U8*)buf, + bytes); + buf[bytes] = '\0'; + LL_INFOS() << "CHANNEL OUT(" << (*it).mChannels.out()<< "): " + << buf << LL_ENDL; + delete[] buf; + buf = NULL; + } + else + { + LL_INFOS() << "CHANNEL OUT(" << (*it).mChannels.out()<< "): (null)" + << LL_ENDL; + } + } #endif #if LL_DEBUG_PROCESS_RETURN_VALUE - // Only bother with the success codes - error codes are logged - // below. - if(LLIOPipe::isSuccess(status)) - { - LL_INFOS() << "Pipe returned: '" + // Only bother with the success codes - error codes are logged + // below. + if(LLIOPipe::isSuccess(status)) + { + LL_INFOS() << "Pipe returned: '" #if LL_DEBUG_PIPE_TYPE_IN_PUMP - << typeid(*((*it).mPipe)).name() << "':'" + << typeid(*((*it).mPipe)).name() << "':'" #endif - << LLIOPipe::lookupStatusString(status) << "'" << LL_ENDL; - } + << LLIOPipe::lookupStatusString(status) << "'" << LL_ENDL; + } #endif - PUMP_DEBUG; - switch(status) - { - case LLIOPipe::STATUS_OK: - // no-op - break; - case LLIOPipe::STATUS_STOP: - PUMP_DEBUG; - status = LLIOPipe::STATUS_OK; - chain.mHead = end; - keep_going = false; - break; - case LLIOPipe::STATUS_DONE: - PUMP_DEBUG; - status = LLIOPipe::STATUS_OK; - chain.mHead = (it + 1); - chain.mEOS = true; - break; - case LLIOPipe::STATUS_BREAK: - PUMP_DEBUG; - status = LLIOPipe::STATUS_OK; - keep_going = false; - break; - case LLIOPipe::STATUS_NEED_PROCESS: - PUMP_DEBUG; - status = LLIOPipe::STATUS_OK; - if(!need_process_signaled) - { - need_process_signaled = true; - chain.mHead = it; - } - break; - default: - PUMP_DEBUG; - if(LLIOPipe::isError(status)) - { - LL_INFOS() << "Pump generated pipe err: '" + PUMP_DEBUG; + switch(status) + { + case LLIOPipe::STATUS_OK: + // no-op + break; + case LLIOPipe::STATUS_STOP: + PUMP_DEBUG; + status = LLIOPipe::STATUS_OK; + chain.mHead = end; + keep_going = false; + break; + case LLIOPipe::STATUS_DONE: + PUMP_DEBUG; + status = LLIOPipe::STATUS_OK; + chain.mHead = (it + 1); + chain.mEOS = true; + break; + case LLIOPipe::STATUS_BREAK: + PUMP_DEBUG; + status = LLIOPipe::STATUS_OK; + keep_going = false; + break; + case LLIOPipe::STATUS_NEED_PROCESS: + PUMP_DEBUG; + status = LLIOPipe::STATUS_OK; + if(!need_process_signaled) + { + need_process_signaled = true; + chain.mHead = it; + } + break; + default: + PUMP_DEBUG; + if(LLIOPipe::isError(status)) + { + LL_INFOS() << "Pump generated pipe err: '" #if LL_DEBUG_PIPE_TYPE_IN_PUMP - << typeid(*((*it).mPipe)).name() << "':'" + << typeid(*((*it).mPipe)).name() << "':'" #endif - << LLIOPipe::lookupStatusString(status) - << "'" << LL_ENDL; + << LLIOPipe::lookupStatusString(status) + << "'" << LL_ENDL; #if LL_DEBUG_SPEW_BUFFER_CHANNEL_IN_ON_ERROR - if(chain.mData) - { - char* buf = NULL; - S32 bytes = chain.mData->countAfter( - (*it).mChannels.in(), - NULL); - if(bytes) - { - buf = new char[bytes + 1]; - chain.mData->readAfter( - (*it).mChannels.in(), - NULL, - (U8*)buf, - bytes); - buf[bytes] = '\0'; - LL_INFOS() << "Input After Error: " << buf << LL_ENDL; - delete[] buf; - buf = NULL; - } - else - { - LL_INFOS() << "Input After Error: (null)" << LL_ENDL; - } - } - else - { - LL_INFOS() << "Input After Error: (null)" << LL_ENDL; - } + if(chain.mData) + { + char* buf = NULL; + S32 bytes = chain.mData->countAfter( + (*it).mChannels.in(), + NULL); + if(bytes) + { + buf = new char[bytes + 1]; + chain.mData->readAfter( + (*it).mChannels.in(), + NULL, + (U8*)buf, + bytes); + buf[bytes] = '\0'; + LL_INFOS() << "Input After Error: " << buf << LL_ENDL; + delete[] buf; + buf = NULL; + } + else + { + LL_INFOS() << "Input After Error: (null)" << LL_ENDL; + } + } + else + { + LL_INFOS() << "Input After Error: (null)" << LL_ENDL; + } #endif - keep_going = false; - chain.mHead = it; - if(!handleChainError(chain, status)) - { - chain.mHead = end; - } - } - else - { - LL_INFOS() << "Unhandled status code: " << status << ":" - << LLIOPipe::lookupStatusString(status) << LL_ENDL; - } - break; - } - PUMP_DEBUG; - } while(keep_going && (++it != end)); - PUMP_DEBUG; + keep_going = false; + chain.mHead = it; + if(!handleChainError(chain, status)) + { + chain.mHead = end; + } + } + else + { + LL_INFOS() << "Unhandled status code: " << status << ":" + << LLIOPipe::lookupStatusString(status) << LL_ENDL; + } + break; + } + PUMP_DEBUG; + } while(keep_going && (++it != end)); + PUMP_DEBUG; } bool LLPumpIO::isChainExpired(LLChainInfo& chain) { - if(!chain.mHasCurlRequest) - { - return false ; - } - - for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter) - { - if(!(*iter).mPipe->isValid()) - { - return true ; - } - } - - return false ; + if(!chain.mHasCurlRequest) + { + return false ; + } + + for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter) + { + if(!(*iter).mPipe->isValid()) + { + return true ; + } + } + + return false ; } bool LLPumpIO::handleChainError( - LLChainInfo& chain, - LLIOPipe::EStatus error) + LLChainInfo& chain, + LLIOPipe::EStatus error) { - links_t::reverse_iterator rit; - if(chain.mHead == chain.mChainLinks.end()) - { - rit = links_t::reverse_iterator(chain.mHead); - } - else - { - rit = links_t::reverse_iterator(chain.mHead + 1); - } - - links_t::reverse_iterator rend = chain.mChainLinks.rend(); - bool handled = false; - bool keep_going = true; - do - { + links_t::reverse_iterator rit; + if(chain.mHead == chain.mChainLinks.end()) + { + rit = links_t::reverse_iterator(chain.mHead); + } + else + { + rit = links_t::reverse_iterator(chain.mHead + 1); + } + + links_t::reverse_iterator rend = chain.mChainLinks.rend(); + bool handled = false; + bool keep_going = true; + do + { #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_DEBUGS() << "Passing error to " << typeid(*((*rit).mPipe)).name() - << "." << LL_ENDL; + LL_DEBUGS() << "Passing error to " << typeid(*((*rit).mPipe)).name() + << "." << LL_ENDL; #endif - error = (*rit).mPipe->handleError(error, this); - switch(error) - { - case LLIOPipe::STATUS_OK: - handled = true; - chain.mHead = rit.base(); - break; - case LLIOPipe::STATUS_STOP: - case LLIOPipe::STATUS_DONE: - case LLIOPipe::STATUS_BREAK: - case LLIOPipe::STATUS_NEED_PROCESS: + error = (*rit).mPipe->handleError(error, this); + switch(error) + { + case LLIOPipe::STATUS_OK: + handled = true; + chain.mHead = rit.base(); + break; + case LLIOPipe::STATUS_STOP: + case LLIOPipe::STATUS_DONE: + case LLIOPipe::STATUS_BREAK: + case LLIOPipe::STATUS_NEED_PROCESS: #if LL_DEBUG_PIPE_TYPE_IN_PUMP - LL_DEBUGS() << "Pipe " << typeid(*((*rit).mPipe)).name() - << " returned code to stop error handler." << LL_ENDL; + LL_DEBUGS() << "Pipe " << typeid(*((*rit).mPipe)).name() + << " returned code to stop error handler." << LL_ENDL; #endif - keep_going = false; - break; - case LLIOPipe::STATUS_EXPIRED: - keep_going = false; - break ; - default: - if(LLIOPipe::isSuccess(error)) - { - LL_INFOS() << "Unhandled status code: " << error << ":" - << LLIOPipe::lookupStatusString(error) << LL_ENDL; - error = LLIOPipe::STATUS_ERROR; - keep_going = false; - } - break; - } - } while(keep_going && !handled && (++rit != rend)); - return handled; + keep_going = false; + break; + case LLIOPipe::STATUS_EXPIRED: + keep_going = false; + break ; + default: + if(LLIOPipe::isSuccess(error)) + { + LL_INFOS() << "Unhandled status code: " << error << ":" + << LLIOPipe::lookupStatusString(error) << LL_ENDL; + error = LLIOPipe::STATUS_ERROR; + keep_going = false; + } + break; + } + } while(keep_going && !handled && (++rit != rend)); + return handled; } /** @@ -1117,34 +1117,34 @@ bool LLPumpIO::handleChainError( */ LLPumpIO::LLChainInfo::LLChainInfo() : - mInit(false), - mLock(0), - mEOS(false), - mHasCurlRequest(false) + mInit(false), + mLock(0), + mEOS(false), + mHasCurlRequest(false) { - mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); + mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); } void LLPumpIO::LLChainInfo::setTimeoutSeconds(F32 timeout) { - if(timeout > 0.0f) - { - mTimer.start(); - mTimer.reset(); - mTimer.setTimerExpirySec(timeout); - } - else - { - mTimer.stop(); - } + if(timeout > 0.0f) + { + mTimer.start(); + mTimer.reset(); + mTimer.setTimerExpirySec(timeout); + } + else + { + mTimer.stop(); + } } void LLPumpIO::LLChainInfo::adjustTimeoutSeconds(F32 delta) { - if(mTimer.getStarted()) - { - F64 expiry = mTimer.expiresAt(); - expiry += delta; - mTimer.setExpiryAt(expiry); - } + if(mTimer.getStarted()) + { + F64 expiry = mTimer.expiresAt(); + expiry += delta; + mTimer.setExpiryAt(expiry); + } } diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index b9eabee710..67e317ed2d 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -1,4 +1,4 @@ -/** +/** * @file llpumpio.h * @author Phoenix * @date 2004-11-19 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,7 +45,7 @@ extern const F32 DEFAULT_CHAIN_EXPIRY_SECS; extern const F32 SHORT_CHAIN_EXPIRY_SECS; extern const F32 NEVER_CHAIN_EXPIRY_SECS; -/** +/** * @class LLPumpIO * @brief Class to manage sets of io chains. * @@ -73,367 +73,367 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS; class LLPumpIO { public: - /** - * @brief Constructor. - */ - LLPumpIO(apr_pool_t* pool); - - /** - * @brief Destructor. - */ - ~LLPumpIO(); - - /** - * @brief Prepare this pump for usage. - * - * If you fail to call this method prior to use, the pump will - * try to work, but will not come with any thread locking - * mechanisms. - * @param pool The apr pool to use. - * @return Returns true if the pump is primed. - */ - bool prime(apr_pool_t* pool); - - /** - * @brief Typedef for having a chain of pipes. - */ - typedef std::vector<LLIOPipe::ptr_t> chain_t; - - /** - * @brief Add a chain to this pump and process in the next cycle. - * - * This method will automatically generate a buffer and assign - * each link in the chain as if it were the consumer to the - * previous. - * @param chain The pipes for the chain - * @param timeout The number of seconds in the future to - * expire. Pass in 0.0f to never expire. - * @param has_curl_request The chain contains LLURLRequest if true. - * @return Returns true if anything was added to the pump. - */ - bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false); - - /** - * @brief Struct to associate a pipe with it's buffer io indexes. - */ - struct LLLinkInfo - { - LLIOPipe::ptr_t mPipe; - LLChannelDescriptors mChannels; - }; - - /** - * @brief Typedef for having a chain of <code>LLLinkInfo</code> - * instances. - */ - typedef std::vector<LLLinkInfo> links_t; - - /** - * @brief Add a chain to this pump and process in the next cycle. - * - * This method provides a slightly more sophisticated method for - * adding a chain where the caller can specify which link elements - * are on what channels. This method will fail if no buffer is - * provided since any calls to generate new channels for the - * buffers will cause unpredictable interleaving of data. - * @param links The pipes and io indexes for the chain - * @param data Shared pointer to data buffer - * @param context Potentially undefined context meta-data for chain. - * @param timeout The number of seconds in the future to - * expire. Pass in 0.0f to never expire. - * @return Returns true if anything was added to the pump. - */ - bool addChain( - const links_t& links, - LLIOPipe::buffer_ptr_t data, - LLSD context, - F32 timeout); - - /** - * @brief Set or clear a timeout for the running chain - * - * @param timeout The number of seconds in the future to - * expire. Pass in 0.0f to never expire. - * @return Returns true if the timer was set. - */ - bool setTimeoutSeconds(F32 timeout); - - /** - * @brief Adjust the timeout of the running chain. - * - * This method has no effect if there is no timeout on the chain. - * @param delta The number of seconds to add to/remove from the timeout. - */ - void adjustTimeoutSeconds(F32 delta); - - /** - * @brief Set up file descriptors for for the running chain. - * @see rebuildPollset() - * - * There is currently a limit of one conditional per pipe. - * *NOTE: The internal mechanism for building a pollset based on - * pipe/pollfd/chain generates an epoll error on linux (and - * probably behaves similarly on other platforms) because the - * pollset rebuilder will add each apr_pollfd_t serially. This - * does not matter for pipes on the same chain, since any - * signalled pipe will eventually invoke a call to process(), but - * is a problem if the same apr_pollfd_t is on different - * chains. Once we have more than just network i/o on the pump, - * this might matter. - * *FIX: Given the structure of the pump and pipe relationship, - * this should probably go through a different mechanism than the - * pump. I think it would be best if the pipe had some kind of - * controller which was passed into <code>process()</code> rather - * than the pump which exposed this interface. - * @param pipe The pipe which is setting a conditional - * @param poll The entire socket and read/write condition - null to remove - * @return Returns true if the poll state was set. - */ - bool setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll); - - /** - * @brief Lock the current chain. - * @see sleepChain() since it relies on the implementation of this method. - * - * This locks the currently running chain so that no more calls to - * <code>process()</code> until you call <code>clearLock()</code> - * with the lock identifier. - * *FIX: Given the structure of the pump and pipe relationship, - * this should probably go through a different mechanism than the - * pump. I think it would be best if the pipe had some kind of - * controller which was passed into <code>process()</code> rather - * than the pump which exposed this interface. - * @return Returns the lock identifer to be used in - * <code>clearLock()</code> or 0 on failure. - */ - S32 setLock(); - - /** - * @brief Clears the identified lock. - * - * @param links A container for the links which will be appended - */ - void clearLock(S32 key); - - /** - * @brief Stop processing a chain for a while. - * @see setLock() - * - * This method will <em>not</em> update the timeout for this - * chain, so it is possible to sleep the chain until it is - * collected by the pump during a timeout cleanup. - * @param seconds The number of seconds in the future to - * resume processing. - * @return Returns true if the - */ - bool sleepChain(F64 seconds); - - /** - * @brief Copy the currently running chain link info - * - * *FIX: Given the structure of the pump and pipe relationship, - * this should probably go through a different mechanism than the - * pump. I think it would be best if the pipe had some kind of - * controller which was passed into <code>process()</code> rather - * than the pump which exposed this interface. - * @param links A container for the links which will be appended - * @return Returns true if the currently running chain was copied. - */ - bool copyCurrentLinkInfo(links_t& links) const; - - /** - * @brief Call this method to call process on all running chains. - * - * This method iterates through the running chains, and if all - * pipe on a chain are unconditionally ready or if any pipe has - * any conditional processiong condition then process will be - * called on every chain which has requested processing. that - * chain has a file descriptor ready, <code>process()</code> will - * be called for all pipes which have requested it. - */ - void pump(const S32& poll_timeout); - void pump(); - - /** - * @brief Add a chain to a special queue which will be called - * during the next call to <code>callback()</code> and then - * dropped from the queue. - * - * @param chain The IO chain that will get one <code>process()</code>. - */ - //void respond(const chain_t& pipes); - - /** - * @brief Add pipe to a special queue which will be called - * during the next call to <code>callback()</code> and then dropped - * from the queue. - * - * This call will add a single pipe, with no buffer, context, or - * channel information to the callback queue. It will be called - * once, and then dropped. - * @param pipe A single io pipe which will be called - * @return Returns true if anything was added to the pump. - */ - bool respond(LLIOPipe* pipe); - - /** - * @brief Add a chain to a special queue which will be called - * during the next call to <code>callback()</code> and then - * dropped from the queue. - * - * It is important to remember that you should not add a data - * buffer or context which may still be in another chain - that - * will almost certainly lead to a problems. Ensure that you are - * done reading and writing to those parameters, have new - * generated, or empty pointers. - * @param links The pipes and io indexes for the chain - * @param data Shared pointer to data buffer - * @param context Potentially undefined context meta-data for chain. - * @return Returns true if anything was added to the pump. - */ - bool respond( - const links_t& links, - LLIOPipe::buffer_ptr_t data, - LLSD context); - - /** - * @brief Run through the callback queue and call <code>process()</code>. - * - * This call will process all prending responses and call process - * on each. This method will then drop all processed callback - * requests which may lead to deleting the referenced objects. - */ - void callback(); - - /** - * @brief Enumeration to send commands to the pump. - */ - enum EControl - { - PAUSE, - RESUME, - }; - - /** - * @brief Send a command to the pump. - * - * @param op What control to send to the pump. - */ - void control(EControl op); + /** + * @brief Constructor. + */ + LLPumpIO(apr_pool_t* pool); + + /** + * @brief Destructor. + */ + ~LLPumpIO(); + + /** + * @brief Prepare this pump for usage. + * + * If you fail to call this method prior to use, the pump will + * try to work, but will not come with any thread locking + * mechanisms. + * @param pool The apr pool to use. + * @return Returns true if the pump is primed. + */ + bool prime(apr_pool_t* pool); + + /** + * @brief Typedef for having a chain of pipes. + */ + typedef std::vector<LLIOPipe::ptr_t> chain_t; + + /** + * @brief Add a chain to this pump and process in the next cycle. + * + * This method will automatically generate a buffer and assign + * each link in the chain as if it were the consumer to the + * previous. + * @param chain The pipes for the chain + * @param timeout The number of seconds in the future to + * expire. Pass in 0.0f to never expire. + * @param has_curl_request The chain contains LLURLRequest if true. + * @return Returns true if anything was added to the pump. + */ + bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false); + + /** + * @brief Struct to associate a pipe with it's buffer io indexes. + */ + struct LLLinkInfo + { + LLIOPipe::ptr_t mPipe; + LLChannelDescriptors mChannels; + }; + + /** + * @brief Typedef for having a chain of <code>LLLinkInfo</code> + * instances. + */ + typedef std::vector<LLLinkInfo> links_t; + + /** + * @brief Add a chain to this pump and process in the next cycle. + * + * This method provides a slightly more sophisticated method for + * adding a chain where the caller can specify which link elements + * are on what channels. This method will fail if no buffer is + * provided since any calls to generate new channels for the + * buffers will cause unpredictable interleaving of data. + * @param links The pipes and io indexes for the chain + * @param data Shared pointer to data buffer + * @param context Potentially undefined context meta-data for chain. + * @param timeout The number of seconds in the future to + * expire. Pass in 0.0f to never expire. + * @return Returns true if anything was added to the pump. + */ + bool addChain( + const links_t& links, + LLIOPipe::buffer_ptr_t data, + LLSD context, + F32 timeout); + + /** + * @brief Set or clear a timeout for the running chain + * + * @param timeout The number of seconds in the future to + * expire. Pass in 0.0f to never expire. + * @return Returns true if the timer was set. + */ + bool setTimeoutSeconds(F32 timeout); + + /** + * @brief Adjust the timeout of the running chain. + * + * This method has no effect if there is no timeout on the chain. + * @param delta The number of seconds to add to/remove from the timeout. + */ + void adjustTimeoutSeconds(F32 delta); + + /** + * @brief Set up file descriptors for for the running chain. + * @see rebuildPollset() + * + * There is currently a limit of one conditional per pipe. + * *NOTE: The internal mechanism for building a pollset based on + * pipe/pollfd/chain generates an epoll error on linux (and + * probably behaves similarly on other platforms) because the + * pollset rebuilder will add each apr_pollfd_t serially. This + * does not matter for pipes on the same chain, since any + * signalled pipe will eventually invoke a call to process(), but + * is a problem if the same apr_pollfd_t is on different + * chains. Once we have more than just network i/o on the pump, + * this might matter. + * *FIX: Given the structure of the pump and pipe relationship, + * this should probably go through a different mechanism than the + * pump. I think it would be best if the pipe had some kind of + * controller which was passed into <code>process()</code> rather + * than the pump which exposed this interface. + * @param pipe The pipe which is setting a conditional + * @param poll The entire socket and read/write condition - null to remove + * @return Returns true if the poll state was set. + */ + bool setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll); + + /** + * @brief Lock the current chain. + * @see sleepChain() since it relies on the implementation of this method. + * + * This locks the currently running chain so that no more calls to + * <code>process()</code> until you call <code>clearLock()</code> + * with the lock identifier. + * *FIX: Given the structure of the pump and pipe relationship, + * this should probably go through a different mechanism than the + * pump. I think it would be best if the pipe had some kind of + * controller which was passed into <code>process()</code> rather + * than the pump which exposed this interface. + * @return Returns the lock identifer to be used in + * <code>clearLock()</code> or 0 on failure. + */ + S32 setLock(); + + /** + * @brief Clears the identified lock. + * + * @param links A container for the links which will be appended + */ + void clearLock(S32 key); + + /** + * @brief Stop processing a chain for a while. + * @see setLock() + * + * This method will <em>not</em> update the timeout for this + * chain, so it is possible to sleep the chain until it is + * collected by the pump during a timeout cleanup. + * @param seconds The number of seconds in the future to + * resume processing. + * @return Returns true if the + */ + bool sleepChain(F64 seconds); + + /** + * @brief Copy the currently running chain link info + * + * *FIX: Given the structure of the pump and pipe relationship, + * this should probably go through a different mechanism than the + * pump. I think it would be best if the pipe had some kind of + * controller which was passed into <code>process()</code> rather + * than the pump which exposed this interface. + * @param links A container for the links which will be appended + * @return Returns true if the currently running chain was copied. + */ + bool copyCurrentLinkInfo(links_t& links) const; + + /** + * @brief Call this method to call process on all running chains. + * + * This method iterates through the running chains, and if all + * pipe on a chain are unconditionally ready or if any pipe has + * any conditional processiong condition then process will be + * called on every chain which has requested processing. that + * chain has a file descriptor ready, <code>process()</code> will + * be called for all pipes which have requested it. + */ + void pump(const S32& poll_timeout); + void pump(); + + /** + * @brief Add a chain to a special queue which will be called + * during the next call to <code>callback()</code> and then + * dropped from the queue. + * + * @param chain The IO chain that will get one <code>process()</code>. + */ + //void respond(const chain_t& pipes); + + /** + * @brief Add pipe to a special queue which will be called + * during the next call to <code>callback()</code> and then dropped + * from the queue. + * + * This call will add a single pipe, with no buffer, context, or + * channel information to the callback queue. It will be called + * once, and then dropped. + * @param pipe A single io pipe which will be called + * @return Returns true if anything was added to the pump. + */ + bool respond(LLIOPipe* pipe); + + /** + * @brief Add a chain to a special queue which will be called + * during the next call to <code>callback()</code> and then + * dropped from the queue. + * + * It is important to remember that you should not add a data + * buffer or context which may still be in another chain - that + * will almost certainly lead to a problems. Ensure that you are + * done reading and writing to those parameters, have new + * generated, or empty pointers. + * @param links The pipes and io indexes for the chain + * @param data Shared pointer to data buffer + * @param context Potentially undefined context meta-data for chain. + * @return Returns true if anything was added to the pump. + */ + bool respond( + const links_t& links, + LLIOPipe::buffer_ptr_t data, + LLSD context); + + /** + * @brief Run through the callback queue and call <code>process()</code>. + * + * This call will process all prending responses and call process + * on each. This method will then drop all processed callback + * requests which may lead to deleting the referenced objects. + */ + void callback(); + + /** + * @brief Enumeration to send commands to the pump. + */ + enum EControl + { + PAUSE, + RESUME, + }; + + /** + * @brief Send a command to the pump. + * + * @param op What control to send to the pump. + */ + void control(EControl op); protected: - /** - * @brief State of the pump - */ - enum EState - { - NORMAL, - PAUSING, - PAUSED - }; - - // instance data - EState mState; - bool mRebuildPollset; - apr_pollset_t* mPollset; - S32 mPollsetClientID; - S32 mNextLock; - std::set<S32> mClearLocks; - - // This is the pump's runnable scheduler used for handling - // expiring locks. - LLRunner mRunner; - - // This structure is the stuff we track while running chains. - struct LLChainInfo - { - // methods - LLChainInfo(); - void setTimeoutSeconds(F32 timeout); - void adjustTimeoutSeconds(F32 delta); - - // basic member data - bool mInit; - bool mEOS; - bool mHasCurlRequest; - S32 mLock; - LLFrameTimer mTimer; - links_t::iterator mHead; - links_t mChainLinks; - LLIOPipe::buffer_ptr_t mData; - LLSD mContext; - - // tracking inside the pump - typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; - typedef std::vector<pipe_conditional_t> conditionals_t; - conditionals_t mDescriptors; - }; - - // All the running chains & info - typedef std::vector<LLChainInfo> pending_chains_t; - pending_chains_t mPendingChains; - typedef std::list<LLChainInfo> running_chains_t; - running_chains_t mRunningChains; - - typedef running_chains_t::iterator current_chain_t; - current_chain_t mCurrentChain; - - // structures necessary for doing callbacks - // since the callbacks only get one chance to run, we do not have - // to maintain a list. - typedef std::vector<LLChainInfo> callbacks_t; - callbacks_t mPendingCallbacks; - callbacks_t mCallbacks; - - // memory allocator for pollsets & mutexes. - apr_pool_t* mPool; - apr_pool_t* mCurrentPool; - S32 mCurrentPoolReallocCount; + /** + * @brief State of the pump + */ + enum EState + { + NORMAL, + PAUSING, + PAUSED + }; + + // instance data + EState mState; + bool mRebuildPollset; + apr_pollset_t* mPollset; + S32 mPollsetClientID; + S32 mNextLock; + std::set<S32> mClearLocks; + + // This is the pump's runnable scheduler used for handling + // expiring locks. + LLRunner mRunner; + + // This structure is the stuff we track while running chains. + struct LLChainInfo + { + // methods + LLChainInfo(); + void setTimeoutSeconds(F32 timeout); + void adjustTimeoutSeconds(F32 delta); + + // basic member data + bool mInit; + bool mEOS; + bool mHasCurlRequest; + S32 mLock; + LLFrameTimer mTimer; + links_t::iterator mHead; + links_t mChainLinks; + LLIOPipe::buffer_ptr_t mData; + LLSD mContext; + + // tracking inside the pump + typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; + typedef std::vector<pipe_conditional_t> conditionals_t; + conditionals_t mDescriptors; + }; + + // All the running chains & info + typedef std::vector<LLChainInfo> pending_chains_t; + pending_chains_t mPendingChains; + typedef std::list<LLChainInfo> running_chains_t; + running_chains_t mRunningChains; + + typedef running_chains_t::iterator current_chain_t; + current_chain_t mCurrentChain; + + // structures necessary for doing callbacks + // since the callbacks only get one chance to run, we do not have + // to maintain a list. + typedef std::vector<LLChainInfo> callbacks_t; + callbacks_t mPendingCallbacks; + callbacks_t mCallbacks; + + // memory allocator for pollsets & mutexes. + apr_pool_t* mPool; + apr_pool_t* mCurrentPool; + S32 mCurrentPoolReallocCount; protected: - void initialize(apr_pool_t* pool); - void cleanup(); - current_chain_t removeRunningChain(current_chain_t& chain) ; - /** - * @brief Given the internal state of the chains, rebuild the pollset - * @see setConditional() - */ - void rebuildPollset(); - - /** - * @brief Process the chain passed in. - * - * This method will potentially modify the internals of the - * chain. On end, the chain.mHead will equal - * chain.mChainLinks.end(). - * @param chain The LLChainInfo object to work on. - */ - void processChain(LLChainInfo& chain); - - /** - * @brief Rewind through the chain to try to recover from an error. - * - * This method will potentially modify the internals of the - * chain. - * @param chain The LLChainInfo object to work on. - * @return Retuns true if someone handled the error - */ - bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error); - - //if the chain is expired, remove it - bool isChainExpired(LLChainInfo& chain) ; + void initialize(apr_pool_t* pool); + void cleanup(); + current_chain_t removeRunningChain(current_chain_t& chain) ; + /** + * @brief Given the internal state of the chains, rebuild the pollset + * @see setConditional() + */ + void rebuildPollset(); + + /** + * @brief Process the chain passed in. + * + * This method will potentially modify the internals of the + * chain. On end, the chain.mHead will equal + * chain.mChainLinks.end(). + * @param chain The LLChainInfo object to work on. + */ + void processChain(LLChainInfo& chain); + + /** + * @brief Rewind through the chain to try to recover from an error. + * + * This method will potentially modify the internals of the + * chain. + * @param chain The LLChainInfo object to work on. + * @return Retuns true if someone handled the error + */ + bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error); + + //if the chain is expired, remove it + bool isChainExpired(LLChainInfo& chain) ; public: - /** - * @brief Return number of running chains. - * - * *NOTE: This is only used in debugging and not considered - * efficient or safe enough for production use. - */ - running_chains_t::size_type runningChains() const - { - return mRunningChains.size(); - } + /** + * @brief Return number of running chains. + * + * *NOTE: This is only used in debugging and not considered + * efficient or safe enough for production use. + */ + running_chains_t::size_type runningChains() const + { + return mRunningChains.size(); + } }; diff --git a/indra/llmessage/llqueryflags.h b/indra/llmessage/llqueryflags.h index 14a62de04f..227d28ba5c 100644 --- a/indra/llmessage/llqueryflags.h +++ b/indra/llmessage/llqueryflags.h @@ -1,25 +1,25 @@ -/** +/** * @file llqueryflags.h * @brief Flags for directory queries * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,73 +30,73 @@ // Binary flags used for Find queries, shared between viewer and dataserver. // DirFindQuery flags -const U32 DFQ_PEOPLE = 0x1 << 0; -const U32 DFQ_ONLINE = 0x1 << 1; -//const U32 DFQ_PLACES = 0x1 << 2; -const U32 DFQ_EVENTS = 0x1 << 3; // This is not set by the 1.21 viewer, but I don't know about older versions. JC -const U32 DFQ_GROUPS = 0x1 << 4; -const U32 DFQ_DATE_EVENTS = 0x1 << 5; +const U32 DFQ_PEOPLE = 0x1 << 0; +const U32 DFQ_ONLINE = 0x1 << 1; +//const U32 DFQ_PLACES = 0x1 << 2; +const U32 DFQ_EVENTS = 0x1 << 3; // This is not set by the 1.21 viewer, but I don't know about older versions. JC +const U32 DFQ_GROUPS = 0x1 << 4; +const U32 DFQ_DATE_EVENTS = 0x1 << 5; -const U32 DFQ_AGENT_OWNED = 0x1 << 6; -const U32 DFQ_FOR_SALE = 0x1 << 7; -const U32 DFQ_GROUP_OWNED = 0x1 << 8; -//const U32 DFQ_AUCTION = 0x1 << 9; -const U32 DFQ_DWELL_SORT = 0x1 << 10; -const U32 DFQ_PG_SIMS_ONLY = 0x1 << 11; -const U32 DFQ_PICTURES_ONLY = 0x1 << 12; -const U32 DFQ_PG_EVENTS_ONLY = 0x1 << 13; +const U32 DFQ_AGENT_OWNED = 0x1 << 6; +const U32 DFQ_FOR_SALE = 0x1 << 7; +const U32 DFQ_GROUP_OWNED = 0x1 << 8; +//const U32 DFQ_AUCTION = 0x1 << 9; +const U32 DFQ_DWELL_SORT = 0x1 << 10; +const U32 DFQ_PG_SIMS_ONLY = 0x1 << 11; +const U32 DFQ_PICTURES_ONLY = 0x1 << 12; +const U32 DFQ_PG_EVENTS_ONLY = 0x1 << 13; const U32 DFQ_MATURE_SIMS_ONLY = 0x1 << 14; -const U32 DFQ_SORT_ASC = 0x1 << 15; -const U32 DFQ_PRICE_SORT = 0x1 << 16; -const U32 DFQ_PER_METER_SORT = 0x1 << 17; -const U32 DFQ_AREA_SORT = 0x1 << 18; -const U32 DFQ_NAME_SORT = 0x1 << 19; +const U32 DFQ_SORT_ASC = 0x1 << 15; +const U32 DFQ_PRICE_SORT = 0x1 << 16; +const U32 DFQ_PER_METER_SORT = 0x1 << 17; +const U32 DFQ_AREA_SORT = 0x1 << 18; +const U32 DFQ_NAME_SORT = 0x1 << 19; -const U32 DFQ_LIMIT_BY_PRICE = 0x1 << 20; -const U32 DFQ_LIMIT_BY_AREA = 0x1 << 21; +const U32 DFQ_LIMIT_BY_PRICE = 0x1 << 20; +const U32 DFQ_LIMIT_BY_AREA = 0x1 << 21; -const U32 DFQ_FILTER_MATURE = 0x1 << 22; -const U32 DFQ_PG_PARCELS_ONLY = 0x1 << 23; +const U32 DFQ_FILTER_MATURE = 0x1 << 22; +const U32 DFQ_PG_PARCELS_ONLY = 0x1 << 23; -const U32 DFQ_INC_PG = 0x1 << 24; // Flags appear in 1.23 viewer or later -const U32 DFQ_INC_MATURE = 0x1 << 25; -const U32 DFQ_INC_ADULT = 0x1 << 26; -const U32 DFQ_INC_NEW_VIEWER = (DFQ_INC_PG | DFQ_INC_MATURE | DFQ_INC_ADULT); // Indicates 1.23 viewer or later +const U32 DFQ_INC_PG = 0x1 << 24; // Flags appear in 1.23 viewer or later +const U32 DFQ_INC_MATURE = 0x1 << 25; +const U32 DFQ_INC_ADULT = 0x1 << 26; +const U32 DFQ_INC_NEW_VIEWER = (DFQ_INC_PG | DFQ_INC_MATURE | DFQ_INC_ADULT); // Indicates 1.23 viewer or later -const U32 DFQ_ADULT_SIMS_ONLY = 0x1 << 27; +const U32 DFQ_ADULT_SIMS_ONLY = 0x1 << 27; // Sell Type flags -const U32 ST_AUCTION = 0x1 << 1; -const U32 ST_NEWBIE = 0x1 << 2; -const U32 ST_MAINLAND = 0x1 << 3; -const U32 ST_ESTATE = 0x1 << 4; +const U32 ST_AUCTION = 0x1 << 1; +const U32 ST_NEWBIE = 0x1 << 2; +const U32 ST_MAINLAND = 0x1 << 3; +const U32 ST_ESTATE = 0x1 << 4; -const U32 ST_ALL = 0xFFFFFFFF; +const U32 ST_ALL = 0xFFFFFFFF; // status flags embedded in search replay messages of classifieds, events, groups, and places. // Places -const U32 STATUS_SEARCH_PLACES_NONE = 0x0; -const U32 STATUS_SEARCH_PLACES_BANNEDWORD = 0x1 << 0; -const U32 STATUS_SEARCH_PLACES_SHORTSTRING = 0x1 << 1; -const U32 STATUS_SEARCH_PLACES_FOUNDNONE = 0x1 << 2; -const U32 STATUS_SEARCH_PLACES_SEARCHDISABLED = 0x1 << 3; -const U32 STATUS_SEARCH_PLACES_ESTATEEMPTY = 0x1 << 4; +const U32 STATUS_SEARCH_PLACES_NONE = 0x0; +const U32 STATUS_SEARCH_PLACES_BANNEDWORD = 0x1 << 0; +const U32 STATUS_SEARCH_PLACES_SHORTSTRING = 0x1 << 1; +const U32 STATUS_SEARCH_PLACES_FOUNDNONE = 0x1 << 2; +const U32 STATUS_SEARCH_PLACES_SEARCHDISABLED = 0x1 << 3; +const U32 STATUS_SEARCH_PLACES_ESTATEEMPTY = 0x1 << 4; // Events -const U32 STATUS_SEARCH_EVENTS_NONE = 0x0; -const U32 STATUS_SEARCH_EVENTS_BANNEDWORD = 0x1 << 0; -const U32 STATUS_SEARCH_EVENTS_SHORTSTRING = 0x1 << 1; -const U32 STATUS_SEARCH_EVENTS_FOUNDNONE = 0x1 << 2; -const U32 STATUS_SEARCH_EVENTS_SEARCHDISABLED = 0x1 << 3; -const U32 STATUS_SEARCH_EVENTS_NODATEOFFSET = 0x1 << 4; -const U32 STATUS_SEARCH_EVENTS_NOCATEGORY = 0x1 << 5; -const U32 STATUS_SEARCH_EVENTS_NOQUERY = 0x1 << 6; +const U32 STATUS_SEARCH_EVENTS_NONE = 0x0; +const U32 STATUS_SEARCH_EVENTS_BANNEDWORD = 0x1 << 0; +const U32 STATUS_SEARCH_EVENTS_SHORTSTRING = 0x1 << 1; +const U32 STATUS_SEARCH_EVENTS_FOUNDNONE = 0x1 << 2; +const U32 STATUS_SEARCH_EVENTS_SEARCHDISABLED = 0x1 << 3; +const U32 STATUS_SEARCH_EVENTS_NODATEOFFSET = 0x1 << 4; +const U32 STATUS_SEARCH_EVENTS_NOCATEGORY = 0x1 << 5; +const U32 STATUS_SEARCH_EVENTS_NOQUERY = 0x1 << 6; //Classifieds -const U32 STATUS_SEARCH_CLASSIFIEDS_NONE = 0x0; -const U32 STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD = 0x1 << 0; -const U32 STATUS_SEARCH_CLASSIFIEDS_SHORTSTRING = 0x1 << 1; -const U32 STATUS_SEARCH_CLASSIFIEDS_FOUNDNONE = 0x1 << 2; -const U32 STATUS_SEARCH_CLASSIFIEDS_SEARCHDISABLED = 0x1 << 3; +const U32 STATUS_SEARCH_CLASSIFIEDS_NONE = 0x0; +const U32 STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD = 0x1 << 0; +const U32 STATUS_SEARCH_CLASSIFIEDS_SHORTSTRING = 0x1 << 1; +const U32 STATUS_SEARCH_CLASSIFIEDS_FOUNDNONE = 0x1 << 2; +const U32 STATUS_SEARCH_CLASSIFIEDS_SEARCHDISABLED = 0x1 << 3; #endif diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index ab2d127f6e..4f23c4d160 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -1,25 +1,25 @@ -/** +/** * @file llregionflags.h * @brief Flags that are sent in the statistics message region_flags field. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,108 +28,108 @@ #define LL_LLREGIONFLAGS_H // Can you be hurt here? Should health be on? -const U64 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0); +const U64 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0); // Can you make landmarks here? -const U64 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1); +const U64 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1); // Do we reset the home position when someone teleports away from here? -const U64 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2); +const U64 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2); // Do we reset the home position when someone teleports away from here? -const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3); +const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3); // Does the sun move? -const U64 REGION_FLAGS_SUN_FIXED = (1 << 4); +const U64 REGION_FLAGS_SUN_FIXED = (1 << 4); // Does the estate owner allow private parcels? const U64 REGION_FLAGS_ALLOW_ACCESS_OVERRIDE = (1 << 5); // Can't change the terrain heightfield, even on owned parcels, // but can plant trees and grass. -const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6); +const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6); // Can't release, sell, or buy land. -const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); +const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); // All content wiped once per night -const U64 REGION_FLAGS_SANDBOX = (1 << 8); +const U64 REGION_FLAGS_SANDBOX = (1 << 8); const U64 REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE = (1 << 9); -const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies -const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); -const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics -const U64 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); +const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies +const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); +const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics +const U64 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16); const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17); -const U64 REGION_FLAGS_BLOCK_DWELL = (1 << 18); +const U64 REGION_FLAGS_BLOCK_DWELL = (1 << 18); // Is flight allowed? -const U64 REGION_FLAGS_BLOCK_FLY = (1 << 19); +const U64 REGION_FLAGS_BLOCK_FLY = (1 << 19); // Is direct teleport (p2p) allowed? -const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20); +const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20); // Is there an administrative override on scripts in the region at the // moment. This is the similar skip scripts, except this flag is // presisted in the database on an estate level. -const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21); +const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21); -const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22); +const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22); -const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); +const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); -const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); +const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); const U64 REGION_FLAGS_BLOCK_FLYOVER = (1 << 27); const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28); const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); -const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); +const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); const U64 REGION_FLAGS_DENY_BOTS = (1 << 31); const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK | - REGION_FLAGS_ALLOW_SET_HOME | + REGION_FLAGS_ALLOW_SET_HOME | REGION_FLAGS_ALLOW_PARCEL_CHANGES | REGION_FLAGS_ALLOW_VOICE; const U64 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT; -const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK - | REGION_FLAGS_ALLOW_SET_HOME; +const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK + | REGION_FLAGS_ALLOW_SET_HOME; const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE - | REGION_FLAGS_SUN_FIXED - | REGION_FLAGS_DENY_ANONYMOUS - | REGION_FLAGS_DENY_AGEUNVERIFIED; + | REGION_FLAGS_SUN_FIXED + | REGION_FLAGS_DENY_ANONYMOUS + | REGION_FLAGS_DENY_AGEUNVERIFIED; inline bool is_flag_set(U64 flags, U64 flag) { - return (flags & flag) != 0; + return (flags & flag) != 0; } inline bool is_prelude( U64 flags ) { - // definition of prelude does not depend on fixed-sun - return !is_flag_set(flags, REGION_FLAGS_PRELUDE_UNSET) && - is_flag_set(flags, REGION_FLAGS_PRELUDE_SET); + // definition of prelude does not depend on fixed-sun + return !is_flag_set(flags, REGION_FLAGS_PRELUDE_UNSET) && + is_flag_set(flags, REGION_FLAGS_PRELUDE_SET); } inline U64 set_prelude_flags(U64 flags) { - // also set the sun-fixed flag - return ((flags & ~REGION_FLAGS_PRELUDE_UNSET) - | (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); + // also set the sun-fixed flag + return ((flags & ~REGION_FLAGS_PRELUDE_UNSET) + | (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); } inline U64 unset_prelude_flags(U64 flags) { - // also unset the fixed-sun flag - return ((flags | REGION_FLAGS_PRELUDE_UNSET) - & ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); + // also unset the fixed-sun flag + return ((flags | REGION_FLAGS_PRELUDE_UNSET) + & ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); } // Region protocols @@ -145,10 +145,10 @@ const U32 ESTATE_TEEN = 5; const U32 ESTATE_LAST_LINDEN = 5; // last linden owned/managed estate // for EstateOwnerRequest, setaccess message -const U32 ESTATE_ACCESS_ALLOWED_AGENTS = 1 << 0; -const U32 ESTATE_ACCESS_ALLOWED_GROUPS = 1 << 1; -const U32 ESTATE_ACCESS_BANNED_AGENTS = 1 << 2; -const U32 ESTATE_ACCESS_MANAGERS = 1 << 3; +const U32 ESTATE_ACCESS_ALLOWED_AGENTS = 1 << 0; +const U32 ESTATE_ACCESS_ALLOWED_GROUPS = 1 << 1; +const U32 ESTATE_ACCESS_BANNED_AGENTS = 1 << 2; +const U32 ESTATE_ACCESS_MANAGERS = 1 << 3; //maximum number of access list entries we can fit in one packet const S32 ESTATE_ACCESS_MAX_ENTRIES_PER_PACKET = 63; @@ -157,51 +157,51 @@ const S32 ESTATE_ACCESS_MAX_ENTRIES_PER_PACKET = 63; const U32 ESTATE_ACCESS_SEND_TO_AGENT_ONLY = 1 << 4; const U32 ESTATE_ACCESS_ALL = ESTATE_ACCESS_ALLOWED_AGENTS - | ESTATE_ACCESS_ALLOWED_GROUPS - | ESTATE_ACCESS_BANNED_AGENTS - | ESTATE_ACCESS_MANAGERS; + | ESTATE_ACCESS_ALLOWED_GROUPS + | ESTATE_ACCESS_BANNED_AGENTS + | ESTATE_ACCESS_MANAGERS; // for EstateOwnerRequest, estateaccessdelta, estateexperiencedelta messages -const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1U << 0; -const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1U << 1; - -const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1U << 2; -const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1U << 3; -const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1U << 4; -const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1U << 5; -const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1U << 6; -const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1U << 7; -const U32 ESTATE_ACCESS_MANAGER_ADD = 1U << 8; -const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9; -const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10; -const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11; +const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1U << 0; +const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1U << 1; + +const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1U << 2; +const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1U << 3; +const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1U << 4; +const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1U << 5; +const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1U << 6; +const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1U << 7; +const U32 ESTATE_ACCESS_MANAGER_ADD = 1U << 8; +const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9; +const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10; +const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11; const S32 ESTATE_MAX_MANAGERS = 20; -const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access -const S32 ESTATE_MAX_BANNED_IDS = 750; // max for banned +const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access +const S32 ESTATE_MAX_BANNED_IDS = 750; // max for banned const S32 ESTATE_MAX_GROUP_IDS = (S32) ESTATE_ACCESS_MAX_ENTRIES_PER_PACKET; // 'Sim Wide Delete' flags -const U32 SWD_OTHERS_LAND_ONLY = (1 << 0); +const U32 SWD_OTHERS_LAND_ONLY = (1 << 0); const U32 SWD_ALWAYS_RETURN_OBJECTS = (1 << 1); -const U32 SWD_SCRIPTED_ONLY = (1 << 2); +const U32 SWD_SCRIPTED_ONLY = (1 << 2); // Controls experience key validity in the estate -const U32 EXPERIENCE_KEY_TYPE_NONE = 0; -const U32 EXPERIENCE_KEY_TYPE_BLOCKED = 1; -const U32 EXPERIENCE_KEY_TYPE_ALLOWED = 2; -const U32 EXPERIENCE_KEY_TYPE_TRUSTED = 3; +const U32 EXPERIENCE_KEY_TYPE_NONE = 0; +const U32 EXPERIENCE_KEY_TYPE_BLOCKED = 1; +const U32 EXPERIENCE_KEY_TYPE_ALLOWED = 2; +const U32 EXPERIENCE_KEY_TYPE_TRUSTED = 3; -const U32 EXPERIENCE_KEY_TYPE_FIRST = EXPERIENCE_KEY_TYPE_BLOCKED; -const U32 EXPERIENCE_KEY_TYPE_LAST = EXPERIENCE_KEY_TYPE_TRUSTED; +const U32 EXPERIENCE_KEY_TYPE_FIRST = EXPERIENCE_KEY_TYPE_BLOCKED; +const U32 EXPERIENCE_KEY_TYPE_LAST = EXPERIENCE_KEY_TYPE_TRUSTED; // -const U32 ESTATE_EXPERIENCE_TRUSTED_ADD = 1U << 2; -const U32 ESTATE_EXPERIENCE_TRUSTED_REMOVE = 1U << 3; -const U32 ESTATE_EXPERIENCE_ALLOWED_ADD = 1U << 4; -const U32 ESTATE_EXPERIENCE_ALLOWED_REMOVE = 1U << 5; -const U32 ESTATE_EXPERIENCE_BLOCKED_ADD = 1U << 6; -const U32 ESTATE_EXPERIENCE_BLOCKED_REMOVE = 1U << 7; +const U32 ESTATE_EXPERIENCE_TRUSTED_ADD = 1U << 2; +const U32 ESTATE_EXPERIENCE_TRUSTED_REMOVE = 1U << 3; +const U32 ESTATE_EXPERIENCE_ALLOWED_ADD = 1U << 4; +const U32 ESTATE_EXPERIENCE_ALLOWED_REMOVE = 1U << 5; +const U32 ESTATE_EXPERIENCE_BLOCKED_ADD = 1U << 6; +const U32 ESTATE_EXPERIENCE_BLOCKED_REMOVE = 1U << 7; const S32 ESTATE_MAX_EXPERIENCE_IDS = 8; diff --git a/indra/llmessage/llregionhandle.h b/indra/llmessage/llregionhandle.h index 284426c148..d68cd4d202 100644 --- a/indra/llmessage/llregionhandle.h +++ b/indra/llmessage/llregionhandle.h @@ -1,25 +1,25 @@ -/** +/** * @file llregionhandle.h * @brief Routines for converting positions to/from region handles. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,94 +33,94 @@ inline U64 to_region_handle(const U32 x_origin, const U32 y_origin) { - U64 region_handle; - region_handle = ((U64)x_origin) << 32; - region_handle |= (U64) y_origin; - return region_handle; + U64 region_handle; + region_handle = ((U64)x_origin) << 32; + region_handle |= (U64) y_origin; + return region_handle; } inline U64 to_region_handle(const LLVector3d& pos_global) { - U32 global_x = (U32)pos_global.mdV[VX]; - global_x -= global_x % 256; + U32 global_x = (U32)pos_global.mdV[VX]; + global_x -= global_x % 256; - U32 global_y = (U32)pos_global.mdV[VY]; - global_y -= global_y % 256; + U32 global_y = (U32)pos_global.mdV[VY]; + global_y -= global_y % 256; - return to_region_handle(global_x, global_y); + return to_region_handle(global_x, global_y); } inline U64 to_region_handle_global(const F32 x_global, const F32 y_global) { - // Round down to the nearest origin - U32 x_origin = (U32)x_global; - x_origin -= x_origin % REGION_WIDTH_U32; - U32 y_origin = (U32)y_global; - y_origin -= y_origin % REGION_WIDTH_U32; - U64 region_handle; - region_handle = ((U64)x_origin) << 32; - region_handle |= (U64) y_origin; - return region_handle; + // Round down to the nearest origin + U32 x_origin = (U32)x_global; + x_origin -= x_origin % REGION_WIDTH_U32; + U32 y_origin = (U32)y_global; + y_origin -= y_origin % REGION_WIDTH_U32; + U64 region_handle; + region_handle = ((U64)x_origin) << 32; + region_handle |= (U64) y_origin; + return region_handle; } inline bool to_region_handle(const F32 x_pos, const F32 y_pos, U64 *region_handle) { - U32 x_int, y_int; - if (x_pos < 0.f) - { -// LL_WARNS() << "to_region_handle:Clamping negative x position " << x_pos << " to zero!" << LL_ENDL; - return false; - } - else - { - x_int = (U32)ll_round(x_pos); - } - if (y_pos < 0.f) - { -// LL_WARNS() << "to_region_handle:Clamping negative y position " << y_pos << " to zero!" << LL_ENDL; - return false; - } - else - { - y_int = (U32)ll_round(y_pos); - } - *region_handle = to_region_handle(x_int, y_int); - return true; + U32 x_int, y_int; + if (x_pos < 0.f) + { +// LL_WARNS() << "to_region_handle:Clamping negative x position " << x_pos << " to zero!" << LL_ENDL; + return false; + } + else + { + x_int = (U32)ll_round(x_pos); + } + if (y_pos < 0.f) + { +// LL_WARNS() << "to_region_handle:Clamping negative y position " << y_pos << " to zero!" << LL_ENDL; + return false; + } + else + { + y_int = (U32)ll_round(y_pos); + } + *region_handle = to_region_handle(x_int, y_int); + return true; } // stuff the word-frame XY location of sim's SouthWest corner in x_pos, y_pos inline void from_region_handle(const U64 ®ion_handle, F32 *x_pos, F32 *y_pos) { - *x_pos = (F32)((U32)(region_handle >> 32)); - *y_pos = (F32)((U32)(region_handle & 0xFFFFFFFF)); + *x_pos = (F32)((U32)(region_handle >> 32)); + *y_pos = (F32)((U32)(region_handle & 0xFFFFFFFF)); } // stuff the word-frame XY location of sim's SouthWest corner in x_pos, y_pos inline void from_region_handle(const U64 ®ion_handle, U32 *x_pos, U32 *y_pos) { - *x_pos = ((U32)(region_handle >> 32)); - *y_pos = ((U32)(region_handle & 0xFFFFFFFF)); + *x_pos = ((U32)(region_handle >> 32)); + *y_pos = ((U32)(region_handle & 0xFFFFFFFF)); } // return the word-frame XY location of sim's SouthWest corner in LLVector3d inline LLVector3d from_region_handle(const U64 ®ion_handle) { - return LLVector3d(((U32)(region_handle >> 32)), (U32)(region_handle & 0xFFFFFFFF), 0.f); + return LLVector3d(((U32)(region_handle >> 32)), (U32)(region_handle & 0xFFFFFFFF), 0.f); } // grid-based region handle encoding. pass in a grid position // (eg: 1000,1000) and this will return the region handle. inline U64 grid_to_region_handle(const U32 grid_x, const U32 grid_y) { - return to_region_handle(grid_x * REGION_WIDTH_UNITS, - grid_y * REGION_WIDTH_UNITS); + return to_region_handle(grid_x * REGION_WIDTH_UNITS, + grid_y * REGION_WIDTH_UNITS); } inline void grid_from_region_handle(const U64& region_handle, U32* grid_x, U32* grid_y) { - from_region_handle(region_handle, grid_x, grid_y); - *grid_x /= REGION_WIDTH_UNITS; - *grid_y /= REGION_WIDTH_UNITS; + from_region_handle(region_handle, grid_x, grid_y); + *grid_x /= REGION_WIDTH_UNITS; + *grid_y /= REGION_WIDTH_UNITS; } - + #endif diff --git a/indra/llmessage/llsdappservices.cpp b/indra/llmessage/llsdappservices.cpp index 4ca45267bd..065bc5196e 100644 --- a/indra/llmessage/llsdappservices.cpp +++ b/indra/llmessage/llsdappservices.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llsdappservices.cpp * @author Phoenix * @date 2006-09-12 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,244 +34,244 @@ void LLSDAppServices::useServices() { - /* - Having this function body here, causes the classes and globals in this - file to be linked into any program that uses the llmessage library. - */ + /* + Having this function body here, causes the classes and globals in this + file to be linked into any program that uses the llmessage library. + */ } class LLHTTPConfigService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("GET an array of all the options in priority order."); - desc.getAPI(); - desc.source(__FILE__, __LINE__); - } - - virtual LLSD simpleGet() const - { - LLSD result; - LLApp* app = LLApp::instance(); - for(int ii = 0; ii < LLApp::PRIORITY_COUNT; ++ii) - { - result.append(app->getOptionData((LLApp::OptionPriority)ii)); - } - return result; - } + virtual void describe(Description& desc) const + { + desc.shortInfo("GET an array of all the options in priority order."); + desc.getAPI(); + desc.source(__FILE__, __LINE__); + } + + virtual LLSD simpleGet() const + { + LLSD result; + LLApp* app = LLApp::instance(); + for(int ii = 0; ii < LLApp::PRIORITY_COUNT; ++ii) + { + result.append(app->getOptionData((LLApp::OptionPriority)ii)); + } + return result; + } }; LLHTTPRegistration<LLHTTPConfigService> - gHTTPRegistratiAppConfig("/app/config"); + gHTTPRegistratiAppConfig("/app/config"); class LLHTTPConfigRuntimeService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("Manipulate a map of runtime-override options."); - desc.getAPI(); - desc.postAPI(); - desc.source(__FILE__, __LINE__); - } - - virtual LLSD simpleGet() const - { - return LLApp::instance()->getOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE); - } + virtual void describe(Description& desc) const + { + desc.shortInfo("Manipulate a map of runtime-override options."); + desc.getAPI(); + desc.postAPI(); + desc.source(__FILE__, __LINE__); + } + + virtual LLSD simpleGet() const + { + return LLApp::instance()->getOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE); + } - virtual void post( - LLHTTPNode::ResponsePtr response, - const LLSD& context, - const LLSD& input) const - { - LLSD result = LLApp::instance()->getOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE); - LLSD::map_const_iterator iter = input.beginMap(); - LLSD::map_const_iterator end = input.endMap(); - for(; iter != end; ++iter) - { - result[(*iter).first] = (*iter).second; - } - LLApp::instance()->setOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE, - result); - response->result(result); - } + virtual void post( + LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + LLSD result = LLApp::instance()->getOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE); + LLSD::map_const_iterator iter = input.beginMap(); + LLSD::map_const_iterator end = input.endMap(); + for(; iter != end; ++iter) + { + result[(*iter).first] = (*iter).second; + } + LLApp::instance()->setOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE, + result); + response->result(result); + } }; LLHTTPRegistration<LLHTTPConfigRuntimeService> - gHTTPRegistrationRuntimeConfig("/app/config/runtime-override"); + gHTTPRegistrationRuntimeConfig("/app/config/runtime-override"); class LLHTTPConfigRuntimeSingleService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("Manipulate a single runtime-override option."); - desc.getAPI(); - desc.putAPI(); - desc.delAPI(); - desc.source(__FILE__, __LINE__); - } - - virtual bool validate(const std::string& name, LLSD& context) const - { - //LL_INFOS() << "validate: " << name << ", " - // << LLSDOStreamer<LLSDNotationFormatter>(context) << LL_ENDL; - if((std::string("PUT") == context[CONTEXT_REQUEST][CONTEXT_VERB].asString()) && !name.empty()) - { - return true; - } - else - { - // This is for GET and DELETE - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE); - if(options.has(name)) return true; - else return false; - } - } + virtual void describe(Description& desc) const + { + desc.shortInfo("Manipulate a single runtime-override option."); + desc.getAPI(); + desc.putAPI(); + desc.delAPI(); + desc.source(__FILE__, __LINE__); + } + + virtual bool validate(const std::string& name, LLSD& context) const + { + //LL_INFOS() << "validate: " << name << ", " + // << LLSDOStreamer<LLSDNotationFormatter>(context) << LL_ENDL; + if((std::string("PUT") == context[CONTEXT_REQUEST][CONTEXT_VERB].asString()) && !name.empty()) + { + return true; + } + else + { + // This is for GET and DELETE + LLSD options = LLApp::instance()->getOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE); + if(options.has(name)) return true; + else return false; + } + } - virtual void get( - LLHTTPNode::ResponsePtr response, - const LLSD& context) const - { - std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE); - response->result(options[name]); - } + virtual void get( + LLHTTPNode::ResponsePtr response, + const LLSD& context) const + { + std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; + LLSD options = LLApp::instance()->getOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE); + response->result(options[name]); + } - virtual void put( - LLHTTPNode::ResponsePtr response, - const LLSD& context, - const LLSD& input) const - { - std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE); - options[name] = input; - LLApp::instance()->setOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE, - options); - response->result(input); - } + virtual void put( + LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; + LLSD options = LLApp::instance()->getOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE); + options[name] = input; + LLApp::instance()->setOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE, + options); + response->result(input); + } - virtual void del( - LLHTTPNode::ResponsePtr response, - const LLSD& context) const - { - std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE); - options.erase(name); - LLApp::instance()->setOptionData( - LLApp::PRIORITY_RUNTIME_OVERRIDE, - options); - response->result(LLSD()); - } + virtual void del( + LLHTTPNode::ResponsePtr response, + const LLSD& context) const + { + std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; + LLSD options = LLApp::instance()->getOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE); + options.erase(name); + LLApp::instance()->setOptionData( + LLApp::PRIORITY_RUNTIME_OVERRIDE, + options); + response->result(LLSD()); + } }; LLHTTPRegistration<LLHTTPConfigRuntimeSingleService> - gHTTPRegistrationRuntimeSingleConfig( - "/app/config/runtime-override/<option-name>"); + gHTTPRegistrationRuntimeSingleConfig( + "/app/config/runtime-override/<option-name>"); template<int PRIORITY> class LLHTTPConfigPriorityService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("Get a map of the options at this priority."); - desc.getAPI(); - desc.source(__FILE__, __LINE__); - } + virtual void describe(Description& desc) const + { + desc.shortInfo("Get a map of the options at this priority."); + desc.getAPI(); + desc.source(__FILE__, __LINE__); + } - virtual void get( - LLHTTPNode::ResponsePtr response, - const LLSD& context) const - { - response->result(LLApp::instance()->getOptionData( - (LLApp::OptionPriority)PRIORITY)); - } + virtual void get( + LLHTTPNode::ResponsePtr response, + const LLSD& context) const + { + response->result(LLApp::instance()->getOptionData( + (LLApp::OptionPriority)PRIORITY)); + } }; LLHTTPRegistration< LLHTTPConfigPriorityService<LLApp::PRIORITY_COMMAND_LINE> > - gHTTPRegistrationCommandLineConfig("/app/config/command-line"); + gHTTPRegistrationCommandLineConfig("/app/config/command-line"); LLHTTPRegistration< - LLHTTPConfigPriorityService<LLApp::PRIORITY_SPECIFIC_CONFIGURATION> > - gHTTPRegistrationSpecificConfig("/app/config/specific"); + LLHTTPConfigPriorityService<LLApp::PRIORITY_SPECIFIC_CONFIGURATION> > + gHTTPRegistrationSpecificConfig("/app/config/specific"); LLHTTPRegistration< - LLHTTPConfigPriorityService<LLApp::PRIORITY_GENERAL_CONFIGURATION> > - gHTTPRegistrationGeneralConfig("/app/config/general"); + LLHTTPConfigPriorityService<LLApp::PRIORITY_GENERAL_CONFIGURATION> > + gHTTPRegistrationGeneralConfig("/app/config/general"); LLHTTPRegistration< LLHTTPConfigPriorityService<LLApp::PRIORITY_DEFAULT> > - gHTTPRegistrationDefaultConfig("/app/config/default"); + gHTTPRegistrationDefaultConfig("/app/config/default"); class LLHTTPLiveConfigService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("Get a map of the currently live options."); - desc.getAPI(); - desc.source(__FILE__, __LINE__); - } + virtual void describe(Description& desc) const + { + desc.shortInfo("Get a map of the currently live options."); + desc.getAPI(); + desc.source(__FILE__, __LINE__); + } - virtual void get( - LLHTTPNode::ResponsePtr response, - const LLSD& context) const - { - LLSD result; - LLApp* app = LLApp::instance(); - LLSD::map_const_iterator iter; - LLSD::map_const_iterator end; - for(int ii = LLApp::PRIORITY_COUNT - 1; ii >= 0; --ii) - { - LLSD options = app->getOptionData((LLApp::OptionPriority)ii); - iter = options.beginMap(); - end = options.endMap(); - for(; iter != end; ++iter) - { - result[(*iter).first] = (*iter).second; - } - } - response->result(result); - } + virtual void get( + LLHTTPNode::ResponsePtr response, + const LLSD& context) const + { + LLSD result; + LLApp* app = LLApp::instance(); + LLSD::map_const_iterator iter; + LLSD::map_const_iterator end; + for(int ii = LLApp::PRIORITY_COUNT - 1; ii >= 0; --ii) + { + LLSD options = app->getOptionData((LLApp::OptionPriority)ii); + iter = options.beginMap(); + end = options.endMap(); + for(; iter != end; ++iter) + { + result[(*iter).first] = (*iter).second; + } + } + response->result(result); + } }; LLHTTPRegistration<LLHTTPLiveConfigService> - gHTTPRegistrationLiveConfig("/app/config/live"); + gHTTPRegistrationLiveConfig("/app/config/live"); class LLHTTPLiveConfigSingleService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("Get the named live option."); - desc.getAPI(); - desc.source(__FILE__, __LINE__); - } + virtual void describe(Description& desc) const + { + desc.shortInfo("Get the named live option."); + desc.getAPI(); + desc.source(__FILE__, __LINE__); + } - virtual bool validate(const std::string& name, LLSD& context) const - { - LL_INFOS() << "LLHTTPLiveConfigSingleService::validate(" << name - << ")" << LL_ENDL; - LLSD option = LLApp::instance()->getOption(name); - if(option.isDefined()) return true; - else return false; - } + virtual bool validate(const std::string& name, LLSD& context) const + { + LL_INFOS() << "LLHTTPLiveConfigSingleService::validate(" << name + << ")" << LL_ENDL; + LLSD option = LLApp::instance()->getOption(name); + if(option.isDefined()) return true; + else return false; + } - virtual void get( - LLHTTPNode::ResponsePtr response, - const LLSD& context) const - { - std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; - response->result(LLApp::instance()->getOption(name)); - } + virtual void get( + LLHTTPNode::ResponsePtr response, + const LLSD& context) const + { + std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["option-name"]; + response->result(LLApp::instance()->getOption(name)); + } }; LLHTTPRegistration<LLHTTPLiveConfigSingleService> - gHTTPRegistrationLiveSingleConfig("/app/config/live/<option-name>"); + gHTTPRegistrationLiveSingleConfig("/app/config/live/<option-name>"); diff --git a/indra/llmessage/llsdappservices.h b/indra/llmessage/llsdappservices.h index e76e20cea9..6b3b7c0da3 100644 --- a/indra/llmessage/llsdappservices.h +++ b/indra/llmessage/llsdappservices.h @@ -1,4 +1,4 @@ -/** +/** * @file llsdappservices.h * @author Phoenix * @date 2006-09-12 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,7 +29,7 @@ #ifndef LL_LLSDAPPSERVICES_H #define LL_LLSDAPPSERVICES_H -/** +/** * @class LLSDAppServices * @brief This class forces a link to llsdappservices if the static * method is called which declares the /app web services. @@ -37,21 +37,21 @@ class LLSDAppServices { public: - /** - * @brief Call this method to declare the /app common web services. - * - * This will register: - * /app/config - * /app/config/runtime-override - * /app/config/runtime-override/<option-name> - * /app/config/command-line - * /app/config/specific - * /app/config/general - * /app/config/default - * /app/config/live - * /app/config/live/<option-name> - */ - static void useServices(); + /** + * @brief Call this method to declare the /app common web services. + * + * This will register: + * /app/config + * /app/config/runtime-override + * /app/config/runtime-override/<option-name> + * /app/config/command-line + * /app/config/specific + * /app/config/general + * /app/config/default + * /app/config/live + * /app/config/live/<option-name> + */ + static void useServices(); }; diff --git a/indra/llmessage/llsdhttpserver.cpp b/indra/llmessage/llsdhttpserver.cpp index 8ac6b3cb12..35f3a45ed6 100644 --- a/indra/llmessage/llsdhttpserver.cpp +++ b/indra/llmessage/llsdhttpserver.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llsdhttpserver.cpp * @brief Standard LLSD services * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,7 +29,7 @@ #include "llhttpnode.h" -/** +/** * This module implements common services that should be included * in all server URL trees. These services facilitate debugging and * introsepction. @@ -37,10 +37,10 @@ void LLHTTPStandardServices::useServices() { - /* - Having this function body here, causes the classes and globals in this - file to be linked into any program that uses the llmessage library. - */ + /* + Having this function body here, causes the classes and globals in this + file to be linked into any program that uses the llmessage library. + */ } @@ -48,103 +48,103 @@ void LLHTTPStandardServices::useServices() class LLHTTPHelloService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("says hello"); - desc.getAPI(); - desc.output("\"hello\""); - desc.source(__FILE__, __LINE__); - } - - virtual LLSD simpleGet() const - { - LLSD result = "hello"; - return result; - } + virtual void describe(Description& desc) const + { + desc.shortInfo("says hello"); + desc.getAPI(); + desc.output("\"hello\""); + desc.source(__FILE__, __LINE__); + } + + virtual LLSD simpleGet() const + { + LLSD result = "hello"; + return result; + } }; LLHTTPRegistration<LLHTTPHelloService> - gHTTPRegistrationWebHello("/web/hello"); + gHTTPRegistrationWebHello("/web/hello"); class LLHTTPEchoService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("echo input"); - desc.postAPI(); - desc.input("<any>"); - desc.output("<the input>"); - desc.source(__FILE__, __LINE__); - } - - virtual LLSD simplePost(const LLSD& params) const - { - return params; - } + virtual void describe(Description& desc) const + { + desc.shortInfo("echo input"); + desc.postAPI(); + desc.input("<any>"); + desc.output("<the input>"); + desc.source(__FILE__, __LINE__); + } + + virtual LLSD simplePost(const LLSD& params) const + { + return params; + } }; LLHTTPRegistration<LLHTTPEchoService> - gHTTPRegistrationWebEcho("/web/echo"); + gHTTPRegistrationWebEcho("/web/echo"); class LLAPIService : public LLHTTPNode { public: - virtual void describe(Description& desc) const - { - desc.shortInfo("information about the URLs this server supports"); - desc.getAPI(); - desc.output("a list of URLs supported"); - desc.source(__FILE__, __LINE__); - } - - virtual bool handles(const LLSD& remainder, LLSD& context) const - { - return followRemainder(remainder) != NULL; - } + virtual void describe(Description& desc) const + { + desc.shortInfo("information about the URLs this server supports"); + desc.getAPI(); + desc.output("a list of URLs supported"); + desc.source(__FILE__, __LINE__); + } + + virtual bool handles(const LLSD& remainder, LLSD& context) const + { + return followRemainder(remainder) != NULL; + } virtual void get(ResponsePtr response, const LLSD& context) const - { - const LLSD& remainder = context[CONTEXT_REQUEST]["remainder"]; - - if (remainder.size() > 0) - { - const LLHTTPNode* node = followRemainder(remainder); - if (!node) - { - response->notFound(); - return; - } - - Description desc; - node->describe(desc); - response->result(desc.getInfo()); - return; - } - - response->result(rootNode()->allNodePaths()); - } + { + const LLSD& remainder = context[CONTEXT_REQUEST]["remainder"]; + + if (remainder.size() > 0) + { + const LLHTTPNode* node = followRemainder(remainder); + if (!node) + { + response->notFound(); + return; + } + + Description desc; + node->describe(desc); + response->result(desc.getInfo()); + return; + } + + response->result(rootNode()->allNodePaths()); + } private: - const LLHTTPNode* followRemainder(const LLSD& remainder) const - { - const LLHTTPNode* node = rootNode(); - - LLSD::array_const_iterator i = remainder.beginArray(); - LLSD::array_const_iterator end = remainder.endArray(); - for (; node && i != end; ++i) - { - node = node->findNode(*i); - } - - return node; - } + const LLHTTPNode* followRemainder(const LLSD& remainder) const + { + const LLHTTPNode* node = rootNode(); + + LLSD::array_const_iterator i = remainder.beginArray(); + LLSD::array_const_iterator end = remainder.endArray(); + for (; node && i != end; ++i) + { + node = node->findNode(*i); + } + + return node; + } }; LLHTTPRegistration<LLAPIService> - gHTTPRegistrationWebServerApi("/web/server/api"); + gHTTPRegistrationWebServerApi("/web/server/api"); diff --git a/indra/llmessage/llsdhttpserver.h b/indra/llmessage/llsdhttpserver.h index 39f9204604..5d748ec73c 100644 --- a/indra/llmessage/llsdhttpserver.h +++ b/indra/llmessage/llsdhttpserver.h @@ -1,25 +1,25 @@ -/** +/** * @file llsdhttpserver.h * @brief Standard LLSD services * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -27,7 +27,7 @@ #ifndef LL_LLSDHTTPSERVER_H #define LL_LLSDHTTPSERVER_H -/** +/** * This module implements and defines common services that should be included * in all server URL trees. These services facilitate debugging and * introsepction. @@ -36,16 +36,16 @@ class LLHTTPStandardServices { public: - static void useServices(); - /**< - Having a call to this function causes the following services to be - registered: - /web/echo -- echo input - /web/hello -- return "hello" - /web/server/api -- return a list of url paths on the server - /web/server/api/<..path..> - -- return description of the path - */ + static void useServices(); + /**< + Having a call to this function causes the following services to be + registered: + /web/echo -- echo input + /web/hello -- return "hello" + /web/server/api -- return a list of url paths on the server + /web/server/api/<..path..> + -- return description of the path + */ }; #endif // LL_LLSDHTTPSERVER_H diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp index 309cf53bef..8d7d51e13f 100644 --- a/indra/llmessage/llsdmessagebuilder.cpp +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llsdmessagebuilder.cpp * @brief LLSDMessageBuilder class implementation. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,12 +40,12 @@ #include "v4math.h" LLSDMessageBuilder::LLSDMessageBuilder() : - mCurrentMessage(LLSD::emptyMap()), - mCurrentBlock(NULL), - mCurrentMessageName(""), - mCurrentBlockName(""), - mbSBuilt(false), - mbSClear(true) + mCurrentMessage(LLSD::emptyMap()), + mCurrentBlock(NULL), + mCurrentMessageName(""), + mCurrentBlockName(""), + mbSBuilt(false), + mbSClear(true) { } @@ -58,160 +58,160 @@ LLSDMessageBuilder::~LLSDMessageBuilder() // virtual void LLSDMessageBuilder::newMessage(const char* name) { - mbSBuilt = false; - mbSClear = false; + mbSBuilt = false; + mbSClear = false; - mCurrentMessage = LLSD::emptyMap(); - mCurrentMessageName = (char*)name; + mCurrentMessage = LLSD::emptyMap(); + mCurrentMessageName = (char*)name; } // virtual void LLSDMessageBuilder::clearMessage() { - mbSBuilt = false; - mbSClear = true; + mbSBuilt = false; + mbSClear = true; - mCurrentMessage = LLSD::emptyMap(); - mCurrentMessageName = ""; + mCurrentMessage = LLSD::emptyMap(); + mCurrentMessageName = ""; } // virtual void LLSDMessageBuilder::nextBlock(const char* blockname) { - LLSD& block = mCurrentMessage[blockname]; - if(block.isUndefined()) - { - block[0] = LLSD::emptyMap(); - mCurrentBlock = &(block[0]); - } - else if(block.isArray()) - { - block[block.size()] = LLSD::emptyMap(); - mCurrentBlock = &(block[block.size() - 1]); - } - else - { - LL_ERRS() << "existing block not array" << LL_ENDL; - } + LLSD& block = mCurrentMessage[blockname]; + if(block.isUndefined()) + { + block[0] = LLSD::emptyMap(); + mCurrentBlock = &(block[0]); + } + else if(block.isArray()) + { + block[block.size()] = LLSD::emptyMap(); + mCurrentBlock = &(block[block.size() - 1]); + } + else + { + LL_ERRS() << "existing block not array" << LL_ENDL; + } } // TODO: Remove this horror... bool LLSDMessageBuilder::removeLastBlock() { - /* TODO: finish implementing this */ - return false; + /* TODO: finish implementing this */ + return false; } void LLSDMessageBuilder::addBinaryData( - const char* varname, - const void* data, - S32 size) + const char* varname, + const void* data, + S32 size) { - std::vector<U8> v; - v.resize(size); - memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size); - (*mCurrentBlock)[varname] = v; + std::vector<U8> v; + v.resize(size); + memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size); + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addS8(const char* varname, S8 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addU8(const char* varname, U8 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addS16(const char* varname, S16 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addU16(const char* varname, U16 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addF32(const char* varname, F32 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addS32(const char* varname, S32 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addU32(const char* varname, U32 v) { - (*mCurrentBlock)[varname] = ll_sd_from_U32(v); + (*mCurrentBlock)[varname] = ll_sd_from_U32(v); } void LLSDMessageBuilder::addU64(const char* varname, U64 v) { - (*mCurrentBlock)[varname] = ll_sd_from_U64(v); + (*mCurrentBlock)[varname] = ll_sd_from_U64(v); } void LLSDMessageBuilder::addF64(const char* varname, F64 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addIPAddr(const char* varname, U32 v) { - (*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v); + (*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v); } void LLSDMessageBuilder::addIPPort(const char* varname, U16 v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addBOOL(const char* varname, bool v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::addString(const char* varname, const char* v) { - if (v) - (*mCurrentBlock)[varname] = v; /* Flawfinder: ignore */ - else - (*mCurrentBlock)[varname] = ""; + if (v) + (*mCurrentBlock)[varname] = v; /* Flawfinder: ignore */ + else + (*mCurrentBlock)[varname] = ""; } void LLSDMessageBuilder::addString(const char* varname, const std::string& v) { - if (v.size()) - (*mCurrentBlock)[varname] = v; - else - (*mCurrentBlock)[varname] = ""; + if (v.size()) + (*mCurrentBlock)[varname] = v; + else + (*mCurrentBlock)[varname] = ""; } void LLSDMessageBuilder::addVector3(const char* varname, const LLVector3& v) { - (*mCurrentBlock)[varname] = ll_sd_from_vector3(v); + (*mCurrentBlock)[varname] = ll_sd_from_vector3(v); } void LLSDMessageBuilder::addVector4(const char* varname, const LLVector4& v) { - (*mCurrentBlock)[varname] = ll_sd_from_vector4(v); + (*mCurrentBlock)[varname] = ll_sd_from_vector4(v); } void LLSDMessageBuilder::addVector3d(const char* varname, const LLVector3d& v) { - (*mCurrentBlock)[varname] = ll_sd_from_vector3d(v); + (*mCurrentBlock)[varname] = ll_sd_from_vector3d(v); } void LLSDMessageBuilder::addQuat(const char* varname, const LLQuaternion& v) { - (*mCurrentBlock)[varname] = ll_sd_from_quaternion(v); + (*mCurrentBlock)[varname] = ll_sd_from_quaternion(v); } void LLSDMessageBuilder::addUUID(const char* varname, const LLUUID& v) { - (*mCurrentBlock)[varname] = v; + (*mCurrentBlock)[varname] = v; } void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length) @@ -220,205 +220,205 @@ void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length) bool LLSDMessageBuilder::isMessageFull(const char* blockname) const { - return false; + return false; } U32 LLSDMessageBuilder::buildMessage(U8*, U32, U8) { - return 0; + return 0; } void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data) { - // copy the blocks - // counting variables used to encode multiple block info - S32 block_count = 0; + // copy the blocks + // counting variables used to encode multiple block info + S32 block_count = 0; char* block_name = NULL; - // loop through msg blocks to loop through variables, totalling up size - // data and filling the new (send) message - LLMsgData::msg_blk_data_map_t::const_iterator iter = - data.mMemberBlocks.begin(); - LLMsgData::msg_blk_data_map_t::const_iterator end = - data.mMemberBlocks.end(); - for(; iter != end; ++iter) - { - const LLMsgBlkData* mbci = iter->second; - if(!mbci) continue; - - // do we need to encode a block code? - if (block_count == 0) - { - block_count = mbci->mBlockNumber; - block_name = (char*)mbci->mName; - } - - // counting down mutliple blocks - block_count--; - - nextBlock(block_name); - - // now loop through the variables - LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); - LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); - - for(; dit != dend; ++dit) - { - const LLMsgVarData& mvci = *dit; - const char* varname = mvci.getName(); - - switch(mvci.getType()) - { - case MVT_FIXED: - addBinaryData(varname, mvci.getData(), mvci.getSize()); - break; - - case MVT_VARIABLE: - { - const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated - if (mvci.getDataSize() == 1 && end == 0) - { - addString(varname, (const char*)mvci.getData()); - } - else - { - addBinaryData(varname, mvci.getData(), mvci.getSize()); - } - break; - } - - case MVT_U8: - addU8(varname, *(U8*)mvci.getData()); - break; - - case MVT_U16: - addU16(varname, *(U16*)mvci.getData()); - break; - - case MVT_U32: - addU32(varname, *(U32*)mvci.getData()); - break; - - case MVT_U64: - addU64(varname, *(U64*)mvci.getData()); - break; - - case MVT_S8: - addS8(varname, *(S8*)mvci.getData()); - break; - - case MVT_S16: - addS16(varname, *(S16*)mvci.getData()); - break; - - case MVT_S32: - addS32(varname, *(S32*)mvci.getData()); - break; - - // S64 not supported in LLSD so we just truncate it - case MVT_S64: - addS32(varname, (S32)*(S64*)mvci.getData()); - break; - - case MVT_F32: - addF32(varname, *(F32*)mvci.getData()); - break; - - case MVT_F64: - addF64(varname, *(F64*)mvci.getData()); - break; - - case MVT_LLVector3: - addVector3(varname, *(LLVector3*)mvci.getData()); - break; - - case MVT_LLVector3d: - addVector3d(varname, *(LLVector3d*)mvci.getData()); - break; - - case MVT_LLVector4: - addVector4(varname, *(LLVector4*)mvci.getData()); - break; - - case MVT_LLQuaternion: - { - LLVector3 v = *(LLVector3*)mvci.getData(); - LLQuaternion q; - q.unpackFromVector3(v); - addQuat(varname, q); - break; - } - - case MVT_LLUUID: - addUUID(varname, *(LLUUID*)mvci.getData()); - break; - - case MVT_BOOL: - addBOOL(varname, *(bool*)mvci.getData()); - break; - - case MVT_IP_ADDR: - addIPAddr(varname, *(U32*)mvci.getData()); - break; - - case MVT_IP_PORT: - addIPPort(varname, *(U16*)mvci.getData()); - break; - - case MVT_U16Vec3: - //treated as an array of 6 bytes - addBinaryData(varname, mvci.getData(), 6); - break; - - case MVT_U16Quat: - //treated as an array of 8 bytes - addBinaryData(varname, mvci.getData(), 8); - break; - - case MVT_S16Array: - addBinaryData(varname, mvci.getData(), mvci.getSize()); - break; - - default: - LL_WARNS() << "Unknown type in conversion of message to LLSD" << LL_ENDL; - break; - } - } - } + // loop through msg blocks to loop through variables, totalling up size + // data and filling the new (send) message + LLMsgData::msg_blk_data_map_t::const_iterator iter = + data.mMemberBlocks.begin(); + LLMsgData::msg_blk_data_map_t::const_iterator end = + data.mMemberBlocks.end(); + for(; iter != end; ++iter) + { + const LLMsgBlkData* mbci = iter->second; + if(!mbci) continue; + + // do we need to encode a block code? + if (block_count == 0) + { + block_count = mbci->mBlockNumber; + block_name = (char*)mbci->mName; + } + + // counting down mutliple blocks + block_count--; + + nextBlock(block_name); + + // now loop through the variables + LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); + LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); + + for(; dit != dend; ++dit) + { + const LLMsgVarData& mvci = *dit; + const char* varname = mvci.getName(); + + switch(mvci.getType()) + { + case MVT_FIXED: + addBinaryData(varname, mvci.getData(), mvci.getSize()); + break; + + case MVT_VARIABLE: + { + const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated + if (mvci.getDataSize() == 1 && end == 0) + { + addString(varname, (const char*)mvci.getData()); + } + else + { + addBinaryData(varname, mvci.getData(), mvci.getSize()); + } + break; + } + + case MVT_U8: + addU8(varname, *(U8*)mvci.getData()); + break; + + case MVT_U16: + addU16(varname, *(U16*)mvci.getData()); + break; + + case MVT_U32: + addU32(varname, *(U32*)mvci.getData()); + break; + + case MVT_U64: + addU64(varname, *(U64*)mvci.getData()); + break; + + case MVT_S8: + addS8(varname, *(S8*)mvci.getData()); + break; + + case MVT_S16: + addS16(varname, *(S16*)mvci.getData()); + break; + + case MVT_S32: + addS32(varname, *(S32*)mvci.getData()); + break; + + // S64 not supported in LLSD so we just truncate it + case MVT_S64: + addS32(varname, (S32)*(S64*)mvci.getData()); + break; + + case MVT_F32: + addF32(varname, *(F32*)mvci.getData()); + break; + + case MVT_F64: + addF64(varname, *(F64*)mvci.getData()); + break; + + case MVT_LLVector3: + addVector3(varname, *(LLVector3*)mvci.getData()); + break; + + case MVT_LLVector3d: + addVector3d(varname, *(LLVector3d*)mvci.getData()); + break; + + case MVT_LLVector4: + addVector4(varname, *(LLVector4*)mvci.getData()); + break; + + case MVT_LLQuaternion: + { + LLVector3 v = *(LLVector3*)mvci.getData(); + LLQuaternion q; + q.unpackFromVector3(v); + addQuat(varname, q); + break; + } + + case MVT_LLUUID: + addUUID(varname, *(LLUUID*)mvci.getData()); + break; + + case MVT_BOOL: + addBOOL(varname, *(bool*)mvci.getData()); + break; + + case MVT_IP_ADDR: + addIPAddr(varname, *(U32*)mvci.getData()); + break; + + case MVT_IP_PORT: + addIPPort(varname, *(U16*)mvci.getData()); + break; + + case MVT_U16Vec3: + //treated as an array of 6 bytes + addBinaryData(varname, mvci.getData(), 6); + break; + + case MVT_U16Quat: + //treated as an array of 8 bytes + addBinaryData(varname, mvci.getData(), 8); + break; + + case MVT_S16Array: + addBinaryData(varname, mvci.getData(), mvci.getSize()); + break; + + default: + LL_WARNS() << "Unknown type in conversion of message to LLSD" << LL_ENDL; + break; + } + } + } } //virtual void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg) { - mCurrentMessage = msg; - LL_DEBUGS() << LLSDNotationStreamer(mCurrentMessage) << LL_ENDL; + mCurrentMessage = msg; + LL_DEBUGS() << LLSDNotationStreamer(mCurrentMessage) << LL_ENDL; } const LLSD& LLSDMessageBuilder::getMessage() const { - return mCurrentMessage; + return mCurrentMessage; } //virtual void LLSDMessageBuilder::setBuilt(bool b) { mbSBuilt = b; } -//virtual +//virtual bool LLSDMessageBuilder::isBuilt() const {return mbSBuilt;} -//virtual +//virtual bool LLSDMessageBuilder::isClear() const {return mbSClear;} -//virtual +//virtual S32 LLSDMessageBuilder::getMessageSize() { - // babbage: size is unknown as message stored as LLSD. - // return non-zero if pending data, as send can be skipped for 0 size. - // return 1 to encourage senders checking size against splitting message. - return mCurrentMessage.size()? 1 : 0; + // babbage: size is unknown as message stored as LLSD. + // return non-zero if pending data, as send can be skipped for 0 size. + // return 1 to encourage senders checking size against splitting message. + return mCurrentMessage.size()? 1 : 0; } -//virtual -const char* LLSDMessageBuilder::getMessageName() const +//virtual +const char* LLSDMessageBuilder::getMessageName() const { - return mCurrentMessageName.c_str(); + return mCurrentMessageName.c_str(); } diff --git a/indra/llmessage/llsdmessagebuilder.h b/indra/llmessage/llsdmessagebuilder.h index 2c728977ca..72ea6d0dd6 100644 --- a/indra/llmessage/llsdmessagebuilder.h +++ b/indra/llmessage/llsdmessagebuilder.h @@ -1,25 +1,25 @@ -/** +/** * @file llsdmessagebuilder.h * @brief Declaration of LLSDMessageBuilder class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,87 +40,87 @@ class LLSDMessageBuilder : public LLMessageBuilder { public: - //CLASS_LOG_TYPE(LLSDMessageBuilder); - - LLSDMessageBuilder(); - virtual ~LLSDMessageBuilder(); - - virtual void newMessage(const char* name); - - virtual void nextBlock(const char* blockname); - virtual bool removeLastBlock(); // TODO: babbage: remove this horror... - - /** All add* methods expect pointers to canonical varname strings. */ - virtual void addBinaryData( - const char* varname, - const void* data, - S32 size); - virtual void addBOOL(const char* varname, bool b); - virtual void addS8(const char* varname, S8 s); - virtual void addU8(const char* varname, U8 u); - virtual void addS16(const char* varname, S16 i); - virtual void addU16(const char* varname, U16 i); - virtual void addF32(const char* varname, F32 f); - virtual void addS32(const char* varname, S32 s); - virtual void addU32(const char* varname, U32 u); - virtual void addU64(const char* varname, U64 lu); - virtual void addF64(const char* varname, F64 d); - virtual void addVector3(const char* varname, const LLVector3& vec); - virtual void addVector4(const char* varname, const LLVector4& vec); - virtual void addVector3d(const char* varname, const LLVector3d& vec); - virtual void addQuat(const char* varname, const LLQuaternion& quat); - virtual void addUUID(const char* varname, const LLUUID& uuid); - virtual void addIPAddr(const char* varname, const U32 ip); - virtual void addIPPort(const char* varname, const U16 port); - virtual void addString(const char* varname, const char* s); - virtual void addString(const char* varname, const std::string& s); - - virtual bool isMessageFull(const char* blockname) const; - virtual void compressMessage(U8*& buf_ptr, U32& buffer_length); - - virtual bool isBuilt() const; - virtual bool isClear() const; - virtual U32 buildMessage(U8* buffer, U32 buffer_size, U8 offset_to_data); + //CLASS_LOG_TYPE(LLSDMessageBuilder); + + LLSDMessageBuilder(); + virtual ~LLSDMessageBuilder(); + + virtual void newMessage(const char* name); + + virtual void nextBlock(const char* blockname); + virtual bool removeLastBlock(); // TODO: babbage: remove this horror... + + /** All add* methods expect pointers to canonical varname strings. */ + virtual void addBinaryData( + const char* varname, + const void* data, + S32 size); + virtual void addBOOL(const char* varname, bool b); + virtual void addS8(const char* varname, S8 s); + virtual void addU8(const char* varname, U8 u); + virtual void addS16(const char* varname, S16 i); + virtual void addU16(const char* varname, U16 i); + virtual void addF32(const char* varname, F32 f); + virtual void addS32(const char* varname, S32 s); + virtual void addU32(const char* varname, U32 u); + virtual void addU64(const char* varname, U64 lu); + virtual void addF64(const char* varname, F64 d); + virtual void addVector3(const char* varname, const LLVector3& vec); + virtual void addVector4(const char* varname, const LLVector4& vec); + virtual void addVector3d(const char* varname, const LLVector3d& vec); + virtual void addQuat(const char* varname, const LLQuaternion& quat); + virtual void addUUID(const char* varname, const LLUUID& uuid); + virtual void addIPAddr(const char* varname, const U32 ip); + virtual void addIPPort(const char* varname, const U16 port); + virtual void addString(const char* varname, const char* s); + virtual void addString(const char* varname, const std::string& s); + + virtual bool isMessageFull(const char* blockname) const; + virtual void compressMessage(U8*& buf_ptr, U32& buffer_length); + + virtual bool isBuilt() const; + virtual bool isClear() const; + virtual U32 buildMessage(U8* buffer, U32 buffer_size, U8 offset_to_data); /**< Null implementation which returns 0. */ - - virtual void clearMessage(); - // TODO: babbage: remove this horror. - virtual void setBuilt(bool b); + virtual void clearMessage(); + + // TODO: babbage: remove this horror. + virtual void setBuilt(bool b); - virtual S32 getMessageSize(); - virtual const char* getMessageName() const; + virtual S32 getMessageSize(); + virtual const char* getMessageName() const; - virtual void copyFromMessageData(const LLMsgData& data); + virtual void copyFromMessageData(const LLMsgData& data); - virtual void copyFromLLSD(const LLSD& msg); + virtual void copyFromLLSD(const LLSD& msg); - const LLSD& getMessage() const; + const LLSD& getMessage() const; private: - /* mCurrentMessage is of the following format: - mCurrentMessage = { 'block_name1' : [ { 'block1_field1' : 'b1f1_data', - 'block1_field2' : 'b1f2_data', - ... - 'block1_fieldn' : 'b1fn_data'}, - { 'block2_field1' : 'b2f1_data', - 'block2_field2' : 'b2f2_data', - ... - 'block2_fieldn' : 'b2fn_data'}, - ... - { 'blockm_field1' : 'bmf1_data', - 'blockm_field2' : 'bmf2_data', - ... - 'blockm_fieldn' : 'bmfn_data'} ], - 'block_name2' : ..., - ... - 'block_namem' } */ - LLSD mCurrentMessage; - LLSD* mCurrentBlock; - std::string mCurrentMessageName; - std::string mCurrentBlockName; - bool mbSBuilt; - bool mbSClear; + /* mCurrentMessage is of the following format: + mCurrentMessage = { 'block_name1' : [ { 'block1_field1' : 'b1f1_data', + 'block1_field2' : 'b1f2_data', + ... + 'block1_fieldn' : 'b1fn_data'}, + { 'block2_field1' : 'b2f1_data', + 'block2_field2' : 'b2f2_data', + ... + 'block2_fieldn' : 'b2fn_data'}, + ... + { 'blockm_field1' : 'bmf1_data', + 'blockm_field2' : 'bmf2_data', + ... + 'blockm_fieldn' : 'bmfn_data'} ], + 'block_name2' : ..., + ... + 'block_namem' } */ + LLSD mCurrentMessage; + LLSD* mCurrentBlock; + std::string mCurrentMessageName; + std::string mCurrentBlockName; + bool mbSBuilt; + bool mbSClear; }; #endif // LL_LLSDMESSAGEBUILDER_H diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp index d533d6535b..8be6158d82 100644 --- a/indra/llmessage/llsdmessagereader.cpp +++ b/indra/llmessage/llsdmessagereader.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llsdmessagereader.cpp * @brief LLSDMessageReader class implementation. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,11 +41,11 @@ #include "v4color.h" LLSDMessageReader::LLSDMessageReader() : - mMessageName(NULL) + mMessageName(NULL) { } -//virtual +//virtual LLSDMessageReader::~LLSDMessageReader() { } @@ -53,292 +53,292 @@ LLSDMessageReader::~LLSDMessageReader() LLSD getLLSD(const LLSD& input, const char* block, const char* var, S32 blocknum) { - // babbage: log error to LL_ERRS() if variable not found to mimic - // LLTemplateMessageReader::getData behaviour - if(NULL == block) - { - LL_ERRS() << "NULL block name" << LL_ENDL; - return LLSD(); - } - if(NULL == var) - { - LL_ERRS() << "NULL var name" << LL_ENDL; - return LLSD(); - } - if(! input[block].isArray()) - { - // NOTE: babbage: need to return default for missing blocks to allow - // backwards/forwards compatibility - handlers must cope with default - // values. - LL_WARNS() << "block " << block << " not found" << LL_ENDL; - return LLSD(); - } + // babbage: log error to LL_ERRS() if variable not found to mimic + // LLTemplateMessageReader::getData behaviour + if(NULL == block) + { + LL_ERRS() << "NULL block name" << LL_ENDL; + return LLSD(); + } + if(NULL == var) + { + LL_ERRS() << "NULL var name" << LL_ENDL; + return LLSD(); + } + if(! input[block].isArray()) + { + // NOTE: babbage: need to return default for missing blocks to allow + // backwards/forwards compatibility - handlers must cope with default + // values. + LL_WARNS() << "block " << block << " not found" << LL_ENDL; + return LLSD(); + } - LLSD result = input[block][blocknum][var]; - if(result.isUndefined()) - { - // NOTE: babbage: need to return default for missing vars to allow - // backwards/forwards compatibility - handlers must cope with default - // values. - LL_WARNS() << "var " << var << " not found" << LL_ENDL; - } - return result; + LLSD result = input[block][blocknum][var]; + if(result.isUndefined()) + { + // NOTE: babbage: need to return default for missing vars to allow + // backwards/forwards compatibility - handlers must cope with default + // values. + LL_WARNS() << "var " << var << " not found" << LL_ENDL; + } + return result; } -//virtual -void LLSDMessageReader::getBinaryData(const char *block, const char *var, - void *datap, S32 size, S32 blocknum, - S32 max_size) +//virtual +void LLSDMessageReader::getBinaryData(const char *block, const char *var, + void *datap, S32 size, S32 blocknum, + S32 max_size) { - std::vector<U8> data = getLLSD(mMessage, block, var, blocknum); - S32 data_size = (S32)data.size(); + std::vector<U8> data = getLLSD(mMessage, block, var, blocknum); + S32 data_size = (S32)data.size(); + + if (size && data_size != size) + { + return; + } + + if (max_size < data_size) + { + data_size = max_size; + } - if (size && data_size != size) - { - return; - } - - if (max_size < data_size) - { - data_size = max_size; - } - - // Calls to memcpy will fail if data_size is not positive. - // Phoenix 2009-02-27 - if(data_size <= 0) - { - return; - } - memcpy(datap, &(data[0]), data_size); + // Calls to memcpy will fail if data_size is not positive. + // Phoenix 2009-02-27 + if(data_size <= 0) + { + return; + } + memcpy(datap, &(data[0]), data_size); } -//virtual -void LLSDMessageReader::getBOOL(const char *block, const char *var, - bool &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getBOOL(const char *block, const char *var, + bool &data, + S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum); + data = getLLSD(mMessage, block, var, blocknum); } -//virtual -void LLSDMessageReader::getS8(const char *block, const char *var, S8 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getS8(const char *block, const char *var, S8 &data, + S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum).asInteger(); + data = getLLSD(mMessage, block, var, blocknum).asInteger(); } -//virtual -void LLSDMessageReader::getU8(const char *block, const char *var, U8 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getU8(const char *block, const char *var, U8 &data, + S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum).asInteger(); + data = getLLSD(mMessage, block, var, blocknum).asInteger(); } -//virtual -void LLSDMessageReader::getS16(const char *block, const char *var, S16 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getS16(const char *block, const char *var, S16 &data, + S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum).asInteger(); + data = getLLSD(mMessage, block, var, blocknum).asInteger(); } -//virtual -void LLSDMessageReader::getU16(const char *block, const char *var, U16 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getU16(const char *block, const char *var, U16 &data, + S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum).asInteger(); + data = getLLSD(mMessage, block, var, blocknum).asInteger(); } -//virtual -void LLSDMessageReader::getS32(const char *block, const char *var, S32 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getS32(const char *block, const char *var, S32 &data, + S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum); + data = getLLSD(mMessage, block, var, blocknum); } -//virtual -void LLSDMessageReader::getF32(const char *block, const char *var, F32 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getF32(const char *block, const char *var, F32 &data, + S32 blocknum) { - data = (F32)getLLSD(mMessage, block, var, blocknum).asReal(); + data = (F32)getLLSD(mMessage, block, var, blocknum).asReal(); } -//virtual -void LLSDMessageReader::getU32(const char *block, const char *var, U32 &data, - S32 blocknum) +//virtual +void LLSDMessageReader::getU32(const char *block, const char *var, U32 &data, + S32 blocknum) { - data = ll_U32_from_sd(getLLSD(mMessage, block, var, blocknum)); + data = ll_U32_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual +//virtual void LLSDMessageReader::getU64(const char *block, const char *var, - U64 &data, S32 blocknum) + U64 &data, S32 blocknum) { - data = ll_U64_from_sd(getLLSD(mMessage, block, var, blocknum)); + data = ll_U64_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual +//virtual void LLSDMessageReader::getF64(const char *block, const char *var, - F64 &data, S32 blocknum) + F64 &data, S32 blocknum) { - data = getLLSD(mMessage, block, var, blocknum); + data = getLLSD(mMessage, block, var, blocknum); } -//virtual -void LLSDMessageReader::getVector3(const char *block, const char *var, - LLVector3 &vec, S32 blocknum) +//virtual +void LLSDMessageReader::getVector3(const char *block, const char *var, + LLVector3 &vec, S32 blocknum) { - vec = ll_vector3_from_sd(getLLSD(mMessage, block, var, blocknum)); + vec = ll_vector3_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual -void LLSDMessageReader::getVector4(const char *block, const char *var, - LLVector4 &vec, S32 blocknum) +//virtual +void LLSDMessageReader::getVector4(const char *block, const char *var, + LLVector4 &vec, S32 blocknum) { - vec = ll_vector4_from_sd(getLLSD(mMessage, block, var, blocknum)); + vec = ll_vector4_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual -void LLSDMessageReader::getVector3d(const char *block, const char *var, - LLVector3d &vec, S32 blocknum) +//virtual +void LLSDMessageReader::getVector3d(const char *block, const char *var, + LLVector3d &vec, S32 blocknum) { - vec = ll_vector3d_from_sd(getLLSD(mMessage, block, var, blocknum)); + vec = ll_vector3d_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual +//virtual void LLSDMessageReader::getQuat(const char *block, const char *var, - LLQuaternion &q, S32 blocknum) + LLQuaternion &q, S32 blocknum) { - q = ll_quaternion_from_sd(getLLSD(mMessage, block, var, blocknum)); + q = ll_quaternion_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual +//virtual void LLSDMessageReader::getUUID(const char *block, const char *var, - LLUUID &uuid, S32 blocknum) + LLUUID &uuid, S32 blocknum) { - uuid = getLLSD(mMessage, block, var, blocknum); + uuid = getLLSD(mMessage, block, var, blocknum); } -//virtual +//virtual void LLSDMessageReader::getIPAddr(const char *block, const char *var, - U32 &ip, S32 blocknum) + U32 &ip, S32 blocknum) { - ip = ll_ipaddr_from_sd(getLLSD(mMessage, block, var, blocknum)); + ip = ll_ipaddr_from_sd(getLLSD(mMessage, block, var, blocknum)); } -//virtual +//virtual void LLSDMessageReader::getIPPort(const char *block, const char *var, - U16 &port, S32 blocknum) + U16 &port, S32 blocknum) { - port = getLLSD(mMessage, block, var, blocknum).asInteger(); + port = getLLSD(mMessage, block, var, blocknum).asInteger(); } -//virtual -void LLSDMessageReader::getString(const char *block, const char *var, - S32 buffer_size, char *buffer, S32 blocknum) +//virtual +void LLSDMessageReader::getString(const char *block, const char *var, + S32 buffer_size, char *buffer, S32 blocknum) { - if(buffer_size <= 0) - { - LL_WARNS() << "buffer_size <= 0" << LL_ENDL; - return; - } - std::string data = getLLSD(mMessage, block, var, blocknum); - S32 data_size = data.size(); - if (data_size >= buffer_size) - { - data_size = buffer_size - 1; - } - memcpy(buffer, data.data(), data_size); - buffer[data_size] = '\0'; + if(buffer_size <= 0) + { + LL_WARNS() << "buffer_size <= 0" << LL_ENDL; + return; + } + std::string data = getLLSD(mMessage, block, var, blocknum); + S32 data_size = data.size(); + if (data_size >= buffer_size) + { + data_size = buffer_size - 1; + } + memcpy(buffer, data.data(), data_size); + buffer[data_size] = '\0'; } -//virtual -void LLSDMessageReader::getString(const char *block, const char *var, - std::string& outstr, S32 blocknum) +//virtual +void LLSDMessageReader::getString(const char *block, const char *var, + std::string& outstr, S32 blocknum) { - outstr = getLLSD(mMessage, block, var, blocknum).asString(); + outstr = getLLSD(mMessage, block, var, blocknum).asString(); } -//virtual -S32 LLSDMessageReader::getNumberOfBlocks(const char *blockname) +//virtual +S32 LLSDMessageReader::getNumberOfBlocks(const char *blockname) { - return mMessage[blockname].size(); + return mMessage[blockname].size(); } S32 getElementSize(const LLSD& llsd) { - LLSD::Type type = llsd.type(); - switch(type) - { - case LLSD::TypeBoolean: - return sizeof(bool); - case LLSD::TypeInteger: - return sizeof(S32); - case LLSD::TypeReal: - return sizeof(F64); - case LLSD::TypeString: - return llsd.size(); - case LLSD::TypeUUID: - return sizeof(LLUUID); - case LLSD::TypeDate: - return sizeof(LLDate); - case LLSD::TypeURI: - return sizeof(LLURI); - case LLSD::TypeBinary: - { - std::vector<U8> data = llsd; - return data.size() * sizeof(U8); - } - case LLSD::TypeMap: - case LLSD::TypeArray: - case LLSD::TypeUndefined: - default: // TypeLLSDTypeEnd, TypeLLSDNumTypes, etc. - return 0; - } - //return 0; -} - -//virtual + LLSD::Type type = llsd.type(); + switch(type) + { + case LLSD::TypeBoolean: + return sizeof(bool); + case LLSD::TypeInteger: + return sizeof(S32); + case LLSD::TypeReal: + return sizeof(F64); + case LLSD::TypeString: + return llsd.size(); + case LLSD::TypeUUID: + return sizeof(LLUUID); + case LLSD::TypeDate: + return sizeof(LLDate); + case LLSD::TypeURI: + return sizeof(LLURI); + case LLSD::TypeBinary: + { + std::vector<U8> data = llsd; + return data.size() * sizeof(U8); + } + case LLSD::TypeMap: + case LLSD::TypeArray: + case LLSD::TypeUndefined: + default: // TypeLLSDTypeEnd, TypeLLSDNumTypes, etc. + return 0; + } + //return 0; +} + +//virtual //Mainly used to find size of binary block of data -S32 LLSDMessageReader::getSize(const char *blockname, const char *varname) +S32 LLSDMessageReader::getSize(const char *blockname, const char *varname) { - return getElementSize(mMessage[blockname][0][varname]); + return getElementSize(mMessage[blockname][0][varname]); } -//virtual -S32 LLSDMessageReader::getSize(const char *blockname, S32 blocknum, - const char *varname) +//virtual +S32 LLSDMessageReader::getSize(const char *blockname, S32 blocknum, + const char *varname) { - return getElementSize(mMessage[blockname][blocknum][varname]); + return getElementSize(mMessage[blockname][blocknum][varname]); } -//virtual +//virtual void LLSDMessageReader::clearMessage() { - mMessage = LLSD(); + mMessage = LLSD(); } -//virtual +//virtual const char* LLSDMessageReader::getMessageName() const { - return mMessageName; + return mMessageName; } -// virtual +// virtual S32 LLSDMessageReader::getMessageSize() const { - return 0; + return 0; } -//virtual +//virtual void LLSDMessageReader::copyToBuilder(LLMessageBuilder& builder) const { - builder.copyFromLLSD(mMessage); + builder.copyFromLLSD(mMessage); } void LLSDMessageReader::setMessage(const char* name, const LLSD& message) { - mMessageName = name; - // TODO: Validate - mMessage = message; + mMessageName = name; + // TODO: Validate + mMessage = message; } diff --git a/indra/llmessage/llsdmessagereader.h b/indra/llmessage/llsdmessagereader.h index 4119de6009..6f4256380b 100644 --- a/indra/llmessage/llsdmessagereader.h +++ b/indra/llmessage/llsdmessagereader.h @@ -1,25 +1,25 @@ -/** +/** * @file llsdmessagereader.h * @brief LLSDMessageReader class Declaration * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,70 +39,70 @@ class LLSDMessageReader : public LLMessageReader { public: - LLSDMessageReader(); - virtual ~LLSDMessageReader(); + LLSDMessageReader(); + virtual ~LLSDMessageReader(); - /** All get* methods expect pointers to canonical strings. */ - virtual void getBinaryData(const char *block, const char *var, - void *datap, S32 size, S32 blocknum = 0, - S32 max_size = S32_MAX); - virtual void getBOOL(const char *block, const char *var, bool &data, - S32 blocknum = 0); - virtual void getS8(const char *block, const char *var, S8 &data, - S32 blocknum = 0); - virtual void getU8(const char *block, const char *var, U8 &data, - S32 blocknum = 0); - virtual void getS16(const char *block, const char *var, S16 &data, - S32 blocknum = 0); - virtual void getU16(const char *block, const char *var, U16 &data, - S32 blocknum = 0); - virtual void getS32(const char *block, const char *var, S32 &data, - S32 blocknum = 0); - virtual void getF32(const char *block, const char *var, F32 &data, - S32 blocknum = 0); - virtual void getU32(const char *block, const char *var, U32 &data, - S32 blocknum = 0); - virtual void getU64(const char *block, const char *var, U64 &data, - S32 blocknum = 0); - virtual void getF64(const char *block, const char *var, F64 &data, - S32 blocknum = 0); - virtual void getVector3(const char *block, const char *var, - LLVector3 &vec, S32 blocknum = 0); - virtual void getVector4(const char *block, const char *var, - LLVector4 &vec, S32 blocknum = 0); - virtual void getVector3d(const char *block, const char *var, - LLVector3d &vec, S32 blocknum = 0); - virtual void getQuat(const char *block, const char *var, LLQuaternion &q, - S32 blocknum = 0); - virtual void getUUID(const char *block, const char *var, LLUUID &uuid, - S32 blocknum = 0); - virtual void getIPAddr(const char *block, const char *var, U32 &ip, - S32 blocknum = 0); - virtual void getIPPort(const char *block, const char *var, U16 &port, - S32 blocknum = 0); - virtual void getString(const char *block, const char *var, - S32 buffer_size, char *buffer, S32 blocknum = 0); - virtual void getString(const char *block, const char *var, std::string& outstr, - S32 blocknum = 0); + /** All get* methods expect pointers to canonical strings. */ + virtual void getBinaryData(const char *block, const char *var, + void *datap, S32 size, S32 blocknum = 0, + S32 max_size = S32_MAX); + virtual void getBOOL(const char *block, const char *var, bool &data, + S32 blocknum = 0); + virtual void getS8(const char *block, const char *var, S8 &data, + S32 blocknum = 0); + virtual void getU8(const char *block, const char *var, U8 &data, + S32 blocknum = 0); + virtual void getS16(const char *block, const char *var, S16 &data, + S32 blocknum = 0); + virtual void getU16(const char *block, const char *var, U16 &data, + S32 blocknum = 0); + virtual void getS32(const char *block, const char *var, S32 &data, + S32 blocknum = 0); + virtual void getF32(const char *block, const char *var, F32 &data, + S32 blocknum = 0); + virtual void getU32(const char *block, const char *var, U32 &data, + S32 blocknum = 0); + virtual void getU64(const char *block, const char *var, U64 &data, + S32 blocknum = 0); + virtual void getF64(const char *block, const char *var, F64 &data, + S32 blocknum = 0); + virtual void getVector3(const char *block, const char *var, + LLVector3 &vec, S32 blocknum = 0); + virtual void getVector4(const char *block, const char *var, + LLVector4 &vec, S32 blocknum = 0); + virtual void getVector3d(const char *block, const char *var, + LLVector3d &vec, S32 blocknum = 0); + virtual void getQuat(const char *block, const char *var, LLQuaternion &q, + S32 blocknum = 0); + virtual void getUUID(const char *block, const char *var, LLUUID &uuid, + S32 blocknum = 0); + virtual void getIPAddr(const char *block, const char *var, U32 &ip, + S32 blocknum = 0); + virtual void getIPPort(const char *block, const char *var, U16 &port, + S32 blocknum = 0); + virtual void getString(const char *block, const char *var, + S32 buffer_size, char *buffer, S32 blocknum = 0); + virtual void getString(const char *block, const char *var, std::string& outstr, + S32 blocknum = 0); - virtual S32 getNumberOfBlocks(const char *blockname); - virtual S32 getSize(const char *blockname, const char *varname); - virtual S32 getSize(const char *blockname, S32 blocknum, - const char *varname); + virtual S32 getNumberOfBlocks(const char *blockname); + virtual S32 getSize(const char *blockname, const char *varname); + virtual S32 getSize(const char *blockname, S32 blocknum, + const char *varname); - virtual void clearMessage(); + virtual void clearMessage(); - virtual const char* getMessageName() const; - virtual S32 getMessageSize() const; + virtual const char* getMessageName() const; + virtual S32 getMessageSize() const; - virtual void copyToBuilder(LLMessageBuilder&) const; + virtual void copyToBuilder(LLMessageBuilder&) const; - /** Expects a pointer to a canonical name string */ - void setMessage(const char* name, const LLSD& msg); + /** Expects a pointer to a canonical name string */ + void setMessage(const char* name, const LLSD& msg); private: - const char* mMessageName; // Canonical (prehashed) string. - LLSD mMessage; + const char* mMessageName; // Canonical (prehashed) string. + LLSD mMessage; }; #endif // LL_LLSDMESSAGEREADER_H diff --git a/indra/llmessage/llservice.cpp b/indra/llmessage/llservice.cpp index ddcc13d969..47027dcfce 100644 --- a/indra/llmessage/llservice.cpp +++ b/indra/llmessage/llservice.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llservice.cpp * @author Phoenix * @date 2005-04-20 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,71 +41,71 @@ LLService::~LLService() // static bool LLService::registerCreator(const std::string& name, creator_t fn) { - LL_INFOS() << "LLService::registerCreator(" << name << ")" << LL_ENDL; - if(name.empty()) - { - return false; - } + LL_INFOS() << "LLService::registerCreator(" << name << ")" << LL_ENDL; + if(name.empty()) + { + return false; + } - creators_t::value_type vt(name, fn); - std::pair<creators_t::iterator, bool> rv = sCreatorFunctors.insert(vt); - return rv.second; + creators_t::value_type vt(name, fn); + std::pair<creators_t::iterator, bool> rv = sCreatorFunctors.insert(vt); + return rv.second; - // alternately... - //std::string name_str(name); - //sCreatorFunctors[name_str] = fn; + // alternately... + //std::string name_str(name); + //sCreatorFunctors[name_str] = fn; } // static LLIOPipe* LLService::activate( - const std::string& name, - LLPumpIO::chain_t& chain, - LLSD context) + const std::string& name, + LLPumpIO::chain_t& chain, + LLSD context) { - if(name.empty()) - { - LL_INFOS() << "LLService::activate - no service specified." << LL_ENDL; - return NULL; - } - creators_t::iterator it = sCreatorFunctors.find(name); - LLIOPipe* rv = NULL; - if(it != sCreatorFunctors.end()) - { - if((*it).second->build(chain, context)) - { - rv = chain[0].get(); - } - else - { - // empty out the chain, because failed service creation - // should just discard this stuff. - LL_WARNS() << "LLService::activate - unable to build chain: " << name - << LL_ENDL; - chain.clear(); - } - } - else - { - LL_WARNS() << "LLService::activate - unable find factory: " << name - << LL_ENDL; - } - return rv; + if(name.empty()) + { + LL_INFOS() << "LLService::activate - no service specified." << LL_ENDL; + return NULL; + } + creators_t::iterator it = sCreatorFunctors.find(name); + LLIOPipe* rv = NULL; + if(it != sCreatorFunctors.end()) + { + if((*it).second->build(chain, context)) + { + rv = chain[0].get(); + } + else + { + // empty out the chain, because failed service creation + // should just discard this stuff. + LL_WARNS() << "LLService::activate - unable to build chain: " << name + << LL_ENDL; + chain.clear(); + } + } + else + { + LL_WARNS() << "LLService::activate - unable find factory: " << name + << LL_ENDL; + } + return rv; } // static bool LLService::discard(const std::string& name) { - if(name.empty()) - { - return false; - } - creators_t::iterator it = sCreatorFunctors.find(name); - if(it != sCreatorFunctors.end()) - { - //(*it).second->discard(); - sCreatorFunctors.erase(it); - return true; - } - return false; + if(name.empty()) + { + return false; + } + creators_t::iterator it = sCreatorFunctors.find(name); + if(it != sCreatorFunctors.end()) + { + //(*it).second->discard(); + sCreatorFunctors.erase(it); + return true; + } + return false; } diff --git a/indra/llmessage/llservice.h b/indra/llmessage/llservice.h index f215acab56..6c32fa8102 100644 --- a/indra/llmessage/llservice.h +++ b/indra/llmessage/llservice.h @@ -1,4 +1,4 @@ -/** +/** * @file llservice.h * @author Phoenix * @date 2004-11-21 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,12 +45,12 @@ class LLServiceCreator; */ namespace boost { - void intrusive_ptr_add_ref(LLServiceCreator* p); - void intrusive_ptr_release(LLServiceCreator* p); + void intrusive_ptr_add_ref(LLServiceCreator* p); + void intrusive_ptr_release(LLServiceCreator* p); }; #endif -/** +/** * @class LLServiceCreator * @brief This class is an abstract base class for classes which create * new <code>LLService</code> instances. @@ -63,41 +63,41 @@ namespace boost class LLServiceCreator { public: - typedef boost::intrusive_ptr<LLService> service_t; - virtual ~LLServiceCreator() {} - virtual service_t activate() = 0; - virtual void discard() = 0; + typedef boost::intrusive_ptr<LLService> service_t; + virtual ~LLServiceCreator() {} + virtual service_t activate() = 0; + virtual void discard() = 0; protected: - LLServiceCreator() : mReferenceCount(0) - { - } + LLServiceCreator() : mReferenceCount(0) + { + } private: - friend void boost::intrusive_ptr_add_ref(LLServiceCreator* p); - friend void boost::intrusive_ptr_release(LLServiceCreator* p); - U32 mReferenceCount; + friend void boost::intrusive_ptr_add_ref(LLServiceCreator* p); + friend void boost::intrusive_ptr_release(LLServiceCreator* p); + U32 mReferenceCount; }; #endif #if 0 namespace boost { - inline void intrusive_ptr_add_ref(LLServiceCreator* p) - { - ++p->mReferenceCount; - } - inline void intrusive_ptr_release(LLServiceCreator* p) - { - if(p && 0 == --p->mReferenceCount) - { - delete p; - } - } + inline void intrusive_ptr_add_ref(LLServiceCreator* p) + { + ++p->mReferenceCount; + } + inline void intrusive_ptr_release(LLServiceCreator* p) + { + if(p && 0 == --p->mReferenceCount) + { + delete p; + } + } }; #endif -/** +/** * @class LLService * @brief This class is the base class for the service classes. * @see LLIOPipe @@ -114,71 +114,71 @@ namespace boost class LLService : public LLIOPipe { public: - //typedef boost::intrusive_ptr<LLServiceCreator> creator_t; - //typedef boost::intrusive_ptr<LLService> service_t; - typedef std::shared_ptr<LLChainIOFactory> creator_t; - - /** - * @brief This method is used to register a protocol name with a - * a functor that creates the service. - * - * THOROUGH_DESCRIPTION - * @param aParameter A brief description of aParameter. - * @return Returns true if a service was successfully registered. - */ - static bool registerCreator(const std::string& name, creator_t fn); - - /** - * @brief This method connects to a service by name. - * - * @param name The name of the service to connect to. - * @param chain The constructed chain including the service instance. - * @param context Context for the activation. - * @return An instance of the service for use or NULL on failure. - */ - static LLIOPipe* activate( - const std::string& name, - LLPumpIO::chain_t& chain, - LLSD context); - - /** - * @brief - * - * @param name The name of the service to discard. - * @return true if service creator was found and discarded. - */ - static bool discard(const std::string& name); + //typedef boost::intrusive_ptr<LLServiceCreator> creator_t; + //typedef boost::intrusive_ptr<LLService> service_t; + typedef std::shared_ptr<LLChainIOFactory> creator_t; + + /** + * @brief This method is used to register a protocol name with a + * a functor that creates the service. + * + * THOROUGH_DESCRIPTION + * @param aParameter A brief description of aParameter. + * @return Returns true if a service was successfully registered. + */ + static bool registerCreator(const std::string& name, creator_t fn); + + /** + * @brief This method connects to a service by name. + * + * @param name The name of the service to connect to. + * @param chain The constructed chain including the service instance. + * @param context Context for the activation. + * @return An instance of the service for use or NULL on failure. + */ + static LLIOPipe* activate( + const std::string& name, + LLPumpIO::chain_t& chain, + LLSD context); + + /** + * @brief + * + * @param name The name of the service to discard. + * @return true if service creator was found and discarded. + */ + static bool discard(const std::string& name); protected: - // The creation factory static data. - typedef std::map<std::string, creator_t> creators_t; - static creators_t sCreatorFunctors; + // The creation factory static data. + typedef std::map<std::string, creator_t> creators_t; + static creators_t sCreatorFunctors; protected: - // construction & destruction. since this class is an abstract - // base class, it is up to Service implementations to actually - // deal with construction and not a public method. How that - // construction takes place will be handled by the service - // creators. - LLService(); - virtual ~LLService(); + // construction & destruction. since this class is an abstract + // base class, it is up to Service implementations to actually + // deal with construction and not a public method. How that + // construction takes place will be handled by the service + // creators. + LLService(); + virtual ~LLService(); protected: - // This frame timer records how long this service has - // existed. Useful for derived services to give themselves a - // lifetime and expiration. - // *NOTE: Phoenix - This functionaity has been moved to the - // pump. 2005-12-13 - //LLFrameTimer mTimer; - - // Since services are designed in an 'ask now, respond later' - // idiom which probably crosses thread boundaries, almost all - // services will need a handle to a response pipe. It will usually - // be the job of the service author to derive a useful - // implementation of response, and up to the service subscriber to - // further derive that class to do something useful when the - // response comes in. - LLIOPipe::ptr_t mResponse; + // This frame timer records how long this service has + // existed. Useful for derived services to give themselves a + // lifetime and expiration. + // *NOTE: Phoenix - This functionaity has been moved to the + // pump. 2005-12-13 + //LLFrameTimer mTimer; + + // Since services are designed in an 'ask now, respond later' + // idiom which probably crosses thread boundaries, almost all + // services will need a handle to a response pipe. It will usually + // be the job of the service author to derive a useful + // implementation of response, and up to the service subscriber to + // further derive that class to do something useful when the + // response comes in. + LLIOPipe::ptr_t mResponse; }; diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp index cf2e42f95c..7dc49d5455 100644 --- a/indra/llmessage/llservicebuilder.cpp +++ b/indra/llmessage/llservicebuilder.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llservicebuilder.cpp * @brief Implementation of the LLServiceBuilder class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,205 +32,205 @@ #include "llsdserialize.h" void LLServiceBuilder::loadServiceDefinitionsFromFile( - const std::string& service_filename) + const std::string& service_filename) { - llifstream service_file(service_filename.c_str(), std::ios::binary); - if(service_file.is_open()) - { - LLSD service_data; - LLSDSerialize::fromXMLDocument(service_data, service_file); - service_file.close(); - // Load service - LLSD service_map = service_data["services"]; - for(LLSD::array_iterator array_itr = service_map.beginArray(); - array_itr != service_map.endArray(); - ++array_itr) - { - LLSD service_llsd = (*array_itr)["service-builder"]; - std::string service_name = (*array_itr)["name"].asString(); - createServiceDefinition(service_name, service_llsd); - } - LL_INFOS() << "loaded config file: " << service_filename << LL_ENDL; - } - else - { - LL_WARNS() << "unable to find config file: " << service_filename << LL_ENDL; - } + llifstream service_file(service_filename.c_str(), std::ios::binary); + if(service_file.is_open()) + { + LLSD service_data; + LLSDSerialize::fromXMLDocument(service_data, service_file); + service_file.close(); + // Load service + LLSD service_map = service_data["services"]; + for(LLSD::array_iterator array_itr = service_map.beginArray(); + array_itr != service_map.endArray(); + ++array_itr) + { + LLSD service_llsd = (*array_itr)["service-builder"]; + std::string service_name = (*array_itr)["name"].asString(); + createServiceDefinition(service_name, service_llsd); + } + LL_INFOS() << "loaded config file: " << service_filename << LL_ENDL; + } + else + { + LL_WARNS() << "unable to find config file: " << service_filename << LL_ENDL; + } } void LLServiceBuilder::createServiceDefinition( - const std::string& service_name, - LLSD& service_llsd) + const std::string& service_name, + LLSD& service_llsd) { - if(service_llsd.isString()) - { - mServiceMap[ service_name ] = service_llsd.asString(); - } - else if(service_llsd.isMap()) - { - for(LLSD::map_iterator map_itr = service_llsd.beginMap(); - map_itr != service_llsd.endMap(); - ++map_itr) - { - std::string compound_builder_name = service_name; - compound_builder_name.append("-"); - compound_builder_name.append((*map_itr).first); - mServiceMap[ compound_builder_name ] = (*map_itr).second.asString(); - } - } + if(service_llsd.isString()) + { + mServiceMap[ service_name ] = service_llsd.asString(); + } + else if(service_llsd.isMap()) + { + for(LLSD::map_iterator map_itr = service_llsd.beginMap(); + map_itr != service_llsd.endMap(); + ++map_itr) + { + std::string compound_builder_name = service_name; + compound_builder_name.append("-"); + compound_builder_name.append((*map_itr).first); + mServiceMap[ compound_builder_name ] = (*map_itr).second.asString(); + } + } } static bool starts_with(const std::string& text, const char* prefix) { - return text.substr(0, strlen(prefix)) == prefix; + return text.substr(0, strlen(prefix)) == prefix; } // TODO: Build a real services.xml for windows development. // and remove the base_url logic below. std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) const { - std::ostringstream service_url; - // Find the service builder - std::map<std::string, std::string>::const_iterator it = - mServiceMap.find(service_name); - if(it != mServiceMap.end()) - { - // construct the service builder url - LLApp* app = LLApp::instance(); - if(app) - { - // We define a base-url for some development configurations - // In production neither of these are defined and all services have full urls - LLSD base_url; + std::ostringstream service_url; + // Find the service builder + std::map<std::string, std::string>::const_iterator it = + mServiceMap.find(service_name); + if(it != mServiceMap.end()) + { + // construct the service builder url + LLApp* app = LLApp::instance(); + if(app) + { + // We define a base-url for some development configurations + // In production neither of these are defined and all services have full urls + LLSD base_url; - if (starts_with(service_name,"cap")) - { - base_url = app->getOption("cap-base-url"); - } + if (starts_with(service_name,"cap")) + { + base_url = app->getOption("cap-base-url"); + } - if (base_url.asString().empty()) - { - base_url = app->getOption("services-base-url"); - } - service_url << base_url.asString(); - } - service_url << it->second; - } - else - { - LL_WARNS() << "Cannot find service " << service_name << LL_ENDL; - } - return service_url.str(); + if (base_url.asString().empty()) + { + base_url = app->getOption("services-base-url"); + } + service_url << base_url.asString(); + } + service_url << it->second; + } + else + { + LL_WARNS() << "Cannot find service " << service_name << LL_ENDL; + } + return service_url.str(); } std::string LLServiceBuilder::buildServiceURI( - const std::string& service_name, - const LLSD& option_map) const + const std::string& service_name, + const LLSD& option_map) const { - return russ_format(buildServiceURI(service_name), option_map); + return russ_format(buildServiceURI(service_name), option_map); } std::string russ_format(const std::string& format_str, const LLSD& context) { - std::string service_url(format_str); - if(!service_url.empty() && context.isMap()) - { - // throw in a ridiculously large limiter to make sure we don't - // loop forever with bad input. - int iterations = 100; - bool keep_looping = true; - while(keep_looping) - { - if(0 == --iterations) - { - keep_looping = false; - } + std::string service_url(format_str); + if(!service_url.empty() && context.isMap()) + { + // throw in a ridiculously large limiter to make sure we don't + // loop forever with bad input. + int iterations = 100; + bool keep_looping = true; + while(keep_looping) + { + if(0 == --iterations) + { + keep_looping = false; + } - int depth = 0; - int deepest = 0; - bool find_match = false; - std::string::iterator iter(service_url.begin()); - std::string::iterator end(service_url.end()); - std::string::iterator deepest_node(service_url.end()); - std::string::iterator deepest_node_end(service_url.end()); - // parse out the variables to replace by going through {}s - // one at a time, starting with the "deepest" in series - // {{}}, and otherwise replacing right-to-left - for(; iter != end; ++iter) - { - switch(*iter) - { - case '{': - ++depth; - if(depth > deepest) - { - deepest = depth; - deepest_node = iter; - find_match = true; - } - break; - case '}': - --depth; - if(find_match) - { - deepest_node_end = iter; - find_match = false; - } - break; - default: - break; - } - } - if((deepest_node == end) || (deepest_node_end == end)) - { - break; - } - //replace the variable we found in the {} above. - // *NOTE: since the c++ implementation only understands - // params and straight string substitution, so it's a - // known distance of 2 to skip the directive. - std::string key(deepest_node + 2, deepest_node_end); - LLSD value = context[key]; - switch(*(deepest_node + 1)) - { - case '$': - if(value.isDefined()) - { - service_url.replace( - deepest_node, - deepest_node_end + 1, - value.asString()); - } - else - { - LL_WARNS() << "Unknown key: " << key << " in option map: " - << LLSDOStreamer<LLSDNotationFormatter>(context) - << LL_ENDL; - keep_looping = false; - } - break; - case '%': - { - std::string query_str = LLURI::mapToQueryString(value); - service_url.replace( - deepest_node, - deepest_node_end + 1, - query_str); - } - break; - default: - LL_INFOS() << "Unknown directive: " << *(deepest_node + 1) - << LL_ENDL; - keep_looping = false; - break; - } - } - } - if (service_url.find('{') != std::string::npos) - { - LL_WARNS() << "Constructed a likely bogus service URL: " << service_url - << LL_ENDL; - } - return service_url; + int depth = 0; + int deepest = 0; + bool find_match = false; + std::string::iterator iter(service_url.begin()); + std::string::iterator end(service_url.end()); + std::string::iterator deepest_node(service_url.end()); + std::string::iterator deepest_node_end(service_url.end()); + // parse out the variables to replace by going through {}s + // one at a time, starting with the "deepest" in series + // {{}}, and otherwise replacing right-to-left + for(; iter != end; ++iter) + { + switch(*iter) + { + case '{': + ++depth; + if(depth > deepest) + { + deepest = depth; + deepest_node = iter; + find_match = true; + } + break; + case '}': + --depth; + if(find_match) + { + deepest_node_end = iter; + find_match = false; + } + break; + default: + break; + } + } + if((deepest_node == end) || (deepest_node_end == end)) + { + break; + } + //replace the variable we found in the {} above. + // *NOTE: since the c++ implementation only understands + // params and straight string substitution, so it's a + // known distance of 2 to skip the directive. + std::string key(deepest_node + 2, deepest_node_end); + LLSD value = context[key]; + switch(*(deepest_node + 1)) + { + case '$': + if(value.isDefined()) + { + service_url.replace( + deepest_node, + deepest_node_end + 1, + value.asString()); + } + else + { + LL_WARNS() << "Unknown key: " << key << " in option map: " + << LLSDOStreamer<LLSDNotationFormatter>(context) + << LL_ENDL; + keep_looping = false; + } + break; + case '%': + { + std::string query_str = LLURI::mapToQueryString(value); + service_url.replace( + deepest_node, + deepest_node_end + 1, + query_str); + } + break; + default: + LL_INFOS() << "Unknown directive: " << *(deepest_node + 1) + << LL_ENDL; + keep_looping = false; + break; + } + } + } + if (service_url.find('{') != std::string::npos) + { + LL_WARNS() << "Constructed a likely bogus service URL: " << service_url + << LL_ENDL; + } + return service_url; } diff --git a/indra/llmessage/llservicebuilder.h b/indra/llmessage/llservicebuilder.h index 968995edf2..be03534514 100644 --- a/indra/llmessage/llservicebuilder.h +++ b/indra/llmessage/llservicebuilder.h @@ -1,25 +1,25 @@ -/** +/** * @file llservicebuilder.h * @brief Declaration of the LLServiceBuilder class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. -* +* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. -* +* * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. -* +* * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* +* * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,56 +47,56 @@ class LLSD; */ std::string russ_format(const std::string& format_str, const LLSD& context); -/** +/** * @class LLServiceBuilder * @brief This class builds urls for us to use when making web service calls. */ class LLServiceBuilder { - LOG_CLASS(LLServiceBuilder); + LOG_CLASS(LLServiceBuilder); public: - LLServiceBuilder(void) {} - ~LLServiceBuilder(void) {} + LLServiceBuilder(void) {} + ~LLServiceBuilder(void) {} - /** - * @brief Initialize this object with the service definitions. - * - * @param service_filename The services definition files -- services.xml. - */ - void loadServiceDefinitionsFromFile(const std::string& service_filename); + /** + * @brief Initialize this object with the service definitions. + * + * @param service_filename The services definition files -- services.xml. + */ + void loadServiceDefinitionsFromFile(const std::string& service_filename); - /** - * @brief Build a service url if the url needs no construction parameters. - * - * @param service_name The name of the service you want to call. - */ - std::string buildServiceURI(const std::string& service_name) const; + /** + * @brief Build a service url if the url needs no construction parameters. + * + * @param service_name The name of the service you want to call. + */ + std::string buildServiceURI(const std::string& service_name) const; - /** - * @brief Build a service url if the url with construction parameters. - * - * The parameter substitution supports string substituition from RUSS: - * [[Recursive_URL_Substitution_Syntax]] - * @param service_name The name of the service you want to call. - * @param option_map The parameters in a map of name:value for the service. - */ - std::string buildServiceURI( - const std::string& service_name, - const LLSD& option_map) const; + /** + * @brief Build a service url if the url with construction parameters. + * + * The parameter substitution supports string substituition from RUSS: + * [[Recursive_URL_Substitution_Syntax]] + * @param service_name The name of the service you want to call. + * @param option_map The parameters in a map of name:value for the service. + */ + std::string buildServiceURI( + const std::string& service_name, + const LLSD& option_map) const; public: - /** - * @brief Helper method which builds construction state for a service - * - * This method should probably be protected, but we need to test this - * method. - */ - void createServiceDefinition( - const std::string& service_name, - LLSD& service_url); + /** + * @brief Helper method which builds construction state for a service + * + * This method should probably be protected, but we need to test this + * method. + */ + void createServiceDefinition( + const std::string& service_name, + LLSD& service_url); protected: - std::map<std::string, std::string> mServiceMap; + std::map<std::string, std::string> mServiceMap; }; diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp index 9f2f2bcda7..39696ea235 100644 --- a/indra/llmessage/llstoredmessage.cpp +++ b/indra/llmessage/llstoredmessage.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llstoredmessage.cpp - * @brief + * @brief * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h index 6ea150fda3..178b75ab04 100644 --- a/indra/llmessage/llstoredmessage.h +++ b/indra/llmessage/llstoredmessage.h @@ -1,25 +1,25 @@ -/** +/** * @file llstoredmessage.h - * @brief + * @brief * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,12 +38,12 @@ class LLMessageSystem; class LLStoredMessage { public: - LLStoredMessage(const std::string& name, const LLSD& message); + LLStoredMessage(const std::string& name, const LLSD& message); private: - friend class LLMessageSystem; + friend class LLMessageSystem; - LLSD mMessage; - std::string mName; + LLSD mMessage; + std::string mName; }; typedef std::shared_ptr<LLStoredMessage> LLStoredMessagePtr; diff --git a/indra/llmessage/lltaskname.h b/indra/llmessage/lltaskname.h index 5dbd9c6223..413242dc05 100644 --- a/indra/llmessage/lltaskname.h +++ b/indra/llmessage/lltaskname.h @@ -1,4 +1,4 @@ -/** +/** * @file lltaskname.h * @brief This contains the current list of valid tasks and is inluded * into both simulator and viewer @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,7 +29,7 @@ #define LL_LLTASKNAME_H // Current valid tasks -// If you add a taskname here you will have to +// If you add a taskname here you will have to // 1) Add an initializer to init_object() in llscript.cpp // 1.1) Add to object_type_to_task_name() in llregion.cpp // 2) Add display code to LLStupidObject::render2(LLAgent* agentp) in llstupidobject.cpp @@ -37,24 +37,24 @@ typedef enum e_lltask_name { - LLTASK_NULL = 0, // Not a valid task - LLTASK_AGENT = 1, // The player's agent in Linden World - LLTASK_CHILD_AGENT = 2, // Child agents sent to adjacent regions -// LLTASK_BASIC_SHOT, // Simple shot that moves in a straight line -// LLTASK_BIG_SHOT, // Big shot that uses gravity - LLTASK_TREE = 5, // A tree -// LLTASK_BIRD, // a bird -// LLTASK_ATOR, // a predator -// LLTASK_SMOKE, // Smoke poof -// LLTASK_SPARK, // Little spark -// LLTASK_ROCK, // Rock - LLTASK_GRASS = 11, // Grass - LLTASK_PSYS = 12, // particle system test example -// LLTASK_ORACLE, -// LLTASK_DEMON, // Maxwell's demon -// LLTASK_LSL_TEST, // Linden Scripting Language Test Object - LLTASK_PRIMITIVE = 16, -// LLTASK_GHOST = 17, // a ghost (Boo!) - LLTASK_TREE_NEW = 18 + LLTASK_NULL = 0, // Not a valid task + LLTASK_AGENT = 1, // The player's agent in Linden World + LLTASK_CHILD_AGENT = 2, // Child agents sent to adjacent regions +// LLTASK_BASIC_SHOT, // Simple shot that moves in a straight line +// LLTASK_BIG_SHOT, // Big shot that uses gravity + LLTASK_TREE = 5, // A tree +// LLTASK_BIRD, // a bird +// LLTASK_ATOR, // a predator +// LLTASK_SMOKE, // Smoke poof +// LLTASK_SPARK, // Little spark +// LLTASK_ROCK, // Rock + LLTASK_GRASS = 11, // Grass + LLTASK_PSYS = 12, // particle system test example +// LLTASK_ORACLE, +// LLTASK_DEMON, // Maxwell's demon +// LLTASK_LSL_TEST, // Linden Scripting Language Test Object + LLTASK_PRIMITIVE = 16, +// LLTASK_GHOST = 17, // a ghost (Boo!) + LLTASK_TREE_NEW = 18 } ELLTaskName; #endif diff --git a/indra/llmessage/llteleportflags.h b/indra/llmessage/llteleportflags.h index fd1e702832..36f9e8e2c8 100644 --- a/indra/llmessage/llteleportflags.h +++ b/indra/llmessage/llteleportflags.h @@ -1,25 +1,25 @@ -/** +/** * @file llteleportflags.h * @brief Teleport flags * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -27,39 +27,39 @@ #ifndef LL_LLTELEPORTFLAGS_H #define LL_LLTELEPORTFLAGS_H -const U32 TELEPORT_FLAGS_DEFAULT = 0; -const U32 TELEPORT_FLAGS_SET_HOME_TO_TARGET = 1 << 0; // newbie leaving prelude -const U32 TELEPORT_FLAGS_SET_LAST_TO_TARGET = 1 << 1; -const U32 TELEPORT_FLAGS_VIA_LURE = 1 << 2; -const U32 TELEPORT_FLAGS_VIA_LANDMARK = 1 << 3; -const U32 TELEPORT_FLAGS_VIA_LOCATION = 1 << 4; -const U32 TELEPORT_FLAGS_VIA_HOME = 1 << 5; -const U32 TELEPORT_FLAGS_VIA_TELEHUB = 1 << 6; -const U32 TELEPORT_FLAGS_VIA_LOGIN = 1 << 7; -const U32 TELEPORT_FLAGS_VIA_GODLIKE_LURE = 1 << 8; -const U32 TELEPORT_FLAGS_GODLIKE = 1 << 9; -const U32 TELEPORT_FLAGS_911 = 1 << 10; -const U32 TELEPORT_FLAGS_DISABLE_CANCEL = 1 << 11; // Used for llTeleportAgentHome() -const U32 TELEPORT_FLAGS_VIA_REGION_ID = 1 << 12; -const U32 TELEPORT_FLAGS_IS_FLYING = 1 << 13; -const U32 TELEPORT_FLAGS_SHOW_RESET_HOME = 1 << 14; -const U32 TELEPORT_FLAGS_FORCE_REDIRECT = 1 << 15; // used to force a redirect to some random location - used when kicking someone from land. -const U32 TELEPORT_FLAGS_VIA_GLOBAL_COORDS = 1 << 16; -const U32 TELEPORT_FLAGS_WITHIN_REGION = 1 << 17; +const U32 TELEPORT_FLAGS_DEFAULT = 0; +const U32 TELEPORT_FLAGS_SET_HOME_TO_TARGET = 1 << 0; // newbie leaving prelude +const U32 TELEPORT_FLAGS_SET_LAST_TO_TARGET = 1 << 1; +const U32 TELEPORT_FLAGS_VIA_LURE = 1 << 2; +const U32 TELEPORT_FLAGS_VIA_LANDMARK = 1 << 3; +const U32 TELEPORT_FLAGS_VIA_LOCATION = 1 << 4; +const U32 TELEPORT_FLAGS_VIA_HOME = 1 << 5; +const U32 TELEPORT_FLAGS_VIA_TELEHUB = 1 << 6; +const U32 TELEPORT_FLAGS_VIA_LOGIN = 1 << 7; +const U32 TELEPORT_FLAGS_VIA_GODLIKE_LURE = 1 << 8; +const U32 TELEPORT_FLAGS_GODLIKE = 1 << 9; +const U32 TELEPORT_FLAGS_911 = 1 << 10; +const U32 TELEPORT_FLAGS_DISABLE_CANCEL = 1 << 11; // Used for llTeleportAgentHome() +const U32 TELEPORT_FLAGS_VIA_REGION_ID = 1 << 12; +const U32 TELEPORT_FLAGS_IS_FLYING = 1 << 13; +const U32 TELEPORT_FLAGS_SHOW_RESET_HOME = 1 << 14; +const U32 TELEPORT_FLAGS_FORCE_REDIRECT = 1 << 15; // used to force a redirect to some random location - used when kicking someone from land. +const U32 TELEPORT_FLAGS_VIA_GLOBAL_COORDS = 1 << 16; +const U32 TELEPORT_FLAGS_WITHIN_REGION = 1 << 17; + +const U32 TELEPORT_FLAGS_MASK_VIA = TELEPORT_FLAGS_VIA_LURE + | TELEPORT_FLAGS_VIA_LANDMARK + | TELEPORT_FLAGS_VIA_LOCATION + | TELEPORT_FLAGS_VIA_HOME + | TELEPORT_FLAGS_VIA_TELEHUB + | TELEPORT_FLAGS_VIA_LOGIN + | TELEPORT_FLAGS_VIA_REGION_ID; -const U32 TELEPORT_FLAGS_MASK_VIA = TELEPORT_FLAGS_VIA_LURE - | TELEPORT_FLAGS_VIA_LANDMARK - | TELEPORT_FLAGS_VIA_LOCATION - | TELEPORT_FLAGS_VIA_HOME - | TELEPORT_FLAGS_VIA_TELEHUB - | TELEPORT_FLAGS_VIA_LOGIN - | TELEPORT_FLAGS_VIA_REGION_ID; - -const U32 LURE_FLAG_NORMAL_LURE = 1 << 0; -const U32 LURE_FLAG_GODLIKE_LURE = 1 << 1; +const U32 LURE_FLAG_NORMAL_LURE = 1 << 0; +const U32 LURE_FLAG_GODLIKE_LURE = 1 << 1; const U32 LURE_FLAG_GODLIKE_PURSUIT = 1 << 2; #endif diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index 62c53dbe55..758d6d343f 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltemplatemessagebuilder.cpp * @brief LLTemplateMessageBuilder class implementation. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,857 +37,857 @@ #include "v4math.h" LLTemplateMessageBuilder::LLTemplateMessageBuilder(const message_template_name_map_t& name_template_map) : - mCurrentSMessageData(NULL), - mCurrentSMessageTemplate(NULL), - mCurrentSDataBlock(NULL), - mCurrentSMessageName(NULL), - mCurrentSBlockName(NULL), - mbSBuilt(false), - mbSClear(true), - mCurrentSendTotal(0), - mMessageTemplates(name_template_map) + mCurrentSMessageData(NULL), + mCurrentSMessageTemplate(NULL), + mCurrentSDataBlock(NULL), + mCurrentSMessageName(NULL), + mCurrentSBlockName(NULL), + mbSBuilt(false), + mbSClear(true), + mCurrentSendTotal(0), + mMessageTemplates(name_template_map) { } //virtual LLTemplateMessageBuilder::~LLTemplateMessageBuilder() { - delete mCurrentSMessageData; - mCurrentSMessageData = NULL; + delete mCurrentSMessageData; + mCurrentSMessageData = NULL; } // virtual void LLTemplateMessageBuilder::newMessage(const char *name) { - mbSBuilt = false; - mbSClear = false; - - mCurrentSendTotal = 0; - - delete mCurrentSMessageData; - mCurrentSMessageData = NULL; - - char* namep = (char*)name; - if (mMessageTemplates.count(namep) > 0) - { - mCurrentSMessageTemplate = mMessageTemplates.find(name)->second; - mCurrentSMessageData = new LLMsgData(namep); - mCurrentSMessageName = namep; - mCurrentSDataBlock = NULL; - mCurrentSBlockName = NULL; - - // add at one of each block - const LLMessageTemplate* msg_template = mMessageTemplates.find(name)->second; - - if (msg_template->getDeprecation() != MD_NOTDEPRECATED) - { - LL_WARNS() << "Sending deprecated message " << namep << LL_ENDL; - } - - LLMessageTemplate::message_block_map_t::const_iterator iter; - for(iter = msg_template->mMemberBlocks.begin(); - iter != msg_template->mMemberBlocks.end(); - ++iter) - { - LLMessageBlock* ci = *iter; - LLMsgBlkData* tblockp = new LLMsgBlkData(ci->mName, 0); - mCurrentSMessageData->addBlock(tblockp); - } - } - else - { - LL_ERRS() << "newMessage - Message " << name << " not registered" << LL_ENDL; - } + mbSBuilt = false; + mbSClear = false; + + mCurrentSendTotal = 0; + + delete mCurrentSMessageData; + mCurrentSMessageData = NULL; + + char* namep = (char*)name; + if (mMessageTemplates.count(namep) > 0) + { + mCurrentSMessageTemplate = mMessageTemplates.find(name)->second; + mCurrentSMessageData = new LLMsgData(namep); + mCurrentSMessageName = namep; + mCurrentSDataBlock = NULL; + mCurrentSBlockName = NULL; + + // add at one of each block + const LLMessageTemplate* msg_template = mMessageTemplates.find(name)->second; + + if (msg_template->getDeprecation() != MD_NOTDEPRECATED) + { + LL_WARNS() << "Sending deprecated message " << namep << LL_ENDL; + } + + LLMessageTemplate::message_block_map_t::const_iterator iter; + for(iter = msg_template->mMemberBlocks.begin(); + iter != msg_template->mMemberBlocks.end(); + ++iter) + { + LLMessageBlock* ci = *iter; + LLMsgBlkData* tblockp = new LLMsgBlkData(ci->mName, 0); + mCurrentSMessageData->addBlock(tblockp); + } + } + else + { + LL_ERRS() << "newMessage - Message " << name << " not registered" << LL_ENDL; + } } // virtual void LLTemplateMessageBuilder::clearMessage() { - mbSBuilt = false; - mbSClear = true; + mbSBuilt = false; + mbSClear = true; - mCurrentSendTotal = 0; + mCurrentSendTotal = 0; - mCurrentSMessageTemplate = NULL; + mCurrentSMessageTemplate = NULL; - delete mCurrentSMessageData; - mCurrentSMessageData = NULL; + delete mCurrentSMessageData; + mCurrentSMessageData = NULL; - mCurrentSMessageName = NULL; - mCurrentSDataBlock = NULL; - mCurrentSBlockName = NULL; + mCurrentSMessageName = NULL; + mCurrentSDataBlock = NULL; + mCurrentSBlockName = NULL; } // virtual void LLTemplateMessageBuilder::nextBlock(const char* blockname) { - char *bnamep = (char *)blockname; - - if (!mCurrentSMessageTemplate) - { - LL_ERRS() << "newMessage not called prior to setBlock" << LL_ENDL; - return; - } - - // now, does this block exist? - const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep); - if (!template_data) - { - LL_ERRS() << "LLTemplateMessageBuilder::nextBlock " << bnamep - << " not a block in " << mCurrentSMessageTemplate->mName << LL_ENDL; - return; - } - - // ok, have we already set this block? - LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep]; - if (block_data->mBlockNumber == 0) - { - // nope! set this as the current block - block_data->mBlockNumber = 1; - mCurrentSDataBlock = block_data; - mCurrentSBlockName = bnamep; - - // add placeholders for each of the variables - for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin(); - iter != template_data->mMemberVariables.end(); iter++) - { - LLMessageVariable& ci = **iter; - mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); - } - return; - } - else - { - // already have this block. . . - // are we supposed to have a new one? - - // if the block is type MBT_SINGLE this is bad! - if (template_data->mType == MBT_SINGLE) - { - LL_ERRS() << "LLTemplateMessageBuilder::nextBlock called multiple times" - << " for " << bnamep << " but is type MBT_SINGLE" << LL_ENDL; - return; - } - - - // if the block is type MBT_MULTIPLE then we need a known number, - // make sure that we're not exceeding it - if ( (template_data->mType == MBT_MULTIPLE) - &&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber)) - { - LL_ERRS() << "LLTemplateMessageBuilder::nextBlock called " - << mCurrentSDataBlock->mBlockNumber << " times for " << bnamep - << " exceeding " << template_data->mNumber - << " specified in type MBT_MULTIPLE." << LL_ENDL; - return; - } - - // ok, we can make a new one - // modify the name to avoid name collision by adding number to end - S32 count = block_data->mBlockNumber; - - // incrememt base name's count - block_data->mBlockNumber++; - - if (block_data->mBlockNumber > MAX_BLOCKS) - { - LL_ERRS() << "Trying to pack too many blocks into MBT_VARIABLE type " - << "(limited to " << MAX_BLOCKS << ")" << LL_ENDL; - } - - // create new name - // Nota Bene: if things are working correctly, - // mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber == - // mCurrentDataBlock->mBlockNumber + 1 - - char *nbnamep = bnamep + count; - - mCurrentSDataBlock = new LLMsgBlkData(bnamep, count); - mCurrentSDataBlock->mName = nbnamep; - mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock; - - // add placeholders for each of the variables - for (LLMessageBlock::message_variable_map_t::const_iterator - iter = template_data->mMemberVariables.begin(), - end = template_data->mMemberVariables.end(); - iter != end; iter++) - { - LLMessageVariable& ci = **iter; - mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); - } - return; - } + char *bnamep = (char *)blockname; + + if (!mCurrentSMessageTemplate) + { + LL_ERRS() << "newMessage not called prior to setBlock" << LL_ENDL; + return; + } + + // now, does this block exist? + const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep); + if (!template_data) + { + LL_ERRS() << "LLTemplateMessageBuilder::nextBlock " << bnamep + << " not a block in " << mCurrentSMessageTemplate->mName << LL_ENDL; + return; + } + + // ok, have we already set this block? + LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep]; + if (block_data->mBlockNumber == 0) + { + // nope! set this as the current block + block_data->mBlockNumber = 1; + mCurrentSDataBlock = block_data; + mCurrentSBlockName = bnamep; + + // add placeholders for each of the variables + for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin(); + iter != template_data->mMemberVariables.end(); iter++) + { + LLMessageVariable& ci = **iter; + mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); + } + return; + } + else + { + // already have this block. . . + // are we supposed to have a new one? + + // if the block is type MBT_SINGLE this is bad! + if (template_data->mType == MBT_SINGLE) + { + LL_ERRS() << "LLTemplateMessageBuilder::nextBlock called multiple times" + << " for " << bnamep << " but is type MBT_SINGLE" << LL_ENDL; + return; + } + + + // if the block is type MBT_MULTIPLE then we need a known number, + // make sure that we're not exceeding it + if ( (template_data->mType == MBT_MULTIPLE) + &&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber)) + { + LL_ERRS() << "LLTemplateMessageBuilder::nextBlock called " + << mCurrentSDataBlock->mBlockNumber << " times for " << bnamep + << " exceeding " << template_data->mNumber + << " specified in type MBT_MULTIPLE." << LL_ENDL; + return; + } + + // ok, we can make a new one + // modify the name to avoid name collision by adding number to end + S32 count = block_data->mBlockNumber; + + // incrememt base name's count + block_data->mBlockNumber++; + + if (block_data->mBlockNumber > MAX_BLOCKS) + { + LL_ERRS() << "Trying to pack too many blocks into MBT_VARIABLE type " + << "(limited to " << MAX_BLOCKS << ")" << LL_ENDL; + } + + // create new name + // Nota Bene: if things are working correctly, + // mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber == + // mCurrentDataBlock->mBlockNumber + 1 + + char *nbnamep = bnamep + count; + + mCurrentSDataBlock = new LLMsgBlkData(bnamep, count); + mCurrentSDataBlock->mName = nbnamep; + mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock; + + // add placeholders for each of the variables + for (LLMessageBlock::message_variable_map_t::const_iterator + iter = template_data->mMemberVariables.begin(), + end = template_data->mMemberVariables.end(); + iter != end; iter++) + { + LLMessageVariable& ci = **iter; + mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); + } + return; + } } // TODO: Remove this horror... bool LLTemplateMessageBuilder::removeLastBlock() { - if (mCurrentSBlockName) - { - if ( (mCurrentSMessageData) - &&(mCurrentSMessageTemplate)) - { - if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1) - { - // At least one block for the current block name. - - // Store the current block name for future reference. - char *block_name = mCurrentSBlockName; - - // Decrement the sent total by the size of the - // data in the message block that we're currently building. - - const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName); - - for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin(); - iter != template_data->mMemberVariables.end(); iter++) - { - LLMessageVariable& ci = **iter; - mCurrentSendTotal -= ci.getSize(); - } - - - // Now we want to find the block that we're blowing away. - - // Get the number of blocks. - LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name]; - S32 num_blocks = block_data->mBlockNumber; - - // Use the same (suspect?) algorithm that's used to generate - // the names in the nextBlock method to find it. - char *block_getting_whacked = block_name + num_blocks - 1; - LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked]; - delete whacked_data; - mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked); - - if (num_blocks <= 1) - { - // we just blew away the last one, so return false - LL_WARNS() << "not blowing away the only block of message " - << mCurrentSMessageName - << ". Block: " << block_name - << ". Number: " << num_blocks - << LL_ENDL; - return false; - } - else - { - // Decrement the counter. - block_data->mBlockNumber--; - return true; - } - } - } - } - return false; + if (mCurrentSBlockName) + { + if ( (mCurrentSMessageData) + &&(mCurrentSMessageTemplate)) + { + if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1) + { + // At least one block for the current block name. + + // Store the current block name for future reference. + char *block_name = mCurrentSBlockName; + + // Decrement the sent total by the size of the + // data in the message block that we're currently building. + + const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName); + + for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin(); + iter != template_data->mMemberVariables.end(); iter++) + { + LLMessageVariable& ci = **iter; + mCurrentSendTotal -= ci.getSize(); + } + + + // Now we want to find the block that we're blowing away. + + // Get the number of blocks. + LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name]; + S32 num_blocks = block_data->mBlockNumber; + + // Use the same (suspect?) algorithm that's used to generate + // the names in the nextBlock method to find it. + char *block_getting_whacked = block_name + num_blocks - 1; + LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked]; + delete whacked_data; + mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked); + + if (num_blocks <= 1) + { + // we just blew away the last one, so return false + LL_WARNS() << "not blowing away the only block of message " + << mCurrentSMessageName + << ". Block: " << block_name + << ". Number: " << num_blocks + << LL_ENDL; + return false; + } + else + { + // Decrement the counter. + block_data->mBlockNumber--; + return true; + } + } + } + } + return false; } // add data to variable in current block void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type, S32 size) { - char *vnamep = (char *)varname; - - // do we have a current message? - if (!mCurrentSMessageTemplate) - { - LL_ERRS() << "newMessage not called prior to addData" << LL_ENDL; - return; - } - - // do we have a current block? - if (!mCurrentSDataBlock) - { - LL_ERRS() << "setBlock not called prior to addData" << LL_ENDL; - return; - } - - // kewl, add the data if it exists - const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep); - if (!var_data || !var_data->getName()) - { - LL_ERRS() << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << LL_ENDL; - return; - } - - // ok, it seems ok. . . are we the correct size? - if (var_data->getType() == MVT_VARIABLE) - { - // Variable 1 can only store 255 bytes, make sure our data is smaller - if ((var_data->getSize() == 1) && - (size > 255)) - { - LL_WARNS() << "Field " << varname << " is a Variable 1 but program " - << "attempted to stuff more than 255 bytes in " - << "(" << size << "). Clamping size and truncating data." << LL_ENDL; - size = 255; - char *truncate = (char *)data; - truncate[254] = 0; // array size is 255 but the last element index is 254 - } - - // no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as - mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize()); - mCurrentSendTotal += size; - } - else - { - if (size != var_data->getSize()) - { - LL_ERRS() << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size " - << var_data->getSize() << LL_ENDL; - return; - } - // alright, smash it in - mCurrentSDataBlock->addData(vnamep, data, size, type); - mCurrentSendTotal += size; - } + char *vnamep = (char *)varname; + + // do we have a current message? + if (!mCurrentSMessageTemplate) + { + LL_ERRS() << "newMessage not called prior to addData" << LL_ENDL; + return; + } + + // do we have a current block? + if (!mCurrentSDataBlock) + { + LL_ERRS() << "setBlock not called prior to addData" << LL_ENDL; + return; + } + + // kewl, add the data if it exists + const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep); + if (!var_data || !var_data->getName()) + { + LL_ERRS() << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << LL_ENDL; + return; + } + + // ok, it seems ok. . . are we the correct size? + if (var_data->getType() == MVT_VARIABLE) + { + // Variable 1 can only store 255 bytes, make sure our data is smaller + if ((var_data->getSize() == 1) && + (size > 255)) + { + LL_WARNS() << "Field " << varname << " is a Variable 1 but program " + << "attempted to stuff more than 255 bytes in " + << "(" << size << "). Clamping size and truncating data." << LL_ENDL; + size = 255; + char *truncate = (char *)data; + truncate[254] = 0; // array size is 255 but the last element index is 254 + } + + // no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as + mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize()); + mCurrentSendTotal += size; + } + else + { + if (size != var_data->getSize()) + { + LL_ERRS() << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size " + << var_data->getSize() << LL_ENDL; + return; + } + // alright, smash it in + mCurrentSDataBlock->addData(vnamep, data, size, type); + mCurrentSendTotal += size; + } } // add data to variable in current block - fails if variable isn't MVT_FIXED void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type) { - char *vnamep = (char *)varname; - - // do we have a current message? - if (!mCurrentSMessageTemplate) - { - LL_ERRS() << "newMessage not called prior to addData" << LL_ENDL; - return; - } - - // do we have a current block? - if (!mCurrentSDataBlock) - { - LL_ERRS() << "setBlock not called prior to addData" << LL_ENDL; - return; - } - - // kewl, add the data if it exists - const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep); - if (!var_data->getName()) - { - LL_ERRS() << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << LL_ENDL; - return; - } - - // ok, it seems ok. . . are we MVT_VARIABLE? - if (var_data->getType() == MVT_VARIABLE) - { - // nope - LL_ERRS() << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << LL_ENDL; - return; - } - else - { - mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type); - mCurrentSendTotal += var_data->getSize(); - } -} - -void LLTemplateMessageBuilder::addBinaryData(const char *varname, - const void *data, S32 size) -{ - addData(varname, data, MVT_FIXED, size); + char *vnamep = (char *)varname; + + // do we have a current message? + if (!mCurrentSMessageTemplate) + { + LL_ERRS() << "newMessage not called prior to addData" << LL_ENDL; + return; + } + + // do we have a current block? + if (!mCurrentSDataBlock) + { + LL_ERRS() << "setBlock not called prior to addData" << LL_ENDL; + return; + } + + // kewl, add the data if it exists + const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep); + if (!var_data->getName()) + { + LL_ERRS() << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << LL_ENDL; + return; + } + + // ok, it seems ok. . . are we MVT_VARIABLE? + if (var_data->getType() == MVT_VARIABLE) + { + // nope + LL_ERRS() << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << LL_ENDL; + return; + } + else + { + mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type); + mCurrentSendTotal += var_data->getSize(); + } +} + +void LLTemplateMessageBuilder::addBinaryData(const char *varname, + const void *data, S32 size) +{ + addData(varname, data, MVT_FIXED, size); } void LLTemplateMessageBuilder::addS8(const char *varname, S8 s) { - addData(varname, &s, MVT_S8, sizeof(s)); + addData(varname, &s, MVT_S8, sizeof(s)); } void LLTemplateMessageBuilder::addU8(const char *varname, U8 u) { - addData(varname, &u, MVT_U8, sizeof(u)); + addData(varname, &u, MVT_U8, sizeof(u)); } void LLTemplateMessageBuilder::addS16(const char *varname, S16 i) { - addData(varname, &i, MVT_S16, sizeof(i)); + addData(varname, &i, MVT_S16, sizeof(i)); } void LLTemplateMessageBuilder::addU16(const char *varname, U16 i) { - addData(varname, &i, MVT_U16, sizeof(i)); + addData(varname, &i, MVT_U16, sizeof(i)); } void LLTemplateMessageBuilder::addF32(const char *varname, F32 f) { - addData(varname, &f, MVT_F32, sizeof(f)); + addData(varname, &f, MVT_F32, sizeof(f)); } void LLTemplateMessageBuilder::addS32(const char *varname, S32 s) { - addData(varname, &s, MVT_S32, sizeof(s)); + addData(varname, &s, MVT_S32, sizeof(s)); } void LLTemplateMessageBuilder::addU32(const char *varname, U32 u) { - addData(varname, &u, MVT_U32, sizeof(u)); + addData(varname, &u, MVT_U32, sizeof(u)); } void LLTemplateMessageBuilder::addU64(const char *varname, U64 lu) { - addData(varname, &lu, MVT_U64, sizeof(lu)); + addData(varname, &lu, MVT_U64, sizeof(lu)); } void LLTemplateMessageBuilder::addF64(const char *varname, F64 d) { - addData(varname, &d, MVT_F64, sizeof(d)); + addData(varname, &d, MVT_F64, sizeof(d)); } void LLTemplateMessageBuilder::addIPAddr(const char *varname, U32 u) { - addData(varname, &u, MVT_IP_ADDR, sizeof(u)); + addData(varname, &u, MVT_IP_ADDR, sizeof(u)); } void LLTemplateMessageBuilder::addIPPort(const char *varname, U16 u) { - u = htons(u); - addData(varname, &u, MVT_IP_PORT, sizeof(u)); + u = htons(u); + addData(varname, &u, MVT_IP_PORT, sizeof(u)); } void LLTemplateMessageBuilder::addBOOL(const char* varname, bool b) { - U8 temp = (b != 0); - addData(varname, &temp, MVT_BOOL, sizeof(temp)); + U8 temp = (b != 0); + addData(varname, &temp, MVT_BOOL, sizeof(temp)); } void LLTemplateMessageBuilder::addString(const char* varname, const char* s) { - if (s) - addData( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */ - else - addData( varname, NULL, MVT_VARIABLE, 0); + if (s) + addData( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */ + else + addData( varname, NULL, MVT_VARIABLE, 0); } void LLTemplateMessageBuilder::addString(const char* varname, const std::string& s) { - if (s.size()) - addData( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1); - else - addData( varname, NULL, MVT_VARIABLE, 0); + if (s.size()) + addData( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1); + else + addData( varname, NULL, MVT_VARIABLE, 0); } void LLTemplateMessageBuilder::addVector3(const char *varname, const LLVector3& vec) { - addData(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV)); + addData(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV)); } void LLTemplateMessageBuilder::addVector4(const char *varname, const LLVector4& vec) { - addData(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV)); + addData(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV)); } void LLTemplateMessageBuilder::addVector3d(const char *varname, const LLVector3d& vec) { - addData(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV)); + addData(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV)); } void LLTemplateMessageBuilder::addQuat(const char *varname, const LLQuaternion& quat) { - addData(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3)); + addData(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3)); } void LLTemplateMessageBuilder::addUUID(const char *varname, const LLUUID& uuid) { - addData(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData)); + addData(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData)); } static S32 zero_code(U8 **data, U32 *data_size) { - // Encoded send buffer needs to be slightly larger since the zero - // coding can potentially increase the size of the send data. - static U8 encodedSendBuffer[2 * MAX_BUFFER_SIZE]; + // Encoded send buffer needs to be slightly larger since the zero + // coding can potentially increase the size of the send data. + static U8 encodedSendBuffer[2 * MAX_BUFFER_SIZE]; - S32 count = *data_size; - - S32 net_gain = 0; - U8 num_zeroes = 0; - - U8 *inptr = (U8 *)*data; - U8 *outptr = (U8 *)encodedSendBuffer; + S32 count = *data_size; + + S32 net_gain = 0; + U8 num_zeroes = 0; + + U8 *inptr = (U8 *)*data; + U8 *outptr = (U8 *)encodedSendBuffer; // skip the packet id field - for (U32 ii = 0; ii < LL_PACKET_ID_SIZE ; ++ii) - { - count--; - *outptr++ = *inptr++; - } + for (U32 ii = 0; ii < LL_PACKET_ID_SIZE ; ++ii) + { + count--; + *outptr++ = *inptr++; + } // build encoded packet, keeping track of net size gain -// sequential zero bytes are encoded as 0 [U8 count] +// sequential zero bytes are encoded as 0 [U8 count] // with 0 0 [count] representing wrap (>256 zeroes) - while (count--) - { - if (!(*inptr)) // in a zero count - { - if (num_zeroes) - { - if (++num_zeroes > 254) - { - *outptr++ = num_zeroes; - num_zeroes = 0; - } - net_gain--; // subseqent zeroes save one - } - else - { - *outptr++ = 0; - net_gain++; // starting a zero count adds one - num_zeroes = 1; - } - inptr++; - } - else - { - if (num_zeroes) - { - *outptr++ = num_zeroes; - num_zeroes = 0; - } - *outptr++ = *inptr++; - } - } - - if (num_zeroes) - { - *outptr++ = num_zeroes; - } - - if (net_gain < 0) - { - // TODO: babbage: reinstate stat collecting... - //mCompressedPacketsOut++; - //mUncompressedBytesOut += *data_size; - - *data = encodedSendBuffer; - *data_size += net_gain; - encodedSendBuffer[0] |= LL_ZERO_CODE_FLAG; // set the head bit to indicate zero coding - - //mCompressedBytesOut += *data_size; - - } - //mTotalBytesOut += *data_size; - - return(net_gain); + while (count--) + { + if (!(*inptr)) // in a zero count + { + if (num_zeroes) + { + if (++num_zeroes > 254) + { + *outptr++ = num_zeroes; + num_zeroes = 0; + } + net_gain--; // subseqent zeroes save one + } + else + { + *outptr++ = 0; + net_gain++; // starting a zero count adds one + num_zeroes = 1; + } + inptr++; + } + else + { + if (num_zeroes) + { + *outptr++ = num_zeroes; + num_zeroes = 0; + } + *outptr++ = *inptr++; + } + } + + if (num_zeroes) + { + *outptr++ = num_zeroes; + } + + if (net_gain < 0) + { + // TODO: babbage: reinstate stat collecting... + //mCompressedPacketsOut++; + //mUncompressedBytesOut += *data_size; + + *data = encodedSendBuffer; + *data_size += net_gain; + encodedSendBuffer[0] |= LL_ZERO_CODE_FLAG; // set the head bit to indicate zero coding + + //mCompressedBytesOut += *data_size; + + } + //mTotalBytesOut += *data_size; + + return(net_gain); } void LLTemplateMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length) { - if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding()) - { - zero_code(&buf_ptr, &buffer_length); - } + if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding()) + { + zero_code(&buf_ptr, &buffer_length); + } } bool LLTemplateMessageBuilder::isMessageFull(const char* blockname) const { - if(mCurrentSendTotal > MTUBYTES) - { - return true; - } - if(!blockname) - { - return false; - } - char* bnamep = (char*)blockname; - S32 max; - - const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep); - - switch(template_data->mType) - { - case MBT_SINGLE: - max = 1; - break; - case MBT_MULTIPLE: - max = template_data->mNumber; - break; - case MBT_VARIABLE: - default: - max = MAX_BLOCKS; - break; - } - if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max) - { - return true; - } - return false; + if(mCurrentSendTotal > MTUBYTES) + { + return true; + } + if(!blockname) + { + return false; + } + char* bnamep = (char*)blockname; + S32 max; + + const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep); + + switch(template_data->mType) + { + case MBT_SINGLE: + max = 1; + break; + case MBT_MULTIPLE: + max = template_data->mNumber; + break; + case MBT_VARIABLE: + default: + max = MAX_BLOCKS; + break; + } + if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max) + { + return true; + } + return false; } static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* template_data, LLMsgData* message_data) { - S32 result = 0; - LLMsgData::msg_blk_data_map_t::const_iterator block_iter = message_data->mMemberBlocks.find(template_data->mName); - const LLMsgBlkData* mbci = block_iter->second; - - // ok, if this is the first block of a repeating pack, set - // block_count and, if it's type MBT_VARIABLE encode a byte - // for how many there are - S32 block_count = mbci->mBlockNumber; - if (template_data->mType == MBT_VARIABLE) - { - // remember that mBlockNumber is a S32 - U8 temp_block_number = (U8)mbci->mBlockNumber; - if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE) - { - memcpy(&buffer[result], &temp_block_number, sizeof(U8)); - result += sizeof(U8); - } - else - { - // Just reporting error is likely not enough. Need - // to check how to abort or error out gracefully - // from this function. XXXTBD - LL_ERRS() << "buildBlock failed. Message excedding " - << "sendBuffersize." << LL_ENDL; - } - } - else if (template_data->mType == MBT_MULTIPLE) - { - if (block_count != template_data->mNumber) - { - // nope! need to fill it in all the way! - LL_ERRS() << "Block " << mbci->mName - << " is type MBT_MULTIPLE but only has data for " - << block_count << " out of its " - << template_data->mNumber << " blocks" << LL_ENDL; - } - } - - while(block_count > 0) - { - // now loop through the variables - for (LLMsgBlkData::msg_var_data_map_t::const_iterator iter = mbci->mMemberVarData.begin(); - iter != mbci->mMemberVarData.end(); iter++) - { - const LLMsgVarData& mvci = *iter; - if (mvci.getSize() == -1) - { - // oops, this variable wasn't ever set! - LL_ERRS() << "The variable " << mvci.getName() << " in block " - << mbci->mName << " of message " - << template_data->mName - << " wasn't set prior to buildMessage call" << LL_ENDL; - } - else - { - S32 data_size = mvci.getDataSize(); - if(data_size > 0) - { - // The type is MVT_VARIABLE, which means that we - // need to encode a size argument. Otherwise, - // there is no need. - S32 size = mvci.getSize(); - U8 sizeb; - U16 sizeh; - switch(data_size) - { - case 1: - sizeb = size; - htolememcpy(&buffer[result], &sizeb, MVT_U8, 1); - break; - case 2: - sizeh = size; - htolememcpy(&buffer[result], &sizeh, MVT_U16, 2); - break; - case 4: - htolememcpy(&buffer[result], &size, MVT_S32, 4); - break; - default: - LL_ERRS() << "Attempting to build variable field with unknown size of " << size << LL_ENDL; - break; - } - result += mvci.getDataSize(); - } - - // if there is any data to pack, pack it - if((mvci.getData() != NULL) && mvci.getSize()) - { - if(result + mvci.getSize() < buffer_size) - { - memcpy( - &buffer[result], - mvci.getData(), - mvci.getSize()); - result += mvci.getSize(); - } - else - { - // Just reporting error is likely not - // enough. Need to check how to abort or error - // out gracefully from this function. XXXTBD - LL_ERRS() << "buildBlock failed. " - << "Attempted to pack " - << (result + mvci.getSize()) - << " bytes into a buffer with size " - << buffer_size << "." << LL_ENDL; - } - } - } - } - - --block_count; - - if (block_iter != message_data->mMemberBlocks.end()) - { - ++block_iter; - if (block_iter != message_data->mMemberBlocks.end()) - { - mbci = block_iter->second; - } - } - } - - return result; + S32 result = 0; + LLMsgData::msg_blk_data_map_t::const_iterator block_iter = message_data->mMemberBlocks.find(template_data->mName); + const LLMsgBlkData* mbci = block_iter->second; + + // ok, if this is the first block of a repeating pack, set + // block_count and, if it's type MBT_VARIABLE encode a byte + // for how many there are + S32 block_count = mbci->mBlockNumber; + if (template_data->mType == MBT_VARIABLE) + { + // remember that mBlockNumber is a S32 + U8 temp_block_number = (U8)mbci->mBlockNumber; + if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE) + { + memcpy(&buffer[result], &temp_block_number, sizeof(U8)); + result += sizeof(U8); + } + else + { + // Just reporting error is likely not enough. Need + // to check how to abort or error out gracefully + // from this function. XXXTBD + LL_ERRS() << "buildBlock failed. Message excedding " + << "sendBuffersize." << LL_ENDL; + } + } + else if (template_data->mType == MBT_MULTIPLE) + { + if (block_count != template_data->mNumber) + { + // nope! need to fill it in all the way! + LL_ERRS() << "Block " << mbci->mName + << " is type MBT_MULTIPLE but only has data for " + << block_count << " out of its " + << template_data->mNumber << " blocks" << LL_ENDL; + } + } + + while(block_count > 0) + { + // now loop through the variables + for (LLMsgBlkData::msg_var_data_map_t::const_iterator iter = mbci->mMemberVarData.begin(); + iter != mbci->mMemberVarData.end(); iter++) + { + const LLMsgVarData& mvci = *iter; + if (mvci.getSize() == -1) + { + // oops, this variable wasn't ever set! + LL_ERRS() << "The variable " << mvci.getName() << " in block " + << mbci->mName << " of message " + << template_data->mName + << " wasn't set prior to buildMessage call" << LL_ENDL; + } + else + { + S32 data_size = mvci.getDataSize(); + if(data_size > 0) + { + // The type is MVT_VARIABLE, which means that we + // need to encode a size argument. Otherwise, + // there is no need. + S32 size = mvci.getSize(); + U8 sizeb; + U16 sizeh; + switch(data_size) + { + case 1: + sizeb = size; + htolememcpy(&buffer[result], &sizeb, MVT_U8, 1); + break; + case 2: + sizeh = size; + htolememcpy(&buffer[result], &sizeh, MVT_U16, 2); + break; + case 4: + htolememcpy(&buffer[result], &size, MVT_S32, 4); + break; + default: + LL_ERRS() << "Attempting to build variable field with unknown size of " << size << LL_ENDL; + break; + } + result += mvci.getDataSize(); + } + + // if there is any data to pack, pack it + if((mvci.getData() != NULL) && mvci.getSize()) + { + if(result + mvci.getSize() < buffer_size) + { + memcpy( + &buffer[result], + mvci.getData(), + mvci.getSize()); + result += mvci.getSize(); + } + else + { + // Just reporting error is likely not + // enough. Need to check how to abort or error + // out gracefully from this function. XXXTBD + LL_ERRS() << "buildBlock failed. " + << "Attempted to pack " + << (result + mvci.getSize()) + << " bytes into a buffer with size " + << buffer_size << "." << LL_ENDL; + } + } + } + } + + --block_count; + + if (block_iter != message_data->mMemberBlocks.end()) + { + ++block_iter; + if (block_iter != message_data->mMemberBlocks.end()) + { + mbci = block_iter->second; + } + } + } + + return result; } // make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer U32 LLTemplateMessageBuilder::buildMessage( - U8* buffer, - U32 buffer_size, - U8 offset_to_data) -{ - // basic algorithm is to loop through the various pieces, building - // size and offset info if we encounter a -1 for mSize at any - // point that variable wasn't given data - - // do we have a current message? - if (!mCurrentSMessageTemplate) - { - LL_ERRS() << "newMessage not called prior to buildMessage" << LL_ENDL; - return 0; - } - - // leave room for flags, packet sequence #, and data offset - // information. - buffer[PHL_OFFSET] = offset_to_data; - U32 result = LL_PACKET_ID_SIZE; - - // encode message number and adjust total_offset - if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH) - { + U8* buffer, + U32 buffer_size, + U8 offset_to_data) +{ + // basic algorithm is to loop through the various pieces, building + // size and offset info if we encounter a -1 for mSize at any + // point that variable wasn't given data + + // do we have a current message? + if (!mCurrentSMessageTemplate) + { + LL_ERRS() << "newMessage not called prior to buildMessage" << LL_ENDL; + return 0; + } + + // leave room for flags, packet sequence #, and data offset + // information. + buffer[PHL_OFFSET] = offset_to_data; + U32 result = LL_PACKET_ID_SIZE; + + // encode message number and adjust total_offset + if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH) + { // old, endian-dependant way -// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8)); +// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8)); // new, independant way - buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber; - result += sizeof(U8); - } - else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM) - { - U8 temp = 255; - memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ - result += sizeof(U8); - - // mask off unsightly bits - temp = mCurrentSMessageTemplate->mMessageNumber & 255; - memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ - result += sizeof(U8); - } - else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW) - { - U8 temp = 255; - U16 message_num; - memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ - result += sizeof(U8); - memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ - result += sizeof(U8); - - // mask off unsightly bits - message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF; - - // convert to network byte order - message_num = htons(message_num); - memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/ - result += sizeof(U16); - } - else - { - LL_ERRS() << "unexpected message frequency in buildMessage" << LL_ENDL; - return 0; - } - - // fast forward through the offset and build the message - result += offset_to_data; - for(LLMessageTemplate::message_block_map_t::const_iterator - iter = mCurrentSMessageTemplate->mMemberBlocks.begin(), - end = mCurrentSMessageTemplate->mMemberBlocks.end(); - iter != end; - ++iter) - { - result += buildBlock(buffer + result, buffer_size - result, *iter, mCurrentSMessageData); - } - mbSBuilt = true; - - return result; + buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber; + result += sizeof(U8); + } + else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM) + { + U8 temp = 255; + memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ + result += sizeof(U8); + + // mask off unsightly bits + temp = mCurrentSMessageTemplate->mMessageNumber & 255; + memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ + result += sizeof(U8); + } + else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW) + { + U8 temp = 255; + U16 message_num; + memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ + result += sizeof(U8); + memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/ + result += sizeof(U8); + + // mask off unsightly bits + message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF; + + // convert to network byte order + message_num = htons(message_num); + memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/ + result += sizeof(U16); + } + else + { + LL_ERRS() << "unexpected message frequency in buildMessage" << LL_ENDL; + return 0; + } + + // fast forward through the offset and build the message + result += offset_to_data; + for(LLMessageTemplate::message_block_map_t::const_iterator + iter = mCurrentSMessageTemplate->mMemberBlocks.begin(), + end = mCurrentSMessageTemplate->mMemberBlocks.end(); + iter != end; + ++iter) + { + result += buildBlock(buffer + result, buffer_size - result, *iter, mCurrentSMessageData); + } + mbSBuilt = true; + + return result; } void LLTemplateMessageBuilder::copyFromMessageData(const LLMsgData& data) { - // copy the blocks - // counting variables used to encode multiple block info - S32 block_count = 0; + // copy the blocks + // counting variables used to encode multiple block info + S32 block_count = 0; char *block_name = NULL; - // loop through msg blocks to loop through variables, totalling up size - // data and filling the new (send) message - LLMsgData::msg_blk_data_map_t::const_iterator iter = - data.mMemberBlocks.begin(); - LLMsgData::msg_blk_data_map_t::const_iterator end = - data.mMemberBlocks.end(); - for(; iter != end; ++iter) - { - const LLMsgBlkData* mbci = iter->second; - if(!mbci) continue; - - // do we need to encode a block code? - if (block_count == 0) - { - block_count = mbci->mBlockNumber; - block_name = (char *)mbci->mName; - } - - // counting down mutliple blocks - block_count--; - - nextBlock(block_name); - - // now loop through the variables - LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); - LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); - - for(; dit != dend; ++dit) - { - const LLMsgVarData& mvci = *dit; - addData(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize()); - } - } -} - -//virtual + // loop through msg blocks to loop through variables, totalling up size + // data and filling the new (send) message + LLMsgData::msg_blk_data_map_t::const_iterator iter = + data.mMemberBlocks.begin(); + LLMsgData::msg_blk_data_map_t::const_iterator end = + data.mMemberBlocks.end(); + for(; iter != end; ++iter) + { + const LLMsgBlkData* mbci = iter->second; + if(!mbci) continue; + + // do we need to encode a block code? + if (block_count == 0) + { + block_count = mbci->mBlockNumber; + block_name = (char *)mbci->mName; + } + + // counting down mutliple blocks + block_count--; + + nextBlock(block_name); + + // now loop through the variables + LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); + LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); + + for(; dit != dend; ++dit) + { + const LLMsgVarData& mvci = *dit; + addData(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize()); + } + } +} + +//virtual void LLTemplateMessageBuilder::copyFromLLSD(const LLSD&) { - // TODO + // TODO } //virtual void LLTemplateMessageBuilder::setBuilt(bool b) { mbSBuilt = b; } -//virtual +//virtual bool LLTemplateMessageBuilder::isBuilt() const {return mbSBuilt;} -//virtual +//virtual bool LLTemplateMessageBuilder::isClear() const {return mbSClear;} -//virtual +//virtual S32 LLTemplateMessageBuilder::getMessageSize() {return mCurrentSendTotal;} -//virtual -const char* LLTemplateMessageBuilder::getMessageName() const +//virtual +const char* LLTemplateMessageBuilder::getMessageName() const { - return mCurrentSMessageName; + return mCurrentSMessageName; } diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h index f02ed0c06d..b86ec4d87d 100644 --- a/indra/llmessage/lltemplatemessagebuilder.h +++ b/indra/llmessage/lltemplatemessagebuilder.h @@ -1,25 +1,25 @@ -/** +/** * @file lltemplatemessagebuilder.h * @brief Declaration of LLTemplateMessageBuilder class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,76 +40,76 @@ class LLMessageTemplate; class LLTemplateMessageBuilder : public LLMessageBuilder { public: - - typedef std::map<const char* , LLMessageTemplate*> message_template_name_map_t; - - LLTemplateMessageBuilder(const message_template_name_map_t&); - virtual ~LLTemplateMessageBuilder(); - - virtual void newMessage(const char* name); - - virtual void nextBlock(const char* blockname); - virtual bool removeLastBlock(); // TODO: babbage: remove this horror... - - /** All add* methods expect pointers to canonical varname strings. */ - virtual void addBinaryData(const char *varname, const void *data, - S32 size); - virtual void addBOOL(const char* varname, bool b); - virtual void addS8(const char* varname, S8 s); - virtual void addU8(const char* varname, U8 u); - virtual void addS16(const char* varname, S16 i); - virtual void addU16(const char* varname, U16 i); - virtual void addF32(const char* varname, F32 f); - virtual void addS32(const char* varname, S32 s); - virtual void addU32(const char* varname, U32 u); - virtual void addU64(const char* varname, U64 lu); - virtual void addF64(const char* varname, F64 d); - virtual void addVector3(const char* varname, const LLVector3& vec); - virtual void addVector4(const char* varname, const LLVector4& vec); - virtual void addVector3d(const char* varname, const LLVector3d& vec); - virtual void addQuat(const char* varname, const LLQuaternion& quat); - virtual void addUUID(const char* varname, const LLUUID& uuid); - virtual void addIPAddr(const char* varname, const U32 ip); - virtual void addIPPort(const char* varname, const U16 port); - virtual void addString(const char* varname, const char* s); - virtual void addString(const char* varname, const std::string& s); - - virtual bool isMessageFull(const char* blockname) const; - virtual void compressMessage(U8*& buf_ptr, U32& buffer_length); - - virtual bool isBuilt() const; - virtual bool isClear() const; - virtual U32 buildMessage(U8* buffer, U32 buffer_size, U8 offset_to_data); + + typedef std::map<const char* , LLMessageTemplate*> message_template_name_map_t; + + LLTemplateMessageBuilder(const message_template_name_map_t&); + virtual ~LLTemplateMessageBuilder(); + + virtual void newMessage(const char* name); + + virtual void nextBlock(const char* blockname); + virtual bool removeLastBlock(); // TODO: babbage: remove this horror... + + /** All add* methods expect pointers to canonical varname strings. */ + virtual void addBinaryData(const char *varname, const void *data, + S32 size); + virtual void addBOOL(const char* varname, bool b); + virtual void addS8(const char* varname, S8 s); + virtual void addU8(const char* varname, U8 u); + virtual void addS16(const char* varname, S16 i); + virtual void addU16(const char* varname, U16 i); + virtual void addF32(const char* varname, F32 f); + virtual void addS32(const char* varname, S32 s); + virtual void addU32(const char* varname, U32 u); + virtual void addU64(const char* varname, U64 lu); + virtual void addF64(const char* varname, F64 d); + virtual void addVector3(const char* varname, const LLVector3& vec); + virtual void addVector4(const char* varname, const LLVector4& vec); + virtual void addVector3d(const char* varname, const LLVector3d& vec); + virtual void addQuat(const char* varname, const LLQuaternion& quat); + virtual void addUUID(const char* varname, const LLUUID& uuid); + virtual void addIPAddr(const char* varname, const U32 ip); + virtual void addIPPort(const char* varname, const U16 port); + virtual void addString(const char* varname, const char* s); + virtual void addString(const char* varname, const std::string& s); + + virtual bool isMessageFull(const char* blockname) const; + virtual void compressMessage(U8*& buf_ptr, U32& buffer_length); + + virtual bool isBuilt() const; + virtual bool isClear() const; + virtual U32 buildMessage(U8* buffer, U32 buffer_size, U8 offset_to_data); /**< Return built message size */ - - virtual void clearMessage(); - // TODO: babbage: remove this horror. - virtual void setBuilt(bool b); + virtual void clearMessage(); + + // TODO: babbage: remove this horror. + virtual void setBuilt(bool b); - virtual S32 getMessageSize(); - virtual const char* getMessageName() const; + virtual S32 getMessageSize(); + virtual const char* getMessageName() const; - virtual void copyFromMessageData(const LLMsgData& data); - virtual void copyFromLLSD(const LLSD&); + virtual void copyFromMessageData(const LLMsgData& data); + virtual void copyFromLLSD(const LLSD&); - LLMsgData* getCurrentMessage() const { return mCurrentSMessageData; } + LLMsgData* getCurrentMessage() const { return mCurrentSMessageData; } private: - void addData(const char* varname, const void* data, - EMsgVariableType type, S32 size); - - void addData(const char* varname, const void* data, - EMsgVariableType type); - - LLMsgData* mCurrentSMessageData; - const LLMessageTemplate* mCurrentSMessageTemplate; - LLMsgBlkData* mCurrentSDataBlock; - char* mCurrentSMessageName; - char* mCurrentSBlockName; - bool mbSBuilt; - bool mbSClear; - S32 mCurrentSendTotal; - const message_template_name_map_t& mMessageTemplates; + void addData(const char* varname, const void* data, + EMsgVariableType type, S32 size); + + void addData(const char* varname, const void* data, + EMsgVariableType type); + + LLMsgData* mCurrentSMessageData; + const LLMessageTemplate* mCurrentSMessageTemplate; + LLMsgBlkData* mCurrentSDataBlock; + char* mCurrentSMessageName; + char* mCurrentSBlockName; + bool mbSBuilt; + bool mbSClear; + S32 mCurrentSendTotal; + const message_template_name_map_t& mMessageTemplates; }; #endif // LL_LLTEMPLATEMESSAGEBUILDER_H diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp index ee7a4e7e71..267c201705 100644 --- a/indra/llmessage/lltemplatemessagedispatcher.cpp +++ b/indra/llmessage/lltemplatemessagedispatcher.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,33 +35,33 @@ LLTemplateMessageDispatcher::LLTemplateMessageDispatcher(LLTemplateMessageReader &template_message_reader) : - mTemplateMessageReader(template_message_reader) + mTemplateMessageReader(template_message_reader) { } void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep) + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) { - std::vector<U8> data = message["body"]["binary-template-data"].asBinary(); - U32 size = data.size(); - if(size == 0) - { - return; - } + std::vector<U8> data = message["body"]["binary-template-data"].asBinary(); + U32 size = data.size(); + if(size == 0) + { + return; + } - LLHost host; - host = gMessageSystem->getSender(); + LLHost host; + host = gMessageSystem->getSender(); - bool validate_message = mTemplateMessageReader.validateMessage(&(data[0]), data.size(), host, true); + bool validate_message = mTemplateMessageReader.validateMessage(&(data[0]), data.size(), host, true); - if (validate_message) - { - mTemplateMessageReader.readMessage(&(data[0]),host); - } - else - { - gMessageSystem->clearReceiveState(); - } + if (validate_message) + { + mTemplateMessageReader.readMessage(&(data[0]),host); + } + else + { + gMessageSystem->clearReceiveState(); + } } diff --git a/indra/llmessage/lltemplatemessagedispatcher.h b/indra/llmessage/lltemplatemessagedispatcher.h index fe77f92074..f33e96bb9e 100644 --- a/indra/llmessage/lltemplatemessagedispatcher.h +++ b/indra/llmessage/lltemplatemessagedispatcher.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,13 +36,13 @@ class LLTemplateMessageDispatcher { public: - LLTemplateMessageDispatcher(LLTemplateMessageReader& template_message_reader); - void dispatch(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep); + LLTemplateMessageDispatcher(LLTemplateMessageReader& template_message_reader); + void dispatch(const std::string& msg_name, + const LLSD& message, + LLHTTPNode::ResponsePtr responsep); private: - LLTemplateMessageReader &mTemplateMessageReader; + LLTemplateMessageReader &mTemplateMessageReader; }; #endif // LLTEMPLATEMESSAGEDISPATCHER_H diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index 064c6e5bd4..b62288590e 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltemplatemessagereader.cpp * @brief LLTemplateMessageReader class implementation. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,493 +39,493 @@ #include "v4math.h" LLTemplateMessageReader::LLTemplateMessageReader(message_template_number_map_t& - number_template_map) : - mReceiveSize(0), - mCurrentRMessageTemplate(NULL), - mCurrentRMessageData(NULL), - mMessageNumbers(number_template_map) + number_template_map) : + mReceiveSize(0), + mCurrentRMessageTemplate(NULL), + mCurrentRMessageData(NULL), + mMessageNumbers(number_template_map) { } -//virtual +//virtual LLTemplateMessageReader::~LLTemplateMessageReader() { - delete mCurrentRMessageData; - mCurrentRMessageData = NULL; + delete mCurrentRMessageData; + mCurrentRMessageData = NULL; } //virtual void LLTemplateMessageReader::clearMessage() { - mReceiveSize = -1; - mCurrentRMessageTemplate = NULL; - delete mCurrentRMessageData; - mCurrentRMessageData = NULL; + mReceiveSize = -1; + mCurrentRMessageTemplate = NULL; + delete mCurrentRMessageData; + mCurrentRMessageData = NULL; } void LLTemplateMessageReader::getData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size) { - // is there a message ready to go? - if (mReceiveSize == -1) - { - LL_ERRS() << "No message waiting for decode 2!" << LL_ENDL; - return; - } - - if (!mCurrentRMessageData) - { - LL_ERRS() << "Invalid mCurrentMessageData in getData!" << LL_ENDL; - return; - } - - char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash. The bnamep is never derefference - char *vnamep = (char *)varname; - - LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - - if (iter == mCurrentRMessageData->mMemberBlocks.end()) - { - LL_ERRS() << "Block " << blockname << " #" << blocknum - << " not in message " << mCurrentRMessageData->mName << LL_ENDL; - return; - } - - LLMsgBlkData *msg_block_data = iter->second; - LLMsgBlkData::msg_var_data_map_t &var_data_map = msg_block_data->mMemberVarData; - - if (var_data_map.find(vnamep) == var_data_map.end()) - { - LL_ERRS() << "Variable "<< vnamep << " not in message " - << mCurrentRMessageData->mName<< " block " << bnamep << LL_ENDL; - return; - } - - LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; - - if (size && size != vardata.getSize()) - { - LL_ERRS() << "Msg " << mCurrentRMessageData->mName - << " variable " << vnamep - << " is size " << vardata.getSize() - << " but copying into buffer of size " << size - << LL_ENDL; - return; - } - - - const S32 vardata_size = vardata.getSize(); - if( max_size >= vardata_size ) - { - switch( vardata_size ) - { - case 1: - *((U8*)datap) = *((U8*)vardata.getData()); - break; - case 2: - *((U16*)datap) = *((U16*)vardata.getData()); - break; - case 4: - *((U32*)datap) = *((U32*)vardata.getData()); - break; - case 8: - ((U32*)datap)[0] = ((U32*)vardata.getData())[0]; - ((U32*)datap)[1] = ((U32*)vardata.getData())[1]; - break; - default: - memcpy(datap, vardata.getData(), vardata_size); - break; - } - } - else - { - LL_WARNS() << "Msg " << mCurrentRMessageData->mName - << " variable " << vnamep - << " is size " << vardata.getSize() - << " but truncated to max size of " << max_size - << LL_ENDL; - - memcpy(datap, vardata.getData(), max_size); - } + // is there a message ready to go? + if (mReceiveSize == -1) + { + LL_ERRS() << "No message waiting for decode 2!" << LL_ENDL; + return; + } + + if (!mCurrentRMessageData) + { + LL_ERRS() << "Invalid mCurrentMessageData in getData!" << LL_ENDL; + return; + } + + char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash. The bnamep is never derefference + char *vnamep = (char *)varname; + + LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); + + if (iter == mCurrentRMessageData->mMemberBlocks.end()) + { + LL_ERRS() << "Block " << blockname << " #" << blocknum + << " not in message " << mCurrentRMessageData->mName << LL_ENDL; + return; + } + + LLMsgBlkData *msg_block_data = iter->second; + LLMsgBlkData::msg_var_data_map_t &var_data_map = msg_block_data->mMemberVarData; + + if (var_data_map.find(vnamep) == var_data_map.end()) + { + LL_ERRS() << "Variable "<< vnamep << " not in message " + << mCurrentRMessageData->mName<< " block " << bnamep << LL_ENDL; + return; + } + + LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; + + if (size && size != vardata.getSize()) + { + LL_ERRS() << "Msg " << mCurrentRMessageData->mName + << " variable " << vnamep + << " is size " << vardata.getSize() + << " but copying into buffer of size " << size + << LL_ENDL; + return; + } + + + const S32 vardata_size = vardata.getSize(); + if( max_size >= vardata_size ) + { + switch( vardata_size ) + { + case 1: + *((U8*)datap) = *((U8*)vardata.getData()); + break; + case 2: + *((U16*)datap) = *((U16*)vardata.getData()); + break; + case 4: + *((U32*)datap) = *((U32*)vardata.getData()); + break; + case 8: + ((U32*)datap)[0] = ((U32*)vardata.getData())[0]; + ((U32*)datap)[1] = ((U32*)vardata.getData())[1]; + break; + default: + memcpy(datap, vardata.getData(), vardata_size); + break; + } + } + else + { + LL_WARNS() << "Msg " << mCurrentRMessageData->mName + << " variable " << vnamep + << " is size " << vardata.getSize() + << " but truncated to max size of " << max_size + << LL_ENDL; + + memcpy(datap, vardata.getData(), max_size); + } } S32 LLTemplateMessageReader::getNumberOfBlocks(const char *blockname) { - // is there a message ready to go? - if (mReceiveSize == -1) - { - LL_ERRS() << "No message waiting for decode 3!" << LL_ENDL; - return -1; - } + // is there a message ready to go? + if (mReceiveSize == -1) + { + LL_ERRS() << "No message waiting for decode 3!" << LL_ENDL; + return -1; + } + + if (!mCurrentRMessageData) + { + LL_ERRS() << "Invalid mCurrentRMessageData in getData!" << LL_ENDL; + return -1; + } - if (!mCurrentRMessageData) - { - LL_ERRS() << "Invalid mCurrentRMessageData in getData!" << LL_ENDL; - return -1; - } + char *bnamep = (char *)blockname; - char *bnamep = (char *)blockname; + LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - - if (iter == mCurrentRMessageData->mMemberBlocks.end()) - { - return 0; - } + if (iter == mCurrentRMessageData->mMemberBlocks.end()) + { + return 0; + } - return (iter->second)->mBlockNumber; + return (iter->second)->mBlockNumber; } S32 LLTemplateMessageReader::getSize(const char *blockname, const char *varname) { - // is there a message ready to go? - if (mReceiveSize == -1) - { // This is a serious error - crash - LL_ERRS() << "No message waiting for decode 4!" << LL_ENDL; - return LL_MESSAGE_ERROR; - } - - if (!mCurrentRMessageData) - { // This is a serious error - crash - LL_ERRS() << "Invalid mCurrentRMessageData in getData!" << LL_ENDL; - return LL_MESSAGE_ERROR; - } - - char *bnamep = (char *)blockname; - - LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - - if (iter == mCurrentRMessageData->mMemberBlocks.end()) - { // don't crash - LL_INFOS() << "Block " << bnamep << " not in message " - << mCurrentRMessageData->mName << LL_ENDL; - return LL_BLOCK_NOT_IN_MESSAGE; - } - - char *vnamep = (char *)varname; - - LLMsgBlkData* msg_data = iter->second; - LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; - - if (!vardata.getName()) - { // don't crash - LL_INFOS() << "Variable " << varname << " not in message " - << mCurrentRMessageData->mName << " block " << bnamep << LL_ENDL; - return LL_VARIABLE_NOT_IN_BLOCK; - } - - if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE) - { // This is a serious error - crash - LL_ERRS() << "Block " << bnamep << " isn't type MBT_SINGLE," - " use getSize with blocknum argument!" << LL_ENDL; - return LL_MESSAGE_ERROR; - } - - return vardata.getSize(); + // is there a message ready to go? + if (mReceiveSize == -1) + { // This is a serious error - crash + LL_ERRS() << "No message waiting for decode 4!" << LL_ENDL; + return LL_MESSAGE_ERROR; + } + + if (!mCurrentRMessageData) + { // This is a serious error - crash + LL_ERRS() << "Invalid mCurrentRMessageData in getData!" << LL_ENDL; + return LL_MESSAGE_ERROR; + } + + char *bnamep = (char *)blockname; + + LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); + + if (iter == mCurrentRMessageData->mMemberBlocks.end()) + { // don't crash + LL_INFOS() << "Block " << bnamep << " not in message " + << mCurrentRMessageData->mName << LL_ENDL; + return LL_BLOCK_NOT_IN_MESSAGE; + } + + char *vnamep = (char *)varname; + + LLMsgBlkData* msg_data = iter->second; + LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; + + if (!vardata.getName()) + { // don't crash + LL_INFOS() << "Variable " << varname << " not in message " + << mCurrentRMessageData->mName << " block " << bnamep << LL_ENDL; + return LL_VARIABLE_NOT_IN_BLOCK; + } + + if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE) + { // This is a serious error - crash + LL_ERRS() << "Block " << bnamep << " isn't type MBT_SINGLE," + " use getSize with blocknum argument!" << LL_ENDL; + return LL_MESSAGE_ERROR; + } + + return vardata.getSize(); } S32 LLTemplateMessageReader::getSize(const char *blockname, S32 blocknum, const char *varname) { - // is there a message ready to go? - if (mReceiveSize == -1) - { // This is a serious error - crash - LL_ERRS() << "No message waiting for decode 5!" << LL_ENDL; - return LL_MESSAGE_ERROR; - } + // is there a message ready to go? + if (mReceiveSize == -1) + { // This is a serious error - crash + LL_ERRS() << "No message waiting for decode 5!" << LL_ENDL; + return LL_MESSAGE_ERROR; + } - if (!mCurrentRMessageData) - { // This is a serious error - crash - LL_ERRS() << "Invalid mCurrentRMessageData in getData!" << LL_ENDL; - return LL_MESSAGE_ERROR; - } + if (!mCurrentRMessageData) + { // This is a serious error - crash + LL_ERRS() << "Invalid mCurrentRMessageData in getData!" << LL_ENDL; + return LL_MESSAGE_ERROR; + } - char *bnamep = (char *)blockname + blocknum; - char *vnamep = (char *)varname; + char *bnamep = (char *)blockname + blocknum; + char *vnamep = (char *)varname; - LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - - if (iter == mCurrentRMessageData->mMemberBlocks.end()) - { // don't crash - LL_INFOS() << "Block " << bnamep << " not in message " - << mCurrentRMessageData->mName << LL_ENDL; - return LL_BLOCK_NOT_IN_MESSAGE; - } + LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - LLMsgBlkData* msg_data = iter->second; - LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; - - if (!vardata.getName()) - { // don't crash - LL_INFOS() << "Variable " << vnamep << " not in message " - << mCurrentRMessageData->mName << " block " << bnamep << LL_ENDL; - return LL_VARIABLE_NOT_IN_BLOCK; - } + if (iter == mCurrentRMessageData->mMemberBlocks.end()) + { // don't crash + LL_INFOS() << "Block " << bnamep << " not in message " + << mCurrentRMessageData->mName << LL_ENDL; + return LL_BLOCK_NOT_IN_MESSAGE; + } + + LLMsgBlkData* msg_data = iter->second; + LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; + + if (!vardata.getName()) + { // don't crash + LL_INFOS() << "Variable " << vnamep << " not in message " + << mCurrentRMessageData->mName << " block " << bnamep << LL_ENDL; + return LL_VARIABLE_NOT_IN_BLOCK; + } - return vardata.getSize(); + return vardata.getSize(); } -void LLTemplateMessageReader::getBinaryData(const char *blockname, - const char *varname, void *datap, - S32 size, S32 blocknum, - S32 max_size) +void LLTemplateMessageReader::getBinaryData(const char *blockname, + const char *varname, void *datap, + S32 size, S32 blocknum, + S32 max_size) { - getData(blockname, varname, datap, size, blocknum, max_size); + getData(blockname, varname, datap, size, blocknum, max_size); } -void LLTemplateMessageReader::getS8(const char *block, const char *var, - S8 &u, S32 blocknum) +void LLTemplateMessageReader::getS8(const char *block, const char *var, + S8 &u, S32 blocknum) { - getData(block, var, &u, sizeof(S8), blocknum); + getData(block, var, &u, sizeof(S8), blocknum); } -void LLTemplateMessageReader::getU8(const char *block, const char *var, - U8 &u, S32 blocknum) +void LLTemplateMessageReader::getU8(const char *block, const char *var, + U8 &u, S32 blocknum) { - getData(block, var, &u, sizeof(U8), blocknum); + getData(block, var, &u, sizeof(U8), blocknum); } -void LLTemplateMessageReader::getBOOL(const char *block, const char *var, - bool &b, S32 blocknum ) +void LLTemplateMessageReader::getBOOL(const char *block, const char *var, + bool &b, S32 blocknum ) { - U8 value; - getData(block, var, &value, sizeof(U8), blocknum); - b = (bool)value; + U8 value; + getData(block, var, &value, sizeof(U8), blocknum); + b = (bool)value; } -void LLTemplateMessageReader::getS16(const char *block, const char *var, - S16 &d, S32 blocknum) +void LLTemplateMessageReader::getS16(const char *block, const char *var, + S16 &d, S32 blocknum) { - getData(block, var, &d, sizeof(S16), blocknum); + getData(block, var, &d, sizeof(S16), blocknum); } -void LLTemplateMessageReader::getU16(const char *block, const char *var, - U16 &d, S32 blocknum) +void LLTemplateMessageReader::getU16(const char *block, const char *var, + U16 &d, S32 blocknum) { - getData(block, var, &d, sizeof(U16), blocknum); + getData(block, var, &d, sizeof(U16), blocknum); } -void LLTemplateMessageReader::getS32(const char *block, const char *var, - S32 &d, S32 blocknum) +void LLTemplateMessageReader::getS32(const char *block, const char *var, + S32 &d, S32 blocknum) { - getData(block, var, &d, sizeof(S32), blocknum); + getData(block, var, &d, sizeof(S32), blocknum); } -void LLTemplateMessageReader::getU32(const char *block, const char *var, - U32 &d, S32 blocknum) +void LLTemplateMessageReader::getU32(const char *block, const char *var, + U32 &d, S32 blocknum) { - getData(block, var, &d, sizeof(U32), blocknum); + getData(block, var, &d, sizeof(U32), blocknum); } -void LLTemplateMessageReader::getU64(const char *block, const char *var, - U64 &d, S32 blocknum) +void LLTemplateMessageReader::getU64(const char *block, const char *var, + U64 &d, S32 blocknum) { - getData(block, var, &d, sizeof(U64), blocknum); + getData(block, var, &d, sizeof(U64), blocknum); } -void LLTemplateMessageReader::getF32(const char *block, const char *var, - F32 &d, S32 blocknum) +void LLTemplateMessageReader::getF32(const char *block, const char *var, + F32 &d, S32 blocknum) { - getData(block, var, &d, sizeof(F32), blocknum); + getData(block, var, &d, sizeof(F32), blocknum); - if( !llfinite( d ) ) - { - LL_WARNS() << "non-finite in getF32Fast " << block << " " << var - << LL_ENDL; - d = 0; - } + if( !llfinite( d ) ) + { + LL_WARNS() << "non-finite in getF32Fast " << block << " " << var + << LL_ENDL; + d = 0; + } } -void LLTemplateMessageReader::getF64(const char *block, const char *var, - F64 &d, S32 blocknum) +void LLTemplateMessageReader::getF64(const char *block, const char *var, + F64 &d, S32 blocknum) { - getData(block, var, &d, sizeof(F64), blocknum); + getData(block, var, &d, sizeof(F64), blocknum); - if( !llfinite( d ) ) - { - LL_WARNS() << "non-finite in getF64Fast " << block << " " << var - << LL_ENDL; - d = 0; - } + if( !llfinite( d ) ) + { + LL_WARNS() << "non-finite in getF64Fast " << block << " " << var + << LL_ENDL; + d = 0; + } } -void LLTemplateMessageReader::getVector3(const char *block, const char *var, - LLVector3 &v, S32 blocknum ) +void LLTemplateMessageReader::getVector3(const char *block, const char *var, + LLVector3 &v, S32 blocknum ) { - getData(block, var, &v.mV[0], sizeof(v.mV), blocknum); + getData(block, var, &v.mV[0], sizeof(v.mV), blocknum); - if( !v.isFinite() ) - { - LL_WARNS() << "non-finite in getVector3Fast " << block << " " - << var << LL_ENDL; - v.zeroVec(); - } + if( !v.isFinite() ) + { + LL_WARNS() << "non-finite in getVector3Fast " << block << " " + << var << LL_ENDL; + v.zeroVec(); + } } -void LLTemplateMessageReader::getVector4(const char *block, const char *var, - LLVector4 &v, S32 blocknum) +void LLTemplateMessageReader::getVector4(const char *block, const char *var, + LLVector4 &v, S32 blocknum) { - getData(block, var, &v.mV[0], sizeof(v.mV), blocknum); + getData(block, var, &v.mV[0], sizeof(v.mV), blocknum); - if( !v.isFinite() ) - { - LL_WARNS() << "non-finite in getVector4Fast " << block << " " - << var << LL_ENDL; - v.zeroVec(); - } + if( !v.isFinite() ) + { + LL_WARNS() << "non-finite in getVector4Fast " << block << " " + << var << LL_ENDL; + v.zeroVec(); + } } -void LLTemplateMessageReader::getVector3d(const char *block, const char *var, - LLVector3d &v, S32 blocknum ) +void LLTemplateMessageReader::getVector3d(const char *block, const char *var, + LLVector3d &v, S32 blocknum ) { - getData(block, var, &v.mdV[0], sizeof(v.mdV), blocknum); + getData(block, var, &v.mdV[0], sizeof(v.mdV), blocknum); - if( !v.isFinite() ) - { - LL_WARNS() << "non-finite in getVector3dFast " << block << " " - << var << LL_ENDL; - v.zeroVec(); - } + if( !v.isFinite() ) + { + LL_WARNS() << "non-finite in getVector3dFast " << block << " " + << var << LL_ENDL; + v.zeroVec(); + } } -void LLTemplateMessageReader::getQuat(const char *block, const char *var, - LLQuaternion &q, S32 blocknum) +void LLTemplateMessageReader::getQuat(const char *block, const char *var, + LLQuaternion &q, S32 blocknum) { - LLVector3 vec; - getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum); - if( vec.isFinite() ) - { - q.unpackFromVector3( vec ); - } - else - { - LL_WARNS() << "non-finite in getQuatFast " << block << " " << var - << LL_ENDL; - q.loadIdentity(); - } + LLVector3 vec; + getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum); + if( vec.isFinite() ) + { + q.unpackFromVector3( vec ); + } + else + { + LL_WARNS() << "non-finite in getQuatFast " << block << " " << var + << LL_ENDL; + q.loadIdentity(); + } } -void LLTemplateMessageReader::getUUID(const char *block, const char *var, - LLUUID &u, S32 blocknum) +void LLTemplateMessageReader::getUUID(const char *block, const char *var, + LLUUID &u, S32 blocknum) { - getData(block, var, &u.mData[0], sizeof(u.mData), blocknum); + getData(block, var, &u.mData[0], sizeof(u.mData), blocknum); } inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum) { - getData(block, var, &u, sizeof(U32), blocknum); + getData(block, var, &u, sizeof(U32), blocknum); } inline void LLTemplateMessageReader::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum) { - getData(block, var, &u, sizeof(U16), blocknum); - u = ntohs(u); + getData(block, var, &u, sizeof(U16), blocknum); + u = ntohs(u); } inline void LLTemplateMessageReader::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum ) { - s[0] = '\0'; - getData(block, var, s, 0, blocknum, buffer_size); - s[buffer_size - 1] = '\0'; + s[0] = '\0'; + getData(block, var, s, 0, blocknum, buffer_size); + s[buffer_size - 1] = '\0'; } inline void LLTemplateMessageReader::getString(const char *block, const char *var, std::string& outstr, S32 blocknum ) { - char s[MTUBYTES + 1]= {0}; // every element is initialized with 0 - getData(block, var, s, 0, blocknum, MTUBYTES); - s[MTUBYTES] = '\0'; - outstr = s; + char s[MTUBYTES + 1]= {0}; // every element is initialized with 0 + getData(block, var, s, 0, blocknum, MTUBYTES); + s[MTUBYTES] = '\0'; + outstr = s; } -//virtual +//virtual S32 LLTemplateMessageReader::getMessageSize() const { - return mReceiveSize; + return mReceiveSize; } // Returns template for the message contained in buffer bool LLTemplateMessageReader::decodeTemplate( - const U8* buffer, S32 buffer_size, // inputs - LLMessageTemplate** msg_template ) // outputs -{ - const U8* header = buffer + LL_PACKET_ID_SIZE; - - // is there a message ready to go? - if (buffer_size <= 0) - { - LL_WARNS() << "No message waiting for decode!" << LL_ENDL; - return(false); - } - - U32 num = 0; - - if (header[0] != 255) - { - // high frequency message - num = header[0]; - } - else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255)) - { - // medium frequency message - num = (255 << 8) | header[1]; - } - else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255)) - { - // low frequency message - U16 message_id_U16 = 0; - // I think this check busts the message system. - // it appears that if there is a NULL in the message #, it won't copy it.... - // what was the goal? - //if(header[2]) - memcpy(&message_id_U16, &header[2], 2); - - // dependant on endian-ness: - // U32 temp = (255 << 24) | (255 << 16) | header[2]; - - // independant of endian-ness: - message_id_U16 = ntohs(message_id_U16); - num = 0xFFFF0000 | message_id_U16; - } - else // bogus packet received (too short) - { - LL_WARNS() << "Packet with unusable length received (too short): " - << buffer_size << LL_ENDL; - return(false); - } - - LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num); - if (temp) - { - *msg_template = temp; - } - else - { + const U8* buffer, S32 buffer_size, // inputs + LLMessageTemplate** msg_template ) // outputs +{ + const U8* header = buffer + LL_PACKET_ID_SIZE; + + // is there a message ready to go? + if (buffer_size <= 0) + { + LL_WARNS() << "No message waiting for decode!" << LL_ENDL; + return(false); + } + + U32 num = 0; + + if (header[0] != 255) + { + // high frequency message + num = header[0]; + } + else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255)) + { + // medium frequency message + num = (255 << 8) | header[1]; + } + else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255)) + { + // low frequency message + U16 message_id_U16 = 0; + // I think this check busts the message system. + // it appears that if there is a NULL in the message #, it won't copy it.... + // what was the goal? + //if(header[2]) + memcpy(&message_id_U16, &header[2], 2); + + // dependant on endian-ness: + // U32 temp = (255 << 24) | (255 << 16) | header[2]; + + // independant of endian-ness: + message_id_U16 = ntohs(message_id_U16); + num = 0xFFFF0000 | message_id_U16; + } + else // bogus packet received (too short) + { + LL_WARNS() << "Packet with unusable length received (too short): " + << buffer_size << LL_ENDL; + return(false); + } + + LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num); + if (temp) + { + *msg_template = temp; + } + else + { // MAINT-7482 - make viewer more tolerant of unknown messages. - LL_WARNS_ONCE() << "Message #" << std::hex << num << std::dec + LL_WARNS_ONCE() << "Message #" << std::hex << num << std::dec << " received but not registered!" << LL_ENDL; - //gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); - return(false); - } + //gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); + return(false); + } - return(true); + return(true); } void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ) { - // we've run off the end of the packet! - LL_WARNS() << "Ran off end of packet " << mCurrentRMessageTemplate->mName -// << " with id " << mCurrentRecvPacketID - << " from " << host - << " trying to read " << wanted - << " bytes at position " << where - << " going past packet end at " << mReceiveSize - << LL_ENDL; - if(gMessageSystem->mVerboseLog) - { - LL_INFOS() << "MSG: -> " << host << "\tREAD PAST END:\t" -// << mCurrentRecvPacketID << " " - << getMessageName() << LL_ENDL; - } - gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET); + // we've run off the end of the packet! + LL_WARNS() << "Ran off end of packet " << mCurrentRMessageTemplate->mName +// << " with id " << mCurrentRecvPacketID + << " from " << host + << " trying to read " << wanted + << " bytes at position " << where + << " going past packet end at " << mReceiveSize + << LL_ENDL; + if(gMessageSystem->mVerboseLog) + { + LL_INFOS() << "MSG: -> " << host << "\tREAD PAST END:\t" +// << mCurrentRecvPacketID << " " + << getMessageName() << LL_ENDL; + } + gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET); } static LLTrace::BlockTimerStatHandle FTM_PROCESS_MESSAGES("Process Messages"); @@ -535,296 +535,296 @@ bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender { LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES); - llassert( mReceiveSize >= 0 ); - llassert( mCurrentRMessageTemplate); - llassert( !mCurrentRMessageData ); - delete mCurrentRMessageData; // just to make sure - - // The offset tells us how may bytes to skip after the end of the - // message name. - U8 offset = buffer[PHL_OFFSET]; - S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency) + offset; - - // create base working data set - mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName); - - // loop through the template building the data structure as we go - LLMessageTemplate::message_block_map_t::const_iterator iter; - for(iter = mCurrentRMessageTemplate->mMemberBlocks.begin(); - iter != mCurrentRMessageTemplate->mMemberBlocks.end(); - ++iter) - { - LLMessageBlock* mbci = *iter; - U8 repeat_number; - S32 i; - - // how many of this block? - - if (mbci->mType == MBT_SINGLE) - { - // just one - repeat_number = 1; - } - else if (mbci->mType == MBT_MULTIPLE) - { - // a known number - repeat_number = mbci->mNumber; - } - else if (mbci->mType == MBT_VARIABLE) - { - // need to read the number from the message - // repeat number is a single byte - if (decode_pos >= mReceiveSize) - { - // commented out - hetgrid says that missing variable blocks - // at end of message are legal - // logRanOffEndOfPacket(sender, decode_pos, 1); - - // default to 0 repeats - repeat_number = 0; - } - else - { - repeat_number = buffer[decode_pos]; - decode_pos++; - } - } - else - { - LL_ERRS() << "Unknown block type" << LL_ENDL; - return false; - } - - LLMsgBlkData* cur_data_block = NULL; - - // now loop through the block - for (i = 0; i < repeat_number; i++) - { - if (i) - { - // build new name to prevent collisions - // TODO: This should really change to a vector - cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); - cur_data_block->mName = mbci->mName + i; - } - else - { - cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); - } - - // add the block to the message - mCurrentRMessageData->addBlock(cur_data_block); - - // now read the variables - for (LLMessageBlock::message_variable_map_t::const_iterator iter = - mbci->mMemberVariables.begin(); - iter != mbci->mMemberVariables.end(); iter++) - { - const LLMessageVariable& mvci = **iter; - - // ok, build out the variables - // add variable block - cur_data_block->addVariable(mvci.getName(), mvci.getType()); - - // what type of variable? - if (mvci.getType() == MVT_VARIABLE) - { - // variable, get the number of bytes to read from the template - S32 data_size = mvci.getSize(); - U8 tsizeb = 0; - U16 tsizeh = 0; - U32 tsize = 0; - - if ((decode_pos + data_size) > mReceiveSize) - { - logRanOffEndOfPacket(sender, decode_pos, data_size); - - // default to 0 length variable blocks - tsize = 0; - } - else - { - switch(data_size) - { - case 1: - htolememcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1); - tsize = tsizeb; - break; - case 2: - htolememcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2); - tsize = tsizeh; - break; - case 4: - htolememcpy(&tsize, &buffer[decode_pos], MVT_U32, 4); - break; - default: - LL_ERRS() << "Attempting to read variable field with unknown size of " << data_size << LL_ENDL; - break; - } - } - decode_pos += data_size; - - cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType()); - decode_pos += tsize; - } - else - { - // fixed! - // so, copy data pointer and set data size to fixed size - if ((decode_pos + mvci.getSize()) > mReceiveSize) - { - logRanOffEndOfPacket(sender, decode_pos, mvci.getSize()); - - // default to 0s. - U32 size = mvci.getSize(); - std::vector<U8> data(size, 0); - cur_data_block->addData(mvci.getName(), &(data[0]), - size, mvci.getType()); - } - else - { - cur_data_block->addData(mvci.getName(), - &buffer[decode_pos], - mvci.getSize(), - mvci.getType()); - } - decode_pos += mvci.getSize(); - } - } - } - } - - if (mCurrentRMessageData->mMemberBlocks.empty() - && !mCurrentRMessageTemplate->mMemberBlocks.empty()) - { - LL_DEBUGS() << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << LL_ENDL; - return false; - } - - { - static LLTimer decode_timer; - - if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) - { - decode_timer.reset(); - } - - if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) ) - { - LL_WARNS() << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << LL_ENDL; - } - - if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) - { - F32 decode_time = decode_timer.getElapsedTimeF32(); - - if (gMessageSystem->getTimingCallback()) - { - (gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName, - decode_time, - gMessageSystem->getTimingCallbackData()); - } - - if (LLMessageReader::getTimeDecodes()) - { - mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time; - - mCurrentRMessageTemplate->mTotalDecoded++; - mCurrentRMessageTemplate->mTotalDecodeTime += decode_time; - - if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time ) - { - mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time; - } - - - if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold()) - { - LL_DEBUGS() << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" << - mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " << - (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << LL_ENDL; - } - } - } - } - return true; + llassert( mReceiveSize >= 0 ); + llassert( mCurrentRMessageTemplate); + llassert( !mCurrentRMessageData ); + delete mCurrentRMessageData; // just to make sure + + // The offset tells us how may bytes to skip after the end of the + // message name. + U8 offset = buffer[PHL_OFFSET]; + S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency) + offset; + + // create base working data set + mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName); + + // loop through the template building the data structure as we go + LLMessageTemplate::message_block_map_t::const_iterator iter; + for(iter = mCurrentRMessageTemplate->mMemberBlocks.begin(); + iter != mCurrentRMessageTemplate->mMemberBlocks.end(); + ++iter) + { + LLMessageBlock* mbci = *iter; + U8 repeat_number; + S32 i; + + // how many of this block? + + if (mbci->mType == MBT_SINGLE) + { + // just one + repeat_number = 1; + } + else if (mbci->mType == MBT_MULTIPLE) + { + // a known number + repeat_number = mbci->mNumber; + } + else if (mbci->mType == MBT_VARIABLE) + { + // need to read the number from the message + // repeat number is a single byte + if (decode_pos >= mReceiveSize) + { + // commented out - hetgrid says that missing variable blocks + // at end of message are legal + // logRanOffEndOfPacket(sender, decode_pos, 1); + + // default to 0 repeats + repeat_number = 0; + } + else + { + repeat_number = buffer[decode_pos]; + decode_pos++; + } + } + else + { + LL_ERRS() << "Unknown block type" << LL_ENDL; + return false; + } + + LLMsgBlkData* cur_data_block = NULL; + + // now loop through the block + for (i = 0; i < repeat_number; i++) + { + if (i) + { + // build new name to prevent collisions + // TODO: This should really change to a vector + cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); + cur_data_block->mName = mbci->mName + i; + } + else + { + cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); + } + + // add the block to the message + mCurrentRMessageData->addBlock(cur_data_block); + + // now read the variables + for (LLMessageBlock::message_variable_map_t::const_iterator iter = + mbci->mMemberVariables.begin(); + iter != mbci->mMemberVariables.end(); iter++) + { + const LLMessageVariable& mvci = **iter; + + // ok, build out the variables + // add variable block + cur_data_block->addVariable(mvci.getName(), mvci.getType()); + + // what type of variable? + if (mvci.getType() == MVT_VARIABLE) + { + // variable, get the number of bytes to read from the template + S32 data_size = mvci.getSize(); + U8 tsizeb = 0; + U16 tsizeh = 0; + U32 tsize = 0; + + if ((decode_pos + data_size) > mReceiveSize) + { + logRanOffEndOfPacket(sender, decode_pos, data_size); + + // default to 0 length variable blocks + tsize = 0; + } + else + { + switch(data_size) + { + case 1: + htolememcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1); + tsize = tsizeb; + break; + case 2: + htolememcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2); + tsize = tsizeh; + break; + case 4: + htolememcpy(&tsize, &buffer[decode_pos], MVT_U32, 4); + break; + default: + LL_ERRS() << "Attempting to read variable field with unknown size of " << data_size << LL_ENDL; + break; + } + } + decode_pos += data_size; + + cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType()); + decode_pos += tsize; + } + else + { + // fixed! + // so, copy data pointer and set data size to fixed size + if ((decode_pos + mvci.getSize()) > mReceiveSize) + { + logRanOffEndOfPacket(sender, decode_pos, mvci.getSize()); + + // default to 0s. + U32 size = mvci.getSize(); + std::vector<U8> data(size, 0); + cur_data_block->addData(mvci.getName(), &(data[0]), + size, mvci.getType()); + } + else + { + cur_data_block->addData(mvci.getName(), + &buffer[decode_pos], + mvci.getSize(), + mvci.getType()); + } + decode_pos += mvci.getSize(); + } + } + } + } + + if (mCurrentRMessageData->mMemberBlocks.empty() + && !mCurrentRMessageTemplate->mMemberBlocks.empty()) + { + LL_DEBUGS() << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << LL_ENDL; + return false; + } + + { + static LLTimer decode_timer; + + if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) + { + decode_timer.reset(); + } + + if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) ) + { + LL_WARNS() << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << LL_ENDL; + } + + if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) + { + F32 decode_time = decode_timer.getElapsedTimeF32(); + + if (gMessageSystem->getTimingCallback()) + { + (gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName, + decode_time, + gMessageSystem->getTimingCallbackData()); + } + + if (LLMessageReader::getTimeDecodes()) + { + mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time; + + mCurrentRMessageTemplate->mTotalDecoded++; + mCurrentRMessageTemplate->mTotalDecodeTime += decode_time; + + if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time ) + { + mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time; + } + + + if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold()) + { + LL_DEBUGS() << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" << + mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " << + (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << LL_ENDL; + } + } + } + } + return true; } bool LLTemplateMessageReader::validateMessage(const U8* buffer, - S32 buffer_size, - const LLHost& sender, - bool trusted) -{ - mReceiveSize = buffer_size; - bool valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); - if(valid) - { - mCurrentRMessageTemplate->mReceiveCount++; - //LL_DEBUGS() << "MessageRecvd:" - // << mCurrentRMessageTemplate->mName - // << " from " << sender << LL_ENDL; - } - - if (valid && isBanned(trusted)) - { - LL_WARNS("Messaging") << "LLMessageSystem::checkMessages " - << "received banned message " - << getMessageName() - << " from " - << ((trusted) ? "trusted " : "untrusted ") - << sender << LL_ENDL; - valid = false; - } - - if(valid && isUdpBanned()) - { - LL_WARNS() << "Received UDP black listed message " - << getMessageName() - << " from " << sender << LL_ENDL; - valid = false; - } - return valid; + S32 buffer_size, + const LLHost& sender, + bool trusted) +{ + mReceiveSize = buffer_size; + bool valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); + if(valid) + { + mCurrentRMessageTemplate->mReceiveCount++; + //LL_DEBUGS() << "MessageRecvd:" + // << mCurrentRMessageTemplate->mName + // << " from " << sender << LL_ENDL; + } + + if (valid && isBanned(trusted)) + { + LL_WARNS("Messaging") << "LLMessageSystem::checkMessages " + << "received banned message " + << getMessageName() + << " from " + << ((trusted) ? "trusted " : "untrusted ") + << sender << LL_ENDL; + valid = false; + } + + if(valid && isUdpBanned()) + { + LL_WARNS() << "Received UDP black listed message " + << getMessageName() + << " from " << sender << LL_ENDL; + valid = false; + } + return valid; } bool LLTemplateMessageReader::readMessage(const U8* buffer, - const LLHost& sender) + const LLHost& sender) { - return decodeData(buffer, sender); + return decodeData(buffer, sender); } -//virtual +//virtual const char* LLTemplateMessageReader::getMessageName() const { - if (!mCurrentRMessageTemplate) - { - // no message currently being read - return ""; - } - return mCurrentRMessageTemplate->mName; + if (!mCurrentRMessageTemplate) + { + // no message currently being read + return ""; + } + return mCurrentRMessageTemplate->mName; } -//virtual +//virtual bool LLTemplateMessageReader::isTrusted() const { - return mCurrentRMessageTemplate->getTrust() == MT_TRUST; + return mCurrentRMessageTemplate->getTrust() == MT_TRUST; } bool LLTemplateMessageReader::isBanned(bool trustedSource) const { - return mCurrentRMessageTemplate->isBanned(trustedSource); + return mCurrentRMessageTemplate->isBanned(trustedSource); } bool LLTemplateMessageReader::isUdpBanned() const { - return mCurrentRMessageTemplate->isUdpBanned(); + return mCurrentRMessageTemplate->isUdpBanned(); } -//virtual +//virtual void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const { - if(NULL == mCurrentRMessageTemplate) + if(NULL == mCurrentRMessageTemplate) { return; } - builder.copyFromMessageData(*mCurrentRMessageData); + builder.copyFromMessageData(*mCurrentRMessageData); } diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h index 14656230e3..6f1977cf83 100644 --- a/indra/llmessage/lltemplatemessagereader.h +++ b/indra/llmessage/lltemplatemessagereader.h @@ -1,25 +1,25 @@ -/** +/** * @file lltemplatemessagereader.h * @brief Declaration of LLTemplateMessageReader class. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,90 +38,90 @@ class LLTemplateMessageReader : public LLMessageReader { public: - typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; - - LLTemplateMessageReader(message_template_number_map_t&); - virtual ~LLTemplateMessageReader(); - - /** All get* methods expect pointers to canonical strings. */ - virtual void getBinaryData(const char *blockname, const char *varname, - void *datap, S32 size, S32 blocknum = 0, - S32 max_size = S32_MAX); - virtual void getBOOL(const char *block, const char *var, bool &data, - S32 blocknum = 0); - virtual void getS8(const char *block, const char *var, S8 &data, - S32 blocknum = 0); - virtual void getU8(const char *block, const char *var, U8 &data, - S32 blocknum = 0); - virtual void getS16(const char *block, const char *var, S16 &data, - S32 blocknum = 0); - virtual void getU16(const char *block, const char *var, U16 &data, - S32 blocknum = 0); - virtual void getS32(const char *block, const char *var, S32 &data, - S32 blocknum = 0); - virtual void getF32(const char *block, const char *var, F32 &data, - S32 blocknum = 0); - virtual void getU32(const char *block, const char *var, U32 &data, - S32 blocknum = 0); - virtual void getU64(const char *block, const char *var, U64 &data, - S32 blocknum = 0); - virtual void getF64(const char *block, const char *var, F64 &data, - S32 blocknum = 0); - virtual void getVector3(const char *block, const char *var, - LLVector3 &vec, S32 blocknum = 0); - virtual void getVector4(const char *block, const char *var, - LLVector4 &vec, S32 blocknum = 0); - virtual void getVector3d(const char *block, const char *var, - LLVector3d &vec, S32 blocknum = 0); - virtual void getQuat(const char *block, const char *var, LLQuaternion &q, - S32 blocknum = 0); - virtual void getUUID(const char *block, const char *var, LLUUID &uuid, - S32 blocknum = 0); - virtual void getIPAddr(const char *block, const char *var, U32 &ip, - S32 blocknum = 0); - virtual void getIPPort(const char *block, const char *var, U16 &port, - S32 blocknum = 0); - virtual void getString(const char *block, const char *var, - S32 buffer_size, char *buffer, S32 blocknum = 0); - virtual void getString(const char *block, const char *var, std::string& outstr, - S32 blocknum = 0); - - virtual S32 getNumberOfBlocks(const char *blockname); - virtual S32 getSize(const char *blockname, const char *varname); - virtual S32 getSize(const char *blockname, S32 blocknum, - const char *varname); - - virtual void clearMessage(); - - virtual const char* getMessageName() const; - virtual S32 getMessageSize() const; - - virtual void copyToBuilder(LLMessageBuilder&) const; - - bool validateMessage(const U8* buffer, S32 buffer_size, - const LLHost& sender, bool trusted = false); - bool readMessage(const U8* buffer, const LLHost& sender); - - bool isTrusted() const; - bool isBanned(bool trusted_source) const; - bool isUdpBanned() const; - + typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; + + LLTemplateMessageReader(message_template_number_map_t&); + virtual ~LLTemplateMessageReader(); + + /** All get* methods expect pointers to canonical strings. */ + virtual void getBinaryData(const char *blockname, const char *varname, + void *datap, S32 size, S32 blocknum = 0, + S32 max_size = S32_MAX); + virtual void getBOOL(const char *block, const char *var, bool &data, + S32 blocknum = 0); + virtual void getS8(const char *block, const char *var, S8 &data, + S32 blocknum = 0); + virtual void getU8(const char *block, const char *var, U8 &data, + S32 blocknum = 0); + virtual void getS16(const char *block, const char *var, S16 &data, + S32 blocknum = 0); + virtual void getU16(const char *block, const char *var, U16 &data, + S32 blocknum = 0); + virtual void getS32(const char *block, const char *var, S32 &data, + S32 blocknum = 0); + virtual void getF32(const char *block, const char *var, F32 &data, + S32 blocknum = 0); + virtual void getU32(const char *block, const char *var, U32 &data, + S32 blocknum = 0); + virtual void getU64(const char *block, const char *var, U64 &data, + S32 blocknum = 0); + virtual void getF64(const char *block, const char *var, F64 &data, + S32 blocknum = 0); + virtual void getVector3(const char *block, const char *var, + LLVector3 &vec, S32 blocknum = 0); + virtual void getVector4(const char *block, const char *var, + LLVector4 &vec, S32 blocknum = 0); + virtual void getVector3d(const char *block, const char *var, + LLVector3d &vec, S32 blocknum = 0); + virtual void getQuat(const char *block, const char *var, LLQuaternion &q, + S32 blocknum = 0); + virtual void getUUID(const char *block, const char *var, LLUUID &uuid, + S32 blocknum = 0); + virtual void getIPAddr(const char *block, const char *var, U32 &ip, + S32 blocknum = 0); + virtual void getIPPort(const char *block, const char *var, U16 &port, + S32 blocknum = 0); + virtual void getString(const char *block, const char *var, + S32 buffer_size, char *buffer, S32 blocknum = 0); + virtual void getString(const char *block, const char *var, std::string& outstr, + S32 blocknum = 0); + + virtual S32 getNumberOfBlocks(const char *blockname); + virtual S32 getSize(const char *blockname, const char *varname); + virtual S32 getSize(const char *blockname, S32 blocknum, + const char *varname); + + virtual void clearMessage(); + + virtual const char* getMessageName() const; + virtual S32 getMessageSize() const; + + virtual void copyToBuilder(LLMessageBuilder&) const; + + bool validateMessage(const U8* buffer, S32 buffer_size, + const LLHost& sender, bool trusted = false); + bool readMessage(const U8* buffer, const LLHost& sender); + + bool isTrusted() const; + bool isBanned(bool trusted_source) const; + bool isUdpBanned() const; + private: - void getData(const char *blockname, const char *varname, void *datap, - S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); + void getData(const char *blockname, const char *varname, void *datap, + S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); - bool decodeTemplate(const U8* buffer, S32 buffer_size, // inputs - LLMessageTemplate** msg_template ); // outputs + bool decodeTemplate(const U8* buffer, S32 buffer_size, // inputs + LLMessageTemplate** msg_template ); // outputs - void logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ); + void logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ); - bool decodeData(const U8* buffer, const LLHost& sender ); + bool decodeData(const U8* buffer, const LLHost& sender ); - S32 mReceiveSize; - LLMessageTemplate* mCurrentRMessageTemplate; - LLMsgData* mCurrentRMessageData; - message_template_number_map_t& mMessageNumbers; + S32 mReceiveSize; + LLMessageTemplate* mCurrentRMessageTemplate; + LLMsgData* mCurrentRMessageData; + message_template_number_map_t& mMessageNumbers; }; #endif // LL_LLTEMPLATEMESSAGEREADER_H diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp index 0cfe5dbf38..5ce96fc551 100644 --- a/indra/llmessage/llthrottle.cpp +++ b/indra/llmessage/llthrottle.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llthrottle.cpp * @brief LLThrottle class used for network bandwidth control. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,108 +34,108 @@ LLThrottle::LLThrottle(const F32 rate) { - mRate = rate; - mAvailable = 0.f; - mLookaheadSecs = 0.25f; - mLastSendTime = LLMessageSystem::getMessageTimeSeconds(true); + mRate = rate; + mAvailable = 0.f; + mLookaheadSecs = 0.25f; + mLastSendTime = LLMessageSystem::getMessageTimeSeconds(true); } void LLThrottle::setRate(const F32 rate) { - // Need to accumulate available bits when adjusting the rate. - mAvailable = getAvailable(); - mLastSendTime = LLMessageSystem::getMessageTimeSeconds(); - mRate = rate; + // Need to accumulate available bits when adjusting the rate. + mAvailable = getAvailable(); + mLastSendTime = LLMessageSystem::getMessageTimeSeconds(); + mRate = rate; } F32 LLThrottle::getAvailable() { - // use a temporary bits_available - // since we don't want to change mBitsAvailable every time - F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime; - return mAvailable + (mRate * elapsed_time.value()); + // use a temporary bits_available + // since we don't want to change mBitsAvailable every time + F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime; + return mAvailable + (mRate * elapsed_time.value()); } bool LLThrottle::checkOverflow(const F32 amount) { - bool retval = true; - - F32 lookahead_amount = mRate * mLookaheadSecs; - - // use a temporary bits_available - // since we don't want to change mBitsAvailable every time - F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime; - F32 amount_available = mAvailable + (mRate * elapsed_time.value()); - - if ((amount_available >= lookahead_amount) || (amount_available > amount)) - { - // ...enough space to send this message - // Also do if > lookahead so we can use if amount > capped amount. - retval = false; - } - - return retval; + bool retval = true; + + F32 lookahead_amount = mRate * mLookaheadSecs; + + // use a temporary bits_available + // since we don't want to change mBitsAvailable every time + F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime; + F32 amount_available = mAvailable + (mRate * elapsed_time.value()); + + if ((amount_available >= lookahead_amount) || (amount_available > amount)) + { + // ...enough space to send this message + // Also do if > lookahead so we can use if amount > capped amount. + retval = false; + } + + return retval; } bool LLThrottle::throttleOverflow(const F32 amount) { - F32Seconds elapsed_time; - F32 lookahead_amount; - bool retval = true; - - lookahead_amount = mRate * mLookaheadSecs; - - F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); - elapsed_time = mt_sec - mLastSendTime; - mLastSendTime = mt_sec; - - mAvailable += mRate * elapsed_time.value(); - - if (mAvailable >= lookahead_amount) - { - // ...channel completely open, so allow send regardless - // of size. This allows sends on very low BPS channels. - mAvailable = lookahead_amount; - retval = false; - } - else if (mAvailable > amount) - { - // ...enough space to send this message - retval = false; - } - - // We actually already sent the bits. - mAvailable -= amount; - - // What if bitsavailable goes negative? - // That's OK, because it means someone is banging on the channel, - // so we need some time to recover. - - return retval; + F32Seconds elapsed_time; + F32 lookahead_amount; + bool retval = true; + + lookahead_amount = mRate * mLookaheadSecs; + + F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); + elapsed_time = mt_sec - mLastSendTime; + mLastSendTime = mt_sec; + + mAvailable += mRate * elapsed_time.value(); + + if (mAvailable >= lookahead_amount) + { + // ...channel completely open, so allow send regardless + // of size. This allows sends on very low BPS channels. + mAvailable = lookahead_amount; + retval = false; + } + else if (mAvailable > amount) + { + // ...enough space to send this message + retval = false; + } + + // We actually already sent the bits. + mAvailable -= amount; + + // What if bitsavailable goes negative? + // That's OK, because it means someone is banging on the channel, + // so we need some time to recover. + + return retval; } -const F32 THROTTLE_LOOKAHEAD_TIME = 1.f; // seconds +const F32 THROTTLE_LOOKAHEAD_TIME = 1.f; // seconds // Make sure that we don't set above these // values, even if the client asks to be set // higher -// Note that these values are replicated on the +// Note that these values are replicated on the // client side to set max bandwidth throttling there, // in llviewerthrottle.cpp. These values are the sum // of the top two tiers of bandwidth there. F32 gThrottleMaximumBPS[TC_EOF] = { - 150000.f, // TC_RESEND - 170000.f, // TC_LAND - 34000.f, // TC_WIND - 34000.f, // TC_CLOUD - 446000.f, // TC_TASK - 446000.f, // TC_TEXTURE - 220000.f, // TC_ASSET + 150000.f, // TC_RESEND + 170000.f, // TC_LAND + 34000.f, // TC_WIND + 34000.f, // TC_CLOUD + 446000.f, // TC_TASK + 446000.f, // TC_TEXTURE + 220000.f, // TC_ASSET }; // Start low until viewer informs us of capability @@ -146,13 +146,13 @@ F32 gThrottleMaximumBPS[TC_EOF] = F32 gThrottleDefaultBPS[TC_EOF] = { - 100000.f, // TC_RESEND - 4000.f, // TC_LAND - 4000.f, // TC_WIND - 4000.f, // TC_CLOUD - 4000.f, // TC_TASK - 4000.f, // TC_TEXTURE - 100000.f, // TC_ASSET + 100000.f, // TC_RESEND + 4000.f, // TC_LAND + 4000.f, // TC_WIND + 4000.f, // TC_CLOUD + 4000.f, // TC_TASK + 4000.f, // TC_TEXTURE + 100000.f, // TC_ASSET }; // Don't throttle down lower than this @@ -160,61 +160,61 @@ F32 gThrottleDefaultBPS[TC_EOF] = // wont. F32 gThrottleMinimumBPS[TC_EOF] = { - 10000.f, // TC_RESEND - 10000.f, // TC_LAND - 4000.f, // TC_WIND - 4000.f, // TC_CLOUD - 20000.f, // TC_TASK - 10000.f, // TC_TEXTURE - 10000.f, // TC_ASSET + 10000.f, // TC_RESEND + 10000.f, // TC_LAND + 4000.f, // TC_WIND + 4000.f, // TC_CLOUD + 20000.f, // TC_TASK + 10000.f, // TC_TEXTURE + 10000.f, // TC_ASSET }; const char* THROTTLE_NAMES[TC_EOF] = { - "Resend ", - "Land ", - "Wind ", - "Cloud ", - "Task ", - "Texture", - "Asset " + "Resend ", + "Land ", + "Wind ", + "Cloud ", + "Task ", + "Texture", + "Asset " }; LLThrottleGroup::LLThrottleGroup() { - S32 i; - for (i = 0; i < TC_EOF; i++) - { - mThrottleTotal[i] = gThrottleDefaultBPS[i]; - mNominalBPS[i] = gThrottleDefaultBPS[i]; - } - - resetDynamicAdjust(); + S32 i; + for (i = 0; i < TC_EOF; i++) + { + mThrottleTotal[i] = gThrottleDefaultBPS[i]; + mNominalBPS[i] = gThrottleDefaultBPS[i]; + } + + resetDynamicAdjust(); } void LLThrottleGroup::packThrottle(LLDataPacker &dp) const { - S32 i; - for (i = 0; i < TC_EOF; i++) - { - dp.packF32(mThrottleTotal[i], "Throttle"); - } + S32 i; + for (i = 0; i < TC_EOF; i++) + { + dp.packF32(mThrottleTotal[i], "Throttle"); + } } void LLThrottleGroup::unpackThrottle(LLDataPacker &dp) { - S32 i; - for (i = 0; i < TC_EOF; i++) - { - F32 temp_throttle; - dp.unpackF32(temp_throttle, "Throttle"); - temp_throttle = llclamp(temp_throttle, 0.f, 2250000.f); - mThrottleTotal[i] = temp_throttle; - if(mThrottleTotal[i] > gThrottleMaximumBPS[i]) - { - mThrottleTotal[i] = gThrottleMaximumBPS[i]; - } - } + S32 i; + for (i = 0; i < TC_EOF; i++) + { + F32 temp_throttle; + dp.unpackF32(temp_throttle, "Throttle"); + temp_throttle = llclamp(temp_throttle, 0.f, 2250000.f); + mThrottleTotal[i] = temp_throttle; + if(mThrottleTotal[i] > gThrottleMaximumBPS[i]) + { + mThrottleTotal[i] = gThrottleMaximumBPS[i]; + } + } } // Call this whenever mNominalBPS changes. Need to reset @@ -222,356 +222,356 @@ void LLThrottleGroup::unpackThrottle(LLDataPacker &dp) // into NOT resetting the system. void LLThrottleGroup::resetDynamicAdjust() { - F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); - S32 i; - for (i = 0; i < TC_EOF; i++) - { - mCurrentBPS[i] = mNominalBPS[i]; - mBitsAvailable[i] = mNominalBPS[i] * THROTTLE_LOOKAHEAD_TIME; - mLastSendTime[i] = mt_sec; - mBitsSentThisPeriod[i] = 0; - mBitsSentHistory[i] = 0; - } - mDynamicAdjustTime = mt_sec; + F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); + S32 i; + for (i = 0; i < TC_EOF; i++) + { + mCurrentBPS[i] = mNominalBPS[i]; + mBitsAvailable[i] = mNominalBPS[i] * THROTTLE_LOOKAHEAD_TIME; + mLastSendTime[i] = mt_sec; + mBitsSentThisPeriod[i] = 0; + mBitsSentHistory[i] = 0; + } + mDynamicAdjustTime = mt_sec; } bool LLThrottleGroup::setNominalBPS(F32* throttle_vec) { - bool changed = false; - S32 i; - for (i = 0; i < TC_EOF; i++) - { - if (mNominalBPS[i] != throttle_vec[i]) - { - changed = true; - mNominalBPS[i] = throttle_vec[i]; - } - } - - // If we changed the nominal settings, reset the dynamic - // adjustment subsystem. - if (changed) - { - resetDynamicAdjust(); - } - - return changed; + bool changed = false; + S32 i; + for (i = 0; i < TC_EOF; i++) + { + if (mNominalBPS[i] != throttle_vec[i]) + { + changed = true; + mNominalBPS[i] = throttle_vec[i]; + } + } + + // If we changed the nominal settings, reset the dynamic + // adjustment subsystem. + if (changed) + { + resetDynamicAdjust(); + } + + return changed; } // Return bits available in the channel -S32 LLThrottleGroup::getAvailable(S32 throttle_cat) +S32 LLThrottleGroup::getAvailable(S32 throttle_cat) { - S32 retval = 0; - - F32 category_bps = mCurrentBPS[throttle_cat]; - F32 lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; - - // use a temporary bits_available - // since we don't want to change mBitsAvailable every time - F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime[throttle_cat]; - F32 bits_available = mBitsAvailable[throttle_cat] + (category_bps * elapsed_time.value()); - - if (bits_available >= lookahead_bits) - { - retval = (S32) gThrottleMaximumBPS[throttle_cat]; - } - else - { - retval = (S32) bits_available; - } - - return retval; + S32 retval = 0; + + F32 category_bps = mCurrentBPS[throttle_cat]; + F32 lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; + + // use a temporary bits_available + // since we don't want to change mBitsAvailable every time + F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime[throttle_cat]; + F32 bits_available = mBitsAvailable[throttle_cat] + (category_bps * elapsed_time.value()); + + if (bits_available >= lookahead_bits) + { + retval = (S32) gThrottleMaximumBPS[throttle_cat]; + } + else + { + retval = (S32) bits_available; + } + + return retval; } bool LLThrottleGroup::checkOverflow(S32 throttle_cat, F32 bits) { - bool retval = true; - - F32 category_bps = mCurrentBPS[throttle_cat]; - F32 lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; - - // use a temporary bits_available - // since we don't want to change mBitsAvailable every time - F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime[throttle_cat]; - F32 bits_available = mBitsAvailable[throttle_cat] + (category_bps * elapsed_time.value()); - - if (bits_available >= lookahead_bits) - { - // ...channel completely open, so allow send regardless - // of size. This allows sends on very low BPS channels. - mBitsAvailable[throttle_cat] = lookahead_bits; - retval = false; - } - else if ( bits_available > bits ) - { - // ...enough space to send this message - retval = false; - } - - return retval; + bool retval = true; + + F32 category_bps = mCurrentBPS[throttle_cat]; + F32 lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; + + // use a temporary bits_available + // since we don't want to change mBitsAvailable every time + F32Seconds elapsed_time = LLMessageSystem::getMessageTimeSeconds() - mLastSendTime[throttle_cat]; + F32 bits_available = mBitsAvailable[throttle_cat] + (category_bps * elapsed_time.value()); + + if (bits_available >= lookahead_bits) + { + // ...channel completely open, so allow send regardless + // of size. This allows sends on very low BPS channels. + mBitsAvailable[throttle_cat] = lookahead_bits; + retval = false; + } + else if ( bits_available > bits ) + { + // ...enough space to send this message + retval = false; + } + + return retval; } bool LLThrottleGroup::throttleOverflow(S32 throttle_cat, F32 bits) { - F32Seconds elapsed_time; - F32 category_bps; - F32 lookahead_bits; - bool retval = true; - - category_bps = mCurrentBPS[throttle_cat]; - lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; - - F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); - elapsed_time = mt_sec - mLastSendTime[throttle_cat]; - mLastSendTime[throttle_cat] = mt_sec; - mBitsAvailable[throttle_cat] += category_bps * elapsed_time.value(); - - if (mBitsAvailable[throttle_cat] >= lookahead_bits) - { - // ...channel completely open, so allow send regardless - // of size. This allows sends on very low BPS channels. - mBitsAvailable[throttle_cat] = lookahead_bits; - retval = false; - } - else if ( mBitsAvailable[throttle_cat] > bits ) - { - // ...enough space to send this message - retval = false; - } - - // We actually already sent the bits. - mBitsAvailable[throttle_cat] -= bits; - - mBitsSentThisPeriod[throttle_cat] += bits; - - // What if bitsavailable goes negative? - // That's OK, because it means someone is banging on the channel, - // so we need some time to recover. - - return retval; + F32Seconds elapsed_time; + F32 category_bps; + F32 lookahead_bits; + bool retval = true; + + category_bps = mCurrentBPS[throttle_cat]; + lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; + + F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); + elapsed_time = mt_sec - mLastSendTime[throttle_cat]; + mLastSendTime[throttle_cat] = mt_sec; + mBitsAvailable[throttle_cat] += category_bps * elapsed_time.value(); + + if (mBitsAvailable[throttle_cat] >= lookahead_bits) + { + // ...channel completely open, so allow send regardless + // of size. This allows sends on very low BPS channels. + mBitsAvailable[throttle_cat] = lookahead_bits; + retval = false; + } + else if ( mBitsAvailable[throttle_cat] > bits ) + { + // ...enough space to send this message + retval = false; + } + + // We actually already sent the bits. + mBitsAvailable[throttle_cat] -= bits; + + mBitsSentThisPeriod[throttle_cat] += bits; + + // What if bitsavailable goes negative? + // That's OK, because it means someone is banging on the channel, + // so we need some time to recover. + + return retval; } bool LLThrottleGroup::dynamicAdjust() { - const F32Seconds DYNAMIC_ADJUST_TIME(1.0f); - const F32 CURRENT_PERIOD_WEIGHT = .25f; // how much weight to give to last period while determining BPS utilization - const F32 BUSY_PERCENT = 0.75f; // if use more than this fraction of BPS, you are busy - const F32 IDLE_PERCENT = 0.70f; // if use less than this fraction, you are "idle" - const F32 TRANSFER_PERCENT = 0.90f; // how much unused bandwidth to take away each adjustment - const F32 RECOVER_PERCENT = 0.25f; // how much to give back during recovery phase - - S32 i; - - F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); - - // Only dynamically adjust every few seconds - if ((mt_sec - mDynamicAdjustTime) < DYNAMIC_ADJUST_TIME) - { - return false; - } - mDynamicAdjustTime = mt_sec; - - // Update historical information - for (i = 0; i < TC_EOF; i++) - { - if (mBitsSentHistory[i] == 0) - { - // first run, just copy current period - mBitsSentHistory[i] = mBitsSentThisPeriod[i]; - } - else - { - // have some history, so weight accordingly - mBitsSentHistory[i] = (1.f - CURRENT_PERIOD_WEIGHT) * mBitsSentHistory[i] - + CURRENT_PERIOD_WEIGHT * mBitsSentThisPeriod[i]; - } - - mBitsSentThisPeriod[i] = 0; - } - - // Look for busy channels - // TODO: Fold into loop above. - bool channels_busy = false; - F32 busy_nominal_sum = 0; - bool channel_busy[TC_EOF]; - bool channel_idle[TC_EOF]; - bool channel_over_nominal[TC_EOF]; - - for (i = 0; i < TC_EOF; i++) - { - // Is this a busy channel? - if (mBitsSentHistory[i] >= BUSY_PERCENT * DYNAMIC_ADJUST_TIME.value() * mCurrentBPS[i]) - { - // this channel is busy - channels_busy = true; - busy_nominal_sum += mNominalBPS[i]; // use for allocation of pooled idle bandwidth - channel_busy[i] = true; - } - else - { - channel_busy[i] = false; - } - - // Is this an idle channel? - if ((mBitsSentHistory[i] < IDLE_PERCENT * DYNAMIC_ADJUST_TIME.value() * mCurrentBPS[i]) && - (mBitsAvailable[i] > 0)) - { - channel_idle[i] = true; - } - else - { - channel_idle[i] = false; - } - - // Is this an overpumped channel? - if (mCurrentBPS[i] > mNominalBPS[i]) - { - channel_over_nominal[i] = true; - } - else - { - channel_over_nominal[i] = false; - } - } - - if (channels_busy) - { - // Some channels are busy. Let's see if we can get them some bandwidth. - F32 used_bps; - F32 avail_bps; - F32 transfer_bps; - - F32 pool_bps = 0; - - for (i = 0; i < TC_EOF; i++) - { - if (channel_idle[i] || channel_over_nominal[i] ) - { - // Either channel i is idle, or has been overpumped. - // Therefore it's a candidate to give up some bandwidth. - // Figure out how much bandwidth it has been using, and how - // much is available to steal. - used_bps = mBitsSentHistory[i] / DYNAMIC_ADJUST_TIME.value(); - - // CRO make sure to keep a minimum amount of throttle available - // CRO NB: channels set to < MINIMUM_BPS will never give up bps, - // which is correct I think - if (used_bps < gThrottleMinimumBPS[i]) - { - used_bps = gThrottleMinimumBPS[i]; - } - - if (channel_over_nominal[i]) - { - F32 unused_current = mCurrentBPS[i] - used_bps; - avail_bps = llmax(mCurrentBPS[i] - mNominalBPS[i], unused_current); - } - else - { - avail_bps = mCurrentBPS[i] - used_bps; - } - - //LL_INFOS() << i << " avail " << avail_bps << LL_ENDL; - - // Historically, a channel could have used more than its current share, - // even if it's idle right now. - // Make sure we don't steal too much. - if (avail_bps < 0) - { - continue; - } - - // Transfer some bandwidth from this channel into the global pool. - transfer_bps = avail_bps * TRANSFER_PERCENT; - mCurrentBPS[i] -= transfer_bps; - pool_bps += transfer_bps; - } - } - - //LL_INFOS() << "Pool BPS: " << pool_bps << LL_ENDL; - // Now redistribute the bandwidth to busy channels. - F32 unused_bps = 0.f; - - for (i = 0; i < TC_EOF; i++) - { - if (channel_busy[i]) - { - F32 add_amount = pool_bps * (mNominalBPS[i] / busy_nominal_sum); - //LL_INFOS() << "Busy " << i << " gets " << pool_bps << LL_ENDL; - mCurrentBPS[i] += add_amount; - - // CRO: make sure this doesn't get too huge - // JC - Actually, need to let mCurrentBPS go less than nominal, otherwise - // you aren't allowing bandwidth to actually be moved from one channel - // to another. - // *TODO: If clamping high end, would be good to re- - // allocate to other channels in the above code. - const F32 MAX_BPS = 4 * mNominalBPS[i]; - if (mCurrentBPS[i] > MAX_BPS) - { - F32 overage = mCurrentBPS[i] - MAX_BPS; - mCurrentBPS[i] -= overage; - unused_bps += overage; - } - - // Paranoia - if (mCurrentBPS[i] < gThrottleMinimumBPS[i]) - { - mCurrentBPS[i] = gThrottleMinimumBPS[i]; - } - } - } - - // For fun, add the overage back in to objects - if (unused_bps > 0.f) - { - mCurrentBPS[TC_TASK] += unused_bps; - } - } - else - { - // No one is busy. - // Make the channel allocations seek toward nominal. - - // Look for overpumped channels - F32 starved_nominal_sum = 0; - F32 avail_bps = 0; - F32 transfer_bps = 0; - F32 pool_bps = 0; - for (i = 0; i < TC_EOF; i++) - { - if (mCurrentBPS[i] > mNominalBPS[i]) - { - avail_bps = (mCurrentBPS[i] - mNominalBPS[i]); - transfer_bps = avail_bps * RECOVER_PERCENT; - - mCurrentBPS[i] -= transfer_bps; - pool_bps += transfer_bps; - } - } - - // Evenly distribute bandwidth to channels currently - // using less than nominal. - for (i = 0; i < TC_EOF; i++) - { - if (mCurrentBPS[i] < mNominalBPS[i]) - { - // We're going to weight allocations by nominal BPS. - starved_nominal_sum += mNominalBPS[i]; - } - } - - for (i = 0; i < TC_EOF; i++) - { - if (mCurrentBPS[i] < mNominalBPS[i]) - { - // Distribute bandwidth according to nominal allocation ratios. - mCurrentBPS[i] += pool_bps * (mNominalBPS[i] / starved_nominal_sum); - } - } - } - return true; + const F32Seconds DYNAMIC_ADJUST_TIME(1.0f); + const F32 CURRENT_PERIOD_WEIGHT = .25f; // how much weight to give to last period while determining BPS utilization + const F32 BUSY_PERCENT = 0.75f; // if use more than this fraction of BPS, you are busy + const F32 IDLE_PERCENT = 0.70f; // if use less than this fraction, you are "idle" + const F32 TRANSFER_PERCENT = 0.90f; // how much unused bandwidth to take away each adjustment + const F32 RECOVER_PERCENT = 0.25f; // how much to give back during recovery phase + + S32 i; + + F64Seconds mt_sec = LLMessageSystem::getMessageTimeSeconds(); + + // Only dynamically adjust every few seconds + if ((mt_sec - mDynamicAdjustTime) < DYNAMIC_ADJUST_TIME) + { + return false; + } + mDynamicAdjustTime = mt_sec; + + // Update historical information + for (i = 0; i < TC_EOF; i++) + { + if (mBitsSentHistory[i] == 0) + { + // first run, just copy current period + mBitsSentHistory[i] = mBitsSentThisPeriod[i]; + } + else + { + // have some history, so weight accordingly + mBitsSentHistory[i] = (1.f - CURRENT_PERIOD_WEIGHT) * mBitsSentHistory[i] + + CURRENT_PERIOD_WEIGHT * mBitsSentThisPeriod[i]; + } + + mBitsSentThisPeriod[i] = 0; + } + + // Look for busy channels + // TODO: Fold into loop above. + bool channels_busy = false; + F32 busy_nominal_sum = 0; + bool channel_busy[TC_EOF]; + bool channel_idle[TC_EOF]; + bool channel_over_nominal[TC_EOF]; + + for (i = 0; i < TC_EOF; i++) + { + // Is this a busy channel? + if (mBitsSentHistory[i] >= BUSY_PERCENT * DYNAMIC_ADJUST_TIME.value() * mCurrentBPS[i]) + { + // this channel is busy + channels_busy = true; + busy_nominal_sum += mNominalBPS[i]; // use for allocation of pooled idle bandwidth + channel_busy[i] = true; + } + else + { + channel_busy[i] = false; + } + + // Is this an idle channel? + if ((mBitsSentHistory[i] < IDLE_PERCENT * DYNAMIC_ADJUST_TIME.value() * mCurrentBPS[i]) && + (mBitsAvailable[i] > 0)) + { + channel_idle[i] = true; + } + else + { + channel_idle[i] = false; + } + + // Is this an overpumped channel? + if (mCurrentBPS[i] > mNominalBPS[i]) + { + channel_over_nominal[i] = true; + } + else + { + channel_over_nominal[i] = false; + } + } + + if (channels_busy) + { + // Some channels are busy. Let's see if we can get them some bandwidth. + F32 used_bps; + F32 avail_bps; + F32 transfer_bps; + + F32 pool_bps = 0; + + for (i = 0; i < TC_EOF; i++) + { + if (channel_idle[i] || channel_over_nominal[i] ) + { + // Either channel i is idle, or has been overpumped. + // Therefore it's a candidate to give up some bandwidth. + // Figure out how much bandwidth it has been using, and how + // much is available to steal. + used_bps = mBitsSentHistory[i] / DYNAMIC_ADJUST_TIME.value(); + + // CRO make sure to keep a minimum amount of throttle available + // CRO NB: channels set to < MINIMUM_BPS will never give up bps, + // which is correct I think + if (used_bps < gThrottleMinimumBPS[i]) + { + used_bps = gThrottleMinimumBPS[i]; + } + + if (channel_over_nominal[i]) + { + F32 unused_current = mCurrentBPS[i] - used_bps; + avail_bps = llmax(mCurrentBPS[i] - mNominalBPS[i], unused_current); + } + else + { + avail_bps = mCurrentBPS[i] - used_bps; + } + + //LL_INFOS() << i << " avail " << avail_bps << LL_ENDL; + + // Historically, a channel could have used more than its current share, + // even if it's idle right now. + // Make sure we don't steal too much. + if (avail_bps < 0) + { + continue; + } + + // Transfer some bandwidth from this channel into the global pool. + transfer_bps = avail_bps * TRANSFER_PERCENT; + mCurrentBPS[i] -= transfer_bps; + pool_bps += transfer_bps; + } + } + + //LL_INFOS() << "Pool BPS: " << pool_bps << LL_ENDL; + // Now redistribute the bandwidth to busy channels. + F32 unused_bps = 0.f; + + for (i = 0; i < TC_EOF; i++) + { + if (channel_busy[i]) + { + F32 add_amount = pool_bps * (mNominalBPS[i] / busy_nominal_sum); + //LL_INFOS() << "Busy " << i << " gets " << pool_bps << LL_ENDL; + mCurrentBPS[i] += add_amount; + + // CRO: make sure this doesn't get too huge + // JC - Actually, need to let mCurrentBPS go less than nominal, otherwise + // you aren't allowing bandwidth to actually be moved from one channel + // to another. + // *TODO: If clamping high end, would be good to re- + // allocate to other channels in the above code. + const F32 MAX_BPS = 4 * mNominalBPS[i]; + if (mCurrentBPS[i] > MAX_BPS) + { + F32 overage = mCurrentBPS[i] - MAX_BPS; + mCurrentBPS[i] -= overage; + unused_bps += overage; + } + + // Paranoia + if (mCurrentBPS[i] < gThrottleMinimumBPS[i]) + { + mCurrentBPS[i] = gThrottleMinimumBPS[i]; + } + } + } + + // For fun, add the overage back in to objects + if (unused_bps > 0.f) + { + mCurrentBPS[TC_TASK] += unused_bps; + } + } + else + { + // No one is busy. + // Make the channel allocations seek toward nominal. + + // Look for overpumped channels + F32 starved_nominal_sum = 0; + F32 avail_bps = 0; + F32 transfer_bps = 0; + F32 pool_bps = 0; + for (i = 0; i < TC_EOF; i++) + { + if (mCurrentBPS[i] > mNominalBPS[i]) + { + avail_bps = (mCurrentBPS[i] - mNominalBPS[i]); + transfer_bps = avail_bps * RECOVER_PERCENT; + + mCurrentBPS[i] -= transfer_bps; + pool_bps += transfer_bps; + } + } + + // Evenly distribute bandwidth to channels currently + // using less than nominal. + for (i = 0; i < TC_EOF; i++) + { + if (mCurrentBPS[i] < mNominalBPS[i]) + { + // We're going to weight allocations by nominal BPS. + starved_nominal_sum += mNominalBPS[i]; + } + } + + for (i = 0; i < TC_EOF; i++) + { + if (mCurrentBPS[i] < mNominalBPS[i]) + { + // Distribute bandwidth according to nominal allocation ratios. + mCurrentBPS[i] += pool_bps * (mNominalBPS[i] / starved_nominal_sum); + } + } + } + return true; } diff --git a/indra/llmessage/llthrottle.h b/indra/llmessage/llthrottle.h index 4eb800de06..b8a8c9f1f7 100644 --- a/indra/llmessage/llthrottle.h +++ b/indra/llmessage/llthrottle.h @@ -1,25 +1,25 @@ -/** +/** * @file llthrottle.h * @brief LLThrottle class used for network bandwidth control * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,64 +37,64 @@ class LLDataPacker; class LLThrottle { public: - LLThrottle(const F32 throttle = 1.f); - ~LLThrottle() { } + LLThrottle(const F32 throttle = 1.f); + ~LLThrottle() { } - void setRate(const F32 rate); - bool checkOverflow(const F32 amount); // I'm about to add an amount, true if would overflow throttle - bool throttleOverflow(const F32 amount); // I just sent amount, true if that overflowed the throttle + void setRate(const F32 rate); + bool checkOverflow(const F32 amount); // I'm about to add an amount, true if would overflow throttle + bool throttleOverflow(const F32 amount); // I just sent amount, true if that overflowed the throttle - F32 getAvailable(); // Return the available bits - F32 getRate() const { return mRate; } + F32 getAvailable(); // Return the available bits + F32 getRate() const { return mRate; } private: - F32 mLookaheadSecs; // Seconds to look ahead, maximum - F32 mRate; // BPS available, dynamically adjusted - F32 mAvailable; // Bits available to send right now on each channel - F64Seconds mLastSendTime; // Time since last send on this channel + F32 mLookaheadSecs; // Seconds to look ahead, maximum + F32 mRate; // BPS available, dynamically adjusted + F32 mAvailable; // Bits available to send right now on each channel + F64Seconds mLastSendTime; // Time since last send on this channel }; typedef enum e_throttle_categories { - TC_RESEND, - TC_LAND, - TC_WIND, - TC_CLOUD, - TC_TASK, - TC_TEXTURE, - TC_ASSET, - TC_EOF + TC_RESEND, + TC_LAND, + TC_WIND, + TC_CLOUD, + TC_TASK, + TC_TEXTURE, + TC_ASSET, + TC_EOF } EThrottleCats; class LLThrottleGroup { public: - LLThrottleGroup(); - ~LLThrottleGroup() { } + LLThrottleGroup(); + ~LLThrottleGroup() { } - void resetDynamicAdjust(); - bool checkOverflow(S32 throttle_cat, F32 bits); // I'm about to send bits, true if would overflow channel - bool throttleOverflow(S32 throttle_cat, F32 bits); // I just sent bits, true if that overflowed the channel - bool dynamicAdjust(); // Shift bandwidth from idle channels to busy channels, true if adjustment occurred - bool setNominalBPS(F32* throttle_vec); // true if any value was different, resets adjustment system if was different + void resetDynamicAdjust(); + bool checkOverflow(S32 throttle_cat, F32 bits); // I'm about to send bits, true if would overflow channel + bool throttleOverflow(S32 throttle_cat, F32 bits); // I just sent bits, true if that overflowed the channel + bool dynamicAdjust(); // Shift bandwidth from idle channels to busy channels, true if adjustment occurred + bool setNominalBPS(F32* throttle_vec); // true if any value was different, resets adjustment system if was different - S32 getAvailable(S32 throttle_cat); // Return bits available in the channel + S32 getAvailable(S32 throttle_cat); // Return bits available in the channel - void packThrottle(LLDataPacker &dp) const; - void unpackThrottle(LLDataPacker &dp); + void packThrottle(LLDataPacker &dp) const; + void unpackThrottle(LLDataPacker &dp); public: - F32 mThrottleTotal[TC_EOF]; // BPS available, sent by viewer, sum for all simulators + F32 mThrottleTotal[TC_EOF]; // BPS available, sent by viewer, sum for all simulators protected: - F32 mNominalBPS[TC_EOF]; // BPS available, adjusted to be just this simulator - F32 mCurrentBPS[TC_EOF]; // BPS available, dynamically adjusted + F32 mNominalBPS[TC_EOF]; // BPS available, adjusted to be just this simulator + F32 mCurrentBPS[TC_EOF]; // BPS available, dynamically adjusted - F32 mBitsAvailable[TC_EOF]; // Bits available to send right now on each channel - F32 mBitsSentThisPeriod[TC_EOF]; // Sent in this dynamic allocation period - F32 mBitsSentHistory[TC_EOF]; // Sent before this dynamic allocation period, adjusted to one period length + F32 mBitsAvailable[TC_EOF]; // Bits available to send right now on each channel + F32 mBitsSentThisPeriod[TC_EOF]; // Sent in this dynamic allocation period + F32 mBitsSentHistory[TC_EOF]; // Sent before this dynamic allocation period, adjusted to one period length - F64Seconds mLastSendTime[TC_EOF]; // Time since last send on this channel - F64Seconds mDynamicAdjustTime; // Only dynamic adjust every 2 seconds or so. + F64Seconds mLastSendTime[TC_EOF]; // Time since last send on this channel + F64Seconds mDynamicAdjustTime; // Only dynamic adjust every 2 seconds or so. }; diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp index bad12101e5..72d623ea42 100644 --- a/indra/llmessage/lltransfermanager.cpp +++ b/indra/llmessage/lltransfermanager.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lltransfermanager.cpp * @brief Improved transfer mechanism for moving data through the * message system. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,124 +49,124 @@ LLTransferSource::stype_scfunc_map LLTransferSource::sSourceCreateMap; // LLTransferManager::LLTransferManager() : - mValid(false) + mValid(false) { - S32 i; - for (i = 0; i < LLTTT_NUM_TYPES; i++) - { - mTransferBitsIn[i] = 0; - mTransferBitsOut[i] = 0; - } + S32 i; + for (i = 0; i < LLTTT_NUM_TYPES; i++) + { + mTransferBitsIn[i] = 0; + mTransferBitsOut[i] = 0; + } } LLTransferManager::~LLTransferManager() { - // LLTransferManager should have been cleaned up by message system shutdown process - llassert(!mValid); - if (mValid) - { - // Usually happens if OS tries to kill viewer - cleanup(); - } + // LLTransferManager should have been cleaned up by message system shutdown process + llassert(!mValid); + if (mValid) + { + // Usually happens if OS tries to kill viewer + cleanup(); + } } void LLTransferManager::init() { - if (mValid) - { - LL_ERRS() << "Double initializing LLTransferManager!" << LL_ENDL; - } - mValid = true; - - // Register message system handlers - gMessageSystem->setHandlerFunc("TransferRequest", processTransferRequest, NULL); - gMessageSystem->setHandlerFunc("TransferInfo", processTransferInfo, NULL); - gMessageSystem->setHandlerFunc("TransferPacket", processTransferPacket, NULL); - gMessageSystem->setHandlerFunc("TransferAbort", processTransferAbort, NULL); + if (mValid) + { + LL_ERRS() << "Double initializing LLTransferManager!" << LL_ENDL; + } + mValid = true; + + // Register message system handlers + gMessageSystem->setHandlerFunc("TransferRequest", processTransferRequest, NULL); + gMessageSystem->setHandlerFunc("TransferInfo", processTransferInfo, NULL); + gMessageSystem->setHandlerFunc("TransferPacket", processTransferPacket, NULL); + gMessageSystem->setHandlerFunc("TransferAbort", processTransferAbort, NULL); } void LLTransferManager::cleanup() { - mValid = false; - - host_tc_map::iterator iter; - for (iter = mTransferConnections.begin(); iter != mTransferConnections.end(); iter++) - { - delete iter->second; - } - mTransferConnections.clear(); + mValid = false; + + host_tc_map::iterator iter; + for (iter = mTransferConnections.begin(); iter != mTransferConnections.end(); iter++) + { + delete iter->second; + } + mTransferConnections.clear(); } void LLTransferManager::updateTransfers() { - host_tc_map::iterator iter,cur; + host_tc_map::iterator iter,cur; - iter = mTransferConnections.begin(); + iter = mTransferConnections.begin(); - while (iter !=mTransferConnections.end()) - { - cur = iter; - iter++; - cur->second->updateTransfers(); - } + while (iter !=mTransferConnections.end()) + { + cur = iter; + iter++; + cur->second->updateTransfers(); + } } void LLTransferManager::cleanupConnection(const LLHost &host) { - host_tc_map::iterator iter; - iter = mTransferConnections.find(host); - if (iter == mTransferConnections.end()) - { - // This can happen legitimately if we've never done a transfer, and we're - // cleaning up a circuit. - //LL_WARNS() << "Cleaning up nonexistent transfer connection to " << host << LL_ENDL; - return; - } - LLTransferConnection *connp = iter->second; - delete connp; - mTransferConnections.erase(iter); + host_tc_map::iterator iter; + iter = mTransferConnections.find(host); + if (iter == mTransferConnections.end()) + { + // This can happen legitimately if we've never done a transfer, and we're + // cleaning up a circuit. + //LL_WARNS() << "Cleaning up nonexistent transfer connection to " << host << LL_ENDL; + return; + } + LLTransferConnection *connp = iter->second; + delete connp; + mTransferConnections.erase(iter); } LLTransferConnection *LLTransferManager::getTransferConnection(const LLHost &host) { - host_tc_map::iterator iter; - iter = mTransferConnections.find(host); - if (iter == mTransferConnections.end()) - { - mTransferConnections[host] = new LLTransferConnection(host); - return mTransferConnections[host]; - } - - return iter->second; + host_tc_map::iterator iter; + iter = mTransferConnections.find(host); + if (iter == mTransferConnections.end()) + { + mTransferConnections[host] = new LLTransferConnection(host); + return mTransferConnections[host]; + } + + return iter->second; } LLTransferSourceChannel *LLTransferManager::getSourceChannel(const LLHost &host, const LLTransferChannelType type) { - LLTransferConnection *tcp = getTransferConnection(host); - if (!tcp) - { - return NULL; - } - return tcp->getSourceChannel(type); + LLTransferConnection *tcp = getTransferConnection(host); + if (!tcp) + { + return NULL; + } + return tcp->getSourceChannel(type); } LLTransferTargetChannel *LLTransferManager::getTargetChannel(const LLHost &host, const LLTransferChannelType type) { - LLTransferConnection *tcp = getTransferConnection(host); - if (!tcp) - { - return NULL; - } - return tcp->getTargetChannel(type); + LLTransferConnection *tcp = getTransferConnection(host); + if (!tcp) + { + return NULL; + } + return tcp->getTargetChannel(type); } // virtual @@ -176,26 +176,26 @@ LLTransferSourceParams::~LLTransferSourceParams() LLTransferSource *LLTransferManager::findTransferSource(const LLUUID &transfer_id) { - // This linear traversal could screw us later if we do lots of - // searches for sources. However, this ONLY happens right now - // in asset transfer callbacks, so this should be relatively quick. - host_tc_map::iterator iter; - for (iter = mTransferConnections.begin(); iter != mTransferConnections.end(); iter++) - { - LLTransferConnection *tcp = iter->second; - LLTransferConnection::tsc_iter sc_iter; - for (sc_iter = tcp->mTransferSourceChannels.begin(); sc_iter != tcp->mTransferSourceChannels.end(); sc_iter++) - { - LLTransferSourceChannel *scp = *sc_iter; - LLTransferSource *sourcep = scp->findTransferSource(transfer_id); - if (sourcep) - { - return sourcep; - } - } - } - - return NULL; + // This linear traversal could screw us later if we do lots of + // searches for sources. However, this ONLY happens right now + // in asset transfer callbacks, so this should be relatively quick. + host_tc_map::iterator iter; + for (iter = mTransferConnections.begin(); iter != mTransferConnections.end(); iter++) + { + LLTransferConnection *tcp = iter->second; + LLTransferConnection::tsc_iter sc_iter; + for (sc_iter = tcp->mTransferSourceChannels.begin(); sc_iter != tcp->mTransferSourceChannels.end(); sc_iter++) + { + LLTransferSourceChannel *scp = *sc_iter; + LLTransferSource *sourcep = scp->findTransferSource(transfer_id); + if (sourcep) + { + return sourcep; + } + } + } + + return NULL; } // @@ -205,426 +205,426 @@ LLTransferSource *LLTransferManager::findTransferSource(const LLUUID &transfer_i //static void LLTransferManager::processTransferRequest(LLMessageSystem *msgp, void **) { - //LL_INFOS() << "LLTransferManager::processTransferRequest" << LL_ENDL; - - LLUUID transfer_id; - LLTransferSourceType source_type; - LLTransferChannelType channel_type; - F32 priority; - - msgp->getUUID("TransferInfo", "TransferID", transfer_id); - msgp->getS32("TransferInfo", "SourceType", (S32 &)source_type); - msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type); - msgp->getF32("TransferInfo", "Priority", priority); - - LLTransferSourceChannel *tscp = gTransferManager.getSourceChannel(msgp->getSender(), channel_type); - - if (!tscp) - { - LL_WARNS() << "Source channel not found" << LL_ENDL; - return; - } - - if (tscp->findTransferSource(transfer_id)) - { - LL_WARNS() << "Duplicate request for transfer " << transfer_id << ", aborting!" << LL_ENDL; - return; - } - - S32 size = msgp->getSize("TransferInfo", "Params"); - if(size > MAX_PARAMS_SIZE) - { - LL_WARNS() << "LLTransferManager::processTransferRequest params too big." - << LL_ENDL; - return; - } - - //LL_INFOS() << transfer_id << ":" << source_type << ":" << channel_type << ":" << priority << LL_ENDL; - LLTransferSource* tsp = LLTransferSource::createSource( - source_type, - transfer_id, - priority); - if(!tsp) - { - LL_WARNS() << "LLTransferManager::processTransferRequest couldn't create" - << " transfer source!" << LL_ENDL; - return; - } - U8 tmp[MAX_PARAMS_SIZE]; - msgp->getBinaryData("TransferInfo", "Params", tmp, size); - - LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE); - bool unpack_ok = tsp->unpackParams(dpb); - if (!unpack_ok) - { - // This should only happen if the data is corrupt or - // incorrectly packed. - // *NOTE: We may want to call abortTransfer(). - LL_WARNS() << "LLTransferManager::processTransferRequest: bad parameters." - << LL_ENDL; - delete tsp; - return; - } - - tscp->addTransferSource(tsp); - tsp->initTransfer(); + //LL_INFOS() << "LLTransferManager::processTransferRequest" << LL_ENDL; + + LLUUID transfer_id; + LLTransferSourceType source_type; + LLTransferChannelType channel_type; + F32 priority; + + msgp->getUUID("TransferInfo", "TransferID", transfer_id); + msgp->getS32("TransferInfo", "SourceType", (S32 &)source_type); + msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type); + msgp->getF32("TransferInfo", "Priority", priority); + + LLTransferSourceChannel *tscp = gTransferManager.getSourceChannel(msgp->getSender(), channel_type); + + if (!tscp) + { + LL_WARNS() << "Source channel not found" << LL_ENDL; + return; + } + + if (tscp->findTransferSource(transfer_id)) + { + LL_WARNS() << "Duplicate request for transfer " << transfer_id << ", aborting!" << LL_ENDL; + return; + } + + S32 size = msgp->getSize("TransferInfo", "Params"); + if(size > MAX_PARAMS_SIZE) + { + LL_WARNS() << "LLTransferManager::processTransferRequest params too big." + << LL_ENDL; + return; + } + + //LL_INFOS() << transfer_id << ":" << source_type << ":" << channel_type << ":" << priority << LL_ENDL; + LLTransferSource* tsp = LLTransferSource::createSource( + source_type, + transfer_id, + priority); + if(!tsp) + { + LL_WARNS() << "LLTransferManager::processTransferRequest couldn't create" + << " transfer source!" << LL_ENDL; + return; + } + U8 tmp[MAX_PARAMS_SIZE]; + msgp->getBinaryData("TransferInfo", "Params", tmp, size); + + LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE); + bool unpack_ok = tsp->unpackParams(dpb); + if (!unpack_ok) + { + // This should only happen if the data is corrupt or + // incorrectly packed. + // *NOTE: We may want to call abortTransfer(). + LL_WARNS() << "LLTransferManager::processTransferRequest: bad parameters." + << LL_ENDL; + delete tsp; + return; + } + + tscp->addTransferSource(tsp); + tsp->initTransfer(); } //static void LLTransferManager::processTransferInfo(LLMessageSystem *msgp, void **) { - //LL_INFOS() << "LLTransferManager::processTransferInfo" << LL_ENDL; - - LLUUID transfer_id; - LLTransferTargetType target_type; - LLTransferChannelType channel_type; - LLTSCode status; - S32 size; - - msgp->getUUID("TransferInfo", "TransferID", transfer_id); - msgp->getS32("TransferInfo", "TargetType", (S32 &)target_type); - msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type); - msgp->getS32("TransferInfo", "Status", (S32 &)status); - msgp->getS32("TransferInfo", "Size", size); - - //LL_INFOS() << transfer_id << ":" << target_type<< ":" << channel_type << LL_ENDL; - LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type); - if (!ttcp) - { - LL_WARNS() << "Target channel not found" << LL_ENDL; - // Should send a message to abort the transfer. - return; - } - - LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id); - if (!ttp) - { - LL_WARNS() << "TransferInfo for unknown transfer! Not able to handle this yet!" << LL_ENDL; - // This could happen if we're doing a push transfer, although to avoid confusion, - // maybe it should be a different message. - return; - } - - if (status != LLTS_OK) - { - LL_WARNS() << transfer_id << ": Non-ok status, cleaning up" << LL_ENDL; - ttp->completionCallback(status); - // Clean up the transfer. - ttcp->deleteTransfer(ttp); - return; - } - - // unpack the params - S32 params_size = msgp->getSize("TransferInfo", "Params"); - if(params_size > MAX_PARAMS_SIZE) - { - LL_WARNS() << "LLTransferManager::processTransferInfo params too big." - << LL_ENDL; - return; - } - else if(params_size > 0) - { - U8 tmp[MAX_PARAMS_SIZE]; - msgp->getBinaryData("TransferInfo", "Params", tmp, params_size); - LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE); - if (!ttp->unpackParams(dpb)) - { - // This should only happen if the data is corrupt or - // incorrectly packed. - LL_WARNS() << "LLTransferManager::processTransferRequest: bad params." - << LL_ENDL; - ttp->abortTransfer(); - ttcp->deleteTransfer(ttp); - return; - } - } - - //LL_INFOS() << "Receiving " << transfer_id << ", size " << size << " bytes" << LL_ENDL; - ttp->setSize(size); - ttp->setGotInfo(true); - - // OK, at this point we to handle any delayed transfer packets (which could happen - // if this packet was lost) - - // This is a lame cut and paste of code down below. If we change the logic down there, - // we HAVE to change the logic up here. - - while (1) - { - S32 packet_id = 0; - U8 tmp_data[MAX_PACKET_DATA_SIZE]; - // See if we've got any delayed packets - packet_id = ttp->getNextPacketID(); - if (ttp->mDelayedPacketMap.find(packet_id) != ttp->mDelayedPacketMap.end()) - { - // Perhaps this stuff should be inside a method in LLTransferPacket? - // I'm too lazy to do it now, though. -// LL_INFOS() << "Playing back delayed packet " << packet_id << LL_ENDL; - LLTransferPacket *packetp = ttp->mDelayedPacketMap[packet_id]; - - // This is somewhat inefficient, but avoids us having to duplicate - // code between the off-the-wire and delayed paths. - packet_id = packetp->mPacketID; - size = packetp->mSize; - if (size) - { - if ((packetp->mDatap != NULL) && (size<(S32)sizeof(tmp_data))) - { - memcpy(tmp_data, packetp->mDatap, size); /*Flawfinder: ignore*/ - } - } - status = packetp->mStatus; - ttp->mDelayedPacketMap.erase(packet_id); - delete packetp; - } - else - { - // No matching delayed packet, we're done. - break; - } - - LLTSCode ret_code = ttp->dataCallback(packet_id, tmp_data, size); - if (ret_code == LLTS_OK) - { - ttp->setLastPacketID(packet_id); - } - - if (status != LLTS_OK) - { - if (status != LLTS_DONE) - { - LL_WARNS() << "LLTransferManager::processTransferInfo Error in playback!" << LL_ENDL; - } - else - { - LL_INFOS() << "LLTransferManager::processTransferInfo replay FINISHED for " << transfer_id << LL_ENDL; - } - // This transfer is done, either via error or not. - ttp->completionCallback(status); - ttcp->deleteTransfer(ttp); - return; - } - } + //LL_INFOS() << "LLTransferManager::processTransferInfo" << LL_ENDL; + + LLUUID transfer_id; + LLTransferTargetType target_type; + LLTransferChannelType channel_type; + LLTSCode status; + S32 size; + + msgp->getUUID("TransferInfo", "TransferID", transfer_id); + msgp->getS32("TransferInfo", "TargetType", (S32 &)target_type); + msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type); + msgp->getS32("TransferInfo", "Status", (S32 &)status); + msgp->getS32("TransferInfo", "Size", size); + + //LL_INFOS() << transfer_id << ":" << target_type<< ":" << channel_type << LL_ENDL; + LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type); + if (!ttcp) + { + LL_WARNS() << "Target channel not found" << LL_ENDL; + // Should send a message to abort the transfer. + return; + } + + LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id); + if (!ttp) + { + LL_WARNS() << "TransferInfo for unknown transfer! Not able to handle this yet!" << LL_ENDL; + // This could happen if we're doing a push transfer, although to avoid confusion, + // maybe it should be a different message. + return; + } + + if (status != LLTS_OK) + { + LL_WARNS() << transfer_id << ": Non-ok status, cleaning up" << LL_ENDL; + ttp->completionCallback(status); + // Clean up the transfer. + ttcp->deleteTransfer(ttp); + return; + } + + // unpack the params + S32 params_size = msgp->getSize("TransferInfo", "Params"); + if(params_size > MAX_PARAMS_SIZE) + { + LL_WARNS() << "LLTransferManager::processTransferInfo params too big." + << LL_ENDL; + return; + } + else if(params_size > 0) + { + U8 tmp[MAX_PARAMS_SIZE]; + msgp->getBinaryData("TransferInfo", "Params", tmp, params_size); + LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE); + if (!ttp->unpackParams(dpb)) + { + // This should only happen if the data is corrupt or + // incorrectly packed. + LL_WARNS() << "LLTransferManager::processTransferRequest: bad params." + << LL_ENDL; + ttp->abortTransfer(); + ttcp->deleteTransfer(ttp); + return; + } + } + + //LL_INFOS() << "Receiving " << transfer_id << ", size " << size << " bytes" << LL_ENDL; + ttp->setSize(size); + ttp->setGotInfo(true); + + // OK, at this point we to handle any delayed transfer packets (which could happen + // if this packet was lost) + + // This is a lame cut and paste of code down below. If we change the logic down there, + // we HAVE to change the logic up here. + + while (1) + { + S32 packet_id = 0; + U8 tmp_data[MAX_PACKET_DATA_SIZE]; + // See if we've got any delayed packets + packet_id = ttp->getNextPacketID(); + if (ttp->mDelayedPacketMap.find(packet_id) != ttp->mDelayedPacketMap.end()) + { + // Perhaps this stuff should be inside a method in LLTransferPacket? + // I'm too lazy to do it now, though. +// LL_INFOS() << "Playing back delayed packet " << packet_id << LL_ENDL; + LLTransferPacket *packetp = ttp->mDelayedPacketMap[packet_id]; + + // This is somewhat inefficient, but avoids us having to duplicate + // code between the off-the-wire and delayed paths. + packet_id = packetp->mPacketID; + size = packetp->mSize; + if (size) + { + if ((packetp->mDatap != NULL) && (size<(S32)sizeof(tmp_data))) + { + memcpy(tmp_data, packetp->mDatap, size); /*Flawfinder: ignore*/ + } + } + status = packetp->mStatus; + ttp->mDelayedPacketMap.erase(packet_id); + delete packetp; + } + else + { + // No matching delayed packet, we're done. + break; + } + + LLTSCode ret_code = ttp->dataCallback(packet_id, tmp_data, size); + if (ret_code == LLTS_OK) + { + ttp->setLastPacketID(packet_id); + } + + if (status != LLTS_OK) + { + if (status != LLTS_DONE) + { + LL_WARNS() << "LLTransferManager::processTransferInfo Error in playback!" << LL_ENDL; + } + else + { + LL_INFOS() << "LLTransferManager::processTransferInfo replay FINISHED for " << transfer_id << LL_ENDL; + } + // This transfer is done, either via error or not. + ttp->completionCallback(status); + ttcp->deleteTransfer(ttp); + return; + } + } } //static void LLTransferManager::processTransferPacket(LLMessageSystem *msgp, void **) { - //LL_INFOS() << "LLTransferManager::processTransferPacket" << LL_ENDL; - - LLUUID transfer_id; - LLTransferChannelType channel_type; - S32 packet_id; - LLTSCode status; - S32 size; - msgp->getUUID("TransferData", "TransferID", transfer_id); - msgp->getS32("TransferData", "ChannelType", (S32 &)channel_type); - msgp->getS32("TransferData", "Packet", packet_id); - msgp->getS32("TransferData", "Status", (S32 &)status); - - // Find the transfer associated with this packet. - //LL_INFOS() << transfer_id << ":" << channel_type << LL_ENDL; - LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type); - if (!ttcp) - { - LL_WARNS() << "Target channel not found" << LL_ENDL; - return; - } - - LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id); - if (!ttp) - { - LL_WARNS() << "Didn't find matching transfer for " << transfer_id - << " processing packet " << packet_id - << " from " << msgp->getSender() << LL_ENDL; - return; - } - - size = msgp->getSize("TransferData", "Data"); - - S32 msg_bytes = 0; - if (msgp->getReceiveCompressedSize()) - { - msg_bytes = msgp->getReceiveCompressedSize(); - } - else - { - msg_bytes = msgp->getReceiveSize(); - } - gTransferManager.addTransferBitsIn(ttcp->mChannelType, msg_bytes*8); - - if ((size < 0) || (size > MAX_PACKET_DATA_SIZE)) - { - LL_WARNS() << "Invalid transfer packet size " << size << LL_ENDL; - return; - } - - U8 tmp_data[MAX_PACKET_DATA_SIZE]; - if (size > 0) - { - // Only pull the data out if the size is > 0 - msgp->getBinaryData("TransferData", "Data", tmp_data, size); - } - - if ((!ttp->gotInfo()) || (ttp->getNextPacketID() != packet_id)) - { - // Put this on a list of packets to be delivered later. - if(!ttp->addDelayedPacket(packet_id, status, tmp_data, size)) - { - // Whoops - failed to add a delayed packet for some reason. - LL_WARNS() << "Too many delayed packets processing transfer " - << transfer_id << " from " << msgp->getSender() << LL_ENDL; - ttp->abortTransfer(); - ttcp->deleteTransfer(ttp); - return; - } + //LL_INFOS() << "LLTransferManager::processTransferPacket" << LL_ENDL; + + LLUUID transfer_id; + LLTransferChannelType channel_type; + S32 packet_id; + LLTSCode status; + S32 size; + msgp->getUUID("TransferData", "TransferID", transfer_id); + msgp->getS32("TransferData", "ChannelType", (S32 &)channel_type); + msgp->getS32("TransferData", "Packet", packet_id); + msgp->getS32("TransferData", "Status", (S32 &)status); + + // Find the transfer associated with this packet. + //LL_INFOS() << transfer_id << ":" << channel_type << LL_ENDL; + LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type); + if (!ttcp) + { + LL_WARNS() << "Target channel not found" << LL_ENDL; + return; + } + + LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id); + if (!ttp) + { + LL_WARNS() << "Didn't find matching transfer for " << transfer_id + << " processing packet " << packet_id + << " from " << msgp->getSender() << LL_ENDL; + return; + } + + size = msgp->getSize("TransferData", "Data"); + + S32 msg_bytes = 0; + if (msgp->getReceiveCompressedSize()) + { + msg_bytes = msgp->getReceiveCompressedSize(); + } + else + { + msg_bytes = msgp->getReceiveSize(); + } + gTransferManager.addTransferBitsIn(ttcp->mChannelType, msg_bytes*8); + + if ((size < 0) || (size > MAX_PACKET_DATA_SIZE)) + { + LL_WARNS() << "Invalid transfer packet size " << size << LL_ENDL; + return; + } + + U8 tmp_data[MAX_PACKET_DATA_SIZE]; + if (size > 0) + { + // Only pull the data out if the size is > 0 + msgp->getBinaryData("TransferData", "Data", tmp_data, size); + } + + if ((!ttp->gotInfo()) || (ttp->getNextPacketID() != packet_id)) + { + // Put this on a list of packets to be delivered later. + if(!ttp->addDelayedPacket(packet_id, status, tmp_data, size)) + { + // Whoops - failed to add a delayed packet for some reason. + LL_WARNS() << "Too many delayed packets processing transfer " + << transfer_id << " from " << msgp->getSender() << LL_ENDL; + ttp->abortTransfer(); + ttcp->deleteTransfer(ttp); + return; + } #if 0 - // Spammy! - const S32 LL_TRANSFER_WARN_GAP = 10; - if(!ttp->gotInfo()) - { - LL_WARNS() << "Got data packet before information in transfer " - << transfer_id << " from " << msgp->getSender() - << ", got " << packet_id << LL_ENDL; - } - else if((packet_id - ttp->getNextPacketID()) > LL_TRANSFER_WARN_GAP) - { - LL_WARNS() << "Out of order packet in transfer " << transfer_id - << " from " << msgp->getSender() << ", got " << packet_id - << " expecting " << ttp->getNextPacketID() << LL_ENDL; - } + // Spammy! + const S32 LL_TRANSFER_WARN_GAP = 10; + if(!ttp->gotInfo()) + { + LL_WARNS() << "Got data packet before information in transfer " + << transfer_id << " from " << msgp->getSender() + << ", got " << packet_id << LL_ENDL; + } + else if((packet_id - ttp->getNextPacketID()) > LL_TRANSFER_WARN_GAP) + { + LL_WARNS() << "Out of order packet in transfer " << transfer_id + << " from " << msgp->getSender() << ", got " << packet_id + << " expecting " << ttp->getNextPacketID() << LL_ENDL; + } #endif - return; - } - - // Loop through this until we're done with all delayed packets - - // - // NOTE: THERE IS A CUT AND PASTE OF THIS CODE IN THE TRANSFERINFO HANDLER - // SO WE CAN PLAY BACK DELAYED PACKETS THERE!!!!!!!!!!!!!!!!!!!!!!!!! - // - bool done = false; - while (!done) - { - LLTSCode ret_code = ttp->dataCallback(packet_id, tmp_data, size); - if (ret_code == LLTS_OK) - { - ttp->setLastPacketID(packet_id); - } - - if (status != LLTS_OK) - { - if (status != LLTS_DONE) - { - LL_WARNS() << "LLTransferManager::processTransferPacket Error in transfer!" << LL_ENDL; - } - else - { -// LL_INFOS() << "LLTransferManager::processTransferPacket done for " << transfer_id << LL_ENDL; - } - // This transfer is done, either via error or not. - ttp->completionCallback(status); - ttcp->deleteTransfer(ttp); - return; - } - - // See if we've got any delayed packets - packet_id = ttp->getNextPacketID(); - if (ttp->mDelayedPacketMap.find(packet_id) != ttp->mDelayedPacketMap.end()) - { - // Perhaps this stuff should be inside a method in LLTransferPacket? - // I'm too lazy to do it now, though. -// LL_INFOS() << "Playing back delayed packet " << packet_id << LL_ENDL; - LLTransferPacket *packetp = ttp->mDelayedPacketMap[packet_id]; - - // This is somewhat inefficient, but avoids us having to duplicate - // code between the off-the-wire and delayed paths. - packet_id = packetp->mPacketID; - size = packetp->mSize; - if (size) - { - if ((packetp->mDatap != NULL) && (size<(S32)sizeof(tmp_data))) - { - memcpy(tmp_data, packetp->mDatap, size); /*Flawfinder: ignore*/ - } - } - status = packetp->mStatus; - ttp->mDelayedPacketMap.erase(packet_id); - delete packetp; - } - else - { - // No matching delayed packet, abort it. - done = true; - } - } + return; + } + + // Loop through this until we're done with all delayed packets + + // + // NOTE: THERE IS A CUT AND PASTE OF THIS CODE IN THE TRANSFERINFO HANDLER + // SO WE CAN PLAY BACK DELAYED PACKETS THERE!!!!!!!!!!!!!!!!!!!!!!!!! + // + bool done = false; + while (!done) + { + LLTSCode ret_code = ttp->dataCallback(packet_id, tmp_data, size); + if (ret_code == LLTS_OK) + { + ttp->setLastPacketID(packet_id); + } + + if (status != LLTS_OK) + { + if (status != LLTS_DONE) + { + LL_WARNS() << "LLTransferManager::processTransferPacket Error in transfer!" << LL_ENDL; + } + else + { +// LL_INFOS() << "LLTransferManager::processTransferPacket done for " << transfer_id << LL_ENDL; + } + // This transfer is done, either via error or not. + ttp->completionCallback(status); + ttcp->deleteTransfer(ttp); + return; + } + + // See if we've got any delayed packets + packet_id = ttp->getNextPacketID(); + if (ttp->mDelayedPacketMap.find(packet_id) != ttp->mDelayedPacketMap.end()) + { + // Perhaps this stuff should be inside a method in LLTransferPacket? + // I'm too lazy to do it now, though. +// LL_INFOS() << "Playing back delayed packet " << packet_id << LL_ENDL; + LLTransferPacket *packetp = ttp->mDelayedPacketMap[packet_id]; + + // This is somewhat inefficient, but avoids us having to duplicate + // code between the off-the-wire and delayed paths. + packet_id = packetp->mPacketID; + size = packetp->mSize; + if (size) + { + if ((packetp->mDatap != NULL) && (size<(S32)sizeof(tmp_data))) + { + memcpy(tmp_data, packetp->mDatap, size); /*Flawfinder: ignore*/ + } + } + status = packetp->mStatus; + ttp->mDelayedPacketMap.erase(packet_id); + delete packetp; + } + else + { + // No matching delayed packet, abort it. + done = true; + } + } } //static void LLTransferManager::processTransferAbort(LLMessageSystem *msgp, void **) { - //LL_INFOS() << "LLTransferManager::processTransferPacket" << LL_ENDL; - - LLUUID transfer_id; - LLTransferChannelType channel_type; - msgp->getUUID("TransferInfo", "TransferID", transfer_id); - msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type); - - // See if it's a target that we're trying to abort - // Find the transfer associated with this packet. - LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type); - if (ttcp) - { - LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id); - if (ttp) - { - ttp->abortTransfer(); - ttcp->deleteTransfer(ttp); - return; - } - } - - // Hmm, not a target. Maybe it's a source. - LLTransferSourceChannel *tscp = gTransferManager.getSourceChannel(msgp->getSender(), channel_type); - if (tscp) - { - LLTransferSource *tsp = tscp->findTransferSource(transfer_id); - if (tsp) - { - tsp->abortTransfer(); - tscp->deleteTransfer(tsp); - return; - } - } - - LL_WARNS() << "Couldn't find transfer " << transfer_id << " to abort!" << LL_ENDL; + //LL_INFOS() << "LLTransferManager::processTransferPacket" << LL_ENDL; + + LLUUID transfer_id; + LLTransferChannelType channel_type; + msgp->getUUID("TransferInfo", "TransferID", transfer_id); + msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type); + + // See if it's a target that we're trying to abort + // Find the transfer associated with this packet. + LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type); + if (ttcp) + { + LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id); + if (ttp) + { + ttp->abortTransfer(); + ttcp->deleteTransfer(ttp); + return; + } + } + + // Hmm, not a target. Maybe it's a source. + LLTransferSourceChannel *tscp = gTransferManager.getSourceChannel(msgp->getSender(), channel_type); + if (tscp) + { + LLTransferSource *tsp = tscp->findTransferSource(transfer_id); + if (tsp) + { + tsp->abortTransfer(); + tscp->deleteTransfer(tsp); + return; + } + } + + LL_WARNS() << "Couldn't find transfer " << transfer_id << " to abort!" << LL_ENDL; } //static void LLTransferManager::reliablePacketCallback(void **user_data, S32 result) { - LLUUID *transfer_idp = (LLUUID *)user_data; - if (result && - transfer_idp != NULL) - { - LLTransferSource *tsp = gTransferManager.findTransferSource(*transfer_idp); - if (tsp) - { - LL_WARNS() << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << LL_ENDL; - LLTransferSourceChannel *tscp = tsp->mChannelp; - tsp->abortTransfer(); - tscp->deleteTransfer(tsp); - } - else - { - LL_WARNS() << "Aborting reliable transfer " << *transfer_idp << " but can't find the LLTransferSource object" << LL_ENDL; - } - } - delete transfer_idp; + LLUUID *transfer_idp = (LLUUID *)user_data; + if (result && + transfer_idp != NULL) + { + LLTransferSource *tsp = gTransferManager.findTransferSource(*transfer_idp); + if (tsp) + { + LL_WARNS() << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << LL_ENDL; + LLTransferSourceChannel *tscp = tsp->mChannelp; + tsp->abortTransfer(); + tscp->deleteTransfer(tsp); + } + else + { + LL_WARNS() << "Aborting reliable transfer " << *transfer_idp << " but can't find the LLTransferSource object" << LL_ENDL; + } + } + delete transfer_idp; } // @@ -633,79 +633,79 @@ void LLTransferManager::reliablePacketCallback(void **user_data, S32 result) LLTransferConnection::LLTransferConnection(const LLHost &host) { - mHost = host; + mHost = host; } LLTransferConnection::~LLTransferConnection() { - tsc_iter itersc; - for (itersc = mTransferSourceChannels.begin(); itersc != mTransferSourceChannels.end(); itersc++) - { - delete *itersc; - } - mTransferSourceChannels.clear(); - - ttc_iter itertc; - for (itertc = mTransferTargetChannels.begin(); itertc != mTransferTargetChannels.end(); itertc++) - { - delete *itertc; - } - mTransferTargetChannels.clear(); + tsc_iter itersc; + for (itersc = mTransferSourceChannels.begin(); itersc != mTransferSourceChannels.end(); itersc++) + { + delete *itersc; + } + mTransferSourceChannels.clear(); + + ttc_iter itertc; + for (itertc = mTransferTargetChannels.begin(); itertc != mTransferTargetChannels.end(); itertc++) + { + delete *itertc; + } + mTransferTargetChannels.clear(); } void LLTransferConnection::updateTransfers() { - // Do stuff for source transfers (basically, send data out). - tsc_iter iter, cur; - iter = mTransferSourceChannels.begin(); - - while (iter !=mTransferSourceChannels.end()) - { - cur = iter; - iter++; - (*cur)->updateTransfers(); - } - - // Do stuff for target transfers - // Primarily, we should be aborting transfers that are irredeemably broken - // (large packet gaps that don't appear to be getting filled in, most likely) - // Probably should NOT be doing timeouts for other things, as new priority scheme - // means that a high priority transfer COULD block a transfer for a long time. + // Do stuff for source transfers (basically, send data out). + tsc_iter iter, cur; + iter = mTransferSourceChannels.begin(); + + while (iter !=mTransferSourceChannels.end()) + { + cur = iter; + iter++; + (*cur)->updateTransfers(); + } + + // Do stuff for target transfers + // Primarily, we should be aborting transfers that are irredeemably broken + // (large packet gaps that don't appear to be getting filled in, most likely) + // Probably should NOT be doing timeouts for other things, as new priority scheme + // means that a high priority transfer COULD block a transfer for a long time. } LLTransferSourceChannel *LLTransferConnection::getSourceChannel(const LLTransferChannelType channel_type) { - tsc_iter iter; - for (iter = mTransferSourceChannels.begin(); iter != mTransferSourceChannels.end(); iter++) - { - if ((*iter)->getChannelType() == channel_type) - { - return *iter; - } - } - - LLTransferSourceChannel *tscp = new LLTransferSourceChannel(channel_type, mHost); - mTransferSourceChannels.push_back(tscp); - return tscp; + tsc_iter iter; + for (iter = mTransferSourceChannels.begin(); iter != mTransferSourceChannels.end(); iter++) + { + if ((*iter)->getChannelType() == channel_type) + { + return *iter; + } + } + + LLTransferSourceChannel *tscp = new LLTransferSourceChannel(channel_type, mHost); + mTransferSourceChannels.push_back(tscp); + return tscp; } LLTransferTargetChannel *LLTransferConnection::getTargetChannel(const LLTransferChannelType channel_type) { - ttc_iter iter; - for (iter = mTransferTargetChannels.begin(); iter != mTransferTargetChannels.end(); iter++) - { - if ((*iter)->getChannelType() == channel_type) - { - return *iter; - } - } - - LLTransferTargetChannel *ttcp = new LLTransferTargetChannel(channel_type, mHost); - mTransferTargetChannels.push_back(ttcp); - return ttcp; + ttc_iter iter; + for (iter = mTransferTargetChannels.begin(); iter != mTransferTargetChannels.end(); iter++) + { + if ((*iter)->getChannelType() == channel_type) + { + return *iter; + } + } + + LLTransferTargetChannel *ttcp = new LLTransferTargetChannel(channel_type, mHost); + mTransferTargetChannels.push_back(ttcp); + return ttcp; } @@ -717,208 +717,208 @@ const S32 DEFAULT_PACKET_SIZE = 1000; LLTransferSourceChannel::LLTransferSourceChannel(const LLTransferChannelType channel_type, const LLHost &host) : - mChannelType(channel_type), - mHost(host), - mTransferSources(LLTransferSource::sSetPriority, LLTransferSource::sGetPriority), - mThrottleID(TC_ASSET) + mChannelType(channel_type), + mHost(host), + mTransferSources(LLTransferSource::sSetPriority, LLTransferSource::sGetPriority), + mThrottleID(TC_ASSET) { } LLTransferSourceChannel::~LLTransferSourceChannel() { - LLPriQueueMap<LLTransferSource*>::pqm_iter iter = - mTransferSources.mMap.begin(); - LLPriQueueMap<LLTransferSource*>::pqm_iter end = - mTransferSources.mMap.end(); - for (; iter != end; ++iter) - { - // Just kill off all of the transfers - (*iter).second->abortTransfer(); - delete iter->second; - } - mTransferSources.mMap.clear(); + LLPriQueueMap<LLTransferSource*>::pqm_iter iter = + mTransferSources.mMap.begin(); + LLPriQueueMap<LLTransferSource*>::pqm_iter end = + mTransferSources.mMap.end(); + for (; iter != end; ++iter) + { + // Just kill off all of the transfers + (*iter).second->abortTransfer(); + delete iter->second; + } + mTransferSources.mMap.clear(); } void LLTransferSourceChannel::updatePriority(LLTransferSource *tsp, const F32 priority) { - mTransferSources.reprioritize(priority, tsp); + mTransferSources.reprioritize(priority, tsp); } void LLTransferSourceChannel::updateTransfers() { - // Actually, this should do the following: - // Decide if we can actually send data. - // If so, update priorities so we know who gets to send it. - // Send data from the sources, while updating until we've sent our throttle allocation. - - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(getHost()); - if (!cdp) - { - return; - } - - if (cdp->isBlocked()) - { - // *NOTE: We need to make sure that the throttle bits - // available gets reset. - - // We DON'T want to send any packets if they're blocked, they'll just end up - // piling up on the other end. - //LL_WARNS() << "Blocking transfers due to blocked circuit for " << getHost() << LL_ENDL; - return; - } - - const S32 throttle_id = mThrottleID; - - LLThrottleGroup &tg = cdp->getThrottleGroup(); - - if (tg.checkOverflow(throttle_id, 0.f)) - { - return; - } - - LLPriQueueMap<LLTransferSource *>::pqm_iter iter, next; - - bool done = false; - for (iter = mTransferSources.mMap.begin(); (iter != mTransferSources.mMap.end()) && !done;) - { - //LL_INFOS() << "LLTransferSourceChannel::updateTransfers()" << LL_ENDL; - // Do stuff. - next = iter; - next++; - - LLTransferSource *tsp = iter->second; - U8 *datap = NULL; - S32 data_size = 0; - bool delete_data = false; - S32 packet_id = 0; - S32 sent_bytes = 0; - LLTSCode status = LLTS_OK; - - // Get the packetID for the next packet that we're transferring. - packet_id = tsp->getNextPacketID(); - status = tsp->dataCallback(packet_id, DEFAULT_PACKET_SIZE, &datap, data_size, delete_data); - - if (status == LLTS_SKIP) - { - // We don't have any data, but we're not done, just go on. - // This will presumably be used for streaming or async transfers that - // are stalled waiting for data from another source. - iter=next; - continue; - } - - LLUUID *cb_uuid = new LLUUID(tsp->getID()); - LLUUID transaction_id = tsp->getID(); - - // Send the data now, even if it's an error. - // The status code will tell the other end what to do. - gMessageSystem->newMessage("TransferPacket"); - gMessageSystem->nextBlock("TransferData"); - gMessageSystem->addUUID("TransferID", tsp->getID()); - gMessageSystem->addS32("ChannelType", getChannelType()); - gMessageSystem->addS32("Packet", packet_id); // HACK! Need to put in a REAL packet id - gMessageSystem->addS32("Status", status); - gMessageSystem->addBinaryData("Data", datap, data_size); - sent_bytes = gMessageSystem->getCurrentSendTotal(); - gMessageSystem->sendReliable(getHost(), LL_DEFAULT_RELIABLE_RETRIES, true, F32Seconds(0.f), - LLTransferManager::reliablePacketCallback, (void**)cb_uuid); - - // Do bookkeeping for the throttle - done = tg.throttleOverflow(throttle_id, sent_bytes*8.f); - gTransferManager.addTransferBitsOut(mChannelType, sent_bytes*8); - - // Clean up our temporary data. - if (delete_data) - { - delete[] datap; - datap = NULL; - } - - if (findTransferSource(transaction_id) == NULL) - { - //Warning! In the case of an aborted transfer, the sendReliable call above calls - //AbortTransfer which in turn calls deleteTransfer which means that somewhere way - //down the chain our current iter can get invalidated resulting in an infrequent - //sim crash. This check gets us to a valid transfer source in this event. - iter=next; - continue; - } - - // Update the packet counter - tsp->setLastPacketID(packet_id); - - switch (status) - { - case LLTS_OK: - // We're OK, don't need to do anything. Keep sending data. - break; - case LLTS_ERROR: - LL_WARNS() << "Error in transfer dataCallback!" << LL_ENDL; - // fall through - case LLTS_DONE: - // We need to clean up this transfer source. - //LL_INFOS() << "LLTransferSourceChannel::updateTransfers() " << tsp->getID() << " done" << LL_ENDL; - tsp->completionCallback(status); - delete tsp; - - mTransferSources.mMap.erase(iter); - iter = next; - break; - default: - LL_ERRS() << "Unknown transfer error code!" << LL_ENDL; - } - - // At this point, we should do priority adjustment (since some transfers like - // streaming transfers will adjust priority based on how much they've sent and time, - // but I'm not going to bother yet. - djs. - } + // Actually, this should do the following: + // Decide if we can actually send data. + // If so, update priorities so we know who gets to send it. + // Send data from the sources, while updating until we've sent our throttle allocation. + + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(getHost()); + if (!cdp) + { + return; + } + + if (cdp->isBlocked()) + { + // *NOTE: We need to make sure that the throttle bits + // available gets reset. + + // We DON'T want to send any packets if they're blocked, they'll just end up + // piling up on the other end. + //LL_WARNS() << "Blocking transfers due to blocked circuit for " << getHost() << LL_ENDL; + return; + } + + const S32 throttle_id = mThrottleID; + + LLThrottleGroup &tg = cdp->getThrottleGroup(); + + if (tg.checkOverflow(throttle_id, 0.f)) + { + return; + } + + LLPriQueueMap<LLTransferSource *>::pqm_iter iter, next; + + bool done = false; + for (iter = mTransferSources.mMap.begin(); (iter != mTransferSources.mMap.end()) && !done;) + { + //LL_INFOS() << "LLTransferSourceChannel::updateTransfers()" << LL_ENDL; + // Do stuff. + next = iter; + next++; + + LLTransferSource *tsp = iter->second; + U8 *datap = NULL; + S32 data_size = 0; + bool delete_data = false; + S32 packet_id = 0; + S32 sent_bytes = 0; + LLTSCode status = LLTS_OK; + + // Get the packetID for the next packet that we're transferring. + packet_id = tsp->getNextPacketID(); + status = tsp->dataCallback(packet_id, DEFAULT_PACKET_SIZE, &datap, data_size, delete_data); + + if (status == LLTS_SKIP) + { + // We don't have any data, but we're not done, just go on. + // This will presumably be used for streaming or async transfers that + // are stalled waiting for data from another source. + iter=next; + continue; + } + + LLUUID *cb_uuid = new LLUUID(tsp->getID()); + LLUUID transaction_id = tsp->getID(); + + // Send the data now, even if it's an error. + // The status code will tell the other end what to do. + gMessageSystem->newMessage("TransferPacket"); + gMessageSystem->nextBlock("TransferData"); + gMessageSystem->addUUID("TransferID", tsp->getID()); + gMessageSystem->addS32("ChannelType", getChannelType()); + gMessageSystem->addS32("Packet", packet_id); // HACK! Need to put in a REAL packet id + gMessageSystem->addS32("Status", status); + gMessageSystem->addBinaryData("Data", datap, data_size); + sent_bytes = gMessageSystem->getCurrentSendTotal(); + gMessageSystem->sendReliable(getHost(), LL_DEFAULT_RELIABLE_RETRIES, true, F32Seconds(0.f), + LLTransferManager::reliablePacketCallback, (void**)cb_uuid); + + // Do bookkeeping for the throttle + done = tg.throttleOverflow(throttle_id, sent_bytes*8.f); + gTransferManager.addTransferBitsOut(mChannelType, sent_bytes*8); + + // Clean up our temporary data. + if (delete_data) + { + delete[] datap; + datap = NULL; + } + + if (findTransferSource(transaction_id) == NULL) + { + //Warning! In the case of an aborted transfer, the sendReliable call above calls + //AbortTransfer which in turn calls deleteTransfer which means that somewhere way + //down the chain our current iter can get invalidated resulting in an infrequent + //sim crash. This check gets us to a valid transfer source in this event. + iter=next; + continue; + } + + // Update the packet counter + tsp->setLastPacketID(packet_id); + + switch (status) + { + case LLTS_OK: + // We're OK, don't need to do anything. Keep sending data. + break; + case LLTS_ERROR: + LL_WARNS() << "Error in transfer dataCallback!" << LL_ENDL; + // fall through + case LLTS_DONE: + // We need to clean up this transfer source. + //LL_INFOS() << "LLTransferSourceChannel::updateTransfers() " << tsp->getID() << " done" << LL_ENDL; + tsp->completionCallback(status); + delete tsp; + + mTransferSources.mMap.erase(iter); + iter = next; + break; + default: + LL_ERRS() << "Unknown transfer error code!" << LL_ENDL; + } + + // At this point, we should do priority adjustment (since some transfers like + // streaming transfers will adjust priority based on how much they've sent and time, + // but I'm not going to bother yet. - djs. + } } void LLTransferSourceChannel::addTransferSource(LLTransferSource *sourcep) { - sourcep->mChannelp = this; - mTransferSources.push(sourcep->getPriority(), sourcep); + sourcep->mChannelp = this; + mTransferSources.push(sourcep->getPriority(), sourcep); } LLTransferSource *LLTransferSourceChannel::findTransferSource(const LLUUID &transfer_id) { - LLPriQueueMap<LLTransferSource *>::pqm_iter iter; - for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++) - { - LLTransferSource *tsp = iter->second; - if (tsp->getID() == transfer_id) - { - return tsp; - } - } - return NULL; + LLPriQueueMap<LLTransferSource *>::pqm_iter iter; + for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++) + { + LLTransferSource *tsp = iter->second; + if (tsp->getID() == transfer_id) + { + return tsp; + } + } + return NULL; } void LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp) { - if (tsp) - { - LLPriQueueMap<LLTransferSource *>::pqm_iter iter; - for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++) - { - if (iter->second == tsp) - { - delete tsp; - mTransferSources.mMap.erase(iter); - return; - } - } - - LL_WARNS() << "Unable to find transfer source id " - << tsp->getID() - << " to delete!" - << LL_ENDL; - } + if (tsp) + { + LLPriQueueMap<LLTransferSource *>::pqm_iter iter; + for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++) + { + if (iter->second == tsp) + { + delete tsp; + mTransferSources.mMap.erase(iter); + return; + } + } + + LL_WARNS() << "Unable to find transfer source id " + << tsp->getID() + << " to delete!" + << LL_ENDL; + } } @@ -927,118 +927,118 @@ void LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp) // LLTransferTargetChannel::LLTransferTargetChannel(const LLTransferChannelType channel_type, const LLHost &host) : - mChannelType(channel_type), - mHost(host) + mChannelType(channel_type), + mHost(host) { } LLTransferTargetChannel::~LLTransferTargetChannel() { - tt_iter iter; - for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++) - { - // Abort all of the current transfers - (*iter)->abortTransfer(); - delete *iter; - } - mTransferTargets.clear(); + tt_iter iter; + for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++) + { + // Abort all of the current transfers + (*iter)->abortTransfer(); + delete *iter; + } + mTransferTargets.clear(); } void LLTransferTargetChannel::requestTransfer( - const LLTransferSourceParams& source_params, - const LLTransferTargetParams& target_params, - const F32 priority) + const LLTransferSourceParams& source_params, + const LLTransferTargetParams& target_params, + const F32 priority) { - LLUUID id; - id.generate(); - LLTransferTarget* ttp = LLTransferTarget::createTarget( - target_params.getType(), - id, - source_params.getType()); - if (!ttp) - { - LL_WARNS() << "LLTransferManager::requestTransfer aborting due to target creation failure!" << LL_ENDL; - return; - } - - ttp->applyParams(target_params); - addTransferTarget(ttp); - - sendTransferRequest(ttp, source_params, priority); + LLUUID id; + id.generate(); + LLTransferTarget* ttp = LLTransferTarget::createTarget( + target_params.getType(), + id, + source_params.getType()); + if (!ttp) + { + LL_WARNS() << "LLTransferManager::requestTransfer aborting due to target creation failure!" << LL_ENDL; + return; + } + + ttp->applyParams(target_params); + addTransferTarget(ttp); + + sendTransferRequest(ttp, source_params, priority); } void LLTransferTargetChannel::sendTransferRequest(LLTransferTarget *targetp, - const LLTransferSourceParams ¶ms, - const F32 priority) + const LLTransferSourceParams ¶ms, + const F32 priority) { - // - // Pack the message with data which explains how to get the source, and - // send it off to the source for this channel. - // - llassert(targetp); - llassert(targetp->getChannel() == this); - - gMessageSystem->newMessage("TransferRequest"); - gMessageSystem->nextBlock("TransferInfo"); - gMessageSystem->addUUID("TransferID", targetp->getID()); - gMessageSystem->addS32("SourceType", params.getType()); - gMessageSystem->addS32("ChannelType", getChannelType()); - gMessageSystem->addF32("Priority", priority); - - U8 tmp[MAX_PARAMS_SIZE]; - LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE); - params.packParams(dp); - S32 len = dp.getCurrentSize(); - gMessageSystem->addBinaryData("Params", tmp, len); - - gMessageSystem->sendReliable(mHost); + // + // Pack the message with data which explains how to get the source, and + // send it off to the source for this channel. + // + llassert(targetp); + llassert(targetp->getChannel() == this); + + gMessageSystem->newMessage("TransferRequest"); + gMessageSystem->nextBlock("TransferInfo"); + gMessageSystem->addUUID("TransferID", targetp->getID()); + gMessageSystem->addS32("SourceType", params.getType()); + gMessageSystem->addS32("ChannelType", getChannelType()); + gMessageSystem->addF32("Priority", priority); + + U8 tmp[MAX_PARAMS_SIZE]; + LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE); + params.packParams(dp); + S32 len = dp.getCurrentSize(); + gMessageSystem->addBinaryData("Params", tmp, len); + + gMessageSystem->sendReliable(mHost); } void LLTransferTargetChannel::addTransferTarget(LLTransferTarget *targetp) { - targetp->mChannelp = this; - mTransferTargets.push_back(targetp); + targetp->mChannelp = this; + mTransferTargets.push_back(targetp); } LLTransferTarget *LLTransferTargetChannel::findTransferTarget(const LLUUID &transfer_id) { - tt_iter iter; - for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++) - { - LLTransferTarget *ttp = *iter; - if (ttp->getID() == transfer_id) - { - return ttp; - } - } - return NULL; + tt_iter iter; + for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++) + { + LLTransferTarget *ttp = *iter; + if (ttp->getID() == transfer_id) + { + return ttp; + } + } + return NULL; } void LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp) { - if (ttp) - { - tt_iter iter; - for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++) - { - if (*iter == ttp) - { - delete ttp; - mTransferTargets.erase(iter); - return; - } - } - - LL_WARNS() << "Unable to find transfer target id " - << ttp->getID() - << " to delete!" - << LL_ENDL; - } + if (ttp) + { + tt_iter iter; + for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++) + { + if (*iter == ttp) + { + delete ttp; + mTransferTargets.erase(iter); + return; + } + } + + LL_WARNS() << "Unable to find transfer target id " + << ttp->getID() + << " to delete!" + << LL_ENDL; + } } @@ -1047,49 +1047,49 @@ void LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp) // LLTransferSource::LLTransferSource(const LLTransferSourceType type, - const LLUUID &transfer_id, - const F32 priority) : - mType(type), - mID(transfer_id), - mChannelp(NULL), - mPriority(priority), - mSize(0), - mLastPacketID(-1) + const LLUUID &transfer_id, + const F32 priority) : + mType(type), + mID(transfer_id), + mChannelp(NULL), + mPriority(priority), + mSize(0), + mLastPacketID(-1) { - setPriority(priority); + setPriority(priority); } LLTransferSource::~LLTransferSource() { - // No actual cleanup of the transfer is done here, this is purely for - // memory cleanup. The completionCallback is guaranteed to get called - // before this happens. + // No actual cleanup of the transfer is done here, this is purely for + // memory cleanup. The completionCallback is guaranteed to get called + // before this happens. } void LLTransferSource::sendTransferStatus(LLTSCode status) { - gMessageSystem->newMessage("TransferInfo"); - gMessageSystem->nextBlock("TransferInfo"); - gMessageSystem->addUUID("TransferID", getID()); - gMessageSystem->addS32("TargetType", LLTTT_UNKNOWN); - gMessageSystem->addS32("ChannelType", mChannelp->getChannelType()); - gMessageSystem->addS32("Status", status); - gMessageSystem->addS32("Size", mSize); - U8 tmp[MAX_PARAMS_SIZE]; - LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE); - packParams(dp); - S32 len = dp.getCurrentSize(); - gMessageSystem->addBinaryData("Params", tmp, len); - gMessageSystem->sendReliable(mChannelp->getHost()); - - // Abort if there was as asset system issue. - if (status != LLTS_OK) - { - completionCallback(status); - mChannelp->deleteTransfer(this); - } + gMessageSystem->newMessage("TransferInfo"); + gMessageSystem->nextBlock("TransferInfo"); + gMessageSystem->addUUID("TransferID", getID()); + gMessageSystem->addS32("TargetType", LLTTT_UNKNOWN); + gMessageSystem->addS32("ChannelType", mChannelp->getChannelType()); + gMessageSystem->addS32("Status", status); + gMessageSystem->addS32("Size", mSize); + U8 tmp[MAX_PARAMS_SIZE]; + LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE); + packParams(dp); + S32 len = dp.getCurrentSize(); + gMessageSystem->addBinaryData("Params", tmp, len); + gMessageSystem->sendReliable(mChannelp->getHost()); + + // Abort if there was as asset system issue. + if (status != LLTS_OK) + { + completionCallback(status); + mChannelp->deleteTransfer(this); + } } @@ -1098,73 +1098,73 @@ void LLTransferSource::sendTransferStatus(LLTSCode status) // future, though. void LLTransferSource::abortTransfer() { - // Send a message down, call the completion callback - LL_INFOS() << "LLTransferSource::Aborting transfer " << getID() << " to " << mChannelp->getHost() << LL_ENDL; - gMessageSystem->newMessage("TransferAbort"); - gMessageSystem->nextBlock("TransferInfo"); - gMessageSystem->addUUID("TransferID", getID()); - gMessageSystem->addS32("ChannelType", mChannelp->getChannelType()); - gMessageSystem->sendReliable(mChannelp->getHost()); - - completionCallback(LLTS_ABORT); + // Send a message down, call the completion callback + LL_INFOS() << "LLTransferSource::Aborting transfer " << getID() << " to " << mChannelp->getHost() << LL_ENDL; + gMessageSystem->newMessage("TransferAbort"); + gMessageSystem->nextBlock("TransferInfo"); + gMessageSystem->addUUID("TransferID", getID()); + gMessageSystem->addS32("ChannelType", mChannelp->getChannelType()); + gMessageSystem->sendReliable(mChannelp->getHost()); + + completionCallback(LLTS_ABORT); } //static void LLTransferSource::registerSourceType(const LLTransferSourceType stype, LLTransferSourceCreateFunc func) { - if (sSourceCreateMap.count(stype)) - { - // Disallow changing what class handles a source type - // Unclear when you would want to do this, and whether it would work. - LL_ERRS() << "Reregistering source type " << stype << LL_ENDL; - } - else - { - sSourceCreateMap[stype] = func; - } + if (sSourceCreateMap.count(stype)) + { + // Disallow changing what class handles a source type + // Unclear when you would want to do this, and whether it would work. + LL_ERRS() << "Reregistering source type " << stype << LL_ENDL; + } + else + { + sSourceCreateMap[stype] = func; + } } //static LLTransferSource *LLTransferSource::createSource(const LLTransferSourceType stype, - const LLUUID &id, - const F32 priority) + const LLUUID &id, + const F32 priority) { - switch (stype) - { - // *NOTE: The source file transfer mechanism is highly insecure and could - // lead to easy exploitation of a server process. - // I have removed all uses of it from the codebase. Phoenix. - // - //case LLTST_FILE: - // return new LLTransferSourceFile(id, priority); - case LLTST_ASSET: - return new LLTransferSourceAsset(id, priority); - default: - { - if (!sSourceCreateMap.count(stype)) - { - // Use the callback to create the source type if it's not there. - LL_WARNS() << "Unknown transfer source type: " << stype << LL_ENDL; - return NULL; - } - return (sSourceCreateMap[stype])(id, priority); - } - } + switch (stype) + { + // *NOTE: The source file transfer mechanism is highly insecure and could + // lead to easy exploitation of a server process. + // I have removed all uses of it from the codebase. Phoenix. + // + //case LLTST_FILE: + // return new LLTransferSourceFile(id, priority); + case LLTST_ASSET: + return new LLTransferSourceAsset(id, priority); + default: + { + if (!sSourceCreateMap.count(stype)) + { + // Use the callback to create the source type if it's not there. + LL_WARNS() << "Unknown transfer source type: " << stype << LL_ENDL; + return NULL; + } + return (sSourceCreateMap[stype])(id, priority); + } + } } // static void LLTransferSource::sSetPriority(LLTransferSource *&tsp, const F32 priority) { - tsp->setPriority(priority); + tsp->setPriority(priority); } // static F32 LLTransferSource::sGetPriority(LLTransferSource *&tsp) { - return tsp->getPriority(); + return tsp->getPriority(); } @@ -1173,26 +1173,26 @@ F32 LLTransferSource::sGetPriority(LLTransferSource *&tsp) // LLTransferPacket::LLTransferPacket(const S32 packet_id, const LLTSCode status, const U8 *datap, const S32 size) : - mPacketID(packet_id), - mStatus(status), - mDatap(NULL), - mSize(size) + mPacketID(packet_id), + mStatus(status), + mDatap(NULL), + mSize(size) { - if (size == 0) - { - return; - } - - mDatap = new U8[size]; - if (mDatap != NULL) - { - memcpy(mDatap, datap, size); /*Flawfinder: ignore*/ - } + if (size == 0) + { + return; + } + + mDatap = new U8[size]; + if (mDatap != NULL) + { + memcpy(mDatap, datap, size); /*Flawfinder: ignore*/ + } } LLTransferPacket::~LLTransferPacket() { - delete[] mDatap; + delete[] mDatap; } // @@ -1200,30 +1200,30 @@ LLTransferPacket::~LLTransferPacket() // LLTransferTarget::LLTransferTarget( - LLTransferTargetType type, - const LLUUID& transfer_id, - LLTransferSourceType source_type) : - mType(type), - mSourceType(source_type), - mID(transfer_id), - mChannelp(NULL), - mGotInfo(false), - mSize(0), - mLastPacketID(-1) + LLTransferTargetType type, + const LLUUID& transfer_id, + LLTransferSourceType source_type) : + mType(type), + mSourceType(source_type), + mID(transfer_id), + mChannelp(NULL), + mGotInfo(false), + mSize(0), + mLastPacketID(-1) { } LLTransferTarget::~LLTransferTarget() { - // No actual cleanup of the transfer is done here, this is purely for - // memory cleanup. The completionCallback is guaranteed to get called - // before this happens. - tpm_iter iter; - for (iter = mDelayedPacketMap.begin(); iter != mDelayedPacketMap.end(); iter++) - { - delete iter->second; - } - mDelayedPacketMap.clear(); + // No actual cleanup of the transfer is done here, this is purely for + // memory cleanup. The completionCallback is guaranteed to get called + // before this happens. + tpm_iter iter; + for (iter = mDelayedPacketMap.begin(); iter != mDelayedPacketMap.end(); iter++) + { + delete iter->second; + } + mDelayedPacketMap.clear(); } // This should never be called directly, the transfer manager is responsible for @@ -1231,67 +1231,67 @@ LLTransferTarget::~LLTransferTarget() // future, though. void LLTransferTarget::abortTransfer() { - // Send a message up, call the completion callback - LL_INFOS() << "LLTransferTarget::Aborting transfer " << getID() << " from " << mChannelp->getHost() << LL_ENDL; - gMessageSystem->newMessage("TransferAbort"); - gMessageSystem->nextBlock("TransferInfo"); - gMessageSystem->addUUID("TransferID", getID()); - gMessageSystem->addS32("ChannelType", mChannelp->getChannelType()); - gMessageSystem->sendReliable(mChannelp->getHost()); - - completionCallback(LLTS_ABORT); + // Send a message up, call the completion callback + LL_INFOS() << "LLTransferTarget::Aborting transfer " << getID() << " from " << mChannelp->getHost() << LL_ENDL; + gMessageSystem->newMessage("TransferAbort"); + gMessageSystem->nextBlock("TransferInfo"); + gMessageSystem->addUUID("TransferID", getID()); + gMessageSystem->addS32("ChannelType", mChannelp->getChannelType()); + gMessageSystem->sendReliable(mChannelp->getHost()); + + completionCallback(LLTS_ABORT); } bool LLTransferTarget::addDelayedPacket( - const S32 packet_id, - const LLTSCode status, - U8* datap, - const S32 size) + const S32 packet_id, + const LLTSCode status, + U8* datap, + const S32 size) { - const transfer_packet_map::size_type LL_MAX_DELAYED_PACKETS = 100; - if(mDelayedPacketMap.size() > LL_MAX_DELAYED_PACKETS) - { - // too many delayed packets - return false; - } - - LLTransferPacket* tpp = new LLTransferPacket( - packet_id, - status, - datap, - size); + const transfer_packet_map::size_type LL_MAX_DELAYED_PACKETS = 100; + if(mDelayedPacketMap.size() > LL_MAX_DELAYED_PACKETS) + { + // too many delayed packets + return false; + } + + LLTransferPacket* tpp = new LLTransferPacket( + packet_id, + status, + datap, + size); #ifdef _DEBUG transfer_packet_map::iterator iter = mDelayedPacketMap.find(packet_id); - if (iter != mDelayedPacketMap.end()) - { + if (iter != mDelayedPacketMap.end()) + { if (!(iter->second->mSize == size) && !(iter->second->mDatap == datap)) { LL_ERRS() << "Packet ALREADY in delayed packet map!" << LL_ENDL; } - } + } #endif - mDelayedPacketMap[packet_id] = tpp; - return true; + mDelayedPacketMap[packet_id] = tpp; + return true; } LLTransferTarget* LLTransferTarget::createTarget( - LLTransferTargetType type, - const LLUUID& id, - LLTransferSourceType source_type) + LLTransferTargetType type, + const LLUUID& id, + LLTransferSourceType source_type) { - switch (type) - { - case LLTTT_FILE: - return new LLTransferTargetFile(id, source_type); - case LLTTT_VFILE: - return new LLTransferTargetVFile(id, source_type); - default: - LL_WARNS() << "Unknown transfer target type: " << type << LL_ENDL; - return NULL; - } + switch (type) + { + case LLTTT_FILE: + return new LLTransferTargetFile(id, source_type); + case LLTTT_VFILE: + return new LLTransferTargetVFile(id, source_type); + default: + LL_WARNS() << "Unknown transfer target type: " << type << LL_ENDL; + return NULL; + } } @@ -1302,100 +1302,100 @@ LLTransferSourceParamsInvItem::LLTransferSourceParamsInvItem() : LLTransferSourc void LLTransferSourceParamsInvItem::setAgentSession(const LLUUID &agent_id, const LLUUID &session_id) { - mAgentID = agent_id; - mSessionID = session_id; + mAgentID = agent_id; + mSessionID = session_id; } void LLTransferSourceParamsInvItem::setInvItem(const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id) { - mOwnerID = owner_id; - mTaskID = task_id; - mItemID = item_id; + mOwnerID = owner_id; + mTaskID = task_id; + mItemID = item_id; } void LLTransferSourceParamsInvItem::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type) { - mAssetID = asset_id; - mAssetType = asset_type; + mAssetID = asset_id; + mAssetType = asset_type; } void LLTransferSourceParamsInvItem::packParams(LLDataPacker &dp) const { - LL_DEBUGS() << "LLTransferSourceParamsInvItem::packParams()" << LL_ENDL; - dp.packUUID(mAgentID, "AgentID"); - dp.packUUID(mSessionID, "SessionID"); - dp.packUUID(mOwnerID, "OwnerID"); - dp.packUUID(mTaskID, "TaskID"); - dp.packUUID(mItemID, "ItemID"); - dp.packUUID(mAssetID, "AssetID"); - dp.packS32(mAssetType, "AssetType"); + LL_DEBUGS() << "LLTransferSourceParamsInvItem::packParams()" << LL_ENDL; + dp.packUUID(mAgentID, "AgentID"); + dp.packUUID(mSessionID, "SessionID"); + dp.packUUID(mOwnerID, "OwnerID"); + dp.packUUID(mTaskID, "TaskID"); + dp.packUUID(mItemID, "ItemID"); + dp.packUUID(mAssetID, "AssetID"); + dp.packS32(mAssetType, "AssetType"); } bool LLTransferSourceParamsInvItem::unpackParams(LLDataPacker &dp) { - S32 tmp_at; + S32 tmp_at; - dp.unpackUUID(mAgentID, "AgentID"); - dp.unpackUUID(mSessionID, "SessionID"); - dp.unpackUUID(mOwnerID, "OwnerID"); - dp.unpackUUID(mTaskID, "TaskID"); - dp.unpackUUID(mItemID, "ItemID"); - dp.unpackUUID(mAssetID, "AssetID"); - dp.unpackS32(tmp_at, "AssetType"); + dp.unpackUUID(mAgentID, "AgentID"); + dp.unpackUUID(mSessionID, "SessionID"); + dp.unpackUUID(mOwnerID, "OwnerID"); + dp.unpackUUID(mTaskID, "TaskID"); + dp.unpackUUID(mItemID, "ItemID"); + dp.unpackUUID(mAssetID, "AssetID"); + dp.unpackS32(tmp_at, "AssetType"); - mAssetType = (LLAssetType::EType)tmp_at; + mAssetType = (LLAssetType::EType)tmp_at; - return true; + return true; } LLTransferSourceParamsEstate::LLTransferSourceParamsEstate() : - LLTransferSourceParams(LLTST_SIM_ESTATE), - mEstateAssetType(ET_NONE), - mAssetType(LLAssetType::AT_NONE) + LLTransferSourceParams(LLTST_SIM_ESTATE), + mEstateAssetType(ET_NONE), + mAssetType(LLAssetType::AT_NONE) { } void LLTransferSourceParamsEstate::setAgentSession(const LLUUID &agent_id, const LLUUID &session_id) { - mAgentID = agent_id; - mSessionID = session_id; + mAgentID = agent_id; + mSessionID = session_id; } void LLTransferSourceParamsEstate::setEstateAssetType(const EstateAssetType etype) { - mEstateAssetType = etype; + mEstateAssetType = etype; } void LLTransferSourceParamsEstate::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type) { - mAssetID = asset_id; - mAssetType = asset_type; + mAssetID = asset_id; + mAssetType = asset_type; } void LLTransferSourceParamsEstate::packParams(LLDataPacker &dp) const { - dp.packUUID(mAgentID, "AgentID"); - // *NOTE: We do not want to pass the session id from the server to - // the client, but I am not sure if anyone expects this value to - // be set on the client. - dp.packUUID(mSessionID, "SessionID"); - dp.packS32(mEstateAssetType, "EstateAssetType"); + dp.packUUID(mAgentID, "AgentID"); + // *NOTE: We do not want to pass the session id from the server to + // the client, but I am not sure if anyone expects this value to + // be set on the client. + dp.packUUID(mSessionID, "SessionID"); + dp.packS32(mEstateAssetType, "EstateAssetType"); } bool LLTransferSourceParamsEstate::unpackParams(LLDataPacker &dp) { - S32 tmp_et; + S32 tmp_et; - dp.unpackUUID(mAgentID, "AgentID"); - dp.unpackUUID(mSessionID, "SessionID"); - dp.unpackS32(tmp_et, "EstateAssetType"); + dp.unpackUUID(mAgentID, "AgentID"); + dp.unpackUUID(mSessionID, "SessionID"); + dp.unpackS32(tmp_et, "EstateAssetType"); - mEstateAssetType = (EstateAssetType)tmp_et; + mEstateAssetType = (EstateAssetType)tmp_et; - return true; + return true; } diff --git a/indra/llmessage/lltransfermanager.h b/indra/llmessage/lltransfermanager.h index 15097642b4..ada5528b49 100644 --- a/indra/llmessage/lltransfermanager.h +++ b/indra/llmessage/lltransfermanager.h @@ -1,4 +1,4 @@ -/** +/** * @file lltransfermanager.h * @brief Improved transfer mechanism for moving data through the * message system. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,50 +46,50 @@ typedef enum e_transfer_channel_type { - LLTCT_UNKNOWN = 0, - LLTCT_MISC, - LLTCT_ASSET, - LLTCT_NUM_TYPES + LLTCT_UNKNOWN = 0, + LLTCT_MISC, + LLTCT_ASSET, + LLTCT_NUM_TYPES } LLTransferChannelType; typedef enum e_transfer_source_type { - LLTST_UNKNOWN = 0, - LLTST_FILE, - LLTST_ASSET, - LLTST_SIM_INV_ITEM, // Simulator specific, may not be handled - LLTST_SIM_ESTATE, // Simulator specific, may not be handled - LLTST_NUM_TYPES + LLTST_UNKNOWN = 0, + LLTST_FILE, + LLTST_ASSET, + LLTST_SIM_INV_ITEM, // Simulator specific, may not be handled + LLTST_SIM_ESTATE, // Simulator specific, may not be handled + LLTST_NUM_TYPES } LLTransferSourceType; typedef enum e_transfer_target_type { - LLTTT_UNKNOWN = 0, - LLTTT_FILE, - LLTTT_VFILE, - LLTTT_NUM_TYPES + LLTTT_UNKNOWN = 0, + LLTTT_FILE, + LLTTT_VFILE, + LLTTT_NUM_TYPES } LLTransferTargetType; // Errors are negative, expected values are positive. typedef enum e_status_codes { - LLTS_OK = 0, - LLTS_DONE = 1, - LLTS_SKIP = 2, - LLTS_ABORT = 3, - LLTS_ERROR = -1, - LLTS_UNKNOWN_SOURCE = -2, // Equivalent of a 404 - LLTS_INSUFFICIENT_PERMISSIONS = -3 // Not enough permissions + LLTS_OK = 0, + LLTS_DONE = 1, + LLTS_SKIP = 2, + LLTS_ABORT = 3, + LLTS_ERROR = -1, + LLTS_UNKNOWN_SOURCE = -2, // Equivalent of a 404 + LLTS_INSUFFICIENT_PERMISSIONS = -3 // Not enough permissions } LLTSCode; // Types of requests for estate wide information typedef enum e_estate_type { - ET_Covenant = 0, - ET_NONE = -1 + ET_Covenant = 0, + ET_NONE = -1 } EstateAssetType; class LLMessageSystem; @@ -106,52 +106,52 @@ class LLTransferTarget; class LLTransferManager { public: - LLTransferManager(); - virtual ~LLTransferManager(); + LLTransferManager(); + virtual ~LLTransferManager(); - void init(); - void cleanup(); + void init(); + void cleanup(); - void updateTransfers(); // Called per frame to push packets out on the various different channels. - void cleanupConnection(const LLHost &host); + void updateTransfers(); // Called per frame to push packets out on the various different channels. + void cleanupConnection(const LLHost &host); - LLTransferSourceChannel *getSourceChannel(const LLHost &host, const LLTransferChannelType stype); - LLTransferTargetChannel *getTargetChannel(const LLHost &host, const LLTransferChannelType stype); + LLTransferSourceChannel *getSourceChannel(const LLHost &host, const LLTransferChannelType stype); + LLTransferTargetChannel *getTargetChannel(const LLHost &host, const LLTransferChannelType stype); - LLTransferSource *findTransferSource(const LLUUID &transfer_id); + LLTransferSource *findTransferSource(const LLUUID &transfer_id); - bool isValid() const { return mValid; } + bool isValid() const { return mValid; } - static void processTransferRequest(LLMessageSystem *mesgsys, void **); - static void processTransferInfo(LLMessageSystem *mesgsys, void **); - static void processTransferPacket(LLMessageSystem *mesgsys, void **); - static void processTransferAbort(LLMessageSystem *mesgsys, void **); + static void processTransferRequest(LLMessageSystem *mesgsys, void **); + static void processTransferInfo(LLMessageSystem *mesgsys, void **); + static void processTransferPacket(LLMessageSystem *mesgsys, void **); + static void processTransferAbort(LLMessageSystem *mesgsys, void **); - static void reliablePacketCallback(void **, S32 result); + static void reliablePacketCallback(void **, S32 result); - S32 getTransferBitsIn(const LLTransferChannelType tctype) const { return mTransferBitsIn[tctype]; } - S32 getTransferBitsOut(const LLTransferChannelType tctype) const { return mTransferBitsOut[tctype]; } - void resetTransferBitsIn(const LLTransferChannelType tctype) { mTransferBitsIn[tctype] = 0; } - void resetTransferBitsOut(const LLTransferChannelType tctype) { mTransferBitsOut[tctype] = 0; } - void addTransferBitsIn(const LLTransferChannelType tctype, const S32 bits) { mTransferBitsIn[tctype] += bits; } - void addTransferBitsOut(const LLTransferChannelType tctype, const S32 bits) { mTransferBitsOut[tctype] += bits; } + S32 getTransferBitsIn(const LLTransferChannelType tctype) const { return mTransferBitsIn[tctype]; } + S32 getTransferBitsOut(const LLTransferChannelType tctype) const { return mTransferBitsOut[tctype]; } + void resetTransferBitsIn(const LLTransferChannelType tctype) { mTransferBitsIn[tctype] = 0; } + void resetTransferBitsOut(const LLTransferChannelType tctype) { mTransferBitsOut[tctype] = 0; } + void addTransferBitsIn(const LLTransferChannelType tctype, const S32 bits) { mTransferBitsIn[tctype] += bits; } + void addTransferBitsOut(const LLTransferChannelType tctype, const S32 bits) { mTransferBitsOut[tctype] += bits; } protected: - LLTransferConnection *getTransferConnection(const LLHost &host); - bool removeTransferConnection(const LLHost &host); + LLTransferConnection *getTransferConnection(const LLHost &host); + bool removeTransferConnection(const LLHost &host); protected: - // Convenient typedefs - typedef std::map<LLHost, LLTransferConnection *> host_tc_map; + // Convenient typedefs + typedef std::map<LLHost, LLTransferConnection *> host_tc_map; - bool mValid; - LLHost mHost; + bool mValid; + LLHost mHost; - S32 mTransferBitsIn[LLTTT_NUM_TYPES]; - S32 mTransferBitsOut[LLTTT_NUM_TYPES]; + S32 mTransferBitsIn[LLTTT_NUM_TYPES]; + S32 mTransferBitsOut[LLTTT_NUM_TYPES]; - // We keep a map between each host and LLTransferConnection. - host_tc_map mTransferConnections; + // We keep a map between each host and LLTransferConnection. + host_tc_map mTransferConnections; }; @@ -161,23 +161,23 @@ protected: class LLTransferConnection { public: - LLTransferConnection(const LLHost &host); - virtual ~LLTransferConnection(); + LLTransferConnection(const LLHost &host); + virtual ~LLTransferConnection(); - void updateTransfers(); + void updateTransfers(); - LLTransferSourceChannel *getSourceChannel(const LLTransferChannelType type); - LLTransferTargetChannel *getTargetChannel(const LLTransferChannelType type); + LLTransferSourceChannel *getSourceChannel(const LLTransferChannelType type); + LLTransferTargetChannel *getTargetChannel(const LLTransferChannelType type); - // Convenient typedefs - typedef std::list<LLTransferSourceChannel *>::iterator tsc_iter; - typedef std::list<LLTransferTargetChannel *>::iterator ttc_iter; - friend class LLTransferManager; + // Convenient typedefs + typedef std::list<LLTransferSourceChannel *>::iterator tsc_iter; + typedef std::list<LLTransferTargetChannel *>::iterator ttc_iter; + friend class LLTransferManager; protected: - LLHost mHost; - std::list<LLTransferSourceChannel *> mTransferSourceChannels; - std::list<LLTransferTargetChannel *> mTransferTargetChannels; + LLHost mHost; + std::list<LLTransferSourceChannel *> mTransferSourceChannels; + std::list<LLTransferTargetChannel *> mTransferTargetChannels; }; @@ -189,32 +189,32 @@ protected: class LLTransferSourceChannel { public: - LLTransferSourceChannel(const LLTransferChannelType channel_type, - const LLHost &host); - virtual ~LLTransferSourceChannel(); + LLTransferSourceChannel(const LLTransferChannelType channel_type, + const LLHost &host); + virtual ~LLTransferSourceChannel(); - void updateTransfers(); + void updateTransfers(); - void updatePriority(LLTransferSource *tsp, const F32 priority); + void updatePriority(LLTransferSource *tsp, const F32 priority); - void addTransferSource(LLTransferSource *sourcep); - LLTransferSource *findTransferSource(const LLUUID &transfer_id); - void deleteTransfer(LLTransferSource *tsp); + void addTransferSource(LLTransferSource *sourcep); + LLTransferSource *findTransferSource(const LLUUID &transfer_id); + void deleteTransfer(LLTransferSource *tsp); - void setThrottleID(const S32 throttle_id) { mThrottleID = throttle_id; } + void setThrottleID(const S32 throttle_id) { mThrottleID = throttle_id; } - LLTransferChannelType getChannelType() const { return mChannelType; } - LLHost getHost() const { return mHost; } + LLTransferChannelType getChannelType() const { return mChannelType; } + LLHost getHost() const { return mHost; } protected: - typedef std::list<LLTransferSource *>::iterator ts_iter; + typedef std::list<LLTransferSource *>::iterator ts_iter; - LLTransferChannelType mChannelType; - LLHost mHost; - LLPriQueueMap<LLTransferSource*> mTransferSources; + LLTransferChannelType mChannelType; + LLHost mHost; + LLPriQueueMap<LLTransferSource*> mTransferSources; - // The throttle that this source channel should use - S32 mThrottleID; + // The throttle that this source channel should use + S32 mThrottleID; }; @@ -224,51 +224,51 @@ protected: class LLTransferTargetChannel { public: - LLTransferTargetChannel(const LLTransferChannelType channel_type, const LLHost &host); - virtual ~LLTransferTargetChannel(); + LLTransferTargetChannel(const LLTransferChannelType channel_type, const LLHost &host); + virtual ~LLTransferTargetChannel(); - void requestTransfer(const LLTransferSourceParams &source_params, - const LLTransferTargetParams &target_params, - const F32 priority); + void requestTransfer(const LLTransferSourceParams &source_params, + const LLTransferTargetParams &target_params, + const F32 priority); - LLTransferTarget *findTransferTarget(const LLUUID &transfer_id); - void deleteTransfer(LLTransferTarget *ttp); + LLTransferTarget *findTransferTarget(const LLUUID &transfer_id); + void deleteTransfer(LLTransferTarget *ttp); - LLTransferChannelType getChannelType() const { return mChannelType; } - LLHost getHost() const { return mHost; } + LLTransferChannelType getChannelType() const { return mChannelType; } + LLHost getHost() const { return mHost; } protected: - void sendTransferRequest(LLTransferTarget *targetp, - const LLTransferSourceParams ¶ms, - const F32 priority); + void sendTransferRequest(LLTransferTarget *targetp, + const LLTransferSourceParams ¶ms, + const F32 priority); - void addTransferTarget(LLTransferTarget *targetp); + void addTransferTarget(LLTransferTarget *targetp); - friend class LLTransferTarget; - friend class LLTransferManager; + friend class LLTransferTarget; + friend class LLTransferManager; protected: - typedef std::list<LLTransferTarget *>::iterator tt_iter; + typedef std::list<LLTransferTarget *>::iterator tt_iter; - LLTransferChannelType mChannelType; - LLHost mHost; - std::list<LLTransferTarget *> mTransferTargets; + LLTransferChannelType mChannelType; + LLHost mHost; + std::list<LLTransferTarget *> mTransferTargets; }; class LLTransferSourceParams { public: - LLTransferSourceParams(const LLTransferSourceType type) : mType(type) { } - virtual ~LLTransferSourceParams(); + LLTransferSourceParams(const LLTransferSourceType type) : mType(type) { } + virtual ~LLTransferSourceParams(); + + virtual void packParams(LLDataPacker &dp) const = 0; + virtual bool unpackParams(LLDataPacker &dp) = 0; - virtual void packParams(LLDataPacker &dp) const = 0; - virtual bool unpackParams(LLDataPacker &dp) = 0; + LLTransferSourceType getType() const { return mType; } - LLTransferSourceType getType() const { return mType; } - protected: - LLTransferSourceType mType; + LLTransferSourceType mType; }; @@ -281,155 +281,155 @@ class LLTransferSource { public: - LLUUID getID() { return mID; } + LLUUID getID() { return mID; } - friend class LLTransferManager; - friend class LLTransferSourceChannel; + friend class LLTransferManager; + friend class LLTransferSourceChannel; protected: - LLTransferSource(const LLTransferSourceType source_type, - const LLUUID &request_id, - const F32 priority); - virtual ~LLTransferSource(); + LLTransferSource(const LLTransferSourceType source_type, + const LLUUID &request_id, + const F32 priority); + virtual ~LLTransferSource(); - void sendTransferStatus(LLTSCode status); // When you've figured out your transfer status, do this + void sendTransferStatus(LLTSCode status); // When you've figured out your transfer status, do this - virtual void initTransfer() = 0; - virtual F32 updatePriority() = 0; - virtual LLTSCode dataCallback(const S32 packet_id, - const S32 max_bytes, - U8 **datap, - S32 &returned_bytes, - bool &delete_returned) = 0; + virtual void initTransfer() = 0; + virtual F32 updatePriority() = 0; + virtual LLTSCode dataCallback(const S32 packet_id, + const S32 max_bytes, + U8 **datap, + S32 &returned_bytes, + bool &delete_returned) = 0; - // The completionCallback is GUARANTEED to be called before the destructor. - virtual void completionCallback(const LLTSCode status) = 0; + // The completionCallback is GUARANTEED to be called before the destructor. + virtual void completionCallback(const LLTSCode status) = 0; - virtual void packParams(LLDataPacker& dp) const = 0; - virtual bool unpackParams(LLDataPacker& dp) = 0; + virtual void packParams(LLDataPacker& dp) const = 0; + virtual bool unpackParams(LLDataPacker& dp) = 0; - virtual S32 getNextPacketID() { return mLastPacketID + 1; } - virtual void setLastPacketID(const S32 packet_id) { mLastPacketID = packet_id; } + virtual S32 getNextPacketID() { return mLastPacketID + 1; } + virtual void setLastPacketID(const S32 packet_id) { mLastPacketID = packet_id; } - // For now, no self-induced priority changes - F32 getPriority() { return mPriority; } - void setPriority(const F32 pri) { mPriority = pri; } + // For now, no self-induced priority changes + F32 getPriority() { return mPriority; } + void setPriority(const F32 pri) { mPriority = pri; } - virtual void abortTransfer(); // DON'T USE THIS ONE, used internally by LLTransferManager + virtual void abortTransfer(); // DON'T USE THIS ONE, used internally by LLTransferManager - static LLTransferSource *createSource(const LLTransferSourceType stype, - const LLUUID &request_id, - const F32 priority); - static void registerSourceType(const LLTransferSourceType stype, LLTransferSourceCreateFunc); + static LLTransferSource *createSource(const LLTransferSourceType stype, + const LLUUID &request_id, + const F32 priority); + static void registerSourceType(const LLTransferSourceType stype, LLTransferSourceCreateFunc); - static void sSetPriority(LLTransferSource *&tsp, const F32 priority); - static F32 sGetPriority(LLTransferSource *&tsp); + static void sSetPriority(LLTransferSource *&tsp, const F32 priority); + static F32 sGetPriority(LLTransferSource *&tsp); protected: - typedef std::map<LLTransferSourceType, LLTransferSourceCreateFunc> stype_scfunc_map; - static stype_scfunc_map sSourceCreateMap; - - LLTransferSourceType mType; - LLUUID mID; - LLTransferSourceChannel *mChannelp; - F32 mPriority; - S32 mSize; - S32 mLastPacketID; + typedef std::map<LLTransferSourceType, LLTransferSourceCreateFunc> stype_scfunc_map; + static stype_scfunc_map sSourceCreateMap; + + LLTransferSourceType mType; + LLUUID mID; + LLTransferSourceChannel *mChannelp; + F32 mPriority; + S32 mSize; + S32 mLastPacketID; }; class LLTransferTargetParams { public: - LLTransferTargetParams(const LLTransferTargetType type) : mType(type) {} - LLTransferTargetType getType() const { return mType; } + LLTransferTargetParams(const LLTransferTargetType type) : mType(type) {} + LLTransferTargetType getType() const { return mType; } protected: - LLTransferTargetType mType; + LLTransferTargetType mType; }; class LLTransferPacket { - // Used for storing a packet that's being delivered later because it's out of order. - // ONLY should be accessed by the following two classes, for now. - friend class LLTransferTarget; - friend class LLTransferManager; + // Used for storing a packet that's being delivered later because it's out of order. + // ONLY should be accessed by the following two classes, for now. + friend class LLTransferTarget; + friend class LLTransferManager; protected: - LLTransferPacket(const S32 packet_id, const LLTSCode status, const U8 *datap, const S32 size); - virtual ~LLTransferPacket(); + LLTransferPacket(const S32 packet_id, const LLTSCode status, const U8 *datap, const S32 size); + virtual ~LLTransferPacket(); protected: - S32 mPacketID; - LLTSCode mStatus; - U8 *mDatap; - S32 mSize; + S32 mPacketID; + LLTSCode mStatus; + U8 *mDatap; + S32 mSize; }; class LLTransferTarget { public: - LLTransferTarget( - LLTransferTargetType target_type, - const LLUUID& transfer_id, - LLTransferSourceType source_type); - virtual ~LLTransferTarget(); - - // Accessors - LLUUID getID() const { return mID; } - LLTransferTargetType getType() const { return mType; } - LLTransferTargetChannel *getChannel() const { return mChannelp; } - LLTransferSourceType getSourceType() const { return mSourceType; } - - // Static functionality - static LLTransferTarget* createTarget( - LLTransferTargetType target_type, - const LLUUID& request_id, - LLTransferSourceType source_type); - - // friends - friend class LLTransferManager; - friend class LLTransferTargetChannel; + LLTransferTarget( + LLTransferTargetType target_type, + const LLUUID& transfer_id, + LLTransferSourceType source_type); + virtual ~LLTransferTarget(); + + // Accessors + LLUUID getID() const { return mID; } + LLTransferTargetType getType() const { return mType; } + LLTransferTargetChannel *getChannel() const { return mChannelp; } + LLTransferSourceType getSourceType() const { return mSourceType; } + + // Static functionality + static LLTransferTarget* createTarget( + LLTransferTargetType target_type, + const LLUUID& request_id, + LLTransferSourceType source_type); + + // friends + friend class LLTransferManager; + friend class LLTransferTargetChannel; protected: - // Implementation - virtual bool unpackParams(LLDataPacker& dp) = 0; - virtual void applyParams(const LLTransferTargetParams ¶ms) = 0; - virtual LLTSCode dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size) = 0; + // Implementation + virtual bool unpackParams(LLDataPacker& dp) = 0; + virtual void applyParams(const LLTransferTargetParams ¶ms) = 0; + virtual LLTSCode dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size) = 0; - // The completionCallback is GUARANTEED to be called before the destructor, so all handling - // of errors/aborts should be done here. - virtual void completionCallback(const LLTSCode status) = 0; + // The completionCallback is GUARANTEED to be called before the destructor, so all handling + // of errors/aborts should be done here. + virtual void completionCallback(const LLTSCode status) = 0; - void abortTransfer(); + void abortTransfer(); - virtual S32 getNextPacketID() { return mLastPacketID + 1; } - virtual void setLastPacketID(const S32 packet_id) { mLastPacketID = packet_id; } - void setSize(const S32 size) { mSize = size; } - void setGotInfo(const bool got_info) { mGotInfo = got_info; } - bool gotInfo() const { return mGotInfo; } + virtual S32 getNextPacketID() { return mLastPacketID + 1; } + virtual void setLastPacketID(const S32 packet_id) { mLastPacketID = packet_id; } + void setSize(const S32 size) { mSize = size; } + void setGotInfo(const bool got_info) { mGotInfo = got_info; } + bool gotInfo() const { return mGotInfo; } - bool addDelayedPacket( - const S32 packet_id, - const LLTSCode status, - U8* datap, - const S32 size); + bool addDelayedPacket( + const S32 packet_id, + const LLTSCode status, + U8* datap, + const S32 size); protected: - typedef std::map<S32, LLTransferPacket *> transfer_packet_map; - typedef std::map<S32, LLTransferPacket *>::iterator tpm_iter; - - LLTransferTargetType mType; - LLTransferSourceType mSourceType; - LLUUID mID; - LLTransferTargetChannel *mChannelp; - bool mGotInfo; - S32 mSize; - S32 mLastPacketID; - - transfer_packet_map mDelayedPacketMap; // Packets that are waiting because of missing/out of order issues + typedef std::map<S32, LLTransferPacket *> transfer_packet_map; + typedef std::map<S32, LLTransferPacket *>::iterator tpm_iter; + + LLTransferTargetType mType; + LLTransferSourceType mSourceType; + LLUUID mID; + LLTransferTargetChannel *mChannelp; + bool mGotInfo; + S32 mSize; + S32 mLastPacketID; + + transfer_packet_map mDelayedPacketMap; // Packets that are waiting because of missing/out of order issues }; @@ -437,31 +437,31 @@ protected: class LLTransferSourceParamsInvItem: public LLTransferSourceParams { public: - LLTransferSourceParamsInvItem(); - virtual ~LLTransferSourceParamsInvItem() {} - /*virtual*/ void packParams(LLDataPacker &dp) const; - /*virtual*/ bool unpackParams(LLDataPacker &dp); - - void setAgentSession(const LLUUID &agent_id, const LLUUID &session_id); - void setInvItem(const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id); - void setAsset(const LLUUID &asset_id, const LLAssetType::EType at); - - LLUUID getAgentID() const { return mAgentID; } - LLUUID getSessionID() const { return mSessionID; } - LLUUID getOwnerID() const { return mOwnerID; } - LLUUID getTaskID() const { return mTaskID; } - LLUUID getItemID() const { return mItemID; } - LLUUID getAssetID() const { return mAssetID; } - LLAssetType::EType getAssetType() const { return mAssetType; } + LLTransferSourceParamsInvItem(); + virtual ~LLTransferSourceParamsInvItem() {} + /*virtual*/ void packParams(LLDataPacker &dp) const; + /*virtual*/ bool unpackParams(LLDataPacker &dp); + + void setAgentSession(const LLUUID &agent_id, const LLUUID &session_id); + void setInvItem(const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id); + void setAsset(const LLUUID &asset_id, const LLAssetType::EType at); + + LLUUID getAgentID() const { return mAgentID; } + LLUUID getSessionID() const { return mSessionID; } + LLUUID getOwnerID() const { return mOwnerID; } + LLUUID getTaskID() const { return mTaskID; } + LLUUID getItemID() const { return mItemID; } + LLUUID getAssetID() const { return mAssetID; } + LLAssetType::EType getAssetType() const { return mAssetType; } protected: - LLUUID mAgentID; - LLUUID mSessionID; - LLUUID mOwnerID; - LLUUID mTaskID; - LLUUID mItemID; - LLUUID mAssetID; - LLAssetType::EType mAssetType; + LLUUID mAgentID; + LLUUID mSessionID; + LLUUID mOwnerID; + LLUUID mTaskID; + LLUUID mItemID; + LLUUID mAssetID; + LLAssetType::EType mAssetType; }; @@ -469,28 +469,28 @@ protected: class LLTransferSourceParamsEstate: public LLTransferSourceParams { public: - LLTransferSourceParamsEstate(); - virtual ~LLTransferSourceParamsEstate() {} - /*virtual*/ void packParams(LLDataPacker &dp) const; - /*virtual*/ bool unpackParams(LLDataPacker &dp); + LLTransferSourceParamsEstate(); + virtual ~LLTransferSourceParamsEstate() {} + /*virtual*/ void packParams(LLDataPacker &dp) const; + /*virtual*/ bool unpackParams(LLDataPacker &dp); - void setAgentSession(const LLUUID &agent_id, const LLUUID &session_id); - void setEstateAssetType(const EstateAssetType etype); - void setAsset(const LLUUID &asset_id, const LLAssetType::EType at); + void setAgentSession(const LLUUID &agent_id, const LLUUID &session_id); + void setEstateAssetType(const EstateAssetType etype); + void setAsset(const LLUUID &asset_id, const LLAssetType::EType at); - LLUUID getAgentID() const { return mAgentID; } - LLUUID getSessionID() const { return mSessionID; } - EstateAssetType getEstateAssetType() const { return mEstateAssetType; } - LLUUID getAssetID() const { return mAssetID; } - LLAssetType::EType getAssetType() const { return mAssetType; } + LLUUID getAgentID() const { return mAgentID; } + LLUUID getSessionID() const { return mSessionID; } + EstateAssetType getEstateAssetType() const { return mEstateAssetType; } + LLUUID getAssetID() const { return mAssetID; } + LLAssetType::EType getAssetType() const { return mAssetType; } protected: - LLUUID mAgentID; - LLUUID mSessionID; - EstateAssetType mEstateAssetType; - // these are set on the sim based on estateinfotype - LLUUID mAssetID; - LLAssetType::EType mAssetType; + LLUUID mAgentID; + LLUUID mSessionID; + EstateAssetType mEstateAssetType; + // these are set on the sim based on estateinfotype + LLUUID mAssetID; + LLAssetType::EType mAssetType; }; diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp index 50956aeb6d..082f12b8bf 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltransfersourceasset.cpp * @brief Transfer system for sending an asset. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,9 +35,9 @@ #include "llfilesystem.h" LLTransferSourceAsset::LLTransferSourceAsset(const LLUUID &request_id, const F32 priority) : - LLTransferSource(LLTST_ASSET, request_id, priority), - mGotResponse(false), - mCurPos(0) + LLTransferSource(LLTST_ASSET, request_id, priority), + mGotResponse(false), + mCurPos(0) { } @@ -48,207 +48,207 @@ LLTransferSourceAsset::~LLTransferSourceAsset() void LLTransferSourceAsset::initTransfer() { - if (gAssetStorage) - { - // *HACK: asset transfers will only be coming from the viewer - // to the simulator. This is subset of assets we allow to be - // simply pulled straight from the asset system. - LLUUID* tidp; - if(LLAssetType::lookupIsAssetFetchByIDAllowed(mParams.getAssetType())) - { - tidp = new LLUUID(getID()); - gAssetStorage->getAssetData( - mParams.getAssetID(), - mParams.getAssetType(), - LLTransferSourceAsset::responderCallback, - tidp, - false); - } - else - { - LL_WARNS() << "Attempted to request blocked asset " - << mParams.getAssetID() << ":" - << LLAssetType::lookupHumanReadable(mParams.getAssetType()) - << LL_ENDL; - sendTransferStatus(LLTS_ERROR); - } - } - else - { - LL_WARNS() << "Attempted to request asset " << mParams.getAssetID() - << ":" << LLAssetType::lookupHumanReadable(mParams.getAssetType()) - << " without an asset system!" << LL_ENDL; - sendTransferStatus(LLTS_ERROR); - } + if (gAssetStorage) + { + // *HACK: asset transfers will only be coming from the viewer + // to the simulator. This is subset of assets we allow to be + // simply pulled straight from the asset system. + LLUUID* tidp; + if(LLAssetType::lookupIsAssetFetchByIDAllowed(mParams.getAssetType())) + { + tidp = new LLUUID(getID()); + gAssetStorage->getAssetData( + mParams.getAssetID(), + mParams.getAssetType(), + LLTransferSourceAsset::responderCallback, + tidp, + false); + } + else + { + LL_WARNS() << "Attempted to request blocked asset " + << mParams.getAssetID() << ":" + << LLAssetType::lookupHumanReadable(mParams.getAssetType()) + << LL_ENDL; + sendTransferStatus(LLTS_ERROR); + } + } + else + { + LL_WARNS() << "Attempted to request asset " << mParams.getAssetID() + << ":" << LLAssetType::lookupHumanReadable(mParams.getAssetType()) + << " without an asset system!" << LL_ENDL; + sendTransferStatus(LLTS_ERROR); + } } F32 LLTransferSourceAsset::updatePriority() { - return 0.f; + return 0.f; } LLTSCode LLTransferSourceAsset::dataCallback(const S32 packet_id, - const S32 max_bytes, - U8 **data_handle, - S32 &returned_bytes, - bool &delete_returned) + const S32 max_bytes, + U8 **data_handle, + S32 &returned_bytes, + bool &delete_returned) { - //LL_INFOS() << "LLTransferSourceAsset::dataCallback" << LL_ENDL; - if (!mGotResponse) - { - return LLTS_SKIP; - } - - LLFileSystem vf(mParams.getAssetID(), mParams.getAssetType(), LLFileSystem::READ); - - if (!vf.getSize()) - { - // Something bad happened with the asset request! - return LLTS_ERROR; - } - - if (packet_id != mLastPacketID + 1) - { - LL_ERRS() << "Can't handle out of order file transfer yet!" << LL_ENDL; - } - - // grab a buffer from the right place in the file - if (!vf.seek(mCurPos, 0)) - { - LL_WARNS() << "LLTransferSourceAsset Can't seek to " << mCurPos << " length " << vf.getSize() << LL_ENDL; - LL_WARNS() << "While sending " << mParams.getAssetID() << LL_ENDL; - return LLTS_ERROR; - } - - delete_returned = true; - U8 *tmpp = new U8[max_bytes]; - *data_handle = tmpp; - if (!vf.read(tmpp, max_bytes)) /* Flawfinder: Ignore */ - { - // Read failure, need to deal with it. - delete[] tmpp; - *data_handle = NULL; - returned_bytes = 0; - delete_returned = false; - return LLTS_ERROR; - } - - returned_bytes = vf.getLastBytesRead(); - mCurPos += returned_bytes; - - - if (vf.eof()) - { - if (!returned_bytes) - { - delete[] tmpp; - *data_handle = NULL; - returned_bytes = 0; - delete_returned = false; - } - return LLTS_DONE; - } - - return LLTS_OK; + //LL_INFOS() << "LLTransferSourceAsset::dataCallback" << LL_ENDL; + if (!mGotResponse) + { + return LLTS_SKIP; + } + + LLFileSystem vf(mParams.getAssetID(), mParams.getAssetType(), LLFileSystem::READ); + + if (!vf.getSize()) + { + // Something bad happened with the asset request! + return LLTS_ERROR; + } + + if (packet_id != mLastPacketID + 1) + { + LL_ERRS() << "Can't handle out of order file transfer yet!" << LL_ENDL; + } + + // grab a buffer from the right place in the file + if (!vf.seek(mCurPos, 0)) + { + LL_WARNS() << "LLTransferSourceAsset Can't seek to " << mCurPos << " length " << vf.getSize() << LL_ENDL; + LL_WARNS() << "While sending " << mParams.getAssetID() << LL_ENDL; + return LLTS_ERROR; + } + + delete_returned = true; + U8 *tmpp = new U8[max_bytes]; + *data_handle = tmpp; + if (!vf.read(tmpp, max_bytes)) /* Flawfinder: Ignore */ + { + // Read failure, need to deal with it. + delete[] tmpp; + *data_handle = NULL; + returned_bytes = 0; + delete_returned = false; + return LLTS_ERROR; + } + + returned_bytes = vf.getLastBytesRead(); + mCurPos += returned_bytes; + + + if (vf.eof()) + { + if (!returned_bytes) + { + delete[] tmpp; + *data_handle = NULL; + returned_bytes = 0; + delete_returned = false; + } + return LLTS_DONE; + } + + return LLTS_OK; } void LLTransferSourceAsset::completionCallback(const LLTSCode status) { - // No matter what happens, all we want to do is close the vfile if - // we've got it open. + // No matter what happens, all we want to do is close the vfile if + // we've got it open. } void LLTransferSourceAsset::packParams(LLDataPacker& dp) const { - //LL_INFOS() << "LLTransferSourceAsset::packParams" << LL_ENDL; - mParams.packParams(dp); + //LL_INFOS() << "LLTransferSourceAsset::packParams" << LL_ENDL; + mParams.packParams(dp); } bool LLTransferSourceAsset::unpackParams(LLDataPacker &dp) { - //LL_INFOS() << "LLTransferSourceAsset::unpackParams" << LL_ENDL; - return mParams.unpackParams(dp); + //LL_INFOS() << "LLTransferSourceAsset::unpackParams" << LL_ENDL; + return mParams.unpackParams(dp); } void LLTransferSourceAsset::responderCallback(const LLUUID& uuid, LLAssetType::EType type, - void *user_data, S32 result, LLExtStat ext_status ) + void *user_data, S32 result, LLExtStat ext_status ) { - LLUUID *tidp = ((LLUUID*) user_data); - LLUUID transfer_id = *(tidp); - delete tidp; - tidp = NULL; - - LLTransferSourceAsset *tsap = (LLTransferSourceAsset *) gTransferManager.findTransferSource(transfer_id); - - if (!tsap) - { - LL_INFOS() << "Aborting transfer " << transfer_id << " callback, transfer source went away" << LL_ENDL; - return; - } - - if (result) - { - LL_INFOS() << "AssetStorage: Error " << gAssetStorage->getErrorString(result) << " downloading uuid " << uuid << LL_ENDL; - } - - LLTSCode status; - - tsap->mGotResponse = true; - if (LL_ERR_NOERR == result) - { - // Everything's OK. - LLFileSystem vf(uuid, type, LLFileSystem::READ); - tsap->mSize = vf.getSize(); - status = LLTS_OK; - } - else - { - // Uh oh, something bad happened when we tried to get this asset! - switch (result) - { - case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE: - status = LLTS_UNKNOWN_SOURCE; - break; - default: - status = LLTS_ERROR; - } - } - - tsap->sendTransferStatus(status); + LLUUID *tidp = ((LLUUID*) user_data); + LLUUID transfer_id = *(tidp); + delete tidp; + tidp = NULL; + + LLTransferSourceAsset *tsap = (LLTransferSourceAsset *) gTransferManager.findTransferSource(transfer_id); + + if (!tsap) + { + LL_INFOS() << "Aborting transfer " << transfer_id << " callback, transfer source went away" << LL_ENDL; + return; + } + + if (result) + { + LL_INFOS() << "AssetStorage: Error " << gAssetStorage->getErrorString(result) << " downloading uuid " << uuid << LL_ENDL; + } + + LLTSCode status; + + tsap->mGotResponse = true; + if (LL_ERR_NOERR == result) + { + // Everything's OK. + LLFileSystem vf(uuid, type, LLFileSystem::READ); + tsap->mSize = vf.getSize(); + status = LLTS_OK; + } + else + { + // Uh oh, something bad happened when we tried to get this asset! + switch (result) + { + case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE: + status = LLTS_UNKNOWN_SOURCE; + break; + default: + status = LLTS_ERROR; + } + } + + tsap->sendTransferStatus(status); } LLTransferSourceParamsAsset::LLTransferSourceParamsAsset() - : LLTransferSourceParams(LLTST_ASSET), + : LLTransferSourceParams(LLTST_ASSET), - mAssetType(LLAssetType::AT_NONE) + mAssetType(LLAssetType::AT_NONE) { } void LLTransferSourceParamsAsset::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type) { - mAssetID = asset_id; - mAssetType = asset_type; + mAssetID = asset_id; + mAssetType = asset_type; } void LLTransferSourceParamsAsset::packParams(LLDataPacker &dp) const { - dp.packUUID(mAssetID, "AssetID"); - dp.packS32(mAssetType, "AssetType"); + dp.packUUID(mAssetID, "AssetID"); + dp.packS32(mAssetType, "AssetType"); } bool LLTransferSourceParamsAsset::unpackParams(LLDataPacker &dp) { - S32 tmp_at; + S32 tmp_at; - dp.unpackUUID(mAssetID, "AssetID"); - dp.unpackS32(tmp_at, "AssetType"); + dp.unpackUUID(mAssetID, "AssetID"); + dp.unpackS32(tmp_at, "AssetType"); - mAssetType = (LLAssetType::EType)tmp_at; + mAssetType = (LLAssetType::EType)tmp_at; - return true; + return true; } diff --git a/indra/llmessage/lltransfersourceasset.h b/indra/llmessage/lltransfersourceasset.h index f2a5dc214e..6c4c39011a 100644 --- a/indra/llmessage/lltransfersourceasset.h +++ b/indra/llmessage/lltransfersourceasset.h @@ -1,25 +1,25 @@ -/** +/** * @file lltransfersourceasset.h * @brief Transfer system for sending an asset. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,47 +35,47 @@ class LLFileSystem; class LLTransferSourceParamsAsset : public LLTransferSourceParams { public: - LLTransferSourceParamsAsset(); - virtual ~LLTransferSourceParamsAsset() {} - /*virtual*/ void packParams(LLDataPacker &dp) const; - /*virtual*/ bool unpackParams(LLDataPacker &dp); + LLTransferSourceParamsAsset(); + virtual ~LLTransferSourceParamsAsset() {} + /*virtual*/ void packParams(LLDataPacker &dp) const; + /*virtual*/ bool unpackParams(LLDataPacker &dp); - void setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type); + void setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type); - LLUUID getAssetID() const { return mAssetID; } - LLAssetType::EType getAssetType() const { return mAssetType; } + LLUUID getAssetID() const { return mAssetID; } + LLAssetType::EType getAssetType() const { return mAssetType; } protected: - LLUUID mAssetID; - LLAssetType::EType mAssetType; + LLUUID mAssetID; + LLAssetType::EType mAssetType; }; class LLTransferSourceAsset : public LLTransferSource { public: - LLTransferSourceAsset(const LLUUID &request_id, const F32 priority); - virtual ~LLTransferSourceAsset(); + LLTransferSourceAsset(const LLUUID &request_id, const F32 priority); + virtual ~LLTransferSourceAsset(); - static void responderCallback(const LLUUID& uuid, LLAssetType::EType type, - void *user_data, S32 result, LLExtStat ext_status ); + static void responderCallback(const LLUUID& uuid, LLAssetType::EType type, + void *user_data, S32 result, LLExtStat ext_status ); protected: - /*virtual*/ void initTransfer(); - /*virtual*/ F32 updatePriority(); - /*virtual*/ LLTSCode dataCallback(const S32 packet_id, - const S32 max_bytes, - U8 **datap, - S32 &returned_bytes, - bool &delete_returned); - /*virtual*/ void completionCallback(const LLTSCode status); + /*virtual*/ void initTransfer(); + /*virtual*/ F32 updatePriority(); + /*virtual*/ LLTSCode dataCallback(const S32 packet_id, + const S32 max_bytes, + U8 **datap, + S32 &returned_bytes, + bool &delete_returned); + /*virtual*/ void completionCallback(const LLTSCode status); - virtual void packParams(LLDataPacker& dp) const; - /*virtual*/ bool unpackParams(LLDataPacker &dp); + virtual void packParams(LLDataPacker& dp) const; + /*virtual*/ bool unpackParams(LLDataPacker &dp); protected: - LLTransferSourceParamsAsset mParams; - bool mGotResponse; + LLTransferSourceParamsAsset mParams; + bool mGotResponse; - S32 mCurPos; + S32 mCurPos; }; #endif // LL_LLTRANSFERSOURCEASSET_H diff --git a/indra/llmessage/lltransfersourcefile.cpp b/indra/llmessage/lltransfersourcefile.cpp index ccf0dd7fe0..77a6c466c7 100644 --- a/indra/llmessage/lltransfersourcefile.cpp +++ b/indra/llmessage/lltransfersourcefile.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltransfersourcefile.cpp * @brief Transfer system for sending a file. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,141 +34,141 @@ #include "lldir.h" LLTransferSourceFile::LLTransferSourceFile(const LLUUID &request_id, const F32 priority) : - LLTransferSource(LLTST_FILE, request_id, priority), - mFP(NULL) + LLTransferSource(LLTST_FILE, request_id, priority), + mFP(NULL) { } LLTransferSourceFile::~LLTransferSourceFile() { - if (mFP) - { - LL_ERRS() << "Destructor called without the completion callback being called!" << LL_ENDL; - } + if (mFP) + { + LL_ERRS() << "Destructor called without the completion callback being called!" << LL_ENDL; + } } void LLTransferSourceFile::initTransfer() { - std::string filename = mParams.getFilename(); - std::string delimiter = gDirUtilp->getDirDelimiter(); - - if((filename == ".") - || (filename == "..") - || (filename.find(delimiter[0]) != std::string::npos)) - { - LL_WARNS() << "Attempting to transfer file " << filename << " with path delimiter, aborting!" << LL_ENDL; - - sendTransferStatus(LLTS_ERROR); - return; - } - // Look for the file. - mFP = LLFile::fopen(mParams.getFilename(), "rb"); /* Flawfinder: ignore */ - if (!mFP) - { - sendTransferStatus(LLTS_ERROR); - return; - } - - // Get the size of the file using the hack from - fseek(mFP,0,SEEK_END); - mSize = ftell(mFP); - fseek(mFP,0,SEEK_SET); - - sendTransferStatus(LLTS_OK); + std::string filename = mParams.getFilename(); + std::string delimiter = gDirUtilp->getDirDelimiter(); + + if((filename == ".") + || (filename == "..") + || (filename.find(delimiter[0]) != std::string::npos)) + { + LL_WARNS() << "Attempting to transfer file " << filename << " with path delimiter, aborting!" << LL_ENDL; + + sendTransferStatus(LLTS_ERROR); + return; + } + // Look for the file. + mFP = LLFile::fopen(mParams.getFilename(), "rb"); /* Flawfinder: ignore */ + if (!mFP) + { + sendTransferStatus(LLTS_ERROR); + return; + } + + // Get the size of the file using the hack from + fseek(mFP,0,SEEK_END); + mSize = ftell(mFP); + fseek(mFP,0,SEEK_SET); + + sendTransferStatus(LLTS_OK); } F32 LLTransferSourceFile::updatePriority() { - return 0.f; + return 0.f; } LLTSCode LLTransferSourceFile::dataCallback(const S32 packet_id, - const S32 max_bytes, - U8 **data_handle, - S32 &returned_bytes, - bool &delete_returned) + const S32 max_bytes, + U8 **data_handle, + S32 &returned_bytes, + bool &delete_returned) { - //LL_INFOS() << "LLTransferSourceFile::dataCallback" << LL_ENDL; - - if (!mFP) - { - LL_ERRS() << "Data callback without file set!" << LL_ENDL; - return LLTS_ERROR; - } - - if (packet_id != mLastPacketID + 1) - { - LL_ERRS() << "Can't handle out of order file transfer yet!" << LL_ENDL; - } - - // Grab up until the max number of bytes from the file. - delete_returned = true; - U8 *tmpp = new U8[max_bytes]; - *data_handle = tmpp; - returned_bytes = (S32)fread(tmpp, 1, max_bytes, mFP); - if (!returned_bytes) - { - delete[] tmpp; - *data_handle = NULL; - returned_bytes = 0; - delete_returned = false; - return LLTS_DONE; - } - - return LLTS_OK; + //LL_INFOS() << "LLTransferSourceFile::dataCallback" << LL_ENDL; + + if (!mFP) + { + LL_ERRS() << "Data callback without file set!" << LL_ENDL; + return LLTS_ERROR; + } + + if (packet_id != mLastPacketID + 1) + { + LL_ERRS() << "Can't handle out of order file transfer yet!" << LL_ENDL; + } + + // Grab up until the max number of bytes from the file. + delete_returned = true; + U8 *tmpp = new U8[max_bytes]; + *data_handle = tmpp; + returned_bytes = (S32)fread(tmpp, 1, max_bytes, mFP); + if (!returned_bytes) + { + delete[] tmpp; + *data_handle = NULL; + returned_bytes = 0; + delete_returned = false; + return LLTS_DONE; + } + + return LLTS_OK; } void LLTransferSourceFile::completionCallback(const LLTSCode status) { - // No matter what happens, all we want to do is close the file pointer if - // we've got it open. - if (mFP) - { - fclose(mFP); - mFP = NULL; - - } - // Delete the file iff the filename begins with "TEMP" - if (mParams.getDeleteOnCompletion() && mParams.getFilename().substr(0, 4) == "TEMP") - { - LLFile::remove(mParams.getFilename()); - } + // No matter what happens, all we want to do is close the file pointer if + // we've got it open. + if (mFP) + { + fclose(mFP); + mFP = NULL; + + } + // Delete the file iff the filename begins with "TEMP" + if (mParams.getDeleteOnCompletion() && mParams.getFilename().substr(0, 4) == "TEMP") + { + LLFile::remove(mParams.getFilename()); + } } void LLTransferSourceFile::packParams(LLDataPacker& dp) const { - //LL_INFOS() << "LLTransferSourceFile::packParams" << LL_ENDL; - mParams.packParams(dp); + //LL_INFOS() << "LLTransferSourceFile::packParams" << LL_ENDL; + mParams.packParams(dp); } bool LLTransferSourceFile::unpackParams(LLDataPacker &dp) { - //LL_INFOS() << "LLTransferSourceFile::unpackParams" << LL_ENDL; - return mParams.unpackParams(dp); + //LL_INFOS() << "LLTransferSourceFile::unpackParams" << LL_ENDL; + return mParams.unpackParams(dp); } LLTransferSourceParamsFile::LLTransferSourceParamsFile() : - LLTransferSourceParams(LLTST_FILE), - mDeleteOnCompletion(false) + LLTransferSourceParams(LLTST_FILE), + mDeleteOnCompletion(false) { } void LLTransferSourceParamsFile::packParams(LLDataPacker &dp) const { - dp.packString(mFilename, "Filename"); - dp.packU8((U8)mDeleteOnCompletion, "Delete"); + dp.packString(mFilename, "Filename"); + dp.packU8((U8)mDeleteOnCompletion, "Delete"); } bool LLTransferSourceParamsFile::unpackParams(LLDataPacker &dp) { - dp.unpackString(mFilename, "Filename"); - U8 delete_flag; - dp.unpackU8(delete_flag, "Delete"); - mDeleteOnCompletion = delete_flag; + dp.unpackString(mFilename, "Filename"); + U8 delete_flag; + dp.unpackU8(delete_flag, "Delete"); + mDeleteOnCompletion = delete_flag; - LL_INFOS() << "Unpacked filename: " << mFilename << LL_ENDL; - return true; + LL_INFOS() << "Unpacked filename: " << mFilename << LL_ENDL; + return true; } diff --git a/indra/llmessage/lltransfersourcefile.h b/indra/llmessage/lltransfersourcefile.h index 60100e5a65..a447ab091b 100644 --- a/indra/llmessage/lltransfersourcefile.h +++ b/indra/llmessage/lltransfersourcefile.h @@ -1,25 +1,25 @@ -/** +/** * @file lltransfersourcefile.h * @brief Transfer system for sending a file. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,44 +32,44 @@ class LLTransferSourceParamsFile : public LLTransferSourceParams { public: - LLTransferSourceParamsFile(); - virtual ~LLTransferSourceParamsFile() {} - /*virtual*/ void packParams(LLDataPacker &dp) const; - /*virtual*/ bool unpackParams(LLDataPacker &dp); + LLTransferSourceParamsFile(); + virtual ~LLTransferSourceParamsFile() {} + /*virtual*/ void packParams(LLDataPacker &dp) const; + /*virtual*/ bool unpackParams(LLDataPacker &dp); - void setFilename(const std::string &filename) { mFilename = filename; } - std::string getFilename() const { return mFilename; } + void setFilename(const std::string &filename) { mFilename = filename; } + std::string getFilename() const { return mFilename; } - void setDeleteOnCompletion(bool enabled) { mDeleteOnCompletion = enabled; } - bool getDeleteOnCompletion() { return mDeleteOnCompletion; } + void setDeleteOnCompletion(bool enabled) { mDeleteOnCompletion = enabled; } + bool getDeleteOnCompletion() { return mDeleteOnCompletion; } protected: - std::string mFilename; - // ONLY DELETE THINGS OFF THE SIM IF THE FILENAME BEGINS IN 'TEMP' - bool mDeleteOnCompletion; + std::string mFilename; + // ONLY DELETE THINGS OFF THE SIM IF THE FILENAME BEGINS IN 'TEMP' + bool mDeleteOnCompletion; }; class LLTransferSourceFile : public LLTransferSource { public: - LLTransferSourceFile(const LLUUID &transfer_id, const F32 priority); - virtual ~LLTransferSourceFile(); + LLTransferSourceFile(const LLUUID &transfer_id, const F32 priority); + virtual ~LLTransferSourceFile(); protected: - /*virtual*/ void initTransfer(); - /*virtual*/ F32 updatePriority(); - /*virtual*/ LLTSCode dataCallback(const S32 packet_id, - const S32 max_bytes, - U8 **datap, - S32 &returned_bytes, - bool &delete_returned); - /*virtual*/ void completionCallback(const LLTSCode status); + /*virtual*/ void initTransfer(); + /*virtual*/ F32 updatePriority(); + /*virtual*/ LLTSCode dataCallback(const S32 packet_id, + const S32 max_bytes, + U8 **datap, + S32 &returned_bytes, + bool &delete_returned); + /*virtual*/ void completionCallback(const LLTSCode status); - virtual void packParams(LLDataPacker& dp) const; - /*virtual*/ bool unpackParams(LLDataPacker &dp); + virtual void packParams(LLDataPacker& dp) const; + /*virtual*/ bool unpackParams(LLDataPacker &dp); protected: - LLTransferSourceParamsFile mParams; - LLFILE *mFP; + LLTransferSourceParamsFile mParams; + LLFILE *mFP; }; #endif // LL_LLTRANSFERSOURCEFILE_H diff --git a/indra/llmessage/lltransfertargetfile.cpp b/indra/llmessage/lltransfertargetfile.cpp index ca0318a2d6..6d8b69fa6f 100644 --- a/indra/llmessage/lltransfertargetfile.cpp +++ b/indra/llmessage/lltransfertargetfile.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltransfertargetfile.cpp * @brief Transfer system for receiving a file. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,99 +33,99 @@ LLTransferTargetFile::LLTransferTargetFile( - const LLUUID& uuid, - LLTransferSourceType src_type) : - LLTransferTarget(LLTTT_FILE, uuid, src_type), - mFP(NULL) + const LLUUID& uuid, + LLTransferSourceType src_type) : + LLTransferTarget(LLTTT_FILE, uuid, src_type), + mFP(NULL) { } LLTransferTargetFile::~LLTransferTargetFile() { - if (mFP) - { - LL_ERRS() << "LLTransferTargetFile::~LLTransferTargetFile - Should have been cleaned up in completion callback" << LL_ENDL; - fclose(mFP); - mFP = NULL; - } + if (mFP) + { + LL_ERRS() << "LLTransferTargetFile::~LLTransferTargetFile - Should have been cleaned up in completion callback" << LL_ENDL; + fclose(mFP); + mFP = NULL; + } } // virtual bool LLTransferTargetFile::unpackParams(LLDataPacker& dp) { - // we can safely ignore this call - return true; + // we can safely ignore this call + return true; } void LLTransferTargetFile::applyParams(const LLTransferTargetParams ¶ms) { - if (params.getType() != mType) - { - LL_WARNS() << "Target parameter type doesn't match!" << LL_ENDL; - return; - } - - mParams = (LLTransferTargetParamsFile &)params; + if (params.getType() != mType) + { + LL_WARNS() << "Target parameter type doesn't match!" << LL_ENDL; + return; + } + + mParams = (LLTransferTargetParamsFile &)params; } LLTSCode LLTransferTargetFile::dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size) { - //LL_INFOS() << "LLTransferTargetFile::dataCallback" << LL_ENDL; - //LL_INFOS() << "Packet: " << packet_id << LL_ENDL; - - if (!mFP) - { - mFP = LLFile::fopen(mParams.mFilename, "wb"); /* Flawfinder: ignore */ - - if (!mFP) - { - LL_WARNS() << "Failure opening " << mParams.mFilename << " for write by LLTransferTargetFile" << LL_ENDL; - return LLTS_ERROR; - } - } - if (!in_size) - { - return LLTS_OK; - } - - S32 count = (S32)fwrite(in_datap, 1, in_size, mFP); - if (count != in_size) - { - LL_WARNS() << "Failure in LLTransferTargetFile::dataCallback!" << LL_ENDL; - return LLTS_ERROR; - } - return LLTS_OK; + //LL_INFOS() << "LLTransferTargetFile::dataCallback" << LL_ENDL; + //LL_INFOS() << "Packet: " << packet_id << LL_ENDL; + + if (!mFP) + { + mFP = LLFile::fopen(mParams.mFilename, "wb"); /* Flawfinder: ignore */ + + if (!mFP) + { + LL_WARNS() << "Failure opening " << mParams.mFilename << " for write by LLTransferTargetFile" << LL_ENDL; + return LLTS_ERROR; + } + } + if (!in_size) + { + return LLTS_OK; + } + + S32 count = (S32)fwrite(in_datap, 1, in_size, mFP); + if (count != in_size) + { + LL_WARNS() << "Failure in LLTransferTargetFile::dataCallback!" << LL_ENDL; + return LLTS_ERROR; + } + return LLTS_OK; } void LLTransferTargetFile::completionCallback(const LLTSCode status) { - LL_INFOS() << "LLTransferTargetFile::completionCallback" << LL_ENDL; - if (mFP) - { - fclose(mFP); - } - - // Still need to gracefully handle error conditions. - switch (status) - { - case LLTS_DONE: - break; - case LLTS_ABORT: - case LLTS_ERROR: - // We're aborting this transfer, we don't want to keep this file. - LL_WARNS() << "Aborting file transfer for " << mParams.mFilename << LL_ENDL; - if (mFP) - { - // Only need to remove file if we successfully opened it. - LLFile::remove(mParams.mFilename); - } - default: - break; - } - - mFP = NULL; - if (mParams.mCompleteCallback) - { - mParams.mCompleteCallback(status, mParams.mUserData); - } + LL_INFOS() << "LLTransferTargetFile::completionCallback" << LL_ENDL; + if (mFP) + { + fclose(mFP); + } + + // Still need to gracefully handle error conditions. + switch (status) + { + case LLTS_DONE: + break; + case LLTS_ABORT: + case LLTS_ERROR: + // We're aborting this transfer, we don't want to keep this file. + LL_WARNS() << "Aborting file transfer for " << mParams.mFilename << LL_ENDL; + if (mFP) + { + // Only need to remove file if we successfully opened it. + LLFile::remove(mParams.mFilename); + } + default: + break; + } + + mFP = NULL; + if (mParams.mCompleteCallback) + { + mParams.mCompleteCallback(status, mParams.mUserData); + } } diff --git a/indra/llmessage/lltransfertargetfile.h b/indra/llmessage/lltransfertargetfile.h index 6d03ff2d2e..43189eb388 100644 --- a/indra/llmessage/lltransfertargetfile.h +++ b/indra/llmessage/lltransfertargetfile.h @@ -1,25 +1,25 @@ -/** +/** * @file lltransfertargetfile.h * @brief Transfer system for receiving a file. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,42 +34,42 @@ typedef void (*LLTTFCompleteCallback)(const LLTSCode status, void *user_data); class LLTransferTargetParamsFile : public LLTransferTargetParams { public: - LLTransferTargetParamsFile() - : LLTransferTargetParams(LLTTT_FILE), + LLTransferTargetParamsFile() + : LLTransferTargetParams(LLTTT_FILE), - mCompleteCallback(NULL), - mUserData(NULL) - {} - void setFilename(const std::string& filename) { mFilename = filename; } - void setCallback(LLTTFCompleteCallback cb, void *user_data) { mCompleteCallback = cb; mUserData = user_data; } + mCompleteCallback(NULL), + mUserData(NULL) + {} + void setFilename(const std::string& filename) { mFilename = filename; } + void setCallback(LLTTFCompleteCallback cb, void *user_data) { mCompleteCallback = cb; mUserData = user_data; } - friend class LLTransferTargetFile; + friend class LLTransferTargetFile; protected: - std::string mFilename; - LLTTFCompleteCallback mCompleteCallback; - void * mUserData; + std::string mFilename; + LLTTFCompleteCallback mCompleteCallback; + void * mUserData; }; class LLTransferTargetFile : public LLTransferTarget { public: - LLTransferTargetFile(const LLUUID& uuid, LLTransferSourceType src_type); - virtual ~LLTransferTargetFile(); + LLTransferTargetFile(const LLUUID& uuid, LLTransferSourceType src_type); + virtual ~LLTransferTargetFile(); - static void requestTransfer(LLTransferTargetChannel *channelp, - const char *local_filename, - const LLTransferSourceParams &source_params, - LLTTFCompleteCallback callback); + static void requestTransfer(LLTransferTargetChannel *channelp, + const char *local_filename, + const LLTransferSourceParams &source_params, + LLTTFCompleteCallback callback); protected: - virtual bool unpackParams(LLDataPacker& dp); - /*virtual*/ void applyParams(const LLTransferTargetParams ¶ms); - /*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size); - /*virtual*/ void completionCallback(const LLTSCode status); + virtual bool unpackParams(LLDataPacker& dp); + /*virtual*/ void applyParams(const LLTransferTargetParams ¶ms); + /*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size); + /*virtual*/ void completionCallback(const LLTSCode status); - LLTransferTargetParamsFile mParams; + LLTransferTargetParamsFile mParams; - LLFILE *mFP; + LLFILE *mFP; }; #endif // LL_LLTRANSFERTARGETFILE_H diff --git a/indra/llmessage/lltransfertargetvfile.cpp b/indra/llmessage/lltransfertargetvfile.cpp index 2806e08ebd..fcf853845b 100644 --- a/indra/llmessage/lltransfertargetvfile.cpp +++ b/indra/llmessage/lltransfertargetvfile.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltransfertargetvfile.cpp * @brief Transfer system for receiving a vfile. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,64 +39,64 @@ void LLTransferTargetVFile::updateQueue(bool shutdown) LLTransferTargetParamsVFile::LLTransferTargetParamsVFile() : - LLTransferTargetParams(LLTTT_VFILE), - mAssetType(LLAssetType::AT_NONE), - mCompleteCallback(NULL), - mRequestDatap(NULL), - mErrCode(0) + LLTransferTargetParams(LLTTT_VFILE), + mAssetType(LLAssetType::AT_NONE), + mCompleteCallback(NULL), + mRequestDatap(NULL), + mErrCode(0) { } void LLTransferTargetParamsVFile::setAsset( - const LLUUID& asset_id, - LLAssetType::EType asset_type) + const LLUUID& asset_id, + LLAssetType::EType asset_type) { - mAssetID = asset_id; - mAssetType = asset_type; + mAssetID = asset_id; + mAssetType = asset_type; } void LLTransferTargetParamsVFile::setCallback(LLTTVFCompleteCallback cb, LLBaseDownloadRequest& request) { - mCompleteCallback = cb; + mCompleteCallback = cb; if (mRequestDatap) { delete mRequestDatap; } - mRequestDatap = request.getCopy(); + mRequestDatap = request.getCopy(); } bool LLTransferTargetParamsVFile::unpackParams(LLDataPacker& dp) { - // if the source provided a new key, assign that to the asset id. - if(dp.hasNext()) - { - LLUUID dummy_id; - dp.unpackUUID(dummy_id, "AgentID"); - dp.unpackUUID(dummy_id, "SessionID"); - dp.unpackUUID(dummy_id, "OwnerID"); - dp.unpackUUID(dummy_id, "TaskID"); - dp.unpackUUID(dummy_id, "ItemID"); - dp.unpackUUID(mAssetID, "AssetID"); - S32 dummy_type; - dp.unpackS32(dummy_type, "AssetType"); - } - - // if we never got an asset id, this will always fail. - if(mAssetID.isNull()) - { - return false; - } - return true; + // if the source provided a new key, assign that to the asset id. + if(dp.hasNext()) + { + LLUUID dummy_id; + dp.unpackUUID(dummy_id, "AgentID"); + dp.unpackUUID(dummy_id, "SessionID"); + dp.unpackUUID(dummy_id, "OwnerID"); + dp.unpackUUID(dummy_id, "TaskID"); + dp.unpackUUID(dummy_id, "ItemID"); + dp.unpackUUID(mAssetID, "AssetID"); + S32 dummy_type; + dp.unpackS32(dummy_type, "AssetType"); + } + + // if we never got an asset id, this will always fail. + if(mAssetID.isNull()) + { + return false; + } + return true; } LLTransferTargetVFile::LLTransferTargetVFile( - const LLUUID& uuid, - LLTransferSourceType src_type) : - LLTransferTarget(LLTTT_VFILE, uuid, src_type), - mNeedsCreate(true) + const LLUUID& uuid, + LLTransferSourceType src_type) : + LLTransferTarget(LLTTT_VFILE, uuid, src_type), + mNeedsCreate(true) { - mTempID.generate(); + mTempID.generate(); } @@ -114,109 +114,109 @@ LLTransferTargetVFile::~LLTransferTargetVFile() // virtual bool LLTransferTargetVFile::unpackParams(LLDataPacker& dp) { - if(LLTST_SIM_INV_ITEM == mSourceType) - { - return mParams.unpackParams(dp); - } - return true; + if(LLTST_SIM_INV_ITEM == mSourceType) + { + return mParams.unpackParams(dp); + } + return true; } void LLTransferTargetVFile::applyParams(const LLTransferTargetParams ¶ms) { - if (params.getType() != mType) - { - LL_WARNS() << "Target parameter type doesn't match!" << LL_ENDL; - return; - } - - mParams = (LLTransferTargetParamsVFile &)params; + if (params.getType() != mType) + { + LL_WARNS() << "Target parameter type doesn't match!" << LL_ENDL; + return; + } + + mParams = (LLTransferTargetParamsVFile &)params; } LLTSCode LLTransferTargetVFile::dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size) { - //LL_INFOS() << "LLTransferTargetFile::dataCallback" << LL_ENDL; - //LL_INFOS() << "Packet: " << packet_id << LL_ENDL; - - LLFileSystem vf(mTempID, mParams.getAssetType(), LLFileSystem::APPEND); - if (mNeedsCreate) - { - mNeedsCreate = false; - } - - if (!in_size) - { - return LLTS_OK; - } - - if (!vf.write(in_datap, in_size)) - { - LL_WARNS() << "Failure in LLTransferTargetVFile::dataCallback!" << LL_ENDL; - return LLTS_ERROR; - } - return LLTS_OK; + //LL_INFOS() << "LLTransferTargetFile::dataCallback" << LL_ENDL; + //LL_INFOS() << "Packet: " << packet_id << LL_ENDL; + + LLFileSystem vf(mTempID, mParams.getAssetType(), LLFileSystem::APPEND); + if (mNeedsCreate) + { + mNeedsCreate = false; + } + + if (!in_size) + { + return LLTS_OK; + } + + if (!vf.write(in_datap, in_size)) + { + LL_WARNS() << "Failure in LLTransferTargetVFile::dataCallback!" << LL_ENDL; + return LLTS_ERROR; + } + return LLTS_OK; } void LLTransferTargetVFile::completionCallback(const LLTSCode status) { - //LL_INFOS() << "LLTransferTargetVFile::completionCallback" << LL_ENDL; - - if (!gAssetStorage) - { - LL_WARNS() << "Aborting vfile transfer after asset storage shut down!" << LL_ENDL; - return; - } - - // Still need to gracefully handle error conditions. - S32 err_code = 0; - switch (status) - { - case LLTS_DONE: - if (!mNeedsCreate) - { - LLFileSystem file(mTempID, mParams.getAssetType(), LLFileSystem::WRITE); - if (!file.rename(mParams.getAssetID(), mParams.getAssetType())) - { - LL_ERRS() << "LLTransferTargetVFile: rename failed" << LL_ENDL; - } - } - err_code = LL_ERR_NOERR; - LL_DEBUGS() << "LLTransferTargetVFile::completionCallback for " - << mParams.getAssetID() << "," - << LLAssetType::lookup(mParams.getAssetType()) - << " with temp id " << mTempID << LL_ENDL; - break; - case LLTS_ERROR: - case LLTS_ABORT: - case LLTS_UNKNOWN_SOURCE: - default: - { - // We're aborting this transfer, we don't want to keep this file. - LL_WARNS() << "Aborting vfile transfer for " << mParams.getAssetID() << LL_ENDL; - LLFileSystem vf(mTempID, mParams.getAssetType(), LLFileSystem::APPEND); - vf.remove(); - } - break; - } - - switch (status) - { - case LLTS_DONE: - err_code = LL_ERR_NOERR; - break; - case LLTS_UNKNOWN_SOURCE: - err_code = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; - break; - case LLTS_INSUFFICIENT_PERMISSIONS: - err_code = LL_ERR_INSUFFICIENT_PERMISSIONS; - break; - case LLTS_ERROR: - case LLTS_ABORT: - default: - err_code = LL_ERR_ASSET_REQUEST_FAILED; - break; - } + //LL_INFOS() << "LLTransferTargetVFile::completionCallback" << LL_ENDL; + + if (!gAssetStorage) + { + LL_WARNS() << "Aborting vfile transfer after asset storage shut down!" << LL_ENDL; + return; + } + + // Still need to gracefully handle error conditions. + S32 err_code = 0; + switch (status) + { + case LLTS_DONE: + if (!mNeedsCreate) + { + LLFileSystem file(mTempID, mParams.getAssetType(), LLFileSystem::WRITE); + if (!file.rename(mParams.getAssetID(), mParams.getAssetType())) + { + LL_ERRS() << "LLTransferTargetVFile: rename failed" << LL_ENDL; + } + } + err_code = LL_ERR_NOERR; + LL_DEBUGS() << "LLTransferTargetVFile::completionCallback for " + << mParams.getAssetID() << "," + << LLAssetType::lookup(mParams.getAssetType()) + << " with temp id " << mTempID << LL_ENDL; + break; + case LLTS_ERROR: + case LLTS_ABORT: + case LLTS_UNKNOWN_SOURCE: + default: + { + // We're aborting this transfer, we don't want to keep this file. + LL_WARNS() << "Aborting vfile transfer for " << mParams.getAssetID() << LL_ENDL; + LLFileSystem vf(mTempID, mParams.getAssetType(), LLFileSystem::APPEND); + vf.remove(); + } + break; + } + + switch (status) + { + case LLTS_DONE: + err_code = LL_ERR_NOERR; + break; + case LLTS_UNKNOWN_SOURCE: + err_code = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; + break; + case LLTS_INSUFFICIENT_PERMISSIONS: + err_code = LL_ERR_INSUFFICIENT_PERMISSIONS; + break; + case LLTS_ERROR: + case LLTS_ABORT: + default: + err_code = LL_ERR_ASSET_REQUEST_FAILED; + break; + } if (mParams.mRequestDatap) { @@ -226,7 +226,7 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status) mParams.getAssetID(), mParams.getAssetType(), mParams.mRequestDatap, - LLExtStat::NONE); + LLExtStat::NONE); } delete mParams.mRequestDatap; mParams.mRequestDatap = NULL; diff --git a/indra/llmessage/lltransfertargetvfile.h b/indra/llmessage/lltransfertargetvfile.h index 2e6e5a8d40..4a78c3c522 100644 --- a/indra/llmessage/lltransfertargetvfile.h +++ b/indra/llmessage/lltransfertargetvfile.h @@ -1,25 +1,25 @@ -/** +/** * @file lltransfertargetvfile.h * @brief Transfer system for receiving a vfile. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,58 +36,58 @@ class LLFileSystem; // Lame, an S32 for now until I figure out the deal with how we want to do // error codes. typedef void (*LLTTVFCompleteCallback)( - S32 status, - const LLUUID& file_id, - LLAssetType::EType file_type, - LLBaseDownloadRequest* user_data, LLExtStat ext_status ); + S32 status, + const LLUUID& file_id, + LLAssetType::EType file_type, + LLBaseDownloadRequest* user_data, LLExtStat ext_status ); class LLTransferTargetParamsVFile : public LLTransferTargetParams { public: - LLTransferTargetParamsVFile(); + LLTransferTargetParamsVFile(); - void setAsset(const LLUUID& asset_id, LLAssetType::EType asset_type); - void setCallback(LLTTVFCompleteCallback cb, LLBaseDownloadRequest& request); + void setAsset(const LLUUID& asset_id, LLAssetType::EType asset_type); + void setCallback(LLTTVFCompleteCallback cb, LLBaseDownloadRequest& request); - LLUUID getAssetID() const { return mAssetID; } - LLAssetType::EType getAssetType() const { return mAssetType; } + LLUUID getAssetID() const { return mAssetID; } + LLAssetType::EType getAssetType() const { return mAssetType; } - friend class LLTransferTargetVFile; + friend class LLTransferTargetVFile; protected: - bool unpackParams(LLDataPacker& dp); + bool unpackParams(LLDataPacker& dp); - LLUUID mAssetID; - LLAssetType::EType mAssetType; + LLUUID mAssetID; + LLAssetType::EType mAssetType; - LLTTVFCompleteCallback mCompleteCallback; - LLBaseDownloadRequest* mRequestDatap; - S32 mErrCode; + LLTTVFCompleteCallback mCompleteCallback; + LLBaseDownloadRequest* mRequestDatap; + S32 mErrCode; }; class LLTransferTargetVFile : public LLTransferTarget { public: - LLTransferTargetVFile(const LLUUID& uuid, LLTransferSourceType src_type); - virtual ~LLTransferTargetVFile(); + LLTransferTargetVFile(const LLUUID& uuid, LLTransferSourceType src_type); + virtual ~LLTransferTargetVFile(); + + //static void requestTransfer(LLTransferTargetChannel* channelp, + // const char* local_filename, + // const LLTransferSourceParams& source_params, + // LLTTVFCompleteCallback callback); - //static void requestTransfer(LLTransferTargetChannel* channelp, - // const char* local_filename, - // const LLTransferSourceParams& source_params, - // LLTTVFCompleteCallback callback); + static void updateQueue(bool shutdown = false); - static void updateQueue(bool shutdown = false); - protected: - virtual bool unpackParams(LLDataPacker& dp); - /*virtual*/ void applyParams(const LLTransferTargetParams& params); - /*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8* in_datap, const S32 in_size); - /*virtual*/ void completionCallback(const LLTSCode status); + virtual bool unpackParams(LLDataPacker& dp); + /*virtual*/ void applyParams(const LLTransferTargetParams& params); + /*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8* in_datap, const S32 in_size); + /*virtual*/ void completionCallback(const LLTSCode status); - LLTransferTargetParamsVFile mParams; + LLTransferTargetParamsVFile mParams; - bool mNeedsCreate; - LLUUID mTempID; + bool mNeedsCreate; + LLUUID mTempID; }; #endif // LL_LLTRANSFERTARGETFILE_H diff --git a/indra/llmessage/lltrustedmessageservice.cpp b/indra/llmessage/lltrustedmessageservice.cpp index 33944f7883..4591a49dce 100644 --- a/indra/llmessage/lltrustedmessageservice.cpp +++ b/indra/llmessage/lltrustedmessageservice.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,50 +36,50 @@ bool LLTrustedMessageService::validate(const std::string& name, LLSD& context) const { - return true; + return true; } void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response, - const LLSD& context, - const LLSD& input) const + const LLSD& context, + const LLSD& input) const { - std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"]; - std::string senderIP = context[CONTEXT_REQUEST][CONTEXT_REMOTE_HOST]; - std::string senderPort = context[CONTEXT_REQUEST][CONTEXT_HEADERS] - ["x-secondlife-udp-listen-port"]; + std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"]; + std::string senderIP = context[CONTEXT_REQUEST][CONTEXT_REMOTE_HOST]; + std::string senderPort = context[CONTEXT_REQUEST][CONTEXT_HEADERS] + ["x-secondlife-udp-listen-port"]; + + LLSD message_data; + std::string sender = senderIP + ":" + senderPort; + message_data["sender"] = sender; + message_data["body"] = input; - LLSD message_data; - std::string sender = senderIP + ":" + senderPort; - message_data["sender"] = sender; - message_data["body"] = input; - - // untrusted senders should not have access to the trusted message - // service, but this can happen in development, so check and warn - LLMessageConfig::SenderTrust trust = - LLMessageConfig::getSenderTrustedness(name); - if ((trust == LLMessageConfig::TRUSTED || - (trust == LLMessageConfig::NOT_SET && - gMessageSystem->isTrustedMessage(name))) - && !gMessageSystem->isTrustedSender(LLHost(sender))) - { - LL_WARNS("Messaging") << "trusted message POST to /trusted-message/" - << name << " from unknown or untrusted sender " - << sender << LL_ENDL; - response->status(HTTP_FORBIDDEN, "Unknown or untrusted sender"); - } - else - { - gMessageSystem->receivedMessageFromTrustedSender(); - if (input.has("binary-template-data")) - { - LL_INFOS() << "Dispatching template: " << input << LL_ENDL; - // try and send this message using udp dispatch - LLMessageSystem::dispatchTemplate(name, message_data, response); - } - else - { - LL_INFOS() << "Dispatching without template: " << input << LL_ENDL; - LLMessageSystem::dispatch(name, message_data, response); - } - } + // untrusted senders should not have access to the trusted message + // service, but this can happen in development, so check and warn + LLMessageConfig::SenderTrust trust = + LLMessageConfig::getSenderTrustedness(name); + if ((trust == LLMessageConfig::TRUSTED || + (trust == LLMessageConfig::NOT_SET && + gMessageSystem->isTrustedMessage(name))) + && !gMessageSystem->isTrustedSender(LLHost(sender))) + { + LL_WARNS("Messaging") << "trusted message POST to /trusted-message/" + << name << " from unknown or untrusted sender " + << sender << LL_ENDL; + response->status(HTTP_FORBIDDEN, "Unknown or untrusted sender"); + } + else + { + gMessageSystem->receivedMessageFromTrustedSender(); + if (input.has("binary-template-data")) + { + LL_INFOS() << "Dispatching template: " << input << LL_ENDL; + // try and send this message using udp dispatch + LLMessageSystem::dispatchTemplate(name, message_data, response); + } + else + { + LL_INFOS() << "Dispatching without template: " << input << LL_ENDL; + LLMessageSystem::dispatch(name, message_data, response); + } + } } diff --git a/indra/llmessage/lltrustedmessageservice.h b/indra/llmessage/lltrustedmessageservice.h index 12a37bb535..c47987a217 100644 --- a/indra/llmessage/lltrustedmessageservice.h +++ b/indra/llmessage/lltrustedmessageservice.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,7 +30,7 @@ #include "linden_common.h" #include "llhttpnode.h" -// These are defined in lliosocket.h/lliosocket.cpp +// These are defined in lliosocket.h/lliosocket.cpp extern const std::string CONTEXT_REMOTE_HOST; extern const std::string CONTEXT_REMOTE_PORT; @@ -40,11 +40,11 @@ class LLTrustedMessageService { public: - bool validate(const std::string& name, LLSD& context) const; - - void post(LLHTTPNode::ResponsePtr response, - const LLSD& context, - const LLSD& input) const; + bool validate(const std::string& name, LLSD& context) const; + + void post(LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const; }; #endif // LLTRUSTEDMESSAGESERVICE_H diff --git a/indra/llmessage/lluseroperation.cpp b/indra/llmessage/lluseroperation.cpp index 6b0cc63686..36ab87086d 100644 --- a/indra/llmessage/lluseroperation.cpp +++ b/indra/llmessage/lluseroperation.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lluseroperation.cpp * @brief LLUserOperation class definition. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,27 +39,27 @@ LLUserOperationMgr* gUserOperationMgr = NULL; ///---------------------------------------------------------------------------- LLUserOperation::LLUserOperation(const LLUUID& agent_id) -: mAgentID(agent_id), - mTimer(), - mNoExpire(false) +: mAgentID(agent_id), + mTimer(), + mNoExpire(false) { - mTransactionID.generate(); + mTransactionID.generate(); } LLUserOperation::LLUserOperation(const LLUUID& agent_id, - const LLUUID& transaction_id) : - mAgentID(agent_id), - mTransactionID(transaction_id), - mTimer(), - mNoExpire(false) + const LLUUID& transaction_id) : + mAgentID(agent_id), + mTransactionID(transaction_id), + mTimer(), + mNoExpire(false) { } // protected constructor which is used by base classes that determine // transaction, agent, et. after construction. LLUserOperation::LLUserOperation() : - mTimer(), - mNoExpire(false) + mTimer(), + mNoExpire(false) { } @@ -69,22 +69,22 @@ LLUserOperation::~LLUserOperation() void LLUserOperation::SetNoExpireFlag(const bool flag) { - mNoExpire = flag; + mNoExpire = flag; } bool LLUserOperation::isExpired() { - if (!mNoExpire) - { - const F32 EXPIRE_TIME_SECS = 10.f; - return mTimer.getElapsedTimeF32() > EXPIRE_TIME_SECS; - } - return false; + if (!mNoExpire) + { + const F32 EXPIRE_TIME_SECS = 10.f; + return mTimer.getElapsedTimeF32() > EXPIRE_TIME_SECS; + } + return false; } void LLUserOperation::expire() { - // by default, do do anything. + // by default, do do anything. } ///---------------------------------------------------------------------------- @@ -98,90 +98,90 @@ LLUserOperationMgr::LLUserOperationMgr() LLUserOperationMgr::~LLUserOperationMgr() { - if (mUserOperationList.size() > 0) - { - LL_WARNS() << "Exiting with user operations pending." << LL_ENDL; - } + if (mUserOperationList.size() > 0) + { + LL_WARNS() << "Exiting with user operations pending." << LL_ENDL; + } } void LLUserOperationMgr::addOperation(LLUserOperation* op) { - if(!op) - { - LL_WARNS() << "Tried to add null op" << LL_ENDL; - return; - } - LLUUID id = op->getTransactionID(); - llassert(mUserOperationList.count(id) == 0); - mUserOperationList[id] = op; + if(!op) + { + LL_WARNS() << "Tried to add null op" << LL_ENDL; + return; + } + LLUUID id = op->getTransactionID(); + llassert(mUserOperationList.count(id) == 0); + mUserOperationList[id] = op; } LLUserOperation* LLUserOperationMgr::findOperation(const LLUUID& tid) { - user_operation_list_t::iterator iter = mUserOperationList.find(tid); - if (iter != mUserOperationList.end()) - return iter->second; - else - return NULL; + user_operation_list_t::iterator iter = mUserOperationList.find(tid); + if (iter != mUserOperationList.end()) + return iter->second; + else + return NULL; } bool LLUserOperationMgr::deleteOperation(LLUserOperation* op) { - size_t rv = 0; - if(op) - { - LLUUID id = op->getTransactionID(); - rv = mUserOperationList.erase(id); - delete op; - op = NULL; - } - return rv != 0; + size_t rv = 0; + if(op) + { + LLUUID id = op->getTransactionID(); + rv = mUserOperationList.erase(id); + delete op; + op = NULL; + } + return rv != 0; } void LLUserOperationMgr::deleteExpiredOperations() { - const S32 MAX_OPS_CONSIDERED = 2000; - S32 ops_left = MAX_OPS_CONSIDERED; - LLUserOperation* op = NULL; - user_operation_list_t::iterator it; - if(mLastOperationConsidered.isNull()) - { - it = mUserOperationList.begin(); - } - else - { - it = mUserOperationList.lower_bound(mLastOperationConsidered); - } - while((ops_left--) && (it != mUserOperationList.end())) - { - op = (*it).second; - if(op && op->isExpired()) - { - LL_DEBUGS() << "expiring: " << (*it).first << LL_ENDL; - op->expire(); - mUserOperationList.erase(it++); - delete op; - } - else if(op) - { - ++it; - } - else - { - mUserOperationList.erase(it++); - } - } - if(it != mUserOperationList.end()) - { - mLastOperationConsidered = (*it).first; - } - else - { - mLastOperationConsidered.setNull(); - } + const S32 MAX_OPS_CONSIDERED = 2000; + S32 ops_left = MAX_OPS_CONSIDERED; + LLUserOperation* op = NULL; + user_operation_list_t::iterator it; + if(mLastOperationConsidered.isNull()) + { + it = mUserOperationList.begin(); + } + else + { + it = mUserOperationList.lower_bound(mLastOperationConsidered); + } + while((ops_left--) && (it != mUserOperationList.end())) + { + op = (*it).second; + if(op && op->isExpired()) + { + LL_DEBUGS() << "expiring: " << (*it).first << LL_ENDL; + op->expire(); + mUserOperationList.erase(it++); + delete op; + } + else if(op) + { + ++it; + } + else + { + mUserOperationList.erase(it++); + } + } + if(it != mUserOperationList.end()) + { + mLastOperationConsidered = (*it).first; + } + else + { + mLastOperationConsidered.setNull(); + } } diff --git a/indra/llmessage/lluseroperation.h b/indra/llmessage/lluseroperation.h index 9d0f4d04d1..c3ac2e350c 100644 --- a/indra/llmessage/lluseroperation.h +++ b/indra/llmessage/lluseroperation.h @@ -1,4 +1,4 @@ -/** +/** * @file lluseroperation.h * @brief LLUserOperation class header file - used for message based * transaction. For example, L$ transactions. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,60 +36,60 @@ class LLUserOperation { public: - LLUserOperation(const LLUUID& agent_id); - LLUserOperation(const LLUUID& agent_id, const LLUUID& transaction_id); - virtual ~LLUserOperation(); + LLUserOperation(const LLUUID& agent_id); + LLUserOperation(const LLUUID& agent_id, const LLUUID& transaction_id); + virtual ~LLUserOperation(); - const LLUUID& getTransactionID() const { return mTransactionID; } - const LLUUID& getAgentID() const { return mAgentID; } + const LLUUID& getTransactionID() const { return mTransactionID; } + const LLUUID& getAgentID() const { return mAgentID; } - // Operation never got necessary data, so expired - virtual bool isExpired(); + // Operation never got necessary data, so expired + virtual bool isExpired(); - // ability to mark this operation as never expiring. - void SetNoExpireFlag(const bool flag); + // ability to mark this operation as never expiring. + void SetNoExpireFlag(const bool flag); - // Send request to the dataserver - virtual void sendRequest() = 0; + // Send request to the dataserver + virtual void sendRequest() = 0; - // Run the operation. This will only be called in the case of an - // actual success or failure of the operation. - virtual bool execute(bool transaction_success) = 0; + // Run the operation. This will only be called in the case of an + // actual success or failure of the operation. + virtual bool execute(bool transaction_success) = 0; - // This method is called when the user op has expired, and is - // about to be deleted by the manager. This gives the user op the - // ability to nack someone when the user op is never evaluated - virtual void expire(); + // This method is called when the user op has expired, and is + // about to be deleted by the manager. This gives the user op the + // ability to nack someone when the user op is never evaluated + virtual void expire(); protected: - LLUserOperation(); - + LLUserOperation(); + protected: - LLUUID mAgentID; - LLUUID mTransactionID; - LLFrameTimer mTimer; - bool mNoExpire; // this is used for operations that expect an answer and will wait till it gets one. + LLUUID mAgentID; + LLUUID mTransactionID; + LLFrameTimer mTimer; + bool mNoExpire; // this is used for operations that expect an answer and will wait till it gets one. }; class LLUserOperationMgr { public: - LLUserOperationMgr(); - ~LLUserOperationMgr(); + LLUserOperationMgr(); + ~LLUserOperationMgr(); + + void addOperation(LLUserOperation* op); + LLUserOperation* findOperation(const LLUUID& transaction_id); + bool deleteOperation(LLUserOperation* op); - void addOperation(LLUserOperation* op); - LLUserOperation* findOperation(const LLUUID& transaction_id); - bool deleteOperation(LLUserOperation* op); + // Call this method every once in a while to clean up old + // transactions. + void deleteExpiredOperations(); - // Call this method every once in a while to clean up old - // transactions. - void deleteExpiredOperations(); - private: - typedef std::map<LLUUID, LLUserOperation*> user_operation_list_t; - user_operation_list_t mUserOperationList; - LLUUID mLastOperationConsidered; + typedef std::map<LLUUID, LLUserOperation*> user_operation_list_t; + user_operation_list_t mUserOperationList; + LLUUID mLastOperationConsidered; }; extern LLUserOperationMgr* gUserOperationMgr; diff --git a/indra/llmessage/llvehicleparams.h b/indra/llmessage/llvehicleparams.h index f34df7744e..fe4b68e3bf 100644 --- a/indra/llmessage/llvehicleparams.h +++ b/indra/llmessage/llvehicleparams.h @@ -1,4 +1,4 @@ -/** +/** * @file llvehicleparams.h * @brief For parameter names that must be shared between the * scripting language and the LLVehicleAction class on the simulator. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,72 +28,72 @@ #ifndef LL_VEHICLE_PARAMS_H #define LL_VEHICLE_PARAMS_H -/** +/** * The idea is that the various parameters that control vehicle * behavior can be tweeked by name using general-purpose script calls. */ typedef enum e_vehicle_param { - VEHICLE_TYPE_NONE, // TYPE_0 - VEHICLE_TYPE_SLED, - VEHICLE_TYPE_CAR, - VEHICLE_TYPE_BOAT, - VEHICLE_TYPE_AIRPLANE, - VEHICLE_TYPE_BALLOON, // TYPE_5 - VEHICLE_TYPE_6, - VEHICLE_TYPE_7, - VEHICLE_TYPE_8, - VEHICLE_TYPE_9, - VEHICLE_TYPE_10, - VEHICLE_TYPE_11, - VEHICLE_TYPE_12, - VEHICLE_TYPE_13, - VEHICLE_TYPE_14, - VEHICLE_TYPE_15, - - // vector parameters - VEHICLE_LINEAR_FRICTION_TIMESCALE, - VEHICLE_ANGULAR_FRICTION_TIMESCALE, - VEHICLE_LINEAR_MOTOR_DIRECTION, - VEHICLE_ANGULAR_MOTOR_DIRECTION, - VEHICLE_LINEAR_MOTOR_OFFSET, - VEHICLE_VECTOR_PARAM_5, - VEHICLE_VECTOR_PARAM_6, - VEHICLE_VECTOR_PARAM_7, - - // floating point parameters - VEHICLE_HOVER_HEIGHT, - VEHICLE_HOVER_EFFICIENCY, - VEHICLE_HOVER_TIMESCALE, - VEHICLE_BUOYANCY, - - VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, - VEHICLE_LINEAR_DEFLECTION_TIMESCALE, - VEHICLE_LINEAR_MOTOR_TIMESCALE, - VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, - - VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, - VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, - VEHICLE_ANGULAR_MOTOR_TIMESCALE, - VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, - - VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, - VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, - - VEHICLE_BANKING_EFFICIENCY, - VEHICLE_BANKING_MIX, - VEHICLE_BANKING_TIMESCALE, - - VEHICLE_FLOAT_PARAM_17, - VEHICLE_FLOAT_PARAM_18, - VEHICLE_FLOAT_PARAM_19, - - // rotation parameters - VEHICLE_REFERENCE_FRAME, - VEHICLE_ROTATION_PARAM_1, - VEHICLE_ROTATION_PARAM_2, - VEHICLE_ROTATION_PARAM_3, + VEHICLE_TYPE_NONE, // TYPE_0 + VEHICLE_TYPE_SLED, + VEHICLE_TYPE_CAR, + VEHICLE_TYPE_BOAT, + VEHICLE_TYPE_AIRPLANE, + VEHICLE_TYPE_BALLOON, // TYPE_5 + VEHICLE_TYPE_6, + VEHICLE_TYPE_7, + VEHICLE_TYPE_8, + VEHICLE_TYPE_9, + VEHICLE_TYPE_10, + VEHICLE_TYPE_11, + VEHICLE_TYPE_12, + VEHICLE_TYPE_13, + VEHICLE_TYPE_14, + VEHICLE_TYPE_15, + + // vector parameters + VEHICLE_LINEAR_FRICTION_TIMESCALE, + VEHICLE_ANGULAR_FRICTION_TIMESCALE, + VEHICLE_LINEAR_MOTOR_DIRECTION, + VEHICLE_ANGULAR_MOTOR_DIRECTION, + VEHICLE_LINEAR_MOTOR_OFFSET, + VEHICLE_VECTOR_PARAM_5, + VEHICLE_VECTOR_PARAM_6, + VEHICLE_VECTOR_PARAM_7, + + // floating point parameters + VEHICLE_HOVER_HEIGHT, + VEHICLE_HOVER_EFFICIENCY, + VEHICLE_HOVER_TIMESCALE, + VEHICLE_BUOYANCY, + + VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, + VEHICLE_LINEAR_DEFLECTION_TIMESCALE, + VEHICLE_LINEAR_MOTOR_TIMESCALE, + VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, + + VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, + VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, + VEHICLE_ANGULAR_MOTOR_TIMESCALE, + VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, + + VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, + VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, + + VEHICLE_BANKING_EFFICIENCY, + VEHICLE_BANKING_MIX, + VEHICLE_BANKING_TIMESCALE, + + VEHICLE_FLOAT_PARAM_17, + VEHICLE_FLOAT_PARAM_18, + VEHICLE_FLOAT_PARAM_19, + + // rotation parameters + VEHICLE_REFERENCE_FRAME, + VEHICLE_ROTATION_PARAM_1, + VEHICLE_ROTATION_PARAM_2, + VEHICLE_ROTATION_PARAM_3, } EVehicleParam; @@ -104,20 +104,20 @@ typedef enum e_vehicle_param const U32 VEHICLE_FLAG_NO_DEFLECTION_UP = 1 << 0; // spring-loads roll only -const U32 VEHICLE_FLAG_LIMIT_ROLL_ONLY = 1 << 1; +const U32 VEHICLE_FLAG_LIMIT_ROLL_ONLY = 1 << 1; // hover flags -const U32 VEHICLE_FLAG_HOVER_WATER_ONLY = 1 << 2; -const U32 VEHICLE_FLAG_HOVER_TERRAIN_ONLY = 1 << 3; -const U32 VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT = 1 << 4; -const U32 VEHICLE_FLAG_HOVER_UP_ONLY = 1 << 5; +const U32 VEHICLE_FLAG_HOVER_WATER_ONLY = 1 << 2; +const U32 VEHICLE_FLAG_HOVER_TERRAIN_ONLY = 1 << 3; +const U32 VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT = 1 << 4; +const U32 VEHICLE_FLAG_HOVER_UP_ONLY = 1 << 5; -// caps world-z component of linear motor to prevent +// caps world-z component of linear motor to prevent // climbing up into the sky -const U32 VEHICLE_FLAG_LIMIT_MOTOR_UP = 1 << 6; +const U32 VEHICLE_FLAG_LIMIT_MOTOR_UP = 1 << 6; -const U32 VEHICLE_FLAG_MOUSELOOK_STEER = 1 << 7; -const U32 VEHICLE_FLAG_MOUSELOOK_BANK = 1 << 8; -const U32 VEHICLE_FLAG_CAMERA_DECOUPLED = 1 << 9; +const U32 VEHICLE_FLAG_MOUSELOOK_STEER = 1 << 7; +const U32 VEHICLE_FLAG_MOUSELOOK_BANK = 1 << 8; +const U32 VEHICLE_FLAG_CAMERA_DECOUPLED = 1 << 9; #endif diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp index 58e85b49b4..358c8be671 100644 --- a/indra/llmessage/llxfer.cpp +++ b/indra/llmessage/llxfer.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llxfer.cpp * @brief implementation of LLXfer class for a single xfer. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,133 +43,133 @@ const U32 LLXfer::XFER_MEM = 3; LLXfer::LLXfer (S32 chunk_size) { - init(chunk_size); + init(chunk_size); } /////////////////////////////////////////////////////////// LLXfer::~LLXfer () { - cleanup(); + cleanup(); } /////////////////////////////////////////////////////////// void LLXfer::init (S32 chunk_size) { - mID = 0; - - mPacketNum = -1; // there's a preincrement before sending the zeroth packet - mXferSize = 0; - - mStatus = e_LL_XFER_UNINITIALIZED; - mWaitingForACK = false; - - mCallback = NULL; - mCallbackDataHandle = NULL; - mCallbackResult = 0; - - mBufferContainsEOF = false; - mBuffer = NULL; - mBufferLength = 0; - mBufferStartOffset = 0; - - mRetries = 0; - - if (chunk_size < 1) - { - chunk_size = LL_XFER_CHUNK_SIZE; - } - mChunkSize = chunk_size; + mID = 0; + + mPacketNum = -1; // there's a preincrement before sending the zeroth packet + mXferSize = 0; + + mStatus = e_LL_XFER_UNINITIALIZED; + mWaitingForACK = false; + + mCallback = NULL; + mCallbackDataHandle = NULL; + mCallbackResult = 0; + + mBufferContainsEOF = false; + mBuffer = NULL; + mBufferLength = 0; + mBufferStartOffset = 0; + + mRetries = 0; + + if (chunk_size < 1) + { + chunk_size = LL_XFER_CHUNK_SIZE; + } + mChunkSize = chunk_size; } - + /////////////////////////////////////////////////////////// void LLXfer::cleanup () { - if (mBuffer) - { - delete[] mBuffer; - mBuffer = NULL; - } + if (mBuffer) + { + delete[] mBuffer; + mBuffer = NULL; + } } /////////////////////////////////////////////////////////// S32 LLXfer::startSend (U64 xfer_id, const LLHost &remote_host) { - LL_WARNS("Xfer") << "unexpected call to base class LLXfer::startSend for " << getFileName() << LL_ENDL; - return (-1); + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::startSend for " << getFileName() << LL_ENDL; + return (-1); } /////////////////////////////////////////////////////////// void LLXfer::closeFileHandle() { - LL_WARNS("Xfer") << "unexpected call to base class LLXfer::closeFileHandle for " << getFileName() << LL_ENDL; + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::closeFileHandle for " << getFileName() << LL_ENDL; } /////////////////////////////////////////////////////////// S32 LLXfer::reopenFileHandle() { - LL_WARNS("Xfer") << "unexpected call to base class LLXfer::reopenFileHandle for " << getFileName() << LL_ENDL; - return (-1); + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::reopenFileHandle for " << getFileName() << LL_ENDL; + return (-1); } /////////////////////////////////////////////////////////// void LLXfer::setXferSize (S32 xfer_size) -{ - mXferSize = xfer_size; -// cout << "starting transfer of size: " << xfer_size << endl; +{ + mXferSize = xfer_size; +// cout << "starting transfer of size: " << xfer_size << endl; } /////////////////////////////////////////////////////////// S32 LLXfer::startDownload() { - LL_WARNS("Xfer") << "undifferentiated LLXfer::startDownload for " << getFileName() - << LL_ENDL; - return (-1); + LL_WARNS("Xfer") << "undifferentiated LLXfer::startDownload for " << getFileName() + << LL_ENDL; + return (-1); } /////////////////////////////////////////////////////////// S32 LLXfer::receiveData (char *datap, S32 data_size) { - S32 retval = 0; - - if (((S32) mBufferLength + data_size) > getMaxBufferSize()) - { // Write existing data to disk if it's larger than the buffer size - retval = flush(); - } - - if (!retval) - { - if (datap != NULL) - { // Append new data to mBuffer - memcpy(&mBuffer[mBufferLength],datap,data_size); /*Flawfinder: ignore*/ - mBufferLength += data_size; - } - else - { - LL_ERRS("Xfer") << "NULL data passed in receiveData" << LL_ENDL; - } - } - - return (retval); + S32 retval = 0; + + if (((S32) mBufferLength + data_size) > getMaxBufferSize()) + { // Write existing data to disk if it's larger than the buffer size + retval = flush(); + } + + if (!retval) + { + if (datap != NULL) + { // Append new data to mBuffer + memcpy(&mBuffer[mBufferLength],datap,data_size); /*Flawfinder: ignore*/ + mBufferLength += data_size; + } + else + { + LL_ERRS("Xfer") << "NULL data passed in receiveData" << LL_ENDL; + } + } + + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer::flush() { - // only files have somewhere to flush to - // if we get called with a flush it means we've blown past our - // allocated buffer size + // only files have somewhere to flush to + // if we get called with a flush it means we've blown past our + // allocated buffer size - return (-1); + return (-1); } @@ -177,212 +177,212 @@ S32 LLXfer::flush() S32 LLXfer::suck(S32 start_position) { - LL_WARNS("Xfer") << "Attempted to send a packet outside the buffer bounds in LLXfer::suck()" << LL_ENDL; - return (-1); + LL_WARNS("Xfer") << "Attempted to send a packet outside the buffer bounds in LLXfer::suck()" << LL_ENDL; + return (-1); } /////////////////////////////////////////////////////////// void LLXfer::sendPacket(S32 packet_num) { - char fdata_buf[LL_XFER_LARGE_PAYLOAD+4]; /* Flawfinder: ignore */ - S32 fdata_size = mChunkSize; - bool last_packet = false; - S32 num_copy = 0; - - // if the desired packet is not in our current buffered excerpt from the file. . . - if (((U32)packet_num*fdata_size < mBufferStartOffset) - || ((U32)llmin((U32)mXferSize,(U32)((U32)(packet_num+1)*fdata_size)) > mBufferStartOffset + mBufferLength)) - - { - if (suck(packet_num*fdata_size)) // returns non-zero on failure - { - abort(LL_ERR_EOF); - return; - } - } - - S32 desired_read_position = 0; - - desired_read_position = packet_num * fdata_size - mBufferStartOffset; - - fdata_size = llmin((S32)mBufferLength-desired_read_position, mChunkSize); - - if (fdata_size < 0) - { - LL_WARNS("Xfer") << "negative data size in xfer send, aborting" << LL_ENDL; - abort(LL_ERR_EOF); - return; - } - - if (((U32)(desired_read_position + fdata_size) >= (U32)mBufferLength) && (mBufferContainsEOF)) - { - last_packet = true; - } - - if (packet_num) - { - num_copy = llmin(fdata_size, (S32)sizeof(fdata_buf)); - num_copy = llmin(num_copy, (S32)(mBufferLength - desired_read_position)); - if (num_copy > 0) - { - memcpy(fdata_buf,&mBuffer[desired_read_position],num_copy); /*Flawfinder: ignore*/ - } - } - else - { - // if we're the first packet, encode size as an additional S32 - // at start of data. - num_copy = llmin(fdata_size, (S32)(sizeof(fdata_buf)-sizeof(S32))); - num_copy = llmin( - num_copy, - (S32)(mBufferLength - desired_read_position)); - if (num_copy > 0) - { - memcpy( /*Flawfinder: ignore*/ - fdata_buf + sizeof(S32), - &mBuffer[desired_read_position], - num_copy); - } - fdata_size += sizeof(S32); - htolememcpy(fdata_buf,&mXferSize, MVT_S32, sizeof(S32)); - } - - S32 encoded_packetnum = encodePacketNum(packet_num,last_packet); - - if (fdata_size) - { - // send the packet - gMessageSystem->newMessageFast(_PREHASH_SendXferPacket); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addU32Fast(_PREHASH_Packet, encoded_packetnum); - - gMessageSystem->nextBlockFast(_PREHASH_DataPacket); - gMessageSystem->addBinaryDataFast(_PREHASH_Data, &fdata_buf,fdata_size); - - S32 sent_something = gMessageSystem->sendMessage(mRemoteHost); - if (sent_something == 0) - { - abort(LL_ERR_CIRCUIT_GONE); - return; - } - - ACKTimer.reset(); - mWaitingForACK = true; - } - if (last_packet) - { - mStatus = e_LL_XFER_COMPLETE; - } - else - { - mStatus = e_LL_XFER_IN_PROGRESS; - } + char fdata_buf[LL_XFER_LARGE_PAYLOAD+4]; /* Flawfinder: ignore */ + S32 fdata_size = mChunkSize; + bool last_packet = false; + S32 num_copy = 0; + + // if the desired packet is not in our current buffered excerpt from the file. . . + if (((U32)packet_num*fdata_size < mBufferStartOffset) + || ((U32)llmin((U32)mXferSize,(U32)((U32)(packet_num+1)*fdata_size)) > mBufferStartOffset + mBufferLength)) + + { + if (suck(packet_num*fdata_size)) // returns non-zero on failure + { + abort(LL_ERR_EOF); + return; + } + } + + S32 desired_read_position = 0; + + desired_read_position = packet_num * fdata_size - mBufferStartOffset; + + fdata_size = llmin((S32)mBufferLength-desired_read_position, mChunkSize); + + if (fdata_size < 0) + { + LL_WARNS("Xfer") << "negative data size in xfer send, aborting" << LL_ENDL; + abort(LL_ERR_EOF); + return; + } + + if (((U32)(desired_read_position + fdata_size) >= (U32)mBufferLength) && (mBufferContainsEOF)) + { + last_packet = true; + } + + if (packet_num) + { + num_copy = llmin(fdata_size, (S32)sizeof(fdata_buf)); + num_copy = llmin(num_copy, (S32)(mBufferLength - desired_read_position)); + if (num_copy > 0) + { + memcpy(fdata_buf,&mBuffer[desired_read_position],num_copy); /*Flawfinder: ignore*/ + } + } + else + { + // if we're the first packet, encode size as an additional S32 + // at start of data. + num_copy = llmin(fdata_size, (S32)(sizeof(fdata_buf)-sizeof(S32))); + num_copy = llmin( + num_copy, + (S32)(mBufferLength - desired_read_position)); + if (num_copy > 0) + { + memcpy( /*Flawfinder: ignore*/ + fdata_buf + sizeof(S32), + &mBuffer[desired_read_position], + num_copy); + } + fdata_size += sizeof(S32); + htolememcpy(fdata_buf,&mXferSize, MVT_S32, sizeof(S32)); + } + + S32 encoded_packetnum = encodePacketNum(packet_num,last_packet); + + if (fdata_size) + { + // send the packet + gMessageSystem->newMessageFast(_PREHASH_SendXferPacket); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addU32Fast(_PREHASH_Packet, encoded_packetnum); + + gMessageSystem->nextBlockFast(_PREHASH_DataPacket); + gMessageSystem->addBinaryDataFast(_PREHASH_Data, &fdata_buf,fdata_size); + + S32 sent_something = gMessageSystem->sendMessage(mRemoteHost); + if (sent_something == 0) + { + abort(LL_ERR_CIRCUIT_GONE); + return; + } + + ACKTimer.reset(); + mWaitingForACK = true; + } + if (last_packet) + { + mStatus = e_LL_XFER_COMPLETE; + } + else + { + mStatus = e_LL_XFER_IN_PROGRESS; + } } /////////////////////////////////////////////////////////// void LLXfer::sendNextPacket() { - mRetries = 0; - sendPacket(++mPacketNum); + mRetries = 0; + sendPacket(++mPacketNum); } /////////////////////////////////////////////////////////// void LLXfer::resendLastPacket() { - mRetries++; - sendPacket(mPacketNum); + mRetries++; + sendPacket(mPacketNum); } /////////////////////////////////////////////////////////// S32 LLXfer::processEOF() { - S32 retval = 0; - - mStatus = e_LL_XFER_COMPLETE; - - if (LL_ERR_NOERR == mCallbackResult) - { - LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " complete: " << getFileName() - << LL_ENDL; - } - else - { - LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " failed, code " - << mCallbackResult << ": " << getFileName() << LL_ENDL; - } - - if (mCallback) - { - mCallback(mCallbackDataHandle,mCallbackResult, LLExtStat::NONE); - } - - return(retval); + S32 retval = 0; + + mStatus = e_LL_XFER_COMPLETE; + + if (LL_ERR_NOERR == mCallbackResult) + { + LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " complete: " << getFileName() + << LL_ENDL; + } + else + { + LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " failed, code " + << mCallbackResult << ": " << getFileName() << LL_ENDL; + } + + if (mCallback) + { + mCallback(mCallbackDataHandle,mCallbackResult, LLExtStat::NONE); + } + + return(retval); } /////////////////////////////////////////////////////////// S32 LLXfer::encodePacketNum(S32 packet_num, bool is_EOF) { - if (is_EOF) - { - packet_num |= 0x80000000; - } - return packet_num; + if (is_EOF) + { + packet_num |= 0x80000000; + } + return packet_num; } /////////////////////////////////////////////////////////// void LLXfer::abort (S32 result_code) { - mCallbackResult = result_code; + mCallbackResult = result_code; - LL_INFOS("Xfer") << "Aborting xfer from " << mRemoteHost << " named " << getFileName() - << " - error: " << result_code << LL_ENDL; + LL_INFOS("Xfer") << "Aborting xfer from " << mRemoteHost << " named " << getFileName() + << " - error: " << result_code << LL_ENDL; - if (result_code != LL_ERR_CIRCUIT_GONE) - { - gMessageSystem->newMessageFast(_PREHASH_AbortXfer); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addS32Fast(_PREHASH_Result, result_code); + if (result_code != LL_ERR_CIRCUIT_GONE) + { + gMessageSystem->newMessageFast(_PREHASH_AbortXfer); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addS32Fast(_PREHASH_Result, result_code); - gMessageSystem->sendMessage(mRemoteHost); - } + gMessageSystem->sendMessage(mRemoteHost); + } - mStatus = e_LL_XFER_ABORTED; + mStatus = e_LL_XFER_ABORTED; } /////////////////////////////////////////////////////////// -std::string LLXfer::getFileName() +std::string LLXfer::getFileName() { - return U64_to_str(mID); + return U64_to_str(mID); } /////////////////////////////////////////////////////////// U32 LLXfer::getXferTypeTag() { - return 0; + return 0; } /////////////////////////////////////////////////////////// S32 LLXfer::getMaxBufferSize () { - return(mXferSize); + return(mXferSize); } std::ostream& operator<< (std::ostream& os, LLXfer &hh) { - os << hh.getFileName() ; - return os; + os << hh.getFileName() ; + return os; } diff --git a/indra/llmessage/llxfer.h b/indra/llmessage/llxfer.h index 6b236df1a5..9a0901a84a 100644 --- a/indra/llmessage/llxfer.h +++ b/indra/llmessage/llxfer.h @@ -1,25 +1,25 @@ -/** +/** * @file llxfer.h * @brief definition of LLXfer class for a single xfer * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,13 +38,13 @@ const int LL_ERR_CANNOT_OPEN_FILE = -42; const int LL_ERR_EOF = -39; typedef enum ELLXferStatus { - e_LL_XFER_UNINITIALIZED, - e_LL_XFER_REGISTERED, // a buffer which has been registered as available for a request - e_LL_XFER_PENDING, // a transfer which has been requested but is waiting for a free slot - e_LL_XFER_IN_PROGRESS, - e_LL_XFER_COMPLETE, - e_LL_XFER_ABORTED, - e_LL_XFER_NONE + e_LL_XFER_UNINITIALIZED, + e_LL_XFER_REGISTERED, // a buffer which has been registered as available for a request + e_LL_XFER_PENDING, // a transfer which has been requested but is waiting for a free slot + e_LL_XFER_IN_PROGRESS, + e_LL_XFER_COMPLETE, + e_LL_XFER_ABORTED, + e_LL_XFER_NONE } ELLXferStatus; class LLXfer @@ -52,66 +52,66 @@ class LLXfer private: protected: S32 mChunkSize; - + public: - U64 mID; - S32 mPacketNum; + U64 mID; + S32 mPacketNum; - LLHost mRemoteHost; - S32 mXferSize; + LLHost mRemoteHost; + S32 mXferSize; - char *mBuffer; - U32 mBufferLength; // Size of valid data, not actual allocated buffer size - U32 mBufferStartOffset; - bool mBufferContainsEOF; + char *mBuffer; + U32 mBufferLength; // Size of valid data, not actual allocated buffer size + U32 mBufferStartOffset; + bool mBufferContainsEOF; - ELLXferStatus mStatus; + ELLXferStatus mStatus; - bool mWaitingForACK; + bool mWaitingForACK; - void (*mCallback)(void **,S32,LLExtStat); - void **mCallbackDataHandle; - S32 mCallbackResult; + void (*mCallback)(void **,S32,LLExtStat); + void **mCallbackDataHandle; + S32 mCallbackResult; - LLTimer ACKTimer; - S32 mRetries; + LLTimer ACKTimer; + S32 mRetries; - static const U32 XFER_FILE; - static const U32 XFER_VFILE; - static const U32 XFER_MEM; + static const U32 XFER_FILE; + static const U32 XFER_VFILE; + static const U32 XFER_MEM; private: protected: public: - LLXfer (S32 chunk_size); - virtual ~LLXfer(); - - void init(S32 chunk_size); - virtual void cleanup(); - - virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); - virtual void closeFileHandle(); - virtual S32 reopenFileHandle(); - virtual void sendPacket(S32 packet_num); - virtual void sendNextPacket(); - virtual void resendLastPacket(); - virtual S32 processEOF(); - virtual S32 startDownload(); - virtual S32 receiveData (char *datap, S32 data_size); - virtual void abort(S32); - - virtual S32 suck(S32 start_position); - virtual S32 flush(); - - virtual S32 encodePacketNum(S32 packet_num, bool is_eof); - virtual void setXferSize (S32 data_size); - virtual S32 getMaxBufferSize(); - - virtual std::string getFileName(); - - virtual U32 getXferTypeTag(); - - friend std::ostream& operator<< (std::ostream& os, LLXfer &hh); + LLXfer (S32 chunk_size); + virtual ~LLXfer(); + + void init(S32 chunk_size); + virtual void cleanup(); + + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); + virtual void sendPacket(S32 packet_num); + virtual void sendNextPacket(); + virtual void resendLastPacket(); + virtual S32 processEOF(); + virtual S32 startDownload(); + virtual S32 receiveData (char *datap, S32 data_size); + virtual void abort(S32); + + virtual S32 suck(S32 start_position); + virtual S32 flush(); + + virtual S32 encodePacketNum(S32 packet_num, bool is_eof); + virtual void setXferSize (S32 data_size); + virtual S32 getMaxBufferSize(); + + virtual std::string getFileName(); + + virtual U32 getXferTypeTag(); + + friend std::ostream& operator<< (std::ostream& os, LLXfer &hh); }; diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp index ef2915ede3..ad15d5969b 100644 --- a/indra/llmessage/llxfer_file.cpp +++ b/indra/llmessage/llxfer_file.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llxfer_file.cpp * @brief implementation of LLXfer_File class for a single xfer (file) * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,20 +49,20 @@ S32 copy_file(const std::string& from, const std::string& to); LLXfer_File::LLXfer_File (S32 chunk_size) : LLXfer(chunk_size) { - init(LLStringUtil::null, false, chunk_size); + init(LLStringUtil::null, false, chunk_size); } LLXfer_File::LLXfer_File (const std::string& local_filename, bool delete_local_on_completion, S32 chunk_size) : LLXfer(chunk_size) { - init(local_filename, delete_local_on_completion, chunk_size); + init(local_filename, delete_local_on_completion, chunk_size); } /////////////////////////////////////////////////////////// LLXfer_File::~LLXfer_File () { - cleanup(); + cleanup(); } /////////////////////////////////////////////////////////// @@ -70,197 +70,197 @@ LLXfer_File::~LLXfer_File () void LLXfer_File::init (const std::string& local_filename, bool delete_local_on_completion, S32 chunk_size) { - mFp = NULL; - mLocalFilename.clear(); - mRemoteFilename.clear(); - mRemotePath = LL_PATH_NONE; - mTempFilename.clear(); - mDeleteLocalOnCompletion = false; - mDeleteRemoteOnCompletion = false; - - if (!local_filename.empty()) - { - mLocalFilename = local_filename.substr(0,LL_MAX_PATH-1); - - // You can only automatically delete .tmp file as a safeguard against nasty messages. - std::string exten = mLocalFilename.substr(mLocalFilename.length()-4, 4); - mDeleteLocalOnCompletion = (delete_local_on_completion && exten == ".tmp"); - } + mFp = NULL; + mLocalFilename.clear(); + mRemoteFilename.clear(); + mRemotePath = LL_PATH_NONE; + mTempFilename.clear(); + mDeleteLocalOnCompletion = false; + mDeleteRemoteOnCompletion = false; + + if (!local_filename.empty()) + { + mLocalFilename = local_filename.substr(0,LL_MAX_PATH-1); + + // You can only automatically delete .tmp file as a safeguard against nasty messages. + std::string exten = mLocalFilename.substr(mLocalFilename.length()-4, 4); + mDeleteLocalOnCompletion = (delete_local_on_completion && exten == ".tmp"); + } } - + /////////////////////////////////////////////////////////// void LLXfer_File::cleanup () { - if (mFp) - { - fclose(mFp); - mFp = NULL; - } - - LLFile::remove(mTempFilename, ENOENT); - - if (mDeleteLocalOnCompletion) - { - LL_DEBUGS("Xfer") << "Removing file: " << mLocalFilename << LL_ENDL; - LLFile::remove(mLocalFilename, ENOENT); - } - else - { - LL_DEBUGS("Xfer") << "Keeping local file: " << mLocalFilename << LL_ENDL; - } - - LLXfer::cleanup(); + if (mFp) + { + fclose(mFp); + mFp = NULL; + } + + LLFile::remove(mTempFilename, ENOENT); + + if (mDeleteLocalOnCompletion) + { + LL_DEBUGS("Xfer") << "Removing file: " << mLocalFilename << LL_ENDL; + LLFile::remove(mLocalFilename, ENOENT); + } + else + { + LL_DEBUGS("Xfer") << "Keeping local file: " << mLocalFilename << LL_ENDL; + } + + LLXfer::cleanup(); } /////////////////////////////////////////////////////////// S32 LLXfer_File::initializeRequest(U64 xfer_id, - const std::string& local_filename, - const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - bool delete_remote_on_completion, - void (*callback)(void**,S32,LLExtStat), - void** user_data) + const std::string& local_filename, + const std::string& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + bool delete_remote_on_completion, + void (*callback)(void**,S32,LLExtStat), + void** user_data) { - S32 retval = 0; // presume success - - mID = xfer_id; - mLocalFilename = local_filename; - mRemoteFilename = remote_filename; - mRemotePath = remote_path; - mRemoteHost = remote_host; - mDeleteRemoteOnCompletion = delete_remote_on_completion; + S32 retval = 0; // presume success + + mID = xfer_id; + mLocalFilename = local_filename; + mRemoteFilename = remote_filename; + mRemotePath = remote_path; + mRemoteHost = remote_host; + mDeleteRemoteOnCompletion = delete_remote_on_completion; - mTempFilename = gDirUtilp->getTempFilename(); + mTempFilename = gDirUtilp->getTempFilename(); - mCallback = callback; - mCallbackDataHandle = user_data; - mCallbackResult = LL_ERR_NOERR; + mCallback = callback; + mCallbackDataHandle = user_data; + mCallbackResult = LL_ERR_NOERR; - LL_INFOS("Xfer") << "Requesting xfer from " << remote_host << " for file: " << mLocalFilename << LL_ENDL; + LL_INFOS("Xfer") << "Requesting xfer from " << remote_host << " for file: " << mLocalFilename << LL_ENDL; - if (mBuffer) - { - delete(mBuffer); - mBuffer = NULL; - } + if (mBuffer) + { + delete(mBuffer); + mBuffer = NULL; + } - mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; - mBufferLength = 0; + mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; + mBufferLength = 0; - mPacketNum = 0; + mPacketNum = 0; - mStatus = e_LL_XFER_PENDING; - return retval; + mStatus = e_LL_XFER_PENDING; + return retval; } /////////////////////////////////////////////////////////// S32 LLXfer_File::startDownload() { - S32 retval = 0; // presume success - mFp = LLFile::fopen(mTempFilename,"w+b"); /* Flawfinder : ignore */ - if (mFp) - { - fclose(mFp); - mFp = NULL; - - // tbd - is it premature to send this message if the queue is backed up? - gMessageSystem->newMessageFast(_PREHASH_RequestXfer); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addStringFast(_PREHASH_Filename, mRemoteFilename); - gMessageSystem->addU8("FilePath", (U8) mRemotePath); - gMessageSystem->addBOOL("DeleteOnCompletion", mDeleteRemoteOnCompletion); - gMessageSystem->addBOOL("UseBigPackets", mChunkSize == LL_XFER_LARGE_PAYLOAD); - gMessageSystem->addUUIDFast(_PREHASH_VFileID, LLUUID::null); - gMessageSystem->addS16Fast(_PREHASH_VFileType, -1); - - gMessageSystem->sendReliable(mRemoteHost); - mStatus = e_LL_XFER_IN_PROGRESS; - } - else - { - LL_WARNS("Xfer") << "Couldn't create file to be received!" << LL_ENDL; - retval = -1; - } - - return (retval); + S32 retval = 0; // presume success + mFp = LLFile::fopen(mTempFilename,"w+b"); /* Flawfinder : ignore */ + if (mFp) + { + fclose(mFp); + mFp = NULL; + + // tbd - is it premature to send this message if the queue is backed up? + gMessageSystem->newMessageFast(_PREHASH_RequestXfer); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addStringFast(_PREHASH_Filename, mRemoteFilename); + gMessageSystem->addU8("FilePath", (U8) mRemotePath); + gMessageSystem->addBOOL("DeleteOnCompletion", mDeleteRemoteOnCompletion); + gMessageSystem->addBOOL("UseBigPackets", mChunkSize == LL_XFER_LARGE_PAYLOAD); + gMessageSystem->addUUIDFast(_PREHASH_VFileID, LLUUID::null); + gMessageSystem->addS16Fast(_PREHASH_VFileType, -1); + + gMessageSystem->sendReliable(mRemoteHost); + mStatus = e_LL_XFER_IN_PROGRESS; + } + else + { + LL_WARNS("Xfer") << "Couldn't create file to be received!" << LL_ENDL; + retval = -1; + } + + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host) { - S32 retval = LL_ERR_NOERR; // presume success - + S32 retval = LL_ERR_NOERR; // presume success + mRemoteHost = remote_host; - mID = xfer_id; - mPacketNum = -1; - -// cout << "Sending file: " << mLocalFilename << endl; - - delete [] mBuffer; - mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; - - mBufferLength = 0; - mBufferStartOffset = 0; - - // We leave the file open, assuming we'll start reading and sending soon - mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ - if (mFp) - { - fseek(mFp,0,SEEK_END); - - S32 file_size = ftell(mFp); - if (file_size <= 0) - { - return LL_ERR_FILE_EMPTY; - } - setXferSize(file_size); - - fseek(mFp,0,SEEK_SET); - } - else - { - LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found." << LL_ENDL; - return (LL_ERR_FILE_NOT_FOUND); - } - - mStatus = e_LL_XFER_PENDING; - - return (retval); + mID = xfer_id; + mPacketNum = -1; + +// cout << "Sending file: " << mLocalFilename << endl; + + delete [] mBuffer; + mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; + + mBufferLength = 0; + mBufferStartOffset = 0; + + // We leave the file open, assuming we'll start reading and sending soon + mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ + if (mFp) + { + fseek(mFp,0,SEEK_END); + + S32 file_size = ftell(mFp); + if (file_size <= 0) + { + return LL_ERR_FILE_EMPTY; + } + setXferSize(file_size); + + fseek(mFp,0,SEEK_SET); + } + else + { + LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found." << LL_ENDL; + return (LL_ERR_FILE_NOT_FOUND); + } + + mStatus = e_LL_XFER_PENDING; + + return (retval); } /////////////////////////////////////////////////////////// void LLXfer_File::closeFileHandle() { - if (mFp) - { - fclose(mFp); - mFp = NULL; - } + if (mFp) + { + fclose(mFp); + mFp = NULL; + } } /////////////////////////////////////////////////////////// S32 LLXfer_File::reopenFileHandle() { - S32 retval = LL_ERR_NOERR; // presume success - - if (mFp == NULL) - { - mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ - if (mFp == NULL) - { - LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL; - retval = LL_ERR_FILE_NOT_FOUND; - } - } - - return retval; + S32 retval = LL_ERR_NOERR; // presume success + + if (mFp == NULL) + { + mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ + if (mFp == NULL) + { + LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + } + + return retval; } @@ -268,168 +268,168 @@ S32 LLXfer_File::reopenFileHandle() S32 LLXfer_File::getMaxBufferSize () { - return(LL_MAX_XFER_FILE_BUFFER); + return(LL_MAX_XFER_FILE_BUFFER); } /////////////////////////////////////////////////////////// S32 LLXfer_File::suck(S32 start_position) { - S32 retval = 0; - - if (mFp) - { - // grab a buffer from the right place in the file - fseek (mFp,start_position,SEEK_SET); - - mBufferLength = (U32)fread(mBuffer,1,LL_MAX_XFER_FILE_BUFFER,mFp); - mBufferStartOffset = start_position; - - if (feof(mFp)) - { - mBufferContainsEOF = true; - } - else - { - mBufferContainsEOF = false; - } - } - else - { - retval = -1; - } - - return (retval); + S32 retval = 0; + + if (mFp) + { + // grab a buffer from the right place in the file + fseek (mFp,start_position,SEEK_SET); + + mBufferLength = (U32)fread(mBuffer,1,LL_MAX_XFER_FILE_BUFFER,mFp); + mBufferStartOffset = start_position; + + if (feof(mFp)) + { + mBufferContainsEOF = true; + } + else + { + mBufferContainsEOF = false; + } + } + else + { + retval = -1; + } + + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_File::flush() { - S32 retval = 0; - if (mBufferLength) - { - if (mFp) - { - LL_ERRS("Xfer") << "Overwriting open file pointer!" << LL_ENDL; - } - mFp = LLFile::fopen(mTempFilename,"a+b"); /* Flawfinder : ignore */ - - if (mFp) - { - S32 write_size = fwrite(mBuffer,1,mBufferLength,mFp); - if (write_size != mBufferLength) - { - LL_WARNS("Xfer") << "Non-matching write size, requested " << mBufferLength - << " but wrote " << write_size - << LL_ENDL; - } - -// LL_INFOS("Xfer") << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL; - fclose(mFp); - mFp = NULL; - - mBufferLength = 0; - } - else - { - LL_WARNS("Xfer") << "LLXfer_File::flush() unable to open " << mTempFilename << " for writing!" << LL_ENDL; - retval = LL_ERR_CANNOT_OPEN_FILE; - } - } - return (retval); + S32 retval = 0; + if (mBufferLength) + { + if (mFp) + { + LL_ERRS("Xfer") << "Overwriting open file pointer!" << LL_ENDL; + } + mFp = LLFile::fopen(mTempFilename,"a+b"); /* Flawfinder : ignore */ + + if (mFp) + { + S32 write_size = fwrite(mBuffer,1,mBufferLength,mFp); + if (write_size != mBufferLength) + { + LL_WARNS("Xfer") << "Non-matching write size, requested " << mBufferLength + << " but wrote " << write_size + << LL_ENDL; + } + +// LL_INFOS("Xfer") << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL; + fclose(mFp); + mFp = NULL; + + mBufferLength = 0; + } + else + { + LL_WARNS("Xfer") << "LLXfer_File::flush() unable to open " << mTempFilename << " for writing!" << LL_ENDL; + retval = LL_ERR_CANNOT_OPEN_FILE; + } + } + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_File::processEOF() { - S32 retval = 0; - mStatus = e_LL_XFER_COMPLETE; + S32 retval = 0; + mStatus = e_LL_XFER_COMPLETE; - S32 flushval = flush(); + S32 flushval = flush(); - // If we have no other errors, our error becomes the error generated by - // flush. - if (!mCallbackResult) - { - mCallbackResult = flushval; - } + // If we have no other errors, our error becomes the error generated by + // flush. + if (!mCallbackResult) + { + mCallbackResult = flushval; + } - LLFile::remove(mLocalFilename, ENOENT); + LLFile::remove(mLocalFilename, ENOENT); - if (!mCallbackResult) - { - if (LLFile::rename(mTempFilename,mLocalFilename)) - { + if (!mCallbackResult) + { + if (LLFile::rename(mTempFilename,mLocalFilename)) + { #if !LL_WINDOWS - S32 error_number = errno; - LL_INFOS("Xfer") << "Rename failure (" << error_number << ") - " - << mTempFilename << " to " << mLocalFilename << LL_ENDL; - if(EXDEV == error_number) - { - if(copy_file(mTempFilename, mLocalFilename) == 0) - { - LL_INFOS("Xfer") << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL; - unlink(mTempFilename.c_str()); - } - else - { - LL_WARNS("Xfer") << "Copy failure - " << mTempFilename << " to " - << mLocalFilename << LL_ENDL; - } - } - else - { - //LLFILE* fp = LLFile::fopen(mTempFilename, "r"); - //LL_WARNS() << "File " << mTempFilename << " does " - // << (!fp ? "not" : "" ) << " exit." << LL_ENDL; - //if(fp) fclose(fp); - //fp = LLFile::fopen(mLocalFilename, "r"); - //LL_WARNS() << "File " << mLocalFilename << " does " - // << (!fp ? "not" : "" ) << " exit." << LL_ENDL; - //if(fp) fclose(fp); - LL_WARNS("Xfer") << "Rename fatally failed, can only handle EXDEV (" - << EXDEV << ")" << LL_ENDL; - } + S32 error_number = errno; + LL_INFOS("Xfer") << "Rename failure (" << error_number << ") - " + << mTempFilename << " to " << mLocalFilename << LL_ENDL; + if(EXDEV == error_number) + { + if(copy_file(mTempFilename, mLocalFilename) == 0) + { + LL_INFOS("Xfer") << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL; + unlink(mTempFilename.c_str()); + } + else + { + LL_WARNS("Xfer") << "Copy failure - " << mTempFilename << " to " + << mLocalFilename << LL_ENDL; + } + } + else + { + //LLFILE* fp = LLFile::fopen(mTempFilename, "r"); + //LL_WARNS() << "File " << mTempFilename << " does " + // << (!fp ? "not" : "" ) << " exit." << LL_ENDL; + //if(fp) fclose(fp); + //fp = LLFile::fopen(mLocalFilename, "r"); + //LL_WARNS() << "File " << mLocalFilename << " does " + // << (!fp ? "not" : "" ) << " exit." << LL_ENDL; + //if(fp) fclose(fp); + LL_WARNS("Xfer") << "Rename fatally failed, can only handle EXDEV (" + << EXDEV << ")" << LL_ENDL; + } #else - LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to " - << mLocalFilename << LL_ENDL; + LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to " + << mLocalFilename << LL_ENDL; #endif - } - } + } + } - if (mFp) - { - fclose(mFp); - mFp = NULL; - } + if (mFp) + { + fclose(mFp); + mFp = NULL; + } - retval = LLXfer::processEOF(); + retval = LLXfer::processEOF(); - return(retval); + return(retval); } /////////////////////////////////////////////////////////// bool LLXfer_File::matchesLocalFilename(const std::string& filename) { - return (filename == mLocalFilename); + return (filename == mLocalFilename); } /////////////////////////////////////////////////////////// bool LLXfer_File::matchesRemoteFilename(const std::string& filename, ELLPath remote_path) { - return ((filename == mRemoteFilename) && (remote_path == mRemotePath)); + return ((filename == mRemoteFilename) && (remote_path == mRemotePath)); } /////////////////////////////////////////////////////////// -std::string LLXfer_File::getFileName() +std::string LLXfer_File::getFileName() { - return mLocalFilename; + return mLocalFilename; } /////////////////////////////////////////////////////////// @@ -438,7 +438,7 @@ std::string LLXfer_File::getFileName() // as long as it's different from the other classes U32 LLXfer_File::getXferTypeTag() { - return LLXfer::XFER_FILE; + return LLXfer::XFER_FILE; } /////////////////////////////////////////////////////////// @@ -451,25 +451,25 @@ U32 LLXfer_File::getXferTypeTag() // production environment. S32 copy_file(const std::string& from, const std::string& to) { - S32 rv = 0; - LLFILE* in = LLFile::fopen(from, "rb"); /*Flawfinder: ignore*/ - LLFILE* out = LLFile::fopen(to, "wb"); /*Flawfinder: ignore*/ - if(in && out) - { - S32 read = 0; - const S32 COPY_BUFFER_SIZE = 16384; - U8 buffer[COPY_BUFFER_SIZE]; - while(((read = fread(buffer, 1, sizeof(buffer), in)) > 0) - && (fwrite(buffer, 1, read, out) == (U32)read)); /* Flawfinder : ignore */ - if(ferror(in) || ferror(out)) rv = -2; - } - else - { - rv = -1; - } - if(in) fclose(in); - if(out) fclose(out); - return rv; + S32 rv = 0; + LLFILE* in = LLFile::fopen(from, "rb"); /*Flawfinder: ignore*/ + LLFILE* out = LLFile::fopen(to, "wb"); /*Flawfinder: ignore*/ + if(in && out) + { + S32 read = 0; + const S32 COPY_BUFFER_SIZE = 16384; + U8 buffer[COPY_BUFFER_SIZE]; + while(((read = fread(buffer, 1, sizeof(buffer), in)) > 0) + && (fwrite(buffer, 1, read, out) == (U32)read)); /* Flawfinder : ignore */ + if(ferror(in) || ferror(out)) rv = -2; + } + else + { + rv = -1; + } + if(in) fclose(in); + if(out) fclose(out); + return rv; } #endif diff --git a/indra/llmessage/llxfer_file.h b/indra/llmessage/llxfer_file.h index 24bfd993bd..f30ef3eed6 100644 --- a/indra/llmessage/llxfer_file.h +++ b/indra/llmessage/llxfer_file.h @@ -1,25 +1,25 @@ -/** +/** * @file llxfer_file.h * @brief definition of LLXfer_File class for a single xfer_file. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,50 +33,50 @@ class LLXfer_File : public LLXfer { protected: - LLFILE *mFp; - std::string mLocalFilename; - std::string mRemoteFilename; - ELLPath mRemotePath; - std::string mTempFilename; + LLFILE *mFp; + std::string mLocalFilename; + std::string mRemoteFilename; + ELLPath mRemotePath; + std::string mTempFilename; - bool mDeleteLocalOnCompletion; - bool mDeleteRemoteOnCompletion; + bool mDeleteLocalOnCompletion; + bool mDeleteRemoteOnCompletion; public: - LLXfer_File (S32 chunk_size); - LLXfer_File (const std::string& local_filename, bool delete_local_on_completion, S32 chunk_size); - virtual ~LLXfer_File(); + LLXfer_File (S32 chunk_size); + LLXfer_File (const std::string& local_filename, bool delete_local_on_completion, S32 chunk_size); + virtual ~LLXfer_File(); - virtual void init(const std::string& local_filename, bool delete_local_on_completion, S32 chunk_size); - virtual void cleanup(); + virtual void init(const std::string& local_filename, bool delete_local_on_completion, S32 chunk_size); + virtual void cleanup(); - virtual S32 initializeRequest(U64 xfer_id, - const std::string& local_filename, - const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - bool delete_remote_on_completion, - void (*callback)(void**,S32,LLExtStat), - void** user_data); - virtual S32 startDownload(); + virtual S32 initializeRequest(U64 xfer_id, + const std::string& local_filename, + const std::string& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + bool delete_remote_on_completion, + void (*callback)(void**,S32,LLExtStat), + void** user_data); + virtual S32 startDownload(); - virtual S32 processEOF(); + virtual S32 processEOF(); - virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); - virtual void closeFileHandle(); - virtual S32 reopenFileHandle(); + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); - virtual S32 suck(S32 start_position); - virtual S32 flush(); + virtual S32 suck(S32 start_position); + virtual S32 flush(); - virtual bool matchesLocalFilename(const std::string& filename); - virtual bool matchesRemoteFilename(const std::string& filename, ELLPath remote_path); + virtual bool matchesLocalFilename(const std::string& filename); + virtual bool matchesRemoteFilename(const std::string& filename, ELLPath remote_path); - virtual S32 getMaxBufferSize(); + virtual S32 getMaxBufferSize(); - virtual U32 getXferTypeTag(); + virtual U32 getXferTypeTag(); - virtual std::string getFileName(); + virtual std::string getFileName(); }; #endif diff --git a/indra/llmessage/llxfer_mem.cpp b/indra/llmessage/llxfer_mem.cpp index 42afaad93b..b619974270 100644 --- a/indra/llmessage/llxfer_mem.cpp +++ b/indra/llmessage/llxfer_mem.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llxfer_mem.cpp * @brief implementation of LLXfer_Mem class for a single xfer * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,149 +36,149 @@ LLXfer_Mem::LLXfer_Mem () : LLXfer(-1) { - init(); + init(); } /////////////////////////////////////////////////////////// LLXfer_Mem::~LLXfer_Mem () { - cleanup(); + cleanup(); } /////////////////////////////////////////////////////////// void LLXfer_Mem::init () { - mRemoteFilename.clear(); - mRemotePath = LL_PATH_NONE; - mDeleteRemoteOnCompletion = false; + mRemoteFilename.clear(); + mRemotePath = LL_PATH_NONE; + mDeleteRemoteOnCompletion = false; } - + /////////////////////////////////////////////////////////// void LLXfer_Mem::cleanup () { - LLXfer::cleanup(); + LLXfer::cleanup(); } /////////////////////////////////////////////////////////// void LLXfer_Mem::setXferSize (S32 xfer_size) -{ - mXferSize = xfer_size; +{ + mXferSize = xfer_size; + + delete[] mBuffer; + mBuffer = new char[xfer_size]; - delete[] mBuffer; - mBuffer = new char[xfer_size]; - - mBufferLength = 0; - mBufferStartOffset = 0; - mBufferContainsEOF = true; + mBufferLength = 0; + mBufferStartOffset = 0; + mBufferContainsEOF = true; -// cout << "starting transfer of size: " << xfer_size << endl; +// cout << "starting transfer of size: " << xfer_size << endl; } /////////////////////////////////////////////////////////// S32 LLXfer_Mem::startSend (U64 xfer_id, const LLHost &remote_host) { - S32 retval = LL_ERR_NOERR; // presume success - - if (mXferSize <= 0) - { - return LL_ERR_FILE_EMPTY; - } + S32 retval = LL_ERR_NOERR; // presume success + + if (mXferSize <= 0) + { + return LL_ERR_FILE_EMPTY; + } mRemoteHost = remote_host; - mID = xfer_id; - mPacketNum = -1; + mID = xfer_id; + mPacketNum = -1; -// cout << "Sending file: " << getFileName() << endl; +// cout << "Sending file: " << getFileName() << endl; - mStatus = e_LL_XFER_PENDING; + mStatus = e_LL_XFER_PENDING; - return (retval); + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_Mem::processEOF() { - S32 retval = 0; + S32 retval = 0; - mStatus = e_LL_XFER_COMPLETE; + mStatus = e_LL_XFER_COMPLETE; - LL_INFOS() << "xfer complete: " << getFileName() << LL_ENDL; + LL_INFOS() << "xfer complete: " << getFileName() << LL_ENDL; - if (mCallback) - { - mCallback((void *)mBuffer,mBufferLength,mCallbackDataHandle,mCallbackResult, LLExtStat::NONE); - } + if (mCallback) + { + mCallback((void *)mBuffer,mBufferLength,mCallbackDataHandle,mCallbackResult, LLExtStat::NONE); + } - return(retval); + return(retval); } /////////////////////////////////////////////////////////// S32 LLXfer_Mem::initializeRequest(U64 xfer_id, - const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - bool delete_remote_on_completion, - void (*callback)(void*,S32,void**,S32,LLExtStat), - void** user_data) + const std::string& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + bool delete_remote_on_completion, + void (*callback)(void*,S32,void**,S32,LLExtStat), + void** user_data) { - S32 retval = 0; // presume success - - mRemoteHost = remote_host; + S32 retval = 0; // presume success + + mRemoteHost = remote_host; - // create a temp filename string using a GUID - mID = xfer_id; - mCallback = callback; - mCallbackDataHandle = user_data; - mCallbackResult = LL_ERR_NOERR; + // create a temp filename string using a GUID + mID = xfer_id; + mCallback = callback; + mCallbackDataHandle = user_data; + mCallbackResult = LL_ERR_NOERR; - mRemoteFilename = remote_filename; - mRemotePath = remote_path; - mDeleteRemoteOnCompletion = delete_remote_on_completion; + mRemoteFilename = remote_filename; + mRemotePath = remote_path; + mDeleteRemoteOnCompletion = delete_remote_on_completion; - LL_INFOS() << "Requesting file: " << remote_filename << LL_ENDL; + LL_INFOS() << "Requesting file: " << remote_filename << LL_ENDL; - delete [] mBuffer; - mBuffer = NULL; + delete [] mBuffer; + mBuffer = NULL; - mBufferLength = 0; - mPacketNum = 0; - mStatus = e_LL_XFER_PENDING; - return retval; + mBufferLength = 0; + mPacketNum = 0; + mStatus = e_LL_XFER_PENDING; + return retval; } ////////////////////////////////////////////////////////// S32 LLXfer_Mem::startDownload() { - S32 retval = 0; // presume success - gMessageSystem->newMessageFast(_PREHASH_RequestXfer); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addStringFast(_PREHASH_Filename, mRemoteFilename); - gMessageSystem->addU8("FilePath", (U8) mRemotePath); - gMessageSystem->addBOOL("DeleteOnCompletion", mDeleteRemoteOnCompletion); - gMessageSystem->addBOOL("UseBigPackets", mChunkSize == LL_XFER_LARGE_PAYLOAD); - gMessageSystem->addUUIDFast(_PREHASH_VFileID, LLUUID::null); - gMessageSystem->addS16Fast(_PREHASH_VFileType, -1); - - gMessageSystem->sendReliable(mRemoteHost); - mStatus = e_LL_XFER_IN_PROGRESS; - - return (retval); + S32 retval = 0; // presume success + gMessageSystem->newMessageFast(_PREHASH_RequestXfer); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addStringFast(_PREHASH_Filename, mRemoteFilename); + gMessageSystem->addU8("FilePath", (U8) mRemotePath); + gMessageSystem->addBOOL("DeleteOnCompletion", mDeleteRemoteOnCompletion); + gMessageSystem->addBOOL("UseBigPackets", mChunkSize == LL_XFER_LARGE_PAYLOAD); + gMessageSystem->addUUIDFast(_PREHASH_VFileID, LLUUID::null); + gMessageSystem->addS16Fast(_PREHASH_VFileType, -1); + + gMessageSystem->sendReliable(mRemoteHost); + mStatus = e_LL_XFER_IN_PROGRESS; + + return (retval); } ////////////////////////////////////////////////////////// U32 LLXfer_Mem::getXferTypeTag() { - return LLXfer::XFER_MEM; + return LLXfer::XFER_MEM; } diff --git a/indra/llmessage/llxfer_mem.h b/indra/llmessage/llxfer_mem.h index 25bd363235..4e87b0ca5a 100644 --- a/indra/llmessage/llxfer_mem.h +++ b/indra/llmessage/llxfer_mem.h @@ -1,25 +1,25 @@ -/** +/** * @file llxfer_mem.h * @brief definition of LLXfer_Mem class for a single xfer * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,37 +36,37 @@ class LLXfer_Mem : public LLXfer { private: protected: - void (*mCallback)(void *, S32, void **, S32, LLExtStat); - std::string mRemoteFilename; - ELLPath mRemotePath; - bool mDeleteRemoteOnCompletion; + void (*mCallback)(void *, S32, void **, S32, LLExtStat); + std::string mRemoteFilename; + ELLPath mRemotePath; + bool mDeleteRemoteOnCompletion; public: private: protected: public: - LLXfer_Mem (); - virtual ~LLXfer_Mem(); + LLXfer_Mem (); + virtual ~LLXfer_Mem(); - virtual void init(); - virtual void cleanup(); + virtual void init(); + virtual void cleanup(); - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); - virtual void setXferSize (S32 data_size); + virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + virtual void setXferSize (S32 data_size); - virtual S32 initializeRequest(U64 xfer_id, - const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - bool delete_remote_on_completion, - void (*callback)(void*,S32,void**,S32,LLExtStat), - void** user_data); - virtual S32 startDownload(); + virtual S32 initializeRequest(U64 xfer_id, + const std::string& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + bool delete_remote_on_completion, + void (*callback)(void*,S32,void**,S32,LLExtStat), + void** user_data); + virtual S32 startDownload(); - virtual S32 processEOF(); + virtual S32 processEOF(); - virtual U32 getXferTypeTag(); + virtual U32 getXferTypeTag(); }; #endif diff --git a/indra/llmessage/llxfer_vfile.cpp b/indra/llmessage/llxfer_vfile.cpp index 3322188694..4f31973f3d 100644 --- a/indra/llmessage/llxfer_vfile.cpp +++ b/indra/llmessage/llxfer_vfile.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llxfer_vfile.cpp * @brief implementation of LLXfer_VFile class for a single xfer (vfile). * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,349 +41,349 @@ const U32 LL_MAX_XFER_FILE_BUFFER = 65536; LLXfer_VFile::LLXfer_VFile () : LLXfer(-1) { - init(LLUUID::null, LLAssetType::AT_NONE); + init(LLUUID::null, LLAssetType::AT_NONE); } LLXfer_VFile::LLXfer_VFile (const LLUUID &local_id, LLAssetType::EType type) : LLXfer(-1) { - init(local_id, type); + init(local_id, type); } /////////////////////////////////////////////////////////// LLXfer_VFile::~LLXfer_VFile () { - cleanup(); + cleanup(); } /////////////////////////////////////////////////////////// void LLXfer_VFile::init (const LLUUID &local_id, LLAssetType::EType type) { - mLocalID = local_id; - mType = type; + mLocalID = local_id; + mType = type; - mVFile = NULL; + mVFile = NULL; - std::string id_string; - mLocalID.toString(id_string); + std::string id_string; + mLocalID.toString(id_string); - mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType)); + mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType)); } - + /////////////////////////////////////////////////////////// void LLXfer_VFile::cleanup () { - if (mTempID.notNull() && - mDeleteTempFile) - { - if (LLFileSystem::getExists(mTempID, mType)) - { - LLFileSystem file(mTempID, mType, LLFileSystem::WRITE); - file.remove(); - } - else - { - LL_WARNS("Xfer") << "LLXfer_VFile::cleanup() can't open to delete cache file " << mTempID << "." << LLAssetType::lookup(mType) - << ", mRemoteID is " << mRemoteID << LL_ENDL; - } - } - - delete mVFile; - mVFile = NULL; - - LLXfer::cleanup(); + if (mTempID.notNull() && + mDeleteTempFile) + { + if (LLFileSystem::getExists(mTempID, mType)) + { + LLFileSystem file(mTempID, mType, LLFileSystem::WRITE); + file.remove(); + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::cleanup() can't open to delete cache file " << mTempID << "." << LLAssetType::lookup(mType) + << ", mRemoteID is " << mRemoteID << LL_ENDL; + } + } + + delete mVFile; + mVFile = NULL; + + LLXfer::cleanup(); } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::initializeRequest(U64 xfer_id, - const LLUUID& local_id, - const LLUUID& remote_id, - LLAssetType::EType type, - const LLHost& remote_host, - void (*callback)(void**,S32,LLExtStat), - void** user_data) + const LLUUID& local_id, + const LLUUID& remote_id, + LLAssetType::EType type, + const LLHost& remote_host, + void (*callback)(void**,S32,LLExtStat), + void** user_data) { - S32 retval = 0; // presume success - - mRemoteHost = remote_host; + S32 retval = 0; // presume success - mLocalID = local_id; - mRemoteID = remote_id; - mType = type; + mRemoteHost = remote_host; - mID = xfer_id; - mCallback = callback; - mCallbackDataHandle = user_data; - mCallbackResult = LL_ERR_NOERR; + mLocalID = local_id; + mRemoteID = remote_id; + mType = type; - std::string id_string; - mLocalID.toString(id_string); + mID = xfer_id; + mCallback = callback; + mCallbackDataHandle = user_data; + mCallbackResult = LL_ERR_NOERR; - mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType)); + std::string id_string; + mLocalID.toString(id_string); - LL_INFOS("Xfer") << "Requesting " << mName << LL_ENDL; + mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType)); - if (mBuffer) - { - delete[] mBuffer; - mBuffer = NULL; - } + LL_INFOS("Xfer") << "Requesting " << mName << LL_ENDL; - mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; + if (mBuffer) + { + delete[] mBuffer; + mBuffer = NULL; + } - mBufferLength = 0; - mPacketNum = 0; - mTempID.generate(); - mDeleteTempFile = true; - mStatus = e_LL_XFER_PENDING; - return retval; + mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; + + mBufferLength = 0; + mPacketNum = 0; + mTempID.generate(); + mDeleteTempFile = true; + mStatus = e_LL_XFER_PENDING; + return retval; } ////////////////////////////////////////////////////////// S32 LLXfer_VFile::startDownload() { - S32 retval = 0; // presume success + S32 retval = 0; // presume success - // Don't need to create the file here, it will happen when data arrives + // Don't need to create the file here, it will happen when data arrives - gMessageSystem->newMessageFast(_PREHASH_RequestXfer); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addStringFast(_PREHASH_Filename, ""); - gMessageSystem->addU8("FilePath", (U8) LL_PATH_NONE); - gMessageSystem->addBOOL("DeleteOnCompletion", false); - gMessageSystem->addBOOL("UseBigPackets", mChunkSize == LL_XFER_LARGE_PAYLOAD); - gMessageSystem->addUUIDFast(_PREHASH_VFileID, mRemoteID); - gMessageSystem->addS16Fast(_PREHASH_VFileType, (S16)mType); + gMessageSystem->newMessageFast(_PREHASH_RequestXfer); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addStringFast(_PREHASH_Filename, ""); + gMessageSystem->addU8("FilePath", (U8) LL_PATH_NONE); + gMessageSystem->addBOOL("DeleteOnCompletion", false); + gMessageSystem->addBOOL("UseBigPackets", mChunkSize == LL_XFER_LARGE_PAYLOAD); + gMessageSystem->addUUIDFast(_PREHASH_VFileID, mRemoteID); + gMessageSystem->addS16Fast(_PREHASH_VFileType, (S16)mType); - gMessageSystem->sendReliable(mRemoteHost); - mStatus = e_LL_XFER_IN_PROGRESS; + gMessageSystem->sendReliable(mRemoteHost); + mStatus = e_LL_XFER_IN_PROGRESS; - return (retval); + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host) { - S32 retval = LL_ERR_NOERR; // presume success - + S32 retval = LL_ERR_NOERR; // presume success + mRemoteHost = remote_host; - mID = xfer_id; - mPacketNum = -1; - -// cout << "Sending file: " << mLocalFilename << endl; - - delete [] mBuffer; - mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; - - mBufferLength = 0; - mBufferStartOffset = 0; - - delete mVFile; - mVFile = NULL; - if(LLFileSystem::getExists(mLocalID, mType)) - { - mVFile = new LLFileSystem(mLocalID, mType, LLFileSystem::READ); - - if (mVFile->getSize() <= 0) - { - LL_WARNS("Xfer") << "LLXfer_VFile::startSend() cache file " << mLocalID << "." << LLAssetType::lookup(mType) - << " has unexpected file size of " << mVFile->getSize() << LL_ENDL; - delete mVFile; - mVFile = NULL; - - return LL_ERR_FILE_EMPTY; - } - } - - if(mVFile) - { - setXferSize(mVFile->getSize()); - mStatus = e_LL_XFER_PENDING; - } - else - { - LL_WARNS("Xfer") << "LLXfer_VFile::startSend() can't read cache file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; - retval = LL_ERR_FILE_NOT_FOUND; - } - - return (retval); + mID = xfer_id; + mPacketNum = -1; + +// cout << "Sending file: " << mLocalFilename << endl; + + delete [] mBuffer; + mBuffer = new char[LL_MAX_XFER_FILE_BUFFER]; + + mBufferLength = 0; + mBufferStartOffset = 0; + + delete mVFile; + mVFile = NULL; + if(LLFileSystem::getExists(mLocalID, mType)) + { + mVFile = new LLFileSystem(mLocalID, mType, LLFileSystem::READ); + + if (mVFile->getSize() <= 0) + { + LL_WARNS("Xfer") << "LLXfer_VFile::startSend() cache file " << mLocalID << "." << LLAssetType::lookup(mType) + << " has unexpected file size of " << mVFile->getSize() << LL_ENDL; + delete mVFile; + mVFile = NULL; + + return LL_ERR_FILE_EMPTY; + } + } + + if(mVFile) + { + setXferSize(mVFile->getSize()); + mStatus = e_LL_XFER_PENDING; + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::startSend() can't read cache file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + + return (retval); } /////////////////////////////////////////////////////////// void LLXfer_VFile::closeFileHandle() { - if (mVFile) - { - delete mVFile; - mVFile = NULL; - } + if (mVFile) + { + delete mVFile; + mVFile = NULL; + } } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::reopenFileHandle() { - S32 retval = LL_ERR_NOERR; // presume success - - if (mVFile == NULL) - { - if (LLFileSystem::getExists(mLocalID, mType)) - { - mVFile = new LLFileSystem(mLocalID, mType, LLFileSystem::READ); - } - else - { - LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read cache file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; - retval = LL_ERR_FILE_NOT_FOUND; - } - } - - return retval; + S32 retval = LL_ERR_NOERR; // presume success + + if (mVFile == NULL) + { + if (LLFileSystem::getExists(mLocalID, mType)) + { + mVFile = new LLFileSystem(mLocalID, mType, LLFileSystem::READ); + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read cache file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + } + + return retval; } /////////////////////////////////////////////////////////// void LLXfer_VFile::setXferSize (S32 xfer_size) -{ - LLXfer::setXferSize(xfer_size); - - // Don't do this on the server side, where we have a persistent mVFile - // It would be nice if LLXFers could tell which end of the pipe they were - if (! mVFile) - { - LLFileSystem file(mTempID, mType, LLFileSystem::APPEND); - } +{ + LLXfer::setXferSize(xfer_size); + + // Don't do this on the server side, where we have a persistent mVFile + // It would be nice if LLXFers could tell which end of the pipe they were + if (! mVFile) + { + LLFileSystem file(mTempID, mType, LLFileSystem::APPEND); + } } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::getMaxBufferSize () { - return(LL_MAX_XFER_FILE_BUFFER); + return(LL_MAX_XFER_FILE_BUFFER); } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::suck(S32 start_position) { - S32 retval = 0; - - if (mVFile) - { - // grab a buffer from the right place in the file - if (! mVFile->seek(start_position, 0)) - { - LL_WARNS("Xfer") << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << LL_ENDL; - LL_WARNS("Xfer") << "While sending file " << mLocalID << LL_ENDL; - return -1; - } - - if (mVFile->read((U8*)mBuffer, LL_MAX_XFER_FILE_BUFFER)) /* Flawfinder : ignore */ - { - mBufferLength = mVFile->getLastBytesRead(); - mBufferStartOffset = start_position; - - mBufferContainsEOF = mVFile->eof(); - } - else - { - retval = -1; - } - } - else - { - retval = -1; - } - - return (retval); + S32 retval = 0; + + if (mVFile) + { + // grab a buffer from the right place in the file + if (! mVFile->seek(start_position, 0)) + { + LL_WARNS("Xfer") << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << LL_ENDL; + LL_WARNS("Xfer") << "While sending file " << mLocalID << LL_ENDL; + return -1; + } + + if (mVFile->read((U8*)mBuffer, LL_MAX_XFER_FILE_BUFFER)) /* Flawfinder : ignore */ + { + mBufferLength = mVFile->getLastBytesRead(); + mBufferStartOffset = start_position; + + mBufferContainsEOF = mVFile->eof(); + } + else + { + retval = -1; + } + } + else + { + retval = -1; + } + + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::flush() { - S32 retval = 0; - if (mBufferLength) - { - LLFileSystem file(mTempID, mType, LLFileSystem::APPEND); - - file.write((U8*)mBuffer, mBufferLength); - - mBufferLength = 0; - } - return (retval); + S32 retval = 0; + if (mBufferLength) + { + LLFileSystem file(mTempID, mType, LLFileSystem::APPEND); + + file.write((U8*)mBuffer, mBufferLength); + + mBufferLength = 0; + } + return (retval); } /////////////////////////////////////////////////////////// S32 LLXfer_VFile::processEOF() { - S32 retval = 0; - mStatus = e_LL_XFER_COMPLETE; - - flush(); - - if (!mCallbackResult) - { - if (LLFileSystem::getExists(mTempID, mType)) - { - LLFileSystem file(mTempID, mType, LLFileSystem::WRITE); - if (!file.rename(mLocalID, mType)) - { - LL_WARNS("Xfer") << "Cache rename of temp file failed: unable to rename " << mTempID << " to " << mLocalID << LL_ENDL; - } - else - { - // Rename worked: the original file is gone. Clear mDeleteTempFile - // so we don't attempt to delete the file in cleanup() - mDeleteTempFile = false; - } - } - else - { - LL_WARNS("Xfer") << "LLXfer_VFile::processEOF() can't open for renaming cache file " << mTempID << "." << LLAssetType::lookup(mType) << LL_ENDL; - } - } - - if (mVFile) - { - delete mVFile; - mVFile = NULL; - } - - retval = LLXfer::processEOF(); - - return(retval); + S32 retval = 0; + mStatus = e_LL_XFER_COMPLETE; + + flush(); + + if (!mCallbackResult) + { + if (LLFileSystem::getExists(mTempID, mType)) + { + LLFileSystem file(mTempID, mType, LLFileSystem::WRITE); + if (!file.rename(mLocalID, mType)) + { + LL_WARNS("Xfer") << "Cache rename of temp file failed: unable to rename " << mTempID << " to " << mLocalID << LL_ENDL; + } + else + { + // Rename worked: the original file is gone. Clear mDeleteTempFile + // so we don't attempt to delete the file in cleanup() + mDeleteTempFile = false; + } + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::processEOF() can't open for renaming cache file " << mTempID << "." << LLAssetType::lookup(mType) << LL_ENDL; + } + } + + if (mVFile) + { + delete mVFile; + mVFile = NULL; + } + + retval = LLXfer::processEOF(); + + return(retval); } //////////////////////////////////////////////////////////// bool LLXfer_VFile::matchesLocalFile(const LLUUID &id, LLAssetType::EType type) { - return (id == mLocalID && type == mType); + return (id == mLocalID && type == mType); } ////////////////////////////////////////////////////////// bool LLXfer_VFile::matchesRemoteFile(const LLUUID &id, LLAssetType::EType type) { - return (id == mRemoteID && type == mType); + return (id == mRemoteID && type == mType); } ////////////////////////////////////////////////////////// -std::string LLXfer_VFile::getFileName() +std::string LLXfer_VFile::getFileName() { - return mName; + return mName; } ////////////////////////////////////////////////////////// @@ -392,6 +392,6 @@ std::string LLXfer_VFile::getFileName() // as long as it's different from the other classes U32 LLXfer_VFile::getXferTypeTag() { - return LLXfer::XFER_VFILE; + return LLXfer::XFER_VFILE; } diff --git a/indra/llmessage/llxfer_vfile.h b/indra/llmessage/llxfer_vfile.h index 032c5e2533..f62da815f8 100644 --- a/indra/llmessage/llxfer_vfile.h +++ b/indra/llmessage/llxfer_vfile.h @@ -1,25 +1,25 @@ -/** +/** * @file llxfer_vfile.h * @brief definition of LLXfer_VFile class for a single xfer_vfile. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,52 +35,52 @@ class LLFileSystem; class LLXfer_VFile : public LLXfer { protected: - LLUUID mLocalID; - LLUUID mRemoteID; - LLUUID mTempID; - LLAssetType::EType mType; - - LLFileSystem *mVFile; + LLUUID mLocalID; + LLUUID mRemoteID; + LLUUID mTempID; + LLAssetType::EType mType; + + LLFileSystem *mVFile; - std::string mName; + std::string mName; - bool mDeleteTempFile; + bool mDeleteTempFile; public: - LLXfer_VFile (); - LLXfer_VFile (const LLUUID &local_id, LLAssetType::EType type); - virtual ~LLXfer_VFile(); + LLXfer_VFile (); + LLXfer_VFile (const LLUUID &local_id, LLAssetType::EType type); + virtual ~LLXfer_VFile(); - virtual void init(const LLUUID &local_id, LLAssetType::EType type); - virtual void cleanup(); + virtual void init(const LLUUID &local_id, LLAssetType::EType type); + virtual void cleanup(); - virtual S32 initializeRequest(U64 xfer_id, - const LLUUID &local_id, - const LLUUID &remote_id, - const LLAssetType::EType type, - const LLHost &remote_host, - void (*callback)(void **,S32,LLExtStat), - void **user_data); - virtual S32 startDownload(); + virtual S32 initializeRequest(U64 xfer_id, + const LLUUID &local_id, + const LLUUID &remote_id, + const LLAssetType::EType type, + const LLHost &remote_host, + void (*callback)(void **,S32,LLExtStat), + void **user_data); + virtual S32 startDownload(); - virtual S32 processEOF(); + virtual S32 processEOF(); - virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); - virtual void closeFileHandle(); - virtual S32 reopenFileHandle(); + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); - virtual S32 suck(S32 start_position); - virtual S32 flush(); + virtual S32 suck(S32 start_position); + virtual S32 flush(); - virtual bool matchesLocalFile(const LLUUID &id, LLAssetType::EType type); - virtual bool matchesRemoteFile(const LLUUID &id, LLAssetType::EType type); + virtual bool matchesLocalFile(const LLUUID &id, LLAssetType::EType type); + virtual bool matchesRemoteFile(const LLUUID &id, LLAssetType::EType type); - virtual void setXferSize(S32 xfer_size); - virtual S32 getMaxBufferSize(); + virtual void setXferSize(S32 xfer_size); + virtual S32 getMaxBufferSize(); - virtual U32 getXferTypeTag(); + virtual U32 getXferTypeTag(); - virtual std::string getFileName(); + virtual std::string getFileName(); }; #endif diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 6187d439d9..f6ed43a4e4 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llxfermanager.cpp * @brief implementation of LLXferManager class for a collection of xfers * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,7 +46,7 @@ const S32 LL_DEFAULT_MAX_REQUEST_FIFO_XFERS = 1000; // Kills the connection if a viewer download queue hits this many requests backed up // Also set in simulator.xml at "hard_limit_outgoing_xfers_per_circuit" -const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500; +const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500; // Use this to show sending some ConfirmXferPacket messages //#define LL_XFER_PROGRESS_MESSAGES 1 @@ -58,88 +58,88 @@ const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500; LLXferManager::LLXferManager () { - init(); + init(); } /////////////////////////////////////////////////////////// LLXferManager::~LLXferManager () { - cleanup(); + cleanup(); } /////////////////////////////////////////////////////////// void LLXferManager::init() { - cleanup(); + cleanup(); - setMaxOutgoingXfersPerCircuit(LL_DEFAULT_MAX_SIMULTANEOUS_XFERS); - setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS); - setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS); + setMaxOutgoingXfersPerCircuit(LL_DEFAULT_MAX_SIMULTANEOUS_XFERS); + setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS); + setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS); - // Turn on or off ack throttling - mUseAckThrottling = false; - setAckThrottleBPS(100000); + // Turn on or off ack throttling + mUseAckThrottling = false; + setAckThrottleBPS(100000); } - + /////////////////////////////////////////////////////////// void LLXferManager::cleanup () { - for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); - mOutgoingHosts.clear(); + for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); + mOutgoingHosts.clear(); - for_each(mSendList.begin(), mSendList.end(), DeletePointer()); - mSendList.clear(); + for_each(mSendList.begin(), mSendList.end(), DeletePointer()); + mSendList.clear(); - for_each(mReceiveList.begin(), mReceiveList.end(), DeletePointer()); - mReceiveList.clear(); + for_each(mReceiveList.begin(), mReceiveList.end(), DeletePointer()); + mReceiveList.clear(); } /////////////////////////////////////////////////////////// void LLXferManager::setMaxIncomingXfers(S32 max_num) { - mMaxIncomingXfers = max_num; + mMaxIncomingXfers = max_num; } /////////////////////////////////////////////////////////// void LLXferManager::setMaxOutgoingXfersPerCircuit(S32 max_num) { - mMaxOutgoingXfersPerCircuit = max_num; + mMaxOutgoingXfersPerCircuit = max_num; } void LLXferManager::setHardLimitOutgoingXfersPerCircuit(S32 max_num) { - mHardLimitOutgoingXfersPerCircuit = max_num; + mHardLimitOutgoingXfersPerCircuit = max_num; } void LLXferManager::setUseAckThrottling(const bool use) { - mUseAckThrottling = use; + mUseAckThrottling = use; } void LLXferManager::setAckThrottleBPS(const F32 bps) { - // Let's figure out the min we can set based on the ack retry rate - // and number of simultaneous. - - // Assuming we're running as slow as possible, this is the lowest ack - // rate we can use. - F32 min_bps = (1000.f * 8.f* mMaxIncomingXfers) / LL_PACKET_TIMEOUT; - - // Set - F32 actual_rate = llmax(min_bps*1.1f, bps); - LL_DEBUGS("AppInit") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL; - LL_DEBUGS("AppInit") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL; - #ifdef LL_XFER_DIAGNOISTIC_LOGGING - LL_INFOS("Xfer") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL; - LL_INFOS("Xfer") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL; - #endif // LL_XFER_DIAGNOISTIC_LOGGING - - mAckThrottle.setRate(actual_rate); + // Let's figure out the min we can set based on the ack retry rate + // and number of simultaneous. + + // Assuming we're running as slow as possible, this is the lowest ack + // rate we can use. + F32 min_bps = (1000.f * 8.f* mMaxIncomingXfers) / LL_PACKET_TIMEOUT; + + // Set + F32 actual_rate = llmax(min_bps*1.1f, bps); + LL_DEBUGS("AppInit") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL; + LL_DEBUGS("AppInit") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL; + #ifdef LL_XFER_DIAGNOISTIC_LOGGING + LL_INFOS("Xfer") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL; + LL_INFOS("Xfer") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL; + #endif // LL_XFER_DIAGNOISTIC_LOGGING + + mAckThrottle.setRate(actual_rate); } @@ -147,69 +147,69 @@ void LLXferManager::setAckThrottleBPS(const F32 bps) void LLXferManager::updateHostStatus() { - // Clear the outgoing host list - for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); - mOutgoingHosts.clear(); - - // Loop through all outgoing xfers and re-build mOutgoingHosts - for (xfer_list_t::iterator send_iter = mSendList.begin(); - send_iter != mSendList.end(); ++send_iter) - { - LLHostStatus *host_statusp = NULL; - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) - { - if ((*iter)->mHost == (*send_iter)->mRemoteHost) - { // Already have this host - host_statusp = *iter; - break; - } - } - if (!host_statusp) - { // Don't have this host, so add it - host_statusp = new LLHostStatus(); - if (host_statusp) - { - host_statusp->mHost = (*send_iter)->mRemoteHost; - mOutgoingHosts.push_front(host_statusp); - } - } - if (host_statusp) - { // Do the accounting - if ((*send_iter)->mStatus == e_LL_XFER_PENDING) - { - host_statusp->mNumPending++; - } - else if ((*send_iter)->mStatus == e_LL_XFER_IN_PROGRESS) - { - host_statusp->mNumActive++; - } - } - } + // Clear the outgoing host list + for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); + mOutgoingHosts.clear(); + + // Loop through all outgoing xfers and re-build mOutgoingHosts + for (xfer_list_t::iterator send_iter = mSendList.begin(); + send_iter != mSendList.end(); ++send_iter) + { + LLHostStatus *host_statusp = NULL; + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) + { + if ((*iter)->mHost == (*send_iter)->mRemoteHost) + { // Already have this host + host_statusp = *iter; + break; + } + } + if (!host_statusp) + { // Don't have this host, so add it + host_statusp = new LLHostStatus(); + if (host_statusp) + { + host_statusp->mHost = (*send_iter)->mRemoteHost; + mOutgoingHosts.push_front(host_statusp); + } + } + if (host_statusp) + { // Do the accounting + if ((*send_iter)->mStatus == e_LL_XFER_PENDING) + { + host_statusp->mNumPending++; + } + else if ((*send_iter)->mStatus == e_LL_XFER_IN_PROGRESS) + { + host_statusp->mNumActive++; + } + } + } #ifdef LL_XFER_DIAGNOISTIC_LOGGING - for (xfer_list_t::iterator send_iter = mSendList.begin(); - send_iter != mSendList.end(); ++send_iter) - { - LLXfer * xferp = *send_iter; - LL_INFOS("Xfer") << "xfer to host " << xferp->mRemoteHost - << " is " << xferp->mXferSize << " bytes" - << ", status " << (S32)(xferp->mStatus) - << ", waiting for ACK: " << (S32)(xferp->mWaitingForACK) - << " in frame " << (S32) LLFrameTimer::getFrameCount() - << LL_ENDL; - } - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) - { - LL_INFOS("Xfer") << "LLXfer host " << (*iter)->mHost.getIPandPort() - << " has " << (*iter)->mNumActive - << " active, " << (*iter)->mNumPending - << " pending" - << " in frame " << (S32) LLFrameTimer::getFrameCount() - << LL_ENDL; - } + for (xfer_list_t::iterator send_iter = mSendList.begin(); + send_iter != mSendList.end(); ++send_iter) + { + LLXfer * xferp = *send_iter; + LL_INFOS("Xfer") << "xfer to host " << xferp->mRemoteHost + << " is " << xferp->mXferSize << " bytes" + << ", status " << (S32)(xferp->mStatus) + << ", waiting for ACK: " << (S32)(xferp->mWaitingForACK) + << " in frame " << (S32) LLFrameTimer::getFrameCount() + << LL_ENDL; + } + + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) + { + LL_INFOS("Xfer") << "LLXfer host " << (*iter)->mHost.getIPandPort() + << " has " << (*iter)->mNumActive + << " active, " << (*iter)->mNumPending + << " pending" + << " in frame " << (S32) LLFrameTimer::getFrameCount() + << LL_ENDL; + } #endif // LL_XFER_DIAGNOISTIC_LOGGING } @@ -218,34 +218,34 @@ void LLXferManager::updateHostStatus() void LLXferManager::printHostStatus() { - LLHostStatus *host_statusp = NULL; - if (!mOutgoingHosts.empty()) - { - LL_INFOS("Xfer") << "Outgoing Xfers:" << LL_ENDL; - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) - { - host_statusp = *iter; - LL_INFOS("Xfer") << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << LL_ENDL; - } - } + LLHostStatus *host_statusp = NULL; + if (!mOutgoingHosts.empty()) + { + LL_INFOS("Xfer") << "Outgoing Xfers:" << LL_ENDL; + + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) + { + host_statusp = *iter; + LL_INFOS("Xfer") << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << LL_ENDL; + } + } } /////////////////////////////////////////////////////////// LLXfer * LLXferManager::findXferByID(U64 id, xfer_list_t & xfer_list) { - for (xfer_list_t::iterator iter = xfer_list.begin(); - iter != xfer_list.end(); - ++iter) - { - if ((*iter)->mID == id) - { - return(*iter); - } - } - return(NULL); + for (xfer_list_t::iterator iter = xfer_list.begin(); + iter != xfer_list.end(); + ++iter) + { + if ((*iter)->mID == id) + { + return(*iter); + } + } + return(NULL); } @@ -254,270 +254,270 @@ LLXfer * LLXferManager::findXferByID(U64 id, xfer_list_t & xfer_list) // WARNING: this invalidates iterators from xfer_list void LLXferManager::removeXfer(LLXfer *delp, xfer_list_t & xfer_list) { - if (delp) - { - std::string direction = "send"; - if (&xfer_list == &mReceiveList) - { - direction = "receive"; - } - - // This assumes that delp will occur in the list once at most - // Find the pointer in the list - for (xfer_list_t::iterator iter = xfer_list.begin(); - iter != xfer_list.end(); - ++iter) - { - if ((*iter) == delp) - { - LL_DEBUGS("Xfer") << "Deleting xfer to host " << (*iter)->mRemoteHost - << " of " << (*iter)->mXferSize << " bytes" - << ", status " << (S32)((*iter)->mStatus) - << " from the " << direction << " list" - << LL_ENDL; - - xfer_list.erase(iter); - delete (delp); - break; - } - } - } + if (delp) + { + std::string direction = "send"; + if (&xfer_list == &mReceiveList) + { + direction = "receive"; + } + + // This assumes that delp will occur in the list once at most + // Find the pointer in the list + for (xfer_list_t::iterator iter = xfer_list.begin(); + iter != xfer_list.end(); + ++iter) + { + if ((*iter) == delp) + { + LL_DEBUGS("Xfer") << "Deleting xfer to host " << (*iter)->mRemoteHost + << " of " << (*iter)->mXferSize << " bytes" + << ", status " << (S32)((*iter)->mStatus) + << " from the " << direction << " list" + << LL_ENDL; + + xfer_list.erase(iter); + delete (delp); + break; + } + } + } } /////////////////////////////////////////////////////////// LLHostStatus * LLXferManager::findHostStatus(const LLHost &host) { - LLHostStatus *host_statusp = NULL; - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) - { - host_statusp = *iter; - if (host_statusp->mHost == host) - { - return (host_statusp); - } - } - return 0; + LLHostStatus *host_statusp = NULL; + + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) + { + host_statusp = *iter; + if (host_statusp->mHost == host) + { + return (host_statusp); + } + } + return 0; } /////////////////////////////////////////////////////////// - + S32 LLXferManager::numPendingXfers(const LLHost &host) { - LLHostStatus *host_statusp = findHostStatus(host); - if (host_statusp) - { - return host_statusp->mNumPending; - } - return 0; + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) + { + return host_statusp->mNumPending; + } + return 0; } /////////////////////////////////////////////////////////// S32 LLXferManager::numActiveXfers(const LLHost &host) { - LLHostStatus *host_statusp = findHostStatus(host); - if (host_statusp) - { - return host_statusp->mNumActive; - } - return 0; + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) + { + return host_statusp->mNumActive; + } + return 0; } /////////////////////////////////////////////////////////// void LLXferManager::changeNumActiveXfers(const LLHost &host, S32 delta) { - LLHostStatus *host_statusp = NULL; - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) - { - host_statusp = *iter; - if (host_statusp->mHost == host) - { - host_statusp->mNumActive += delta; - } - } + LLHostStatus *host_statusp = NULL; + + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) + { + host_statusp = *iter; + if (host_statusp->mHost == host) + { + host_statusp->mNumActive += delta; + } + } } /////////////////////////////////////////////////////////// void LLXferManager::registerCallbacks(LLMessageSystem *msgsystem) { - msgsystem->setHandlerFuncFast(_PREHASH_ConfirmXferPacket, process_confirm_packet, NULL); - msgsystem->setHandlerFuncFast(_PREHASH_RequestXfer, process_request_xfer, NULL); - msgsystem->setHandlerFuncFast(_PREHASH_SendXferPacket, continue_file_receive, NULL); - msgsystem->setHandlerFuncFast(_PREHASH_AbortXfer, process_abort_xfer, NULL); + msgsystem->setHandlerFuncFast(_PREHASH_ConfirmXferPacket, process_confirm_packet, NULL); + msgsystem->setHandlerFuncFast(_PREHASH_RequestXfer, process_request_xfer, NULL); + msgsystem->setHandlerFuncFast(_PREHASH_SendXferPacket, continue_file_receive, NULL); + msgsystem->setHandlerFuncFast(_PREHASH_AbortXfer, process_abort_xfer, NULL); } /////////////////////////////////////////////////////////// U64 LLXferManager::getNextID () { - LLUUID a_guid; + LLUUID a_guid; + + a_guid.generate(); - a_guid.generate(); - - return(*((U64*)(a_guid.mData))); + return(*((U64*)(a_guid.mData))); } /////////////////////////////////////////////////////////// S32 LLXferManager::encodePacketNum(S32 packet_num, bool is_EOF) { - if (is_EOF) - { - packet_num |= 0x80000000; - } - return packet_num; + if (is_EOF) + { + packet_num |= 0x80000000; + } + return packet_num; } /////////////////////////////////////////////////////////// S32 LLXferManager::decodePacketNum(S32 packet_num) { - return(packet_num & 0x0FFFFFFF); + return(packet_num & 0x0FFFFFFF); } /////////////////////////////////////////////////////////// bool LLXferManager::isLastPacket(S32 packet_num) { - return(packet_num & 0x80000000); + return(packet_num & 0x80000000); } /////////////////////////////////////////////////////////// U64 LLXferManager::requestFile(const std::string& local_filename, - const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - bool delete_remote_on_completion, - void (*callback)(void**,S32,LLExtStat), - void** user_data, - bool is_priority, - bool use_big_packets) + const std::string& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + bool delete_remote_on_completion, + void (*callback)(void**,S32,LLExtStat), + void** user_data, + bool is_priority, + bool use_big_packets) { - LLXfer_File* file_xfer_p = NULL; - - // First check to see if it's already requested - for (xfer_list_t::iterator iter = mReceiveList.begin(); - iter != mReceiveList.end(); ++iter) - { - if ((*iter)->getXferTypeTag() == LLXfer::XFER_FILE) - { - file_xfer_p = (LLXfer_File*)(*iter); - if (file_xfer_p->matchesLocalFilename(local_filename) - && file_xfer_p->matchesRemoteFilename(remote_filename, remote_path) - && (remote_host == file_xfer_p->mRemoteHost) - && (callback == file_xfer_p->mCallback) - && (user_data == file_xfer_p->mCallbackDataHandle)) - { - // Already have the request (already in progress) - return (*iter)->mID; - } - } - } - - U64 xfer_id = 0; - - S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1; - file_xfer_p = new LLXfer_File(chunk_size); - if (file_xfer_p) - { - addToList(file_xfer_p, mReceiveList, is_priority); - - // Remove any file by the same name that happens to be lying - // around. - // Note: according to AaronB, this is here to deal with locks on files that were - // in transit during a crash, - if(delete_remote_on_completion && - (remote_filename.substr(remote_filename.length()-4) == ".tmp")) - { - LLFile::remove(local_filename, ENOENT); - } - xfer_id = getNextID(); - file_xfer_p->initializeRequest( - xfer_id, - local_filename, - remote_filename, - remote_path, - remote_host, - delete_remote_on_completion, - callback,user_data); - startPendingDownloads(); - } - else - { - LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL; - } - return xfer_id; + LLXfer_File* file_xfer_p = NULL; + + // First check to see if it's already requested + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); ++iter) + { + if ((*iter)->getXferTypeTag() == LLXfer::XFER_FILE) + { + file_xfer_p = (LLXfer_File*)(*iter); + if (file_xfer_p->matchesLocalFilename(local_filename) + && file_xfer_p->matchesRemoteFilename(remote_filename, remote_path) + && (remote_host == file_xfer_p->mRemoteHost) + && (callback == file_xfer_p->mCallback) + && (user_data == file_xfer_p->mCallbackDataHandle)) + { + // Already have the request (already in progress) + return (*iter)->mID; + } + } + } + + U64 xfer_id = 0; + + S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1; + file_xfer_p = new LLXfer_File(chunk_size); + if (file_xfer_p) + { + addToList(file_xfer_p, mReceiveList, is_priority); + + // Remove any file by the same name that happens to be lying + // around. + // Note: according to AaronB, this is here to deal with locks on files that were + // in transit during a crash, + if(delete_remote_on_completion && + (remote_filename.substr(remote_filename.length()-4) == ".tmp")) + { + LLFile::remove(local_filename, ENOENT); + } + xfer_id = getNextID(); + file_xfer_p->initializeRequest( + xfer_id, + local_filename, + remote_filename, + remote_path, + remote_host, + delete_remote_on_completion, + callback,user_data); + startPendingDownloads(); + } + else + { + LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL; + } + return xfer_id; } void LLXferManager::requestVFile(const LLUUID& local_id, - const LLUUID& remote_id, - LLAssetType::EType type, - const LLHost& remote_host, - void (*callback)(void**,S32,LLExtStat), - void** user_data, - bool is_priority) + const LLUUID& remote_id, + LLAssetType::EType type, + const LLHost& remote_host, + void (*callback)(void**,S32,LLExtStat), + void** user_data, + bool is_priority) { - LLXfer_VFile * xfer_p = NULL; - - for (xfer_list_t::iterator iter = mReceiveList.begin(); - iter != mReceiveList.end(); ++iter) - { // Find any matching existing requests - if ((*iter)->getXferTypeTag() == LLXfer::XFER_VFILE) - { - xfer_p = (LLXfer_VFile*) (*iter); - if (xfer_p->matchesLocalFile(local_id, type) - && xfer_p->matchesRemoteFile(remote_id, type) - && (remote_host == xfer_p->mRemoteHost) - && (callback == xfer_p->mCallback) - && (user_data == xfer_p->mCallbackDataHandle)) - - { // Have match, don't add a duplicate - #ifdef LL_XFER_DIAGNOISTIC_LOGGING - LL_INFOS("Xfer") << "Dropping duplicate xfer request for " << remote_id - << " on " << remote_host.getIPandPort() - << " local id " << local_id - << LL_ENDL; - #endif // LL_XFER_DIAGNOISTIC_LOGGING - - return; - } - } - } - - xfer_p = new LLXfer_VFile(); - if (xfer_p) - { - #ifdef LL_XFER_DIAGNOISTIC_LOGGING - LL_INFOS("Xfer") << "Starting file xfer for " << remote_id - << " type " << LLAssetType::lookupHumanReadable(type) - << " from " << xfer_p->mRemoteHost.getIPandPort() - << ", local id " << local_id - << LL_ENDL; - #endif // LL_XFER_DIAGNOISTIC_LOGGING - - addToList(xfer_p, mReceiveList, is_priority); - ((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(), - local_id, - remote_id, - type, - remote_host, - callback, - user_data); - startPendingDownloads(); - } - else - { - LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL; - } + LLXfer_VFile * xfer_p = NULL; + + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); ++iter) + { // Find any matching existing requests + if ((*iter)->getXferTypeTag() == LLXfer::XFER_VFILE) + { + xfer_p = (LLXfer_VFile*) (*iter); + if (xfer_p->matchesLocalFile(local_id, type) + && xfer_p->matchesRemoteFile(remote_id, type) + && (remote_host == xfer_p->mRemoteHost) + && (callback == xfer_p->mCallback) + && (user_data == xfer_p->mCallbackDataHandle)) + + { // Have match, don't add a duplicate + #ifdef LL_XFER_DIAGNOISTIC_LOGGING + LL_INFOS("Xfer") << "Dropping duplicate xfer request for " << remote_id + << " on " << remote_host.getIPandPort() + << " local id " << local_id + << LL_ENDL; + #endif // LL_XFER_DIAGNOISTIC_LOGGING + + return; + } + } + } + + xfer_p = new LLXfer_VFile(); + if (xfer_p) + { + #ifdef LL_XFER_DIAGNOISTIC_LOGGING + LL_INFOS("Xfer") << "Starting file xfer for " << remote_id + << " type " << LLAssetType::lookupHumanReadable(type) + << " from " << xfer_p->mRemoteHost.getIPandPort() + << ", local id " << local_id + << LL_ENDL; + #endif // LL_XFER_DIAGNOISTIC_LOGGING + + addToList(xfer_p, mReceiveList, is_priority); + ((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(), + local_id, + remote_id, + type, + remote_host, + callback, + user_data); + startPendingDownloads(); + } + else + { + LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL; + } } @@ -525,105 +525,105 @@ void LLXferManager::requestVFile(const LLUUID& local_id, void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user_data*/) { - // there's sometimes an extra 4 bytes added to an xfer payload - const S32 BUF_SIZE = LL_XFER_LARGE_PAYLOAD + 4; - char fdata_buf[BUF_SIZE]; /* Flawfinder : ignore */ - S32 fdata_size; - U64 id; - S32 packetnum; - LLXfer * xferp; - - mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); - mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetnum); - - fdata_size = mesgsys->getSizeFast(_PREHASH_DataPacket,_PREHASH_Data); - if (fdata_size < 0 || - fdata_size > BUF_SIZE) - { - char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_WARNS("Xfer") << "Received invalid xfer data size of " << fdata_size - << " in packet number " << packetnum - << " from " << mesgsys->getSender() - << " for xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) - << LL_ENDL; - return; - } - mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, fdata_size, 0, BUF_SIZE); - - xferp = findXferByID(id, mReceiveList); - if (!xferp) - { - char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_WARNS("Xfer") << "received xfer data from " << mesgsys->getSender() - << " for non-existent xfer id: " - << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL; - return; - } - - S32 xfer_size; - - if (decodePacketNum(packetnum) != xferp->mPacketNum) // is the packet different from what we were expecting? - { - // confirm it if it was a resend of the last one, since the confirmation might have gotten dropped - if (decodePacketNum(packetnum) == (xferp->mPacketNum - 1)) - { - LL_INFOS("Xfer") << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << LL_ENDL; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); - } - else - { - LL_INFOS("Xfer") << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << LL_ENDL; - } - return; - } - - S32 result = 0; - - if (xferp->mPacketNum == 0) // first packet has size encoded as additional S32 at beginning of data - { - ntohmemcpy(&xfer_size,fdata_buf,MVT_S32,sizeof(S32)); - + // there's sometimes an extra 4 bytes added to an xfer payload + const S32 BUF_SIZE = LL_XFER_LARGE_PAYLOAD + 4; + char fdata_buf[BUF_SIZE]; /* Flawfinder : ignore */ + S32 fdata_size; + U64 id; + S32 packetnum; + LLXfer * xferp; + + mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); + mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetnum); + + fdata_size = mesgsys->getSizeFast(_PREHASH_DataPacket,_PREHASH_Data); + if (fdata_size < 0 || + fdata_size > BUF_SIZE) + { + char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ + LL_WARNS("Xfer") << "Received invalid xfer data size of " << fdata_size + << " in packet number " << packetnum + << " from " << mesgsys->getSender() + << " for xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) + << LL_ENDL; + return; + } + mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, fdata_size, 0, BUF_SIZE); + + xferp = findXferByID(id, mReceiveList); + if (!xferp) + { + char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ + LL_WARNS("Xfer") << "received xfer data from " << mesgsys->getSender() + << " for non-existent xfer id: " + << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL; + return; + } + + S32 xfer_size; + + if (decodePacketNum(packetnum) != xferp->mPacketNum) // is the packet different from what we were expecting? + { + // confirm it if it was a resend of the last one, since the confirmation might have gotten dropped + if (decodePacketNum(packetnum) == (xferp->mPacketNum - 1)) + { + LL_INFOS("Xfer") << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << LL_ENDL; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); + } + else + { + LL_INFOS("Xfer") << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << LL_ENDL; + } + return; + } + + S32 result = 0; + + if (xferp->mPacketNum == 0) // first packet has size encoded as additional S32 at beginning of data + { + ntohmemcpy(&xfer_size,fdata_buf,MVT_S32,sizeof(S32)); + // do any necessary things on first packet ie. allocate memory - xferp->setXferSize(xfer_size); - - // adjust buffer start and size - result = xferp->receiveData(&(fdata_buf[sizeof(S32)]),fdata_size-(sizeof(S32))); - } - else - { - result = xferp->receiveData(fdata_buf,fdata_size); - } - - if (result == LL_ERR_CANNOT_OPEN_FILE) - { - xferp->abort(LL_ERR_CANNOT_OPEN_FILE); - removeXfer(xferp,mReceiveList); - startPendingDownloads(); - return; - } - - xferp->mPacketNum++; // expect next packet - - if (!mUseAckThrottling) - { - // No throttling, confirm right away - sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); - } - else - { - // Throttling, put on queue to be confirmed later. - LLXferAckInfo ack_info; - ack_info.mID = id; - ack_info.mPacketNum = decodePacketNum(packetnum); - ack_info.mRemoteHost = mesgsys->getSender(); - mXferAckQueue.push_back(ack_info); - } - - if (isLastPacket(packetnum)) - { - xferp->processEOF(); - removeXfer(xferp,mReceiveList); - startPendingDownloads(); - } + xferp->setXferSize(xfer_size); + + // adjust buffer start and size + result = xferp->receiveData(&(fdata_buf[sizeof(S32)]),fdata_size-(sizeof(S32))); + } + else + { + result = xferp->receiveData(fdata_buf,fdata_size); + } + + if (result == LL_ERR_CANNOT_OPEN_FILE) + { + xferp->abort(LL_ERR_CANNOT_OPEN_FILE); + removeXfer(xferp,mReceiveList); + startPendingDownloads(); + return; + } + + xferp->mPacketNum++; // expect next packet + + if (!mUseAckThrottling) + { + // No throttling, confirm right away + sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); + } + else + { + // Throttling, put on queue to be confirmed later. + LLXferAckInfo ack_info; + ack_info.mID = id; + ack_info.mPacketNum = decodePacketNum(packetnum); + ack_info.mRemoteHost = mesgsys->getSender(); + mXferAckQueue.push_back(ack_info); + } + + if (isLastPacket(packetnum)) + { + xferp->processEOF(); + removeXfer(xferp,mReceiveList); + startPendingDownloads(); + } } /////////////////////////////////////////////////////////// @@ -631,363 +631,363 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host) { #ifdef LL_XFER_PROGRESS_MESSAGES - if (!(packetnum % 50)) - { - cout << "confirming xfer packet #" << packetnum << endl; - } + if (!(packetnum % 50)) + { + cout << "confirming xfer packet #" << packetnum << endl; + } #endif - mesgsys->newMessageFast(_PREHASH_ConfirmXferPacket); - mesgsys->nextBlockFast(_PREHASH_XferID); - mesgsys->addU64Fast(_PREHASH_ID, id); - mesgsys->addU32Fast(_PREHASH_Packet, packetnum); + mesgsys->newMessageFast(_PREHASH_ConfirmXferPacket); + mesgsys->nextBlockFast(_PREHASH_XferID); + mesgsys->addU64Fast(_PREHASH_ID, id); + mesgsys->addU32Fast(_PREHASH_Packet, packetnum); - // Ignore a circuit failure here, we'll catch it with another message - mesgsys->sendMessage(remote_host); + // Ignore a circuit failure here, we'll catch it with another message + mesgsys->sendMessage(remote_host); } /////////////////////////////////////////////////////////// static bool find_and_remove(std::multiset<std::string>& files, - const std::string& filename) + const std::string& filename) { - std::multiset<std::string>::iterator ptr; - if ( (ptr = files.find(filename)) != files.end()) - { - //erase(filename) erases *all* entries with that key - files.erase(ptr); - return true; - } - return false; + std::multiset<std::string>::iterator ptr; + if ( (ptr = files.find(filename)) != files.end()) + { + //erase(filename) erases *all* entries with that key + files.erase(ptr); + return true; + } + return false; } void LLXferManager::expectFileForRequest(const std::string& filename) { - mExpectedRequests.insert(filename); + mExpectedRequests.insert(filename); } bool LLXferManager::validateFileForRequest(const std::string& filename) { - return find_and_remove(mExpectedRequests, filename); + return find_and_remove(mExpectedRequests, filename); } void LLXferManager::expectFileForTransfer(const std::string& filename) { - mExpectedTransfers.insert(filename); + mExpectedTransfers.insert(filename); } bool LLXferManager::validateFileForTransfer(const std::string& filename) { - return find_and_remove(mExpectedTransfers, filename); + return find_and_remove(mExpectedTransfers, filename); } /* Present in fireengine, not used by viewer void LLXferManager::expectVFileForRequest(const std::string& filename) { - mExpectedVFileRequests.insert(filename); + mExpectedVFileRequests.insert(filename); } bool LLXferManager::validateVFileForRequest(const std::string& filename) { - return find_and_remove(mExpectedVFileRequests, filename); + return find_and_remove(mExpectedVFileRequests, filename); } void LLXferManager::expectVFileForTransfer(const std::string& filename) { - mExpectedVFileTransfers.insert(filename); + mExpectedVFileTransfers.insert(filename); } bool LLXferManager::validateVFileForTransfer(const std::string& filename) { - return find_and_remove(mExpectedVFileTransfers, filename); + return find_and_remove(mExpectedVFileTransfers, filename); } */ static bool remove_prefix(std::string& filename, const std::string& prefix) { - if (std::equal(prefix.begin(), prefix.end(), filename.begin())) - { - filename = filename.substr(prefix.length()); - return true; - } - return false; + if (std::equal(prefix.begin(), prefix.end(), filename.begin())) + { + filename = filename.substr(prefix.length()); + return true; + } + return false; } static bool verify_cache_filename(const std::string& filename) { - //NOTE: This routine is only used to check file names that our own - // code places in the cache directory. As such, it can be limited - // to this very restrictive file name pattern. It does not need to - // handle other characters. The only known uses of this are (with examples): - // sim to sim object pass: fc0b72d8-9456-63d9-a802-a557ef847313.tmp - // sim to viewer mute list: mute_b78eacd0-1244-448e-93ca-28ede242f647.tmp - // sim to viewer task inventory: inventory_d8ab59d2-baf0-0e79-c4c2-a3f99b9fcf45.tmp - - //IMPORTANT: Do not broaden the filenames accepted by this routine - // without careful analysis. Anything allowed by this function can - // be downloaded by the viewer. - - size_t len = filename.size(); - //const boost::regex expr("[0-9a-zA-Z_-]<1,46>\.tmp"); - if (len < 5 || len > 50) - { - return false; - } - for(size_t i=0; i<(len-4); ++i) - { - char c = filename[i]; - bool ok = isalnum(c) || '_'==c || '-'==c; - if (!ok) - { - return false; - } - } - return filename[len-4] == '.' - && filename[len-3] == 't' - && filename[len-2] == 'm' - && filename[len-1] == 'p'; + //NOTE: This routine is only used to check file names that our own + // code places in the cache directory. As such, it can be limited + // to this very restrictive file name pattern. It does not need to + // handle other characters. The only known uses of this are (with examples): + // sim to sim object pass: fc0b72d8-9456-63d9-a802-a557ef847313.tmp + // sim to viewer mute list: mute_b78eacd0-1244-448e-93ca-28ede242f647.tmp + // sim to viewer task inventory: inventory_d8ab59d2-baf0-0e79-c4c2-a3f99b9fcf45.tmp + + //IMPORTANT: Do not broaden the filenames accepted by this routine + // without careful analysis. Anything allowed by this function can + // be downloaded by the viewer. + + size_t len = filename.size(); + //const boost::regex expr("[0-9a-zA-Z_-]<1,46>\.tmp"); + if (len < 5 || len > 50) + { + return false; + } + for(size_t i=0; i<(len-4); ++i) + { + char c = filename[i]; + bool ok = isalnum(c) || '_'==c || '-'==c; + if (!ok) + { + return false; + } + } + return filename[len-4] == '.' + && filename[len-3] == 't' + && filename[len-2] == 'm' + && filename[len-1] == 'p'; } void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/) { - - U64 id; - std::string local_filename; - ELLPath local_path = LL_PATH_NONE; - S32 result = LL_ERR_NOERR; - LLUUID uuid; - LLAssetType::EType type; - S16 type_s16; - bool b_use_big_packets; - - mesgsys->getBOOL("XferID", "UseBigPackets", b_use_big_packets); - - mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); - char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_INFOS("Xfer") << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) - << " to " << mesgsys->getSender() << LL_ENDL; - - mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename); - - { - U8 local_path_u8; - mesgsys->getU8("XferID", "FilePath", local_path_u8); - local_path = (ELLPath)local_path_u8; - } - - mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid); - mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16); - type = (LLAssetType::EType)type_s16; - - LLXfer *xferp; - - if (uuid != LLUUID::null) - { // Request for an asset - use a cache file - if(NULL == LLAssetType::lookup(type)) - { - LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":" - << type_s16 << " to " << mesgsys->getSender() << LL_ENDL; - return; - } - - LL_INFOS("Xfer") << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL; - - xferp = (LLXfer *)new LLXfer_VFile(uuid, type); - if (xferp) - { - mSendList.push_front(xferp); - result = xferp->startSend(id,mesgsys->getSender()); - } - else - { - LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL; - } - } - else if (!local_filename.empty()) - { // Was given a file name to send - // See DEV-21775 for detailed security issues - - if (local_path == LL_PATH_NONE) - { - // this handles legacy simulators that are passing objects - // by giving a filename that explicitly names the cache directory - static const std::string legacy_cache_prefix = "data/"; - if (remove_prefix(local_filename, legacy_cache_prefix)) - { - local_path = LL_PATH_CACHE; - } - } - - switch (local_path) - { - case LL_PATH_NONE: - if(!validateFileForTransfer(local_filename)) - { - LL_WARNS("Xfer") << "SECURITY: Unapproved filename '" << local_filename << LL_ENDL; - return; - } - break; - - case LL_PATH_CACHE: - if(!verify_cache_filename(local_filename)) - { - LL_WARNS("Xfer") << "SECURITY: Illegal cache filename '" << local_filename << LL_ENDL; - return; - } - break; - - default: - LL_WARNS("Xfer") << "SECURITY: Restricted file dir enum: " << (U32)local_path << LL_ENDL; - return; - } - - // If we want to use a special path (e.g. LL_PATH_CACHE), we want to make sure we create the - // proper expanded filename. - std::string expanded_filename; - if (local_path != LL_PATH_NONE) - { - expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename ); - } - else - { - expanded_filename = local_filename; - } - LL_INFOS("Xfer") << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << LL_ENDL; - - bool delete_local_on_completion = false; - mesgsys->getBOOL("XferID", "DeleteOnCompletion", delete_local_on_completion); - - // -1 chunk_size causes it to use the default - xferp = (LLXfer *)new LLXfer_File(expanded_filename, delete_local_on_completion, b_use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1); - - if (xferp) - { - mSendList.push_front(xferp); - result = xferp->startSend(id,mesgsys->getSender()); - } - else - { - LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL; - } - } - else - { // no uuid or filename - use the ID sent - char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_INFOS("Xfer") << "starting memory transfer: " - << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " - << mesgsys->getSender() << LL_ENDL; - - xferp = findXferByID(id, mSendList); - - if (xferp) - { - result = xferp->startSend(id,mesgsys->getSender()); - } - else - { - LL_INFOS("Xfer") << "Warning: xfer ID " << U64_BUF << " not found." << LL_ENDL; - result = LL_ERR_FILE_NOT_FOUND; - } - } - - if (result) - { - if (xferp) - { - xferp->abort(result); - removeXfer(xferp, mSendList); - } - else // can happen with a memory transfer not found - { - LL_INFOS("Xfer") << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << LL_ENDL; - - mesgsys->newMessageFast(_PREHASH_AbortXfer); - mesgsys->nextBlockFast(_PREHASH_XferID); - mesgsys->addU64Fast(_PREHASH_ID, id); - mesgsys->addS32Fast(_PREHASH_Result, result); - - mesgsys->sendMessage(mesgsys->getSender()); - } - } - else if(xferp) - { - // Figure out how many transfers the host has requested - LLHostStatus *host_statusp = findHostStatus(xferp->mRemoteHost); - if (host_statusp) - { - if (host_statusp->mNumActive < mMaxOutgoingXfersPerCircuit) - { // Not many transfers in progress already, so start immediately - xferp->sendNextPacket(); - changeNumActiveXfers(xferp->mRemoteHost,1); - LL_DEBUGS("Xfer") << "Starting xfer ID " << U64_to_str(id) << " immediately" << LL_ENDL; - } - else if (mHardLimitOutgoingXfersPerCircuit == 0 || - (host_statusp->mNumActive + host_statusp->mNumPending) < mHardLimitOutgoingXfersPerCircuit) - { // Must close the file handle and wait for earlier ones to complete - LL_INFOS("Xfer") << " queueing xfer request id " << U64_to_str(id) << ", " - << host_statusp->mNumActive << " active and " - << host_statusp->mNumPending << " pending ahead of this one" - << LL_ENDL; - xferp->closeFileHandle(); // Close the file handle until we're ready to send again - } - else if (mHardLimitOutgoingXfersPerCircuit > 0) - { // Way too many requested ... it's time to stop being nice and kill the circuit - xferp->closeFileHandle(); // Close the file handle in any case - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(xferp->mRemoteHost); - if (cdp) - { - if (cdp->getTrusted()) - { // Trusted internal circuit - don't kill it - LL_WARNS("Xfer") << "Trusted circuit to " << xferp->mRemoteHost << " has too many xfer requests in the queue " - << host_statusp->mNumActive << " active and " - << host_statusp->mNumPending << " pending ahead of this one" - << LL_ENDL; - } - else - { // Untrusted circuit - time to stop messing around and kill it - LL_WARNS("Xfer") << "Killing circuit to " << xferp->mRemoteHost << " for having too many xfer requests in the queue " - << host_statusp->mNumActive << " active and " - << host_statusp->mNumPending << " pending ahead of this one" - << LL_ENDL; - gMessageSystem->disableCircuit(xferp->mRemoteHost); - } - } - else - { // WTF? Why can't we find a circuit? Try to kill it off - LL_WARNS("Xfer") << "Backlog with circuit to " << xferp->mRemoteHost << " with too many xfer requests in the queue " - << host_statusp->mNumActive << " active and " - << host_statusp->mNumPending << " pending ahead of this one" - << " but no LLCircuitData found???" - << LL_ENDL; - gMessageSystem->disableCircuit(xferp->mRemoteHost); - } - } - } - else - { - LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << U64_to_str(id) - << " host " << xferp->mRemoteHost << LL_ENDL; - } - } - else - { - LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << U64_to_str(id) << LL_ENDL; - } + + U64 id; + std::string local_filename; + ELLPath local_path = LL_PATH_NONE; + S32 result = LL_ERR_NOERR; + LLUUID uuid; + LLAssetType::EType type; + S16 type_s16; + bool b_use_big_packets; + + mesgsys->getBOOL("XferID", "UseBigPackets", b_use_big_packets); + + mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); + char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ + LL_INFOS("Xfer") << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) + << " to " << mesgsys->getSender() << LL_ENDL; + + mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename); + + { + U8 local_path_u8; + mesgsys->getU8("XferID", "FilePath", local_path_u8); + local_path = (ELLPath)local_path_u8; + } + + mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid); + mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16); + type = (LLAssetType::EType)type_s16; + + LLXfer *xferp; + + if (uuid != LLUUID::null) + { // Request for an asset - use a cache file + if(NULL == LLAssetType::lookup(type)) + { + LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":" + << type_s16 << " to " << mesgsys->getSender() << LL_ENDL; + return; + } + + LL_INFOS("Xfer") << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL; + + xferp = (LLXfer *)new LLXfer_VFile(uuid, type); + if (xferp) + { + mSendList.push_front(xferp); + result = xferp->startSend(id,mesgsys->getSender()); + } + else + { + LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL; + } + } + else if (!local_filename.empty()) + { // Was given a file name to send + // See DEV-21775 for detailed security issues + + if (local_path == LL_PATH_NONE) + { + // this handles legacy simulators that are passing objects + // by giving a filename that explicitly names the cache directory + static const std::string legacy_cache_prefix = "data/"; + if (remove_prefix(local_filename, legacy_cache_prefix)) + { + local_path = LL_PATH_CACHE; + } + } + + switch (local_path) + { + case LL_PATH_NONE: + if(!validateFileForTransfer(local_filename)) + { + LL_WARNS("Xfer") << "SECURITY: Unapproved filename '" << local_filename << LL_ENDL; + return; + } + break; + + case LL_PATH_CACHE: + if(!verify_cache_filename(local_filename)) + { + LL_WARNS("Xfer") << "SECURITY: Illegal cache filename '" << local_filename << LL_ENDL; + return; + } + break; + + default: + LL_WARNS("Xfer") << "SECURITY: Restricted file dir enum: " << (U32)local_path << LL_ENDL; + return; + } + + // If we want to use a special path (e.g. LL_PATH_CACHE), we want to make sure we create the + // proper expanded filename. + std::string expanded_filename; + if (local_path != LL_PATH_NONE) + { + expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename ); + } + else + { + expanded_filename = local_filename; + } + LL_INFOS("Xfer") << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << LL_ENDL; + + bool delete_local_on_completion = false; + mesgsys->getBOOL("XferID", "DeleteOnCompletion", delete_local_on_completion); + + // -1 chunk_size causes it to use the default + xferp = (LLXfer *)new LLXfer_File(expanded_filename, delete_local_on_completion, b_use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1); + + if (xferp) + { + mSendList.push_front(xferp); + result = xferp->startSend(id,mesgsys->getSender()); + } + else + { + LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL; + } + } + else + { // no uuid or filename - use the ID sent + char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ + LL_INFOS("Xfer") << "starting memory transfer: " + << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " + << mesgsys->getSender() << LL_ENDL; + + xferp = findXferByID(id, mSendList); + + if (xferp) + { + result = xferp->startSend(id,mesgsys->getSender()); + } + else + { + LL_INFOS("Xfer") << "Warning: xfer ID " << U64_BUF << " not found." << LL_ENDL; + result = LL_ERR_FILE_NOT_FOUND; + } + } + + if (result) + { + if (xferp) + { + xferp->abort(result); + removeXfer(xferp, mSendList); + } + else // can happen with a memory transfer not found + { + LL_INFOS("Xfer") << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << LL_ENDL; + + mesgsys->newMessageFast(_PREHASH_AbortXfer); + mesgsys->nextBlockFast(_PREHASH_XferID); + mesgsys->addU64Fast(_PREHASH_ID, id); + mesgsys->addS32Fast(_PREHASH_Result, result); + + mesgsys->sendMessage(mesgsys->getSender()); + } + } + else if(xferp) + { + // Figure out how many transfers the host has requested + LLHostStatus *host_statusp = findHostStatus(xferp->mRemoteHost); + if (host_statusp) + { + if (host_statusp->mNumActive < mMaxOutgoingXfersPerCircuit) + { // Not many transfers in progress already, so start immediately + xferp->sendNextPacket(); + changeNumActiveXfers(xferp->mRemoteHost,1); + LL_DEBUGS("Xfer") << "Starting xfer ID " << U64_to_str(id) << " immediately" << LL_ENDL; + } + else if (mHardLimitOutgoingXfersPerCircuit == 0 || + (host_statusp->mNumActive + host_statusp->mNumPending) < mHardLimitOutgoingXfersPerCircuit) + { // Must close the file handle and wait for earlier ones to complete + LL_INFOS("Xfer") << " queueing xfer request id " << U64_to_str(id) << ", " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + xferp->closeFileHandle(); // Close the file handle until we're ready to send again + } + else if (mHardLimitOutgoingXfersPerCircuit > 0) + { // Way too many requested ... it's time to stop being nice and kill the circuit + xferp->closeFileHandle(); // Close the file handle in any case + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(xferp->mRemoteHost); + if (cdp) + { + if (cdp->getTrusted()) + { // Trusted internal circuit - don't kill it + LL_WARNS("Xfer") << "Trusted circuit to " << xferp->mRemoteHost << " has too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + } + else + { // Untrusted circuit - time to stop messing around and kill it + LL_WARNS("Xfer") << "Killing circuit to " << xferp->mRemoteHost << " for having too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + gMessageSystem->disableCircuit(xferp->mRemoteHost); + } + } + else + { // WTF? Why can't we find a circuit? Try to kill it off + LL_WARNS("Xfer") << "Backlog with circuit to " << xferp->mRemoteHost << " with too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << " but no LLCircuitData found???" + << LL_ENDL; + gMessageSystem->disableCircuit(xferp->mRemoteHost); + } + } + } + else + { + LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << U64_to_str(id) + << " host " << xferp->mRemoteHost << LL_ENDL; + } + } + else + { + LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << U64_to_str(id) << LL_ENDL; + } } - + /////////////////////////////////////////////////////////// // Return true if host is in a transfer-flood sitation. Same check for both internal and external hosts bool LLXferManager::isHostFlooded(const LLHost & host) { - bool flooded = false; - LLHostStatus *host_statusp = findHostStatus(host); - if (host_statusp) - { - flooded = (mHardLimitOutgoingXfersPerCircuit > 0 && - (host_statusp->mNumActive + host_statusp->mNumPending) >= (S32)(mHardLimitOutgoingXfersPerCircuit * 0.8f)); - } - - return flooded; + bool flooded = false; + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) + { + flooded = (mHardLimitOutgoingXfersPerCircuit > 0 && + (host_statusp->mNumActive + host_statusp->mNumPending) >= (S32)(mHardLimitOutgoingXfersPerCircuit * 0.8f)); + } + + return flooded; } @@ -995,26 +995,26 @@ bool LLXferManager::isHostFlooded(const LLHost & host) void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*user_data*/) { - U64 id = 0; - S32 packetNum = 0; - - mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); - mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetNum); - - LLXfer* xferp = findXferByID(id, mSendList); - if (xferp) - { -// cout << "confirmed packet #" << packetNum << " ping: "<< xferp->ACKTimer.getElapsedTimeF32() << endl; - xferp->mWaitingForACK = false; - if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) - { - xferp->sendNextPacket(); - } - else - { - removeXfer(xferp, mSendList); - } - } + U64 id = 0; + S32 packetNum = 0; + + mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); + mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetNum); + + LLXfer* xferp = findXferByID(id, mSendList); + if (xferp) + { +// cout << "confirmed packet #" << packetNum << " ping: "<< xferp->ACKTimer.getElapsedTimeF32() << endl; + xferp->mWaitingForACK = false; + if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) + { + xferp->sendNextPacket(); + } + else + { + removeXfer(xferp, mSendList); + } + } } /////////////////////////////////////////////////////////// @@ -1022,229 +1022,229 @@ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*use // Called from LLMessageSystem::processAcks() void LLXferManager::retransmitUnackedPackets() { - LLXfer *xferp; - - xfer_list_t::iterator iter = mReceiveList.begin(); - while (iter != mReceiveList.end()) - { - xferp = (*iter); - if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) - { - // if the circuit dies, abort - if (! gMessageSystem->mCircuitInfo.isCircuitAlive( xferp->mRemoteHost )) - { - LL_WARNS("Xfer") << "Xfer found in progress on dead circuit, aborting transfer to " - << xferp->mRemoteHost.getIPandPort() - << LL_ENDL; - xferp->mCallbackResult = LL_ERR_CIRCUIT_GONE; - xferp->processEOF(); - - iter = mReceiveList.erase(iter); // iter is set to next one after the deletion point - delete (xferp); - continue; - } - - } - ++iter; - } - - // Re-build mOutgoingHosts data - updateHostStatus(); - - F32 et; - iter = mSendList.begin(); - while (iter != mSendList.end()) - { - xferp = (*iter); - if (xferp->mWaitingForACK && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_PACKET_TIMEOUT)) - { - if (xferp->mRetries > LL_PACKET_RETRY_LIMIT) - { - LL_INFOS("Xfer") << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL; - xferp->abort(LL_ERR_TCP_TIMEOUT); - iter = mSendList.erase(iter); - delete xferp; - continue; - } - else - { - LL_INFOS("Xfer") << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL; - xferp->resendLastPacket(); - } - } - else if ((xferp->mStatus == e_LL_XFER_REGISTERED) && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_XFER_REGISTRATION_TIMEOUT)) - { - LL_INFOS("Xfer") << "registered xfer never requested, xfer dropped" << LL_ENDL; - xferp->abort(LL_ERR_TCP_TIMEOUT); - iter = mSendList.erase(iter); - delete xferp; - continue; - } - else if (xferp->mStatus == e_LL_XFER_ABORTED) - { - LL_WARNS("Xfer") << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL; - iter = mSendList.erase(iter); - delete xferp; - continue; - } - else if (xferp->mStatus == e_LL_XFER_PENDING) - { -// LL_INFOS("Xfer") << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL; - if (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit) - { - if (xferp->reopenFileHandle()) - { - LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << U64_to_str(xferp->mID) - << " to host " << xferp->mRemoteHost << LL_ENDL; - xferp->abort(LL_ERR_CANNOT_OPEN_FILE); - iter = mSendList.erase(iter); - delete xferp; - continue; - } - else - { // No error re-opening the file, send the first packet - LL_DEBUGS("Xfer") << "Moving pending xfer ID " << U64_to_str(xferp->mID) << " to active" << LL_ENDL; - xferp->sendNextPacket(); - changeNumActiveXfers(xferp->mRemoteHost,1); - } - } - } - ++iter; - } // end while() loop - - // - // HACK - if we're using xfer confirm throttling, throttle our xfer confirms here - // so we don't blow through bandwidth. - // - - while (mXferAckQueue.size()) - { - if (mAckThrottle.checkOverflow(1000.0f*8.0f)) - { - break; - } - //LL_INFOS("Xfer") << "Confirm packet queue length:" << mXferAckQueue.size() << LL_ENDL; - LLXferAckInfo ack_info = mXferAckQueue.front(); - mXferAckQueue.pop_front(); - //LL_INFOS("Xfer") << "Sending confirm packet" << LL_ENDL; - sendConfirmPacket(gMessageSystem, ack_info.mID, ack_info.mPacketNum, ack_info.mRemoteHost); - mAckThrottle.throttleOverflow(1000.f*8.f); // Assume 1000 bytes/packet - } + LLXfer *xferp; + + xfer_list_t::iterator iter = mReceiveList.begin(); + while (iter != mReceiveList.end()) + { + xferp = (*iter); + if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) + { + // if the circuit dies, abort + if (! gMessageSystem->mCircuitInfo.isCircuitAlive( xferp->mRemoteHost )) + { + LL_WARNS("Xfer") << "Xfer found in progress on dead circuit, aborting transfer to " + << xferp->mRemoteHost.getIPandPort() + << LL_ENDL; + xferp->mCallbackResult = LL_ERR_CIRCUIT_GONE; + xferp->processEOF(); + + iter = mReceiveList.erase(iter); // iter is set to next one after the deletion point + delete (xferp); + continue; + } + + } + ++iter; + } + + // Re-build mOutgoingHosts data + updateHostStatus(); + + F32 et; + iter = mSendList.begin(); + while (iter != mSendList.end()) + { + xferp = (*iter); + if (xferp->mWaitingForACK && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_PACKET_TIMEOUT)) + { + if (xferp->mRetries > LL_PACKET_RETRY_LIMIT) + { + LL_INFOS("Xfer") << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL; + xferp->abort(LL_ERR_TCP_TIMEOUT); + iter = mSendList.erase(iter); + delete xferp; + continue; + } + else + { + LL_INFOS("Xfer") << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL; + xferp->resendLastPacket(); + } + } + else if ((xferp->mStatus == e_LL_XFER_REGISTERED) && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_XFER_REGISTRATION_TIMEOUT)) + { + LL_INFOS("Xfer") << "registered xfer never requested, xfer dropped" << LL_ENDL; + xferp->abort(LL_ERR_TCP_TIMEOUT); + iter = mSendList.erase(iter); + delete xferp; + continue; + } + else if (xferp->mStatus == e_LL_XFER_ABORTED) + { + LL_WARNS("Xfer") << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL; + iter = mSendList.erase(iter); + delete xferp; + continue; + } + else if (xferp->mStatus == e_LL_XFER_PENDING) + { +// LL_INFOS("Xfer") << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL; + if (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit) + { + if (xferp->reopenFileHandle()) + { + LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << U64_to_str(xferp->mID) + << " to host " << xferp->mRemoteHost << LL_ENDL; + xferp->abort(LL_ERR_CANNOT_OPEN_FILE); + iter = mSendList.erase(iter); + delete xferp; + continue; + } + else + { // No error re-opening the file, send the first packet + LL_DEBUGS("Xfer") << "Moving pending xfer ID " << U64_to_str(xferp->mID) << " to active" << LL_ENDL; + xferp->sendNextPacket(); + changeNumActiveXfers(xferp->mRemoteHost,1); + } + } + } + ++iter; + } // end while() loop + + // + // HACK - if we're using xfer confirm throttling, throttle our xfer confirms here + // so we don't blow through bandwidth. + // + + while (mXferAckQueue.size()) + { + if (mAckThrottle.checkOverflow(1000.0f*8.0f)) + { + break; + } + //LL_INFOS("Xfer") << "Confirm packet queue length:" << mXferAckQueue.size() << LL_ENDL; + LLXferAckInfo ack_info = mXferAckQueue.front(); + mXferAckQueue.pop_front(); + //LL_INFOS("Xfer") << "Sending confirm packet" << LL_ENDL; + sendConfirmPacket(gMessageSystem, ack_info.mID, ack_info.mPacketNum, ack_info.mRemoteHost); + mAckThrottle.throttleOverflow(1000.f*8.f); // Assume 1000 bytes/packet + } } /////////////////////////////////////////////////////////// void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code) { - LLXfer * xferp = findXferByID(xfer_id, mReceiveList); - if (xferp) - { - if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) - { - // causes processAbort(); - xferp->abort(result_code); - } - else - { - xferp->mCallbackResult = result_code; - xferp->processEOF(); //should notify requester - removeXfer(xferp, mReceiveList); - } - // Since already removed or marked as aborted no need - // to wait for processAbort() to start new download - startPendingDownloads(); - } + LLXfer * xferp = findXferByID(xfer_id, mReceiveList); + if (xferp) + { + if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) + { + // causes processAbort(); + xferp->abort(result_code); + } + else + { + xferp->mCallbackResult = result_code; + xferp->processEOF(); //should notify requester + removeXfer(xferp, mReceiveList); + } + // Since already removed or marked as aborted no need + // to wait for processAbort() to start new download + startPendingDownloads(); + } } /////////////////////////////////////////////////////////// void LLXferManager::processAbort (LLMessageSystem *mesgsys, void ** /*user_data*/) { - U64 id = 0; - S32 result_code = 0; - LLXfer * xferp; - - mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); - mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Result, result_code); - - xferp = findXferByID(id, mReceiveList); - if (xferp) - { - xferp->mCallbackResult = result_code; - xferp->processEOF(); - removeXfer(xferp, mReceiveList); - startPendingDownloads(); - } + U64 id = 0; + S32 result_code = 0; + LLXfer * xferp; + + mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); + mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Result, result_code); + + xferp = findXferByID(id, mReceiveList); + if (xferp) + { + xferp->mCallbackResult = result_code; + xferp->processEOF(); + removeXfer(xferp, mReceiveList); + startPendingDownloads(); + } } /////////////////////////////////////////////////////////// void LLXferManager::startPendingDownloads() { - // This method goes through the list, and starts pending - // operations until active downloads == mMaxIncomingXfers. I copy - // the pending xfers into a temporary data structure because the - // xfers are stored as an intrusive linked list where older - // requests get pushed toward the back. Thus, if we didn't do a - // stateful iteration, it would be possible for old requests to - // never start. - LLXfer* xferp; - std::list<LLXfer*> pending_downloads; - S32 download_count = 0; - S32 pending_count = 0; - for (xfer_list_t::iterator iter = mReceiveList.begin(); - iter != mReceiveList.end(); - ++iter) - { - xferp = (*iter); - if(xferp->mStatus == e_LL_XFER_PENDING) - { // Count and accumulate pending downloads - ++pending_count; - pending_downloads.push_front(xferp); - } - else if(xferp->mStatus == e_LL_XFER_IN_PROGRESS) - { // Count downloads in progress - ++download_count; - } - } - - S32 start_count = mMaxIncomingXfers - download_count; - - LL_DEBUGS("Xfer") << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: " - << download_count << " XFER_PENDING: " << pending_count - << " startring " << llmin(start_count, pending_count) << LL_ENDL; - - if((start_count > 0) && (pending_count > 0)) - { - S32 result; - for (std::list<LLXfer*>::iterator iter = pending_downloads.begin(); - iter != pending_downloads.end(); ++iter) - { - xferp = *iter; - if (start_count-- <= 0) - break; - result = xferp->startDownload(); - if(result) - { - xferp->abort(result); - ++start_count; - } - } - } + // This method goes through the list, and starts pending + // operations until active downloads == mMaxIncomingXfers. I copy + // the pending xfers into a temporary data structure because the + // xfers are stored as an intrusive linked list where older + // requests get pushed toward the back. Thus, if we didn't do a + // stateful iteration, it would be possible for old requests to + // never start. + LLXfer* xferp; + std::list<LLXfer*> pending_downloads; + S32 download_count = 0; + S32 pending_count = 0; + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); + ++iter) + { + xferp = (*iter); + if(xferp->mStatus == e_LL_XFER_PENDING) + { // Count and accumulate pending downloads + ++pending_count; + pending_downloads.push_front(xferp); + } + else if(xferp->mStatus == e_LL_XFER_IN_PROGRESS) + { // Count downloads in progress + ++download_count; + } + } + + S32 start_count = mMaxIncomingXfers - download_count; + + LL_DEBUGS("Xfer") << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: " + << download_count << " XFER_PENDING: " << pending_count + << " startring " << llmin(start_count, pending_count) << LL_ENDL; + + if((start_count > 0) && (pending_count > 0)) + { + S32 result; + for (std::list<LLXfer*>::iterator iter = pending_downloads.begin(); + iter != pending_downloads.end(); ++iter) + { + xferp = *iter; + if (start_count-- <= 0) + break; + result = xferp->startDownload(); + if(result) + { + xferp->abort(result); + ++start_count; + } + } + } } /////////////////////////////////////////////////////////// void LLXferManager::addToList(LLXfer* xferp, xfer_list_t & xfer_list, bool is_priority) { - if(is_priority) - { - xfer_list.push_back(xferp); - } - else - { - xfer_list.push_front(xferp); - } + if(is_priority) + { + xfer_list.push_back(xferp); + } + else + { + xfer_list.push_front(xferp); + } } /////////////////////////////////////////////////////////// @@ -1256,47 +1256,47 @@ LLXferManager *gXferManager = NULL; void start_xfer_manager() { - gXferManager = new LLXferManager(); + gXferManager = new LLXferManager(); } void cleanup_xfer_manager() { - if (gXferManager) - { - delete(gXferManager); - gXferManager = NULL; - } + if (gXferManager) + { + delete(gXferManager); + gXferManager = NULL; + } } void process_confirm_packet (LLMessageSystem *mesgsys, void **user_data) { - gXferManager->processConfirmation(mesgsys,user_data); + gXferManager->processConfirmation(mesgsys,user_data); } void process_request_xfer(LLMessageSystem *mesgsys, void **user_data) { - gXferManager->processFileRequest(mesgsys,user_data); + gXferManager->processFileRequest(mesgsys,user_data); } void continue_file_receive(LLMessageSystem *mesgsys, void **user_data) { #if LL_TEST_XFER_REXMIT - if (ll_frand() > 0.05f) - { + if (ll_frand() > 0.05f) + { #endif - gXferManager->processReceiveData(mesgsys,user_data); + gXferManager->processReceiveData(mesgsys,user_data); #if LL_TEST_XFER_REXMIT - } - else - { - cout << "oops! dropped a xfer packet" << endl; - } + } + else + { + cout << "oops! dropped a xfer packet" << endl; + } #endif } void process_abort_xfer(LLMessageSystem *mesgsys, void **user_data) { - gXferManager->processAbort(mesgsys,user_data); + gXferManager->processAbort(mesgsys,user_data); } diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h index 5b42e781eb..3be5f5a228 100644 --- a/indra/llmessage/llxfermanager.h +++ b/indra/llmessage/llxfermanager.h @@ -1,4 +1,4 @@ -/** +/** * @file llxfermanager.h * @brief definition of LLXferManager class for a keeping track of * multiple xfers @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,7 +29,7 @@ #define LL_LLXFERMANAGER_H /** - * this manager keeps both a send list and a receive list; anything with a + * this manager keeps both a send list and a receive list; anything with a * LLXferManager can send and receive files via messages */ @@ -46,167 +46,167 @@ class LLXfer; class LLHostStatus { public: - LLHost mHost; - S32 mNumActive; - S32 mNumPending; + LLHost mHost; + S32 mNumActive; + S32 mNumPending; - LLHostStatus() {mNumActive = 0; mNumPending = 0;}; - virtual ~LLHostStatus(){}; + LLHostStatus() {mNumActive = 0; mNumPending = 0;}; + virtual ~LLHostStatus(){}; }; // Class stores ack information, to be put on list so we can throttle xfer rate. class LLXferAckInfo { public: - LLXferAckInfo(U32 dummy = 0) - { - mID = 0; - mPacketNum = -1; - } - - U64 mID; - S32 mPacketNum; - LLHost mRemoteHost; + LLXferAckInfo(U32 dummy = 0) + { + mID = 0; + mPacketNum = -1; + } + + U64 mID; + S32 mPacketNum; + LLHost mRemoteHost; }; class LLXferManager { protected: - S32 mMaxOutgoingXfersPerCircuit; - S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection - S32 mMaxIncomingXfers; + S32 mMaxOutgoingXfersPerCircuit; + S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection + S32 mMaxIncomingXfers; - bool mUseAckThrottling; // Use ack throttling to cap file xfer bandwidth - std::deque<LLXferAckInfo> mXferAckQueue; - LLThrottle mAckThrottle; + bool mUseAckThrottling; // Use ack throttling to cap file xfer bandwidth + std::deque<LLXferAckInfo> mXferAckQueue; + LLThrottle mAckThrottle; public: - // This enumeration is useful in the requestFile() to specify if - // an xfer must happen asap. - enum - { - LOW_PRIORITY = false, - HIGH_PRIORITY = true, - }; + // This enumeration is useful in the requestFile() to specify if + // an xfer must happen asap. + enum + { + LOW_PRIORITY = false, + HIGH_PRIORITY = true, + }; - // Linked FIFO list, add to the front and pull from back - typedef std::deque<LLXfer *> xfer_list_t; - xfer_list_t mSendList; - xfer_list_t mReceiveList; + // Linked FIFO list, add to the front and pull from back + typedef std::deque<LLXfer *> xfer_list_t; + xfer_list_t mSendList; + xfer_list_t mReceiveList; - typedef std::list<LLHostStatus*> status_list_t; - status_list_t mOutgoingHosts; + typedef std::list<LLHostStatus*> status_list_t; + status_list_t mOutgoingHosts; protected: - // implementation methods - virtual void startPendingDownloads(); - virtual void addToList(LLXfer* xferp, xfer_list_t & xfer_list, bool is_priority); - std::multiset<std::string> mExpectedTransfers; // files that are authorized to transfer out - std::multiset<std::string> mExpectedRequests; // files that are authorized to be downloaded on top of - std::multiset<std::string> mExpectedVFileTransfers; // files that are authorized to transfer out - std::multiset<std::string> mExpectedVFileRequests; // files that are authorized to be downloaded on top of + // implementation methods + virtual void startPendingDownloads(); + virtual void addToList(LLXfer* xferp, xfer_list_t & xfer_list, bool is_priority); + std::multiset<std::string> mExpectedTransfers; // files that are authorized to transfer out + std::multiset<std::string> mExpectedRequests; // files that are authorized to be downloaded on top of + std::multiset<std::string> mExpectedVFileTransfers; // files that are authorized to transfer out + std::multiset<std::string> mExpectedVFileRequests; // files that are authorized to be downloaded on top of public: - LLXferManager(); - virtual ~LLXferManager(); + LLXferManager(); + virtual ~LLXferManager(); - virtual void init(); - virtual void cleanup(); + virtual void init(); + virtual void cleanup(); - void setUseAckThrottling(const bool use); - void setAckThrottleBPS(const F32 bps); + void setUseAckThrottling(const bool use); + void setAckThrottleBPS(const F32 bps); // list management routines - virtual LLXfer *findXferByID(U64 id, xfer_list_t & xfer_list); - virtual void removeXfer (LLXfer *delp, xfer_list_t & xfer_list); + virtual LLXfer *findXferByID(U64 id, xfer_list_t & xfer_list); + virtual void removeXfer (LLXfer *delp, xfer_list_t & xfer_list); - LLHostStatus * findHostStatus(const LLHost &host); - virtual S32 numActiveXfers(const LLHost &host); - virtual S32 numPendingXfers(const LLHost &host); + LLHostStatus * findHostStatus(const LLHost &host); + virtual S32 numActiveXfers(const LLHost &host); + virtual S32 numPendingXfers(const LLHost &host); - virtual void changeNumActiveXfers(const LLHost &host, S32 delta); + virtual void changeNumActiveXfers(const LLHost &host, S32 delta); - virtual void setMaxOutgoingXfersPerCircuit (S32 max_num); - virtual void setHardLimitOutgoingXfersPerCircuit(S32 max_num); - virtual void setMaxIncomingXfers(S32 max_num); - virtual void updateHostStatus(); - virtual void printHostStatus(); + virtual void setMaxOutgoingXfersPerCircuit (S32 max_num); + virtual void setHardLimitOutgoingXfersPerCircuit(S32 max_num); + virtual void setMaxIncomingXfers(S32 max_num); + virtual void updateHostStatus(); + virtual void printHostStatus(); // general utility routines - virtual void registerCallbacks(LLMessageSystem *mesgsys); - virtual U64 getNextID (); - virtual S32 encodePacketNum(S32 packet_num, bool is_eof); - virtual S32 decodePacketNum(S32 packet_num); - virtual bool isLastPacket(S32 packet_num); + virtual void registerCallbacks(LLMessageSystem *mesgsys); + virtual U64 getNextID (); + virtual S32 encodePacketNum(S32 packet_num, bool is_eof); + virtual S32 decodePacketNum(S32 packet_num); + virtual bool isLastPacket(S32 packet_num); // file requesting routines // .. to file - virtual U64 requestFile(const std::string& local_filename, - const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - bool delete_remote_on_completion, - void (*callback)(void**,S32,LLExtStat), void** user_data, - bool is_priority = false, - bool use_big_packets = false); - /* + virtual U64 requestFile(const std::string& local_filename, + const std::string& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + bool delete_remote_on_completion, + void (*callback)(void**,S32,LLExtStat), void** user_data, + bool is_priority = false, + bool use_big_packets = false); + /* // .. to memory - virtual void requestFile(const std::string& remote_filename, - ELLPath remote_path, - const LLHost &remote_host, - bool delete_remote_on_completion, - void (*callback)(void*, S32, void**, S32, LLExtStat), - void** user_data, - bool is_priority = false); - */ + virtual void requestFile(const std::string& remote_filename, + ELLPath remote_path, + const LLHost &remote_host, + bool delete_remote_on_completion, + void (*callback)(void*, S32, void**, S32, LLExtStat), + void** user_data, + bool is_priority = false); + */ // vfile requesting // .. to vfile - virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id, - LLAssetType::EType type, - const LLHost& remote_host, - void (*callback)(void**,S32,LLExtStat), void** user_data, - bool is_priority = false); - /** - When arbitrary files are requested to be transfered (by giving a dir of LL_PATH_NONE) - they must be "expected", but having something pre-authorize them. This pair of functions - maintains a pre-authorized list. The first function adds something to the list, the second - checks if is authorized, removing it if so. In this way, a file is only authorized for - a single use. - */ - virtual void expectFileForTransfer(const std::string& filename); - virtual bool validateFileForTransfer(const std::string& filename); - /** - Same idea, but for the viewer about to call InitiateDownload to track what it requested. - */ - virtual void expectFileForRequest(const std::string& filename); - virtual bool validateFileForRequest(const std::string& filename); - - /** - Same idea but for VFiles, kept separate to avoid namespace overlap - */ - /* Present in fireengine, not used by viewer - virtual void expectVFileForTransfer(const std::string& filename); - virtual bool validateVFileForTransfer(const std::string& filename); - virtual void expectVFileForRequest(const std::string& filename); - virtual bool validateVFileForRequest(const std::string& filename); - */ - - virtual void processReceiveData (LLMessageSystem *mesgsys, void **user_data); - virtual void sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host); + virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id, + LLAssetType::EType type, + const LLHost& remote_host, + void (*callback)(void**,S32,LLExtStat), void** user_data, + bool is_priority = false); + /** + When arbitrary files are requested to be transfered (by giving a dir of LL_PATH_NONE) + they must be "expected", but having something pre-authorize them. This pair of functions + maintains a pre-authorized list. The first function adds something to the list, the second + checks if is authorized, removing it if so. In this way, a file is only authorized for + a single use. + */ + virtual void expectFileForTransfer(const std::string& filename); + virtual bool validateFileForTransfer(const std::string& filename); + /** + Same idea, but for the viewer about to call InitiateDownload to track what it requested. + */ + virtual void expectFileForRequest(const std::string& filename); + virtual bool validateFileForRequest(const std::string& filename); + + /** + Same idea but for VFiles, kept separate to avoid namespace overlap + */ + /* Present in fireengine, not used by viewer + virtual void expectVFileForTransfer(const std::string& filename); + virtual bool validateVFileForTransfer(const std::string& filename); + virtual void expectVFileForRequest(const std::string& filename); + virtual bool validateVFileForRequest(const std::string& filename); + */ + + virtual void processReceiveData (LLMessageSystem *mesgsys, void **user_data); + virtual void sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host); // file sending routines - virtual void processFileRequest (LLMessageSystem *mesgsys, void **user_data); - virtual void processConfirmation (LLMessageSystem *mesgsys, void **user_data); - virtual void retransmitUnackedPackets (); + virtual void processFileRequest (LLMessageSystem *mesgsys, void **user_data); + virtual void processConfirmation (LLMessageSystem *mesgsys, void **user_data); + virtual void retransmitUnackedPackets (); // error handling - void abortRequestById(U64 xfer_id, S32 result_code); - virtual void processAbort (LLMessageSystem *mesgsys, void **user_data); + void abortRequestById(U64 xfer_id, S32 result_code); + virtual void processAbort (LLMessageSystem *mesgsys, void **user_data); - virtual bool isHostFlooded(const LLHost & host); + virtual bool isHostFlooded(const LLHost & host); }; -extern LLXferManager* gXferManager; +extern LLXferManager* gXferManager; // initialization and garbage collection void start_xfer_manager(); diff --git a/indra/llmessage/llxorcipher.cpp b/indra/llmessage/llxorcipher.cpp index 17651b1ecf..8db4fca629 100644 --- a/indra/llmessage/llxorcipher.cpp +++ b/indra/llmessage/llxorcipher.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llxorcipher.cpp * @brief Implementation of LLXORCipher * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,94 +35,94 @@ ///---------------------------------------------------------------------------- LLXORCipher::LLXORCipher(const U8* pad, U32 pad_len) : - mPad(NULL), - mHead(NULL), - mPadLen(0) + mPad(NULL), + mHead(NULL), + mPadLen(0) { - init(pad, pad_len); + init(pad, pad_len); } // Destroys the object LLXORCipher::~LLXORCipher() { - init(NULL, 0); + init(NULL, 0); } LLXORCipher::LLXORCipher(const LLXORCipher& cipher) : - mPad(NULL), - mHead(NULL), - mPadLen(0) + mPad(NULL), + mHead(NULL), + mPadLen(0) { - init(cipher.mPad, cipher.mPadLen); + init(cipher.mPad, cipher.mPadLen); } LLXORCipher& LLXORCipher::operator=(const LLXORCipher& cipher) { - if(this == &cipher) return *this; - init(cipher.mPad, cipher.mPadLen); - return *this; + if(this == &cipher) return *this; + init(cipher.mPad, cipher.mPadLen); + return *this; } U32 LLXORCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) { - if(!src || !src_len || !dst || !dst_len || !mPad) return 0; - U8* pad_end = mPad + mPadLen; - U32 count = src_len; - while(count--) - { - *dst++ = *src++ ^ *mHead++; - if(mHead >= pad_end) mHead = mPad; - } - return src_len; + if(!src || !src_len || !dst || !dst_len || !mPad) return 0; + U8* pad_end = mPad + mPadLen; + U32 count = src_len; + while(count--) + { + *dst++ = *src++ ^ *mHead++; + if(mHead >= pad_end) mHead = mPad; + } + return src_len; } U32 LLXORCipher::decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) { - // xor is a symetric cipher, thus, just call the other function. - return encrypt(src, src_len, dst, dst_len); + // xor is a symetric cipher, thus, just call the other function. + return encrypt(src, src_len, dst, dst_len); } U32 LLXORCipher::requiredEncryptionSpace(U32 len) const { - return len; + return len; } void LLXORCipher::init(const U8* pad, U32 pad_len) { - if(mPad) - { - delete [] mPad; - mPad = NULL; - mPadLen = 0; - } - if(pad && pad_len) - { - mPadLen = pad_len; - mPad = new U8[mPadLen]; - if (mPad != NULL) - { - memcpy(mPad, pad, mPadLen); /* Flawfinder : ignore */ - } - } - mHead = mPad; + if(mPad) + { + delete [] mPad; + mPad = NULL; + mPadLen = 0; + } + if(pad && pad_len) + { + mPadLen = pad_len; + mPad = new U8[mPadLen]; + if (mPad != NULL) + { + memcpy(mPad, pad, mPadLen); /* Flawfinder : ignore */ + } + } + mHead = mPad; } #ifdef _DEBUG // static bool LLXORCipher::testHarness() { - const U32 PAD_LEN = 3; - const U8 PAD[] = "abc"; - const S32 MSG_LENGTH = 12; - const char MESSAGE[MSG_LENGTH+1] = "gesundheight"; /* Flawfinder : ignore */ - U8 encrypted[MSG_LENGTH]; - U8 decrypted[MSG_LENGTH]; + const U32 PAD_LEN = 3; + const U8 PAD[] = "abc"; + const S32 MSG_LENGTH = 12; + const char MESSAGE[MSG_LENGTH+1] = "gesundheight"; /* Flawfinder : ignore */ + U8 encrypted[MSG_LENGTH]; + U8 decrypted[MSG_LENGTH]; - LLXORCipher cipher(PAD, PAD_LEN); - cipher.encrypt((U8*)MESSAGE, MSG_LENGTH, encrypted, MSG_LENGTH); - cipher.decrypt(encrypted, MSG_LENGTH, decrypted, MSG_LENGTH); + LLXORCipher cipher(PAD, PAD_LEN); + cipher.encrypt((U8*)MESSAGE, MSG_LENGTH, encrypted, MSG_LENGTH); + cipher.decrypt(encrypted, MSG_LENGTH, decrypted, MSG_LENGTH); - if(0 != memcmp((void*)MESSAGE, decrypted, MSG_LENGTH)) return false; - return true; + if(0 != memcmp((void*)MESSAGE, decrypted, MSG_LENGTH)) return false; + return true; } #endif diff --git a/indra/llmessage/llxorcipher.h b/indra/llmessage/llxorcipher.h index cd1fed3ba4..50ea997b4d 100644 --- a/indra/llmessage/llxorcipher.h +++ b/indra/llmessage/llxorcipher.h @@ -1,24 +1,24 @@ -/** +/** * @file llxorcipher.h * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,31 +37,31 @@ class LLXORCipher : public LLCipher { public: - LLXORCipher(const U8* pad, U32 pad_len); - LLXORCipher(const LLXORCipher& cipher); - virtual ~LLXORCipher(); - LLXORCipher& operator=(const LLXORCipher& cipher); + LLXORCipher(const U8* pad, U32 pad_len); + LLXORCipher(const LLXORCipher& cipher); + virtual ~LLXORCipher(); + LLXORCipher& operator=(const LLXORCipher& cipher); - // Cipher functions - U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) override; - U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) override; - U32 requiredEncryptionSpace(U32 src_len) const override; + // Cipher functions + U32 encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) override; + U32 decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) override; + U32 requiredEncryptionSpace(U32 src_len) const override; - // special syntactic-sugar since xor can be performed in place. - bool encrypt(U8* buf, U32 len) { return encrypt((const U8*)buf, len, buf, len) > 0; } - bool decrypt(U8* buf, U32 len) { return decrypt((const U8*)buf, len, buf, len) > 0; } + // special syntactic-sugar since xor can be performed in place. + bool encrypt(U8* buf, U32 len) { return encrypt((const U8*)buf, len, buf, len) > 0; } + bool decrypt(U8* buf, U32 len) { return decrypt((const U8*)buf, len, buf, len) > 0; } #ifdef _DEBUG - // This function runs tests to make sure the crc is - // working. Returns true if it is. - static bool testHarness(); + // This function runs tests to make sure the crc is + // working. Returns true if it is. + static bool testHarness(); #endif protected: - void init(const U8* pad, U32 pad_len); - U8* mPad; - U8* mHead; - U32 mPadLen; + void init(const U8* pad, U32 pad_len); + U8* mPad; + U8* mHead; + U32 mPadLen; }; #endif diff --git a/indra/llmessage/machine.cpp b/indra/llmessage/machine.cpp index 1e9c9c3c9a..feb4ebfa8b 100644 --- a/indra/llmessage/machine.cpp +++ b/indra/llmessage/machine.cpp @@ -1,25 +1,25 @@ -/** +/** * @file machine.cpp * @brief LLMachine class header file * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,27 +30,27 @@ #include "llerror.h" void LLMachine::setMachinePort(S32 port) -{ - if (port < 0) - { - LL_INFOS() << "Can't assign a negative number to LLMachine::mPort" << LL_ENDL; - mHost.setPort(0); - } - else - { - mHost.setPort(port); - } +{ + if (port < 0) + { + LL_INFOS() << "Can't assign a negative number to LLMachine::mPort" << LL_ENDL; + mHost.setPort(0); + } + else + { + mHost.setPort(port); + } } -void LLMachine::setControlPort( S32 port ) +void LLMachine::setControlPort( S32 port ) { - if (port < 0) - { - LL_INFOS() << "Can't assign a negative number to LLMachine::mControlPort" << LL_ENDL; - mControlPort = 0; - } - else - { - mControlPort = port; - } + if (port < 0) + { + LL_INFOS() << "Can't assign a negative number to LLMachine::mControlPort" << LL_ENDL; + mControlPort = 0; + } + else + { + mControlPort = port; + } } diff --git a/indra/llmessage/machine.h b/indra/llmessage/machine.h index 831503741c..05d366cbc3 100644 --- a/indra/llmessage/machine.h +++ b/indra/llmessage/machine.h @@ -1,25 +1,25 @@ -/** +/** * @file machine.h * @brief LLMachine class header file * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,13 +32,13 @@ typedef enum e_machine_type { - MT_NULL, - MT_SIMULATOR, - MT_VIEWER, - MT_SPACE_SERVER, - MT_OBJECT_REPOSITORY, - MT_PROXY, - MT_EOF + MT_NULL, + MT_SIMULATOR, + MT_VIEWER, + MT_SPACE_SERVER, + MT_OBJECT_REPOSITORY, + MT_PROXY, + MT_EOF } EMachineType; const U32 ADDRESS_STRING_SIZE = 12; @@ -46,50 +46,50 @@ const U32 ADDRESS_STRING_SIZE = 12; class LLMachine { public: - LLMachine() - : mMachineType(MT_NULL), mControlPort(0) {} + LLMachine() + : mMachineType(MT_NULL), mControlPort(0) {} - LLMachine(EMachineType machine_type, U32 ip, S32 port) - : mMachineType(machine_type), mControlPort(0), mHost(ip,port) {} + LLMachine(EMachineType machine_type, U32 ip, S32 port) + : mMachineType(machine_type), mControlPort(0), mHost(ip,port) {} - LLMachine(EMachineType machine_type, const LLHost &host) - : mMachineType(machine_type) {mHost = host; mControlPort = 0;} + LLMachine(EMachineType machine_type, const LLHost &host) + : mMachineType(machine_type) {mHost = host; mControlPort = 0;} - ~LLMachine() {} + ~LLMachine() {} - // get functions - EMachineType getMachineType() const { return mMachineType; } - U32 getMachineIP() const { return mHost.getAddress(); } - S32 getMachinePort() const { return mHost.getPort(); } - const LLHost &getMachineHost() const { return mHost; } - // The control port is the listen port of the parent process that - // launched this machine. 0 means none or not known. - const S32 &getControlPort() const { return mControlPort; } - bool isValid() const { return (mHost.getPort() != 0); } // true if corresponds to functioning machine + // get functions + EMachineType getMachineType() const { return mMachineType; } + U32 getMachineIP() const { return mHost.getAddress(); } + S32 getMachinePort() const { return mHost.getPort(); } + const LLHost &getMachineHost() const { return mHost; } + // The control port is the listen port of the parent process that + // launched this machine. 0 means none or not known. + const S32 &getControlPort() const { return mControlPort; } + bool isValid() const { return (mHost.getPort() != 0); } // true if corresponds to functioning machine - // set functions - void setMachineType(EMachineType machine_type) { mMachineType = machine_type; } - void setMachineIP(U32 ip) { mHost.setAddress(ip); } - void setMachineHost(const LLHost &host) { mHost = host; } + // set functions + void setMachineType(EMachineType machine_type) { mMachineType = machine_type; } + void setMachineIP(U32 ip) { mHost.setAddress(ip); } + void setMachineHost(const LLHost &host) { mHost = host; } - void setMachinePort(S32 port); - void setControlPort( S32 port ); + void setMachinePort(S32 port); + void setControlPort( S32 port ); - // member variables + // member variables // Someday these should be made private. -// When they are, some of the code that breaks should +// When they are, some of the code that breaks should // become member functions of LLMachine -- Leviathan //private: - // I fixed the others, somebody should fix these! - djs - EMachineType mMachineType; + // I fixed the others, somebody should fix these! - djs + EMachineType mMachineType; protected: - S32 mControlPort; - LLHost mHost; + S32 mControlPort; + LLHost mHost; }; #endif diff --git a/indra/llmessage/mean_collision_data.h b/indra/llmessage/mean_collision_data.h index 29de091603..5b5b3f2fd2 100644 --- a/indra/llmessage/mean_collision_data.h +++ b/indra/llmessage/mean_collision_data.h @@ -1,4 +1,4 @@ -/** +/** * @file mean_collision_data.h * @brief data type to log interactions between stuff and agents that * might be community standards violations @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,60 +36,60 @@ const S32 MAX_MEAN_COLLISIONS = 5; typedef enum e_mean_collision_types { - MEAN_INVALID, - MEAN_BUMP, - MEAN_LLPUSHOBJECT, - MEAN_SELECTED_OBJECT_COLLIDE, - MEAN_SCRIPTED_OBJECT_COLLIDE, - MEAN_PHYSICAL_OBJECT_COLLIDE, - MEAN_EOF + MEAN_INVALID, + MEAN_BUMP, + MEAN_LLPUSHOBJECT, + MEAN_SELECTED_OBJECT_COLLIDE, + MEAN_SCRIPTED_OBJECT_COLLIDE, + MEAN_PHYSICAL_OBJECT_COLLIDE, + MEAN_EOF } EMeanCollisionType; class LLMeanCollisionData { public: - LLMeanCollisionData(const LLUUID &victim, const LLUUID &perp, time_t time, EMeanCollisionType type, F32 mag) - : mVictim(victim), mPerp(perp), mTime(time), mType(type), mMag(mag) - { - } - - LLMeanCollisionData(LLMeanCollisionData *mcd) - : mVictim(mcd->mVictim), mPerp(mcd->mPerp), mTime(mcd->mTime), mType(mcd->mType), mMag(mcd->mMag), - mFullName(mcd->mFullName) - { - } - - friend std::ostream& operator<<(std::ostream& s, const LLMeanCollisionData &a) - { - switch(a.mType) - { - case MEAN_BUMP: - s << "Mean Collision: " << a.mPerp << " bumped " << a.mVictim << " with a velocity of " << a.mMag << " at " << ctime(&a.mTime); - break; - case MEAN_LLPUSHOBJECT: - s << "Mean Collision: " << a.mPerp << " llPushObject-ed " << a.mVictim << " with a total force of " << a.mMag << " at "<< ctime(&a.mTime); - break; - case MEAN_SELECTED_OBJECT_COLLIDE: - s << "Mean Collision: " << a.mPerp << " dragged an object into " << a.mVictim << " with a velocity of " << a.mMag << " at "<< ctime(&a.mTime); - break; - case MEAN_SCRIPTED_OBJECT_COLLIDE: - s << "Mean Collision: " << a.mPerp << " smacked " << a.mVictim << " with a scripted object with velocity of " << a.mMag << " at "<< ctime(&a.mTime); - break; - case MEAN_PHYSICAL_OBJECT_COLLIDE: - s << "Mean Collision: " << a.mPerp << " smacked " << a.mVictim << " with a physical object with velocity of " << a.mMag << " at "<< ctime(&a.mTime); - break; - default: - break; - } - return s; - } + LLMeanCollisionData(const LLUUID &victim, const LLUUID &perp, time_t time, EMeanCollisionType type, F32 mag) + : mVictim(victim), mPerp(perp), mTime(time), mType(type), mMag(mag) + { + } + + LLMeanCollisionData(LLMeanCollisionData *mcd) + : mVictim(mcd->mVictim), mPerp(mcd->mPerp), mTime(mcd->mTime), mType(mcd->mType), mMag(mcd->mMag), + mFullName(mcd->mFullName) + { + } + + friend std::ostream& operator<<(std::ostream& s, const LLMeanCollisionData &a) + { + switch(a.mType) + { + case MEAN_BUMP: + s << "Mean Collision: " << a.mPerp << " bumped " << a.mVictim << " with a velocity of " << a.mMag << " at " << ctime(&a.mTime); + break; + case MEAN_LLPUSHOBJECT: + s << "Mean Collision: " << a.mPerp << " llPushObject-ed " << a.mVictim << " with a total force of " << a.mMag << " at "<< ctime(&a.mTime); + break; + case MEAN_SELECTED_OBJECT_COLLIDE: + s << "Mean Collision: " << a.mPerp << " dragged an object into " << a.mVictim << " with a velocity of " << a.mMag << " at "<< ctime(&a.mTime); + break; + case MEAN_SCRIPTED_OBJECT_COLLIDE: + s << "Mean Collision: " << a.mPerp << " smacked " << a.mVictim << " with a scripted object with velocity of " << a.mMag << " at "<< ctime(&a.mTime); + break; + case MEAN_PHYSICAL_OBJECT_COLLIDE: + s << "Mean Collision: " << a.mPerp << " smacked " << a.mVictim << " with a physical object with velocity of " << a.mMag << " at "<< ctime(&a.mTime); + break; + default: + break; + } + return s; + } - LLUUID mVictim; - LLUUID mPerp; - time_t mTime; - EMeanCollisionType mType; - F32 mMag; - std::string mFullName; + LLUUID mVictim; + LLUUID mPerp; + time_t mTime; + EMeanCollisionType mType; + F32 mMag; + std::string mFullName; }; diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 272bf9b672..e705c36ff8 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -1,25 +1,25 @@ -/** +/** * @file message.cpp * @brief LLMessageSystem class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -94,84 +94,84 @@ std::string get_shared_secret(); class LLMessagePollInfo { public: - apr_socket_t *mAPRSocketp; - apr_pollfd_t mPollFD; + apr_socket_t *mAPRSocketp; + apr_pollfd_t mPollFD; }; class LLMessageHandlerBridge : public LLHTTPNode { - virtual bool validate(const std::string& name, LLSD& context) const - { return true; } + virtual bool validate(const std::string& name, LLSD& context) const + { return true; } - virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context, - const LLSD& input) const; + virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context, + const LLSD& input) const; }; -//virtual -void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response, - const LLSD& context, const LLSD& input) const -{ - std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"]; - char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str()); - - LL_DEBUGS() << "Setting mLastSender " << input["sender"].asString() << LL_ENDL; - gMessageSystem->mLastSender = LLHost(input["sender"].asString()); - gMessageSystem->mPacketsIn += 1; - gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]); - LockMessageReader rdr(gMessageSystem->mMessageReader, gMessageSystem->mLLSDMessageReader); - - if(gMessageSystem->callHandler(namePtr, false, gMessageSystem)) - { - response->result(LLSD()); - } - else - { - response->notFound(); - } +//virtual +void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response, + const LLSD& context, const LLSD& input) const +{ + std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"]; + char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str()); + + LL_DEBUGS() << "Setting mLastSender " << input["sender"].asString() << LL_ENDL; + gMessageSystem->mLastSender = LLHost(input["sender"].asString()); + gMessageSystem->mPacketsIn += 1; + gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]); + LockMessageReader rdr(gMessageSystem->mMessageReader, gMessageSystem->mLLSDMessageReader); + + if(gMessageSystem->callHandler(namePtr, false, gMessageSystem)) + { + response->result(LLSD()); + } + else + { + response->notFound(); + } } LLHTTPRegistration<LLMessageHandlerBridge> - gHTTPRegistrationMessageWildcard("/message/<message-name>"); + gHTTPRegistrationMessageWildcard("/message/<message-name>"); //virtual LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder() { - // even abstract base classes need a concrete destructor + // even abstract base classes need a concrete destructor } static const char* nullToEmpty(const char* s) { - static char emptyString[] = ""; - return s? s : emptyString; + static char emptyString[] = ""; + return s? s : emptyString; } void LLMessageSystem::init() { - // initialize member variables - mVerboseLog = false; + // initialize member variables + mVerboseLog = false; - mbError = false; - mErrorCode = 0; - mSendReliable = false; + mbError = false; + mErrorCode = 0; + mSendReliable = false; - mUnackedListDepth = 0; - mUnackedListSize = 0; - mDSMaxListDepth = 0; + mUnackedListDepth = 0; + mUnackedListSize = 0; + mDSMaxListDepth = 0; - mNumberHighFreqMessages = 0; - mNumberMediumFreqMessages = 0; - mNumberLowFreqMessages = 0; - mPacketsIn = mPacketsOut = 0; - mBytesIn = mBytesOut = 0; - mCompressedPacketsIn = mCompressedPacketsOut = 0; - mReliablePacketsIn = mReliablePacketsOut = 0; + mNumberHighFreqMessages = 0; + mNumberMediumFreqMessages = 0; + mNumberLowFreqMessages = 0; + mPacketsIn = mPacketsOut = 0; + mBytesIn = mBytesOut = 0; + mCompressedPacketsIn = mCompressedPacketsOut = 0; + mReliablePacketsIn = mReliablePacketsOut = 0; - mCompressedBytesIn = 0; - mCompressedBytesOut = 0; - mUncompressedBytesIn = 0; - mUncompressedBytesOut = 0; - mTotalBytesIn = 0; - mTotalBytesOut = 0; + mCompressedBytesIn = 0; + mCompressedBytesOut = 0; + mUncompressedBytesIn = 0; + mUncompressedBytesOut = 0; + mTotalBytesIn = 0; + mTotalBytesOut = 0; mDroppedPackets = 0; // total dropped packets in mResentPackets = 0; // total resent packets out @@ -179,105 +179,105 @@ void LLMessageSystem::init() mOffCircuitPackets = 0; // total # of off-circuit packets rejected mInvalidOnCircuitPackets = 0; // total # of on-circuit packets rejected - mOurCircuitCode = 0; + mOurCircuitCode = 0; - mIncomingCompressedSize = 0; - mCurrentRecvPacketID = 0; + mIncomingCompressedSize = 0; + mCurrentRecvPacketID = 0; - mMessageFileVersionNumber = 0.f; + mMessageFileVersionNumber = 0.f; - mTimingCallback = NULL; - mTimingCallbackData = NULL; + mTimingCallback = NULL; + mTimingCallbackData = NULL; - mMessageBuilder = NULL; - LockMessageReader(mMessageReader, NULL); + mMessageBuilder = NULL; + LockMessageReader(mMessageReader, NULL); } // Read file and build message templates -LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, - S32 version_major, - S32 version_minor, - S32 version_patch, - bool failure_is_fatal, - const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : - mCircuitInfo(F32Seconds(circuit_heartbeat_interval), F32Seconds(circuit_timeout)), - mLastMessageFromTrustedMessageService(false) +LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, + S32 version_major, + S32 version_minor, + S32 version_patch, + bool failure_is_fatal, + const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : + mCircuitInfo(F32Seconds(circuit_heartbeat_interval), F32Seconds(circuit_timeout)), + mLastMessageFromTrustedMessageService(false) { - init(); + init(); - mSendSize = 0; + mSendSize = 0; - mSystemVersionMajor = version_major; - mSystemVersionMinor = version_minor; - mSystemVersionPatch = version_patch; - mSystemVersionServer = 0; - mVersionFlags = 0x0; + mSystemVersionMajor = version_major; + mSystemVersionMinor = version_minor; + mSystemVersionPatch = version_patch; + mSystemVersionServer = 0; + mVersionFlags = 0x0; - // default to not accepting packets from not alive circuits - mbProtected = true; + // default to not accepting packets from not alive circuits + mbProtected = true; - // default to blocking trusted connections on a public interface if one is specified - mBlockUntrustedInterface = true; + // default to blocking trusted connections on a public interface if one is specified + mBlockUntrustedInterface = true; - mSendPacketFailureCount = 0; + mSendPacketFailureCount = 0; - mCircuitPrintFreq = F32Seconds(60.f); + mCircuitPrintFreq = F32Seconds(60.f); - loadTemplateFile(filename, failure_is_fatal); + loadTemplateFile(filename, failure_is_fatal); - mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates); - mLLSDMessageBuilder = new LLSDMessageBuilder(); - mMessageBuilder = NULL; + mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates); + mLLSDMessageBuilder = new LLSDMessageBuilder(); + mMessageBuilder = NULL; - mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers); - mLLSDMessageReader = new LLSDMessageReader(); + mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers); + mLLSDMessageReader = new LLSDMessageReader(); - // initialize various bits of net info - mSocket = 0; - mPort = port; + // initialize various bits of net info + mSocket = 0; + mPort = port; - S32 error = start_net(mSocket, mPort); - if (error != 0) - { - mbError = true; - mErrorCode = error; - } -// LL_DEBUGS("Messaging") << << "*** port: " << mPort << LL_ENDL; + S32 error = start_net(mSocket, mPort); + if (error != 0) + { + mbError = true; + mErrorCode = error; + } +// LL_DEBUGS("Messaging") << << "*** port: " << mPort << LL_ENDL; - // - // Create the data structure that we can poll on - // - if (!gAPRPoolp) - { - LL_ERRS("Messaging") << "No APR pool before message system initialization!" << LL_ENDL; - ll_init_apr(); - } - apr_socket_t *aprSocketp = NULL; - apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); + // + // Create the data structure that we can poll on + // + if (!gAPRPoolp) + { + LL_ERRS("Messaging") << "No APR pool before message system initialization!" << LL_ENDL; + ll_init_apr(); + } + apr_socket_t *aprSocketp = NULL; + apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); - mPollInfop = new LLMessagePollInfo; - mPollInfop->mAPRSocketp = aprSocketp; - mPollInfop->mPollFD.p = gAPRPoolp; - mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; - mPollInfop->mPollFD.reqevents = APR_POLLIN; - mPollInfop->mPollFD.rtnevents = 0; - mPollInfop->mPollFD.desc.s = aprSocketp; - mPollInfop->mPollFD.client_data = NULL; + mPollInfop = new LLMessagePollInfo; + mPollInfop->mAPRSocketp = aprSocketp; + mPollInfop->mPollFD.p = gAPRPoolp; + mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; + mPollInfop->mPollFD.reqevents = APR_POLLIN; + mPollInfop->mPollFD.rtnevents = 0; + mPollInfop->mPollFD.desc.s = aprSocketp; + mPollInfop->mPollFD.client_data = NULL; - F64Seconds mt_sec = getMessageTimeSeconds(); - mResendDumpTime = mt_sec; - mMessageCountTime = mt_sec; - mCircuitPrintTime = mt_sec; - mCurrentMessageTime = F64Seconds(mt_sec); + F64Seconds mt_sec = getMessageTimeSeconds(); + mResendDumpTime = mt_sec; + mMessageCountTime = mt_sec; + mCircuitPrintTime = mt_sec; + mCurrentMessageTime = F64Seconds(mt_sec); - // Constants for dumping output based on message processing time/count - mNumMessageCounts = 0; - mMaxMessageCounts = 200; // >= 0 means dump warnings - mMaxMessageTime = F32Seconds(1.f); + // Constants for dumping output based on message processing time/count + mNumMessageCounts = 0; + mMaxMessageCounts = 200; // >= 0 means dump warnings + mMaxMessageTime = F32Seconds(1.f); - mTrueReceiveSize = 0; + mTrueReceiveSize = 0; - mReceiveTime = F32Seconds(0.f); + mReceiveTime = F32Seconds(0.f); } @@ -285,200 +285,200 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, // Read file and build message templates void LLMessageSystem::loadTemplateFile(const std::string& filename, bool failure_is_fatal) { - if(filename.empty()) - { - LL_ERRS("Messaging") << "No template filename specified" << LL_ENDL; - mbError = true; - return; - } - - std::string template_body; - if(!_read_file_into_string(template_body, filename)) - { - if (failure_is_fatal) { - LL_ERRS("Messaging") << "Failed to open template: " << filename << LL_ENDL; - } else { - LL_WARNS("Messaging") << "Failed to open template: " << filename << LL_ENDL; - } - mbError = true; - return; - } - - LLTemplateTokenizer tokens(template_body); - LLTemplateParser parsed(tokens); - mMessageFileVersionNumber = parsed.getVersion(); + if(filename.empty()) + { + LL_ERRS("Messaging") << "No template filename specified" << LL_ENDL; + mbError = true; + return; + } + + std::string template_body; + if(!_read_file_into_string(template_body, filename)) + { + if (failure_is_fatal) { + LL_ERRS("Messaging") << "Failed to open template: " << filename << LL_ENDL; + } else { + LL_WARNS("Messaging") << "Failed to open template: " << filename << LL_ENDL; + } + mbError = true; + return; + } + + LLTemplateTokenizer tokens(template_body); + LLTemplateParser parsed(tokens); + mMessageFileVersionNumber = parsed.getVersion(); S32 count = 0; - for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin(); - iter != parsed.getMessagesEnd(); - iter++) - { - addTemplate(*iter); + for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin(); + iter != parsed.getMessagesEnd(); + iter++) + { + addTemplate(*iter); count++; - } + } LL_INFOS("Messaging") << "Read " << count << " messages from " << filename << LL_ENDL; } LLMessageSystem::~LLMessageSystem() { - mMessageTemplates.clear(); // don't delete templates. - for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer()); - mMessageNumbers.clear(); - - if (!mbError) - { - end_net(mSocket); - } - mSocket = 0; - - delete mTemplateMessageReader; - mTemplateMessageReader = NULL; + mMessageTemplates.clear(); // don't delete templates. + for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer()); + mMessageNumbers.clear(); + + if (!mbError) + { + end_net(mSocket); + } + mSocket = 0; + + delete mTemplateMessageReader; + mTemplateMessageReader = NULL; - delete mTemplateMessageBuilder; - mTemplateMessageBuilder = NULL; - mMessageBuilder = NULL; + delete mTemplateMessageBuilder; + mTemplateMessageBuilder = NULL; + mMessageBuilder = NULL; - delete mLLSDMessageReader; - mLLSDMessageReader = NULL; + delete mLLSDMessageReader; + mLLSDMessageReader = NULL; - delete mLLSDMessageBuilder; - mLLSDMessageBuilder = NULL; + delete mLLSDMessageBuilder; + mLLSDMessageBuilder = NULL; - delete mPollInfop; - mPollInfop = NULL; + delete mPollInfop; + mPollInfop = NULL; - mIncomingCompressedSize = 0; - mCurrentRecvPacketID = 0; + mIncomingCompressedSize = 0; + mCurrentRecvPacketID = 0; } void LLMessageSystem::clearReceiveState() { - mCurrentRecvPacketID = 0; - mIncomingCompressedSize = 0; - mLastSender.invalidate(); - mLastReceivingIF.invalidate(); - mMessageReader->clearMessage(); - mLastMessageFromTrustedMessageService = false; + mCurrentRecvPacketID = 0; + mIncomingCompressedSize = 0; + mLastSender.invalidate(); + mLastReceivingIF.invalidate(); + mMessageReader->clearMessage(); + mLastMessageFromTrustedMessageService = false; } bool LLMessageSystem::poll(F32 seconds) { - S32 num_socks; - apr_status_t status; - status = apr_poll(&(mPollInfop->mPollFD), 1, &num_socks,(U64)(seconds*1000000.f)); - if (status != APR_TIMEUP) - { - ll_apr_warn_status(status); - } - if (num_socks) - { - return true; - } - else - { - return false; - } + S32 num_socks; + apr_status_t status; + status = apr_poll(&(mPollInfop->mPollFD), 1, &num_socks,(U64)(seconds*1000000.f)); + if (status != APR_TIMEUP) + { + ll_apr_warn_status(status); + } + if (num_socks) + { + return true; + } + else + { + return false; + } } bool LLMessageSystem::isTrustedSender(const LLHost& host) const { - LLCircuitData* cdp = mCircuitInfo.findCircuit(host); - if(NULL == cdp) - { - return false; - } - return cdp->getTrusted(); + LLCircuitData* cdp = mCircuitInfo.findCircuit(host); + if(NULL == cdp) + { + return false; + } + return cdp->getTrusted(); } void LLMessageSystem::receivedMessageFromTrustedSender() { - mLastMessageFromTrustedMessageService = true; + mLastMessageFromTrustedMessageService = true; } bool LLMessageSystem::isTrustedSender() const -{ - return mLastMessageFromTrustedMessageService || - isTrustedSender(getSender()); +{ + return mLastMessageFromTrustedMessageService || + isTrustedSender(getSender()); } -static LLMessageSystem::message_template_name_map_t::const_iterator -findTemplate(const LLMessageSystem::message_template_name_map_t& templates, - std::string name) +static LLMessageSystem::message_template_name_map_t::const_iterator +findTemplate(const LLMessageSystem::message_template_name_map_t& templates, + std::string name) { - const char* namePrehash = LLMessageStringTable::getInstance()->getString(name.c_str()); - if(NULL == namePrehash) {return templates.end();} - return templates.find(namePrehash); + const char* namePrehash = LLMessageStringTable::getInstance()->getString(name.c_str()); + if(NULL == namePrehash) {return templates.end();} + return templates.find(namePrehash); } bool LLMessageSystem::isTrustedMessage(const std::string& name) const { - message_template_name_map_t::const_iterator iter = - findTemplate(mMessageTemplates, name); - if(iter == mMessageTemplates.end()) {return false;} - return iter->second->getTrust() == MT_TRUST; + message_template_name_map_t::const_iterator iter = + findTemplate(mMessageTemplates, name); + if(iter == mMessageTemplates.end()) {return false;} + return iter->second->getTrust() == MT_TRUST; } bool LLMessageSystem::isUntrustedMessage(const std::string& name) const { - message_template_name_map_t::const_iterator iter = - findTemplate(mMessageTemplates, name); - if(iter == mMessageTemplates.end()) {return false;} - return iter->second->getTrust() == MT_NOTRUST; + message_template_name_map_t::const_iterator iter = + findTemplate(mMessageTemplates, name); + if(iter == mMessageTemplates.end()) {return false;} + return iter->second->getTrust() == MT_NOTRUST; } LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host, - bool resetPacketId) -{ - LLCircuitData* cdp = mCircuitInfo.findCircuit(host); - if (!cdp) - { - // This packet comes from a circuit we don't know about. - - // Are we rejecting off-circuit packets? - if (mbProtected) - { - // cdp is already NULL, so we don't need to unset it. - } - else - { - // nope, open the new circuit - cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID); - - if(resetPacketId) - { - // I added this - I think it's correct - DJS - // reset packet in ID - cdp->setPacketInID(mCurrentRecvPacketID); - } - // And claim the packet is on the circuit we just added. - } - } - else - { - // this is an old circuit. . . is it still alive? - if (!cdp->isAlive()) - { - // nope. don't accept if we're protected - if (mbProtected) - { - // don't accept packets from unexpected sources - cdp = NULL; - } - else - { - // wake up the circuit - cdp->setAlive(true); - - if(resetPacketId) - { - // reset packet in ID - cdp->setPacketInID(mCurrentRecvPacketID); - } - } - } - } - return cdp; + bool resetPacketId) +{ + LLCircuitData* cdp = mCircuitInfo.findCircuit(host); + if (!cdp) + { + // This packet comes from a circuit we don't know about. + + // Are we rejecting off-circuit packets? + if (mbProtected) + { + // cdp is already NULL, so we don't need to unset it. + } + else + { + // nope, open the new circuit + cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID); + + if(resetPacketId) + { + // I added this - I think it's correct - DJS + // reset packet in ID + cdp->setPacketInID(mCurrentRecvPacketID); + } + // And claim the packet is on the circuit we just added. + } + } + else + { + // this is an old circuit. . . is it still alive? + if (!cdp->isAlive()) + { + // nope. don't accept if we're protected + if (mbProtected) + { + // don't accept packets from unexpected sources + cdp = NULL; + } + else + { + // wake up the circuit + cdp->setAlive(true); + + if(resetPacketId) + { + // reset packet in ID + cdp->setPacketInID(mCurrentRecvPacketID); + } + } + } + } + return cdp; } // Returns true if a valid, on-circuit message has been received. @@ -486,476 +486,476 @@ LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host, // mMessageReader has been set to mTemplateMessageReader. bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count ) { - // Pump - bool valid_packet = false; - - LLTransferTargetVFile::updateQueue(); - - if (!mNumMessageCounts) - { - // This is the first message being handled after a resetReceiveCounts, - // we must be starting the message processing loop. Reset the timers. - mCurrentMessageTime = totalTime(); - mMessageCountTime = getMessageTimeSeconds(); - } - - // loop until either no packets or a valid packet - // i.e., burn through packets from unregistered circuits - S32 receive_size = 0; - do - { - clearReceiveState(); - - bool recv_reliable = false; - bool recv_resent = false; - S32 acks = 0; - S32 true_rcv_size = 0; - - U8* buffer = mTrueReceiveBuffer; - - mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer); - // If you want to dump all received packets into SecondLife.log, uncomment this - //dumpPacketToLog(); - - receive_size = mTrueReceiveSize; - mLastSender = mPacketRing.getLastSender(); - mLastReceivingIF = mPacketRing.getLastReceivingInterface(); - - if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE) - { - // A receive size of zero is OK, that means that there are no more packets available. - // Ones that are non-zero but below the minimum packet size are worrisome. - if (receive_size > 0) - { - LL_WARNS("Messaging") << "Invalid (too short) packet discarded " << receive_size << LL_ENDL; - callExceptionFunc(MX_PACKET_TOO_SHORT); - } - // no data in packet receive buffer - valid_packet = false; - } - else - { - LLHost host; - LLCircuitData* cdp; - - // note if packet acks are appended. - if(buffer[0] & LL_ACK_FLAG) - { - acks += buffer[--receive_size]; - true_rcv_size = receive_size; - if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE))) - { - receive_size -= acks * sizeof(TPACKETID); - } - else - { - // mal-formed packet. ignore it and continue with - // the next one - LL_WARNS("Messaging") << "Malformed packet received. Packet size " - << receive_size << " with invalid no. of acks " << acks - << LL_ENDL; - valid_packet = false; - continue; - } - } - - // process the message as normal - mIncomingCompressedSize = zeroCodeExpand(&buffer, &receive_size); - mCurrentRecvPacketID = ntohl(*((U32*)(&buffer[1]))); - host = getSender(); - - const bool resetPacketId = true; - cdp = findCircuit(host, resetPacketId); - - // At this point, cdp is now a pointer to the circuit that - // this message came in on if it's valid, and NULL if the - // circuit was bogus. - - if(cdp && (acks > 0) && ((S32)(acks * sizeof(TPACKETID)) < (true_rcv_size))) - { - TPACKETID packet_id; - U32 mem_id=0; - for(S32 i = 0; i < acks; ++i) - { - true_rcv_size -= sizeof(TPACKETID); - memcpy(&mem_id, &mTrueReceiveBuffer[true_rcv_size], /* Flawfinder: ignore*/ - sizeof(TPACKETID)); - packet_id = ntohl(mem_id); - //LL_INFOS("Messaging") << "got ack: " << packet_id << LL_ENDL; - cdp->ackReliablePacket(packet_id); - } - if (!cdp->getUnackedPacketCount()) - { - // Remove this circuit from the list of circuits with unacked packets - mCircuitInfo.mUnackedCircuitMap.erase(cdp->mHost); - } - } - - if (buffer[0] & LL_RELIABLE_FLAG) - { - recv_reliable = true; - } - if (buffer[0] & LL_RESENT_FLAG) - { - recv_resent = true; - if (cdp && cdp->isDuplicateResend(mCurrentRecvPacketID)) - { - // We need to ACK here to suppress - // further resends of packets we've - // already seen. - if (recv_reliable) - { - //mAckList.addData(new LLPacketAck(host, mCurrentRecvPacketID)); - // *************************************** - // TESTING CODE - //if(mCircuitInfo.mCurrentCircuit->mHost != host) - //{ - // LL_WARNS("Messaging") << "DISCARDED PACKET HOST MISMATCH! HOST: " - // << host << " CIRCUIT: " - // << mCircuitInfo.mCurrentCircuit->mHost - // << LL_ENDL; - //} - // *************************************** - //mCircuitInfo.mCurrentCircuit->mAcks.put(mCurrentRecvPacketID); - cdp->collectRAck(mCurrentRecvPacketID); - } - - LL_DEBUGS("Messaging") << "Discarding duplicate resend from " << host << LL_ENDL; - if(mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << host; - std::string tbuf; - tbuf = llformat( "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID); - str << tbuf << "(unknown)" - << (recv_reliable ? " reliable" : "") - << " resent " - << ((acks > 0) ? "acks" : "") - << " DISCARD DUPLICATE"; - LL_INFOS("Messaging") << str.str() << LL_ENDL; - } - mPacketsIn++; - valid_packet = false; - continue; - } - } - - // UseCircuitCode can be a valid, off-circuit packet. - // But we don't want to acknowledge UseCircuitCode until the circuit is - // available, which is why the acknowledgement test is done above. JC - bool trusted = cdp && cdp->getTrusted(); - valid_packet = mTemplateMessageReader->validateMessage( - buffer, - receive_size, - host, - trusted); - if (!valid_packet) - { - clearReceiveState(); - } - - // UseCircuitCode is allowed in even from an invalid circuit, so that - // we can toss circuits around. - if( - valid_packet && - !cdp && - (mTemplateMessageReader->getMessageName() != - _PREHASH_UseCircuitCode)) - { - logMsgFromInvalidCircuit( host, recv_reliable ); - clearReceiveState(); - valid_packet = false; - } - - if( - valid_packet && - cdp && - !cdp->getTrusted() && - mTemplateMessageReader->isTrusted()) - { - logTrustedMsgFromUntrustedCircuit( host ); - clearReceiveState(); - - sendDenyTrustedCircuit(host); - valid_packet = false; - } - - if( valid_packet ) - { - logValidMsg(cdp, host, recv_reliable, recv_resent, acks>0 ); - valid_packet = mTemplateMessageReader->readMessage(buffer, host); - } - - // It's possible that the circuit went away, because ANY message can disable the circuit - // (for example, UseCircuit, CloseCircuit, DisableSimulator). Find it again. - cdp = mCircuitInfo.findCircuit(host); - - if (valid_packet) - { - mPacketsIn++; - mBytesIn += mTrueReceiveSize; - - // ACK here for valid packets that we've seen - // for the first time. - if (cdp && recv_reliable) - { - // Add to the recently received list for duplicate suppression - cdp->mRecentlyReceivedReliablePackets[mCurrentRecvPacketID] = getMessageTimeUsecs(); - - // Put it onto the list of packets to be acked - cdp->collectRAck(mCurrentRecvPacketID); - mReliablePacketsIn++; - } - } - else - { - if (mbProtected && (!cdp)) - { - LL_WARNS("Messaging") << "Invalid Packet from invalid circuit " << host << LL_ENDL; - mOffCircuitPackets++; - } - else - { - mInvalidOnCircuitPackets++; - } - } - } - } while (!valid_packet && receive_size > 0); - - F64Seconds mt_sec = getMessageTimeSeconds(); - // Check to see if we need to print debug info - if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq) - { - dumpCircuitInfo(); - mCircuitPrintTime = mt_sec; - } - - if( !valid_packet ) - { - clearReceiveState(); - } - - return valid_packet; -} - -S32 LLMessageSystem::getReceiveBytes() const -{ - if (getReceiveCompressedSize()) - { - return getReceiveCompressedSize() * 8; - } - else - { - return getReceiveSize() * 8; - } + // Pump + bool valid_packet = false; + + LLTransferTargetVFile::updateQueue(); + + if (!mNumMessageCounts) + { + // This is the first message being handled after a resetReceiveCounts, + // we must be starting the message processing loop. Reset the timers. + mCurrentMessageTime = totalTime(); + mMessageCountTime = getMessageTimeSeconds(); + } + + // loop until either no packets or a valid packet + // i.e., burn through packets from unregistered circuits + S32 receive_size = 0; + do + { + clearReceiveState(); + + bool recv_reliable = false; + bool recv_resent = false; + S32 acks = 0; + S32 true_rcv_size = 0; + + U8* buffer = mTrueReceiveBuffer; + + mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer); + // If you want to dump all received packets into SecondLife.log, uncomment this + //dumpPacketToLog(); + + receive_size = mTrueReceiveSize; + mLastSender = mPacketRing.getLastSender(); + mLastReceivingIF = mPacketRing.getLastReceivingInterface(); + + if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE) + { + // A receive size of zero is OK, that means that there are no more packets available. + // Ones that are non-zero but below the minimum packet size are worrisome. + if (receive_size > 0) + { + LL_WARNS("Messaging") << "Invalid (too short) packet discarded " << receive_size << LL_ENDL; + callExceptionFunc(MX_PACKET_TOO_SHORT); + } + // no data in packet receive buffer + valid_packet = false; + } + else + { + LLHost host; + LLCircuitData* cdp; + + // note if packet acks are appended. + if(buffer[0] & LL_ACK_FLAG) + { + acks += buffer[--receive_size]; + true_rcv_size = receive_size; + if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE))) + { + receive_size -= acks * sizeof(TPACKETID); + } + else + { + // mal-formed packet. ignore it and continue with + // the next one + LL_WARNS("Messaging") << "Malformed packet received. Packet size " + << receive_size << " with invalid no. of acks " << acks + << LL_ENDL; + valid_packet = false; + continue; + } + } + + // process the message as normal + mIncomingCompressedSize = zeroCodeExpand(&buffer, &receive_size); + mCurrentRecvPacketID = ntohl(*((U32*)(&buffer[1]))); + host = getSender(); + + const bool resetPacketId = true; + cdp = findCircuit(host, resetPacketId); + + // At this point, cdp is now a pointer to the circuit that + // this message came in on if it's valid, and NULL if the + // circuit was bogus. + + if(cdp && (acks > 0) && ((S32)(acks * sizeof(TPACKETID)) < (true_rcv_size))) + { + TPACKETID packet_id; + U32 mem_id=0; + for(S32 i = 0; i < acks; ++i) + { + true_rcv_size -= sizeof(TPACKETID); + memcpy(&mem_id, &mTrueReceiveBuffer[true_rcv_size], /* Flawfinder: ignore*/ + sizeof(TPACKETID)); + packet_id = ntohl(mem_id); + //LL_INFOS("Messaging") << "got ack: " << packet_id << LL_ENDL; + cdp->ackReliablePacket(packet_id); + } + if (!cdp->getUnackedPacketCount()) + { + // Remove this circuit from the list of circuits with unacked packets + mCircuitInfo.mUnackedCircuitMap.erase(cdp->mHost); + } + } + + if (buffer[0] & LL_RELIABLE_FLAG) + { + recv_reliable = true; + } + if (buffer[0] & LL_RESENT_FLAG) + { + recv_resent = true; + if (cdp && cdp->isDuplicateResend(mCurrentRecvPacketID)) + { + // We need to ACK here to suppress + // further resends of packets we've + // already seen. + if (recv_reliable) + { + //mAckList.addData(new LLPacketAck(host, mCurrentRecvPacketID)); + // *************************************** + // TESTING CODE + //if(mCircuitInfo.mCurrentCircuit->mHost != host) + //{ + // LL_WARNS("Messaging") << "DISCARDED PACKET HOST MISMATCH! HOST: " + // << host << " CIRCUIT: " + // << mCircuitInfo.mCurrentCircuit->mHost + // << LL_ENDL; + //} + // *************************************** + //mCircuitInfo.mCurrentCircuit->mAcks.put(mCurrentRecvPacketID); + cdp->collectRAck(mCurrentRecvPacketID); + } + + LL_DEBUGS("Messaging") << "Discarding duplicate resend from " << host << LL_ENDL; + if(mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << host; + std::string tbuf; + tbuf = llformat( "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID); + str << tbuf << "(unknown)" + << (recv_reliable ? " reliable" : "") + << " resent " + << ((acks > 0) ? "acks" : "") + << " DISCARD DUPLICATE"; + LL_INFOS("Messaging") << str.str() << LL_ENDL; + } + mPacketsIn++; + valid_packet = false; + continue; + } + } + + // UseCircuitCode can be a valid, off-circuit packet. + // But we don't want to acknowledge UseCircuitCode until the circuit is + // available, which is why the acknowledgement test is done above. JC + bool trusted = cdp && cdp->getTrusted(); + valid_packet = mTemplateMessageReader->validateMessage( + buffer, + receive_size, + host, + trusted); + if (!valid_packet) + { + clearReceiveState(); + } + + // UseCircuitCode is allowed in even from an invalid circuit, so that + // we can toss circuits around. + if( + valid_packet && + !cdp && + (mTemplateMessageReader->getMessageName() != + _PREHASH_UseCircuitCode)) + { + logMsgFromInvalidCircuit( host, recv_reliable ); + clearReceiveState(); + valid_packet = false; + } + + if( + valid_packet && + cdp && + !cdp->getTrusted() && + mTemplateMessageReader->isTrusted()) + { + logTrustedMsgFromUntrustedCircuit( host ); + clearReceiveState(); + + sendDenyTrustedCircuit(host); + valid_packet = false; + } + + if( valid_packet ) + { + logValidMsg(cdp, host, recv_reliable, recv_resent, acks>0 ); + valid_packet = mTemplateMessageReader->readMessage(buffer, host); + } + + // It's possible that the circuit went away, because ANY message can disable the circuit + // (for example, UseCircuit, CloseCircuit, DisableSimulator). Find it again. + cdp = mCircuitInfo.findCircuit(host); + + if (valid_packet) + { + mPacketsIn++; + mBytesIn += mTrueReceiveSize; + + // ACK here for valid packets that we've seen + // for the first time. + if (cdp && recv_reliable) + { + // Add to the recently received list for duplicate suppression + cdp->mRecentlyReceivedReliablePackets[mCurrentRecvPacketID] = getMessageTimeUsecs(); + + // Put it onto the list of packets to be acked + cdp->collectRAck(mCurrentRecvPacketID); + mReliablePacketsIn++; + } + } + else + { + if (mbProtected && (!cdp)) + { + LL_WARNS("Messaging") << "Invalid Packet from invalid circuit " << host << LL_ENDL; + mOffCircuitPackets++; + } + else + { + mInvalidOnCircuitPackets++; + } + } + } + } while (!valid_packet && receive_size > 0); + + F64Seconds mt_sec = getMessageTimeSeconds(); + // Check to see if we need to print debug info + if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq) + { + dumpCircuitInfo(); + mCircuitPrintTime = mt_sec; + } + + if( !valid_packet ) + { + clearReceiveState(); + } + + return valid_packet; +} + +S32 LLMessageSystem::getReceiveBytes() const +{ + if (getReceiveCompressedSize()) + { + return getReceiveCompressedSize() * 8; + } + else + { + return getReceiveSize() * 8; + } } void LLMessageSystem::processAcks(LockMessageChecker&, F32 collect_time) { - F64Seconds mt_sec = getMessageTimeSeconds(); - { - gTransferManager.updateTransfers(); - - if (gXferManager) - { - gXferManager->retransmitUnackedPackets(); - } - - if (gAssetStorage) - { - gAssetStorage->checkForTimeouts(); - } - } - - bool dump = false; - { - // Check the status of circuits - mCircuitInfo.updateWatchDogTimers(this); - - //resend any necessary packets - mCircuitInfo.resendUnackedPackets(mUnackedListDepth, mUnackedListSize); - - //cycle through ack list for each host we need to send acks to - mCircuitInfo.sendAcks(collect_time); - - if (!mDenyTrustedCircuitSet.empty()) - { - LL_INFOS("Messaging") << "Sending queued DenyTrustedCircuit messages." << LL_ENDL; - for (host_set_t::iterator hostit = mDenyTrustedCircuitSet.begin(); hostit != mDenyTrustedCircuitSet.end(); ++hostit) - { - reallySendDenyTrustedCircuit(*hostit); - } - mDenyTrustedCircuitSet.clear(); - } - - if (mMaxMessageCounts >= 0) - { - if (mNumMessageCounts >= mMaxMessageCounts) - { - dump = true; - } - } - - if (mMaxMessageTime >= F32Seconds(0.f)) - { - // This is one of the only places where we're required to get REAL message system time. - mReceiveTime = getMessageTimeSeconds(true) - mMessageCountTime; - if (mReceiveTime > mMaxMessageTime) - { - dump = true; - } - } - } - - if (dump) - { - dumpReceiveCounts(); - } - resetReceiveCounts(); - - if ((mt_sec - mResendDumpTime) > CIRCUIT_DUMP_TIMEOUT) - { - mResendDumpTime = mt_sec; - mCircuitInfo.dumpResends(); - } + F64Seconds mt_sec = getMessageTimeSeconds(); + { + gTransferManager.updateTransfers(); + + if (gXferManager) + { + gXferManager->retransmitUnackedPackets(); + } + + if (gAssetStorage) + { + gAssetStorage->checkForTimeouts(); + } + } + + bool dump = false; + { + // Check the status of circuits + mCircuitInfo.updateWatchDogTimers(this); + + //resend any necessary packets + mCircuitInfo.resendUnackedPackets(mUnackedListDepth, mUnackedListSize); + + //cycle through ack list for each host we need to send acks to + mCircuitInfo.sendAcks(collect_time); + + if (!mDenyTrustedCircuitSet.empty()) + { + LL_INFOS("Messaging") << "Sending queued DenyTrustedCircuit messages." << LL_ENDL; + for (host_set_t::iterator hostit = mDenyTrustedCircuitSet.begin(); hostit != mDenyTrustedCircuitSet.end(); ++hostit) + { + reallySendDenyTrustedCircuit(*hostit); + } + mDenyTrustedCircuitSet.clear(); + } + + if (mMaxMessageCounts >= 0) + { + if (mNumMessageCounts >= mMaxMessageCounts) + { + dump = true; + } + } + + if (mMaxMessageTime >= F32Seconds(0.f)) + { + // This is one of the only places where we're required to get REAL message system time. + mReceiveTime = getMessageTimeSeconds(true) - mMessageCountTime; + if (mReceiveTime > mMaxMessageTime) + { + dump = true; + } + } + } + + if (dump) + { + dumpReceiveCounts(); + } + resetReceiveCounts(); + + if ((mt_sec - mResendDumpTime) > CIRCUIT_DUMP_TIMEOUT) + { + mResendDumpTime = mt_sec; + mCircuitInfo.dumpResends(); + } } void LLMessageSystem::copyMessageReceivedToSend() { - // NOTE: babbage: switch builder to match reader to avoid - // converting message format - if(mMessageReader == mTemplateMessageReader) - { - mMessageBuilder = mTemplateMessageBuilder; - } - else - { - mMessageBuilder = mLLSDMessageBuilder; - } - mSendReliable = false; - mMessageBuilder->newMessage(mMessageReader->getMessageName()); - mMessageReader->copyToBuilder(*mMessageBuilder); + // NOTE: babbage: switch builder to match reader to avoid + // converting message format + if(mMessageReader == mTemplateMessageReader) + { + mMessageBuilder = mTemplateMessageBuilder; + } + else + { + mMessageBuilder = mLLSDMessageBuilder; + } + mSendReliable = false; + mMessageBuilder->newMessage(mMessageReader->getMessageName()); + mMessageReader->copyToBuilder(*mMessageBuilder); } LLSD LLMessageSystem::getReceivedMessageLLSD() const { - LLSDMessageBuilder builder; - mMessageReader->copyToBuilder(builder); - return builder.getMessage(); + LLSDMessageBuilder builder; + mMessageReader->copyToBuilder(builder); + return builder.getMessage(); } -LLSD LLMessageSystem::getBuiltMessageLLSD() const +LLSD LLMessageSystem::getBuiltMessageLLSD() const { - LLSD result; - if (mLLSDMessageBuilder == mMessageBuilder) - { - result = mLLSDMessageBuilder->getMessage(); - } - else - { - // TODO: implement as below? - LL_ERRS() << "Message not built as LLSD." << LL_ENDL; - } - return result; + LLSD result; + if (mLLSDMessageBuilder == mMessageBuilder) + { + result = mLLSDMessageBuilder->getMessage(); + } + else + { + // TODO: implement as below? + LL_ERRS() << "Message not built as LLSD." << LL_ENDL; + } + return result; } LLSD LLMessageSystem::wrapReceivedTemplateData() const { - if(mMessageReader == mTemplateMessageReader) - { - LLTemplateMessageBuilder builder(mMessageTemplates); - builder.newMessage(mMessageReader->getMessageName()); - mMessageReader->copyToBuilder(builder); - U8 buffer[MAX_BUFFER_SIZE]; - const U8 offset_to_data = 0; - U32 size = builder.buildMessage(buffer, MAX_BUFFER_SIZE, - offset_to_data); - std::vector<U8> binary_data(buffer, buffer+size); - LLSD wrapped_data = LLSD::emptyMap(); - wrapped_data["binary-template-data"] = binary_data; - return wrapped_data; - } - else - { - return getReceivedMessageLLSD(); - } + if(mMessageReader == mTemplateMessageReader) + { + LLTemplateMessageBuilder builder(mMessageTemplates); + builder.newMessage(mMessageReader->getMessageName()); + mMessageReader->copyToBuilder(builder); + U8 buffer[MAX_BUFFER_SIZE]; + const U8 offset_to_data = 0; + U32 size = builder.buildMessage(buffer, MAX_BUFFER_SIZE, + offset_to_data); + std::vector<U8> binary_data(buffer, buffer+size); + LLSD wrapped_data = LLSD::emptyMap(); + wrapped_data["binary-template-data"] = binary_data; + return wrapped_data; + } + else + { + return getReceivedMessageLLSD(); + } } LLSD LLMessageSystem::wrapBuiltTemplateData() const { - LLSD result; - if (mLLSDMessageBuilder == mMessageBuilder) - { - result = getBuiltMessageLLSD(); - } - else - { - U8 buffer[MAX_BUFFER_SIZE]; - const U8 offset_to_data = 0; - U32 size = mTemplateMessageBuilder->buildMessage( - buffer, MAX_BUFFER_SIZE, - offset_to_data); - std::vector<U8> binary_data(buffer, buffer+size); - LLSD wrapped_data = LLSD::emptyMap(); - wrapped_data["binary-template-data"] = binary_data; - result = wrapped_data; - } - return result; + LLSD result; + if (mLLSDMessageBuilder == mMessageBuilder) + { + result = getBuiltMessageLLSD(); + } + else + { + U8 buffer[MAX_BUFFER_SIZE]; + const U8 offset_to_data = 0; + U32 size = mTemplateMessageBuilder->buildMessage( + buffer, MAX_BUFFER_SIZE, + offset_to_data); + std::vector<U8> binary_data(buffer, buffer+size); + LLSD wrapped_data = LLSD::emptyMap(); + wrapped_data["binary-template-data"] = binary_data; + result = wrapped_data; + } + return result; } LLStoredMessagePtr LLMessageSystem::getReceivedMessage() const { - const std::string& name = mMessageReader->getMessageName(); - LLSD message = wrapReceivedTemplateData(); + const std::string& name = mMessageReader->getMessageName(); + LLSD message = wrapReceivedTemplateData(); - return LLStoredMessagePtr(new LLStoredMessage(name, message)); + return LLStoredMessagePtr(new LLStoredMessage(name, message)); } LLStoredMessagePtr LLMessageSystem::getBuiltMessage() const { - const std::string& name = mMessageBuilder->getMessageName(); - LLSD message = wrapBuiltTemplateData(); + const std::string& name = mMessageBuilder->getMessageName(); + LLSD message = wrapBuiltTemplateData(); - return LLStoredMessagePtr(new LLStoredMessage(name, message)); + return LLStoredMessagePtr(new LLStoredMessage(name, message)); } S32 LLMessageSystem::sendMessage(const LLHost &host, LLStoredMessagePtr message) { - return sendMessage(host, message->mName.c_str(), message->mMessage); + return sendMessage(host, message->mName.c_str(), message->mMessage); } void LLMessageSystem::clearMessage() { - mSendReliable = false; - mMessageBuilder->clearMessage(); + mSendReliable = false; + mMessageBuilder->clearMessage(); } // set block to add data to within current message void LLMessageSystem::nextBlockFast(const char *blockname) { - mMessageBuilder->nextBlock(blockname); + mMessageBuilder->nextBlock(blockname); } void LLMessageSystem::nextBlock(const char *blockname) { - nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname)); + nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname)); } bool LLMessageSystem::isSendFull(const char* blockname) { - char* stringTableName = NULL; - if(NULL != blockname) - { - stringTableName = LLMessageStringTable::getInstance()->getString(blockname); - } - return isSendFullFast(stringTableName); + char* stringTableName = NULL; + if(NULL != blockname) + { + stringTableName = LLMessageStringTable::getInstance()->getString(blockname); + } + return isSendFullFast(stringTableName); } bool LLMessageSystem::isSendFullFast(const char* blockname) { - return mMessageBuilder->isMessageFull(blockname); + return mMessageBuilder->isMessageFull(blockname); } @@ -963,200 +963,200 @@ bool LLMessageSystem::isSendFullFast(const char* blockname) // TODO: Babbage: Remove this horror. bool LLMessageSystem::removeLastBlock() { - return mMessageBuilder->removeLastBlock(); + return mMessageBuilder->removeLastBlock(); } S32 LLMessageSystem::sendReliable(const LLHost &host) { - return sendReliable(host, LL_DEFAULT_RELIABLE_RETRIES, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); + return sendReliable(host, LL_DEFAULT_RELIABLE_RETRIES, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); } S32 LLMessageSystem::sendSemiReliable(const LLHost &host, void (*callback)(void **,S32), void ** callback_data) { - F32Seconds timeout; + F32Seconds timeout; - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS, - F32Seconds(LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged())); - } - else - { - timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX; - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS, + F32Seconds(LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged())); + } + else + { + timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX; + } - constexpr S32 retries = 0; - constexpr bool ping_based_timeout = false; - return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data); + constexpr S32 retries = 0; + constexpr bool ping_based_timeout = false; + return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data); } // send the message via a UDP packet -S32 LLMessageSystem::sendReliable( const LLHost &host, - S32 retries, - bool ping_based_timeout, - F32Seconds timeout, - void (*callback)(void **,S32), - void ** callback_data) -{ - if (ping_based_timeout) - { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, F32Seconds(LL_RELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged())); - } - else - { - timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, F32Seconds(LL_RELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX)); - } - } - - mSendReliable = true; - mReliablePacketParams.set(host, retries, ping_based_timeout, timeout, - callback, callback_data, - const_cast<char*>(mMessageBuilder->getMessageName())); - return sendMessage(host); +S32 LLMessageSystem::sendReliable( const LLHost &host, + S32 retries, + bool ping_based_timeout, + F32Seconds timeout, + void (*callback)(void **,S32), + void ** callback_data) +{ + if (ping_based_timeout) + { + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, F32Seconds(LL_RELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged())); + } + else + { + timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, F32Seconds(LL_RELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX)); + } + } + + mSendReliable = true; + mReliablePacketParams.set(host, retries, ping_based_timeout, timeout, + callback, callback_data, + const_cast<char*>(mMessageBuilder->getMessageName())); + return sendMessage(host); } void LLMessageSystem::forwardMessage(const LLHost &host) { - copyMessageReceivedToSend(); - sendMessage(host); + copyMessageReceivedToSend(); + sendMessage(host); } void LLMessageSystem::forwardReliable(const LLHost &host) { - copyMessageReceivedToSend(); - sendReliable(host); + copyMessageReceivedToSend(); + sendReliable(host); } void LLMessageSystem::forwardReliable(const U32 circuit_code) { - copyMessageReceivedToSend(); - sendReliable(findHost(circuit_code)); + copyMessageReceivedToSend(); + sendReliable(findHost(circuit_code)); } -S32 LLMessageSystem::forwardReliable( const LLHost &host, - S32 retries, - bool ping_based_timeout, - F32Seconds timeout, - void (*callback)(void **,S32), - void ** callback_data) +S32 LLMessageSystem::forwardReliable( const LLHost &host, + S32 retries, + bool ping_based_timeout, + F32Seconds timeout, + void (*callback)(void **,S32), + void ** callback_data) { - copyMessageReceivedToSend(); - return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data); + copyMessageReceivedToSend(); + return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data); } S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void **,S32), void ** callback_data) { - F32Seconds timeout; - - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS, - F32Seconds(LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged())); - } - else - { - timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX; - } - - S32 send_bytes = 0; - if (mMessageBuilder->getMessageSize()) - { - mSendReliable = true; - // No need for ping-based retry as not going to retry - mReliablePacketParams.set(host, 0, false, timeout, callback, - callback_data, - const_cast<char*>(mMessageBuilder->getMessageName())); - send_bytes = sendMessage(host); - clearMessage(); - } - else - { - delete callback_data; - } - return send_bytes; + F32Seconds timeout; + + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS, + F32Seconds(LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged())); + } + else + { + timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX; + } + + S32 send_bytes = 0; + if (mMessageBuilder->getMessageSize()) + { + mSendReliable = true; + // No need for ping-based retry as not going to retry + mReliablePacketParams.set(host, 0, false, timeout, callback, + callback_data, + const_cast<char*>(mMessageBuilder->getMessageName())); + send_bytes = sendMessage(host); + clearMessage(); + } + else + { + delete callback_data; + } + return send_bytes; } S32 LLMessageSystem::flushReliable(const LLHost &host) { - S32 send_bytes = 0; - if (mMessageBuilder->getMessageSize()) - { - send_bytes = sendReliable(host); - } - clearMessage(); - return send_bytes; + S32 send_bytes = 0; + if (mMessageBuilder->getMessageSize()) + { + send_bytes = sendReliable(host); + } + clearMessage(); + return send_bytes; } // This can be called from signal handlers, // so should should not use LL_INFOS(). S32 LLMessageSystem::sendMessage(const LLHost &host) { - if (! mMessageBuilder->isBuilt()) - { - mSendSize = mMessageBuilder->buildMessage( - mSendBuffer, - MAX_BUFFER_SIZE, - 0); - } - - if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message - { - return 0; - } - - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (!cdp) - { - // this is a new circuit! - // are we protected? - if (mbProtected) - { - // yup! don't send packets to an unknown circuit - if(mVerboseLog) - { - LL_INFOS_ONCE("Messaging") << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t" - << mMessageBuilder->getMessageName() << LL_ENDL; - } - LL_WARNS_ONCE("Messaging") << "sendMessage - Trying to send " - << mMessageBuilder->getMessageName() << " on unknown circuit " - << host << LL_ENDL; - return 0; - } - else - { - // nope, open the new circuit - - cdp = mCircuitInfo.addCircuitData(host, 0); - } - } - else - { - // this is an old circuit. . . is it still alive? - if (!cdp->isAlive()) - { - // nope. don't send to dead circuits - if(mVerboseLog) - { - LL_INFOS("Messaging") << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t" - << mMessageBuilder->getMessageName() << LL_ENDL; - } - LL_WARNS("Messaging") << "sendMessage - Trying to send message " - << mMessageBuilder->getMessageName() << " to dead circuit " - << host << LL_ENDL; - return 0; - } - } - - // NOTE: babbage: LLSD message -> HTTP, template message -> UDP - if(mMessageBuilder == mLLSDMessageBuilder) - { - LLSD message = mLLSDMessageBuilder->getMessage(); + if (! mMessageBuilder->isBuilt()) + { + mSendSize = mMessageBuilder->buildMessage( + mSendBuffer, + MAX_BUFFER_SIZE, + 0); + } + + if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message + { + return 0; + } + + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (!cdp) + { + // this is a new circuit! + // are we protected? + if (mbProtected) + { + // yup! don't send packets to an unknown circuit + if(mVerboseLog) + { + LL_INFOS_ONCE("Messaging") << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t" + << mMessageBuilder->getMessageName() << LL_ENDL; + } + LL_WARNS_ONCE("Messaging") << "sendMessage - Trying to send " + << mMessageBuilder->getMessageName() << " on unknown circuit " + << host << LL_ENDL; + return 0; + } + else + { + // nope, open the new circuit + + cdp = mCircuitInfo.addCircuitData(host, 0); + } + } + else + { + // this is an old circuit. . . is it still alive? + if (!cdp->isAlive()) + { + // nope. don't send to dead circuits + if(mVerboseLog) + { + LL_INFOS("Messaging") << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t" + << mMessageBuilder->getMessageName() << LL_ENDL; + } + LL_WARNS("Messaging") << "sendMessage - Trying to send message " + << mMessageBuilder->getMessageName() << " to dead circuit " + << host << LL_ENDL; + return 0; + } + } + + // NOTE: babbage: LLSD message -> HTTP, template message -> UDP + if(mMessageBuilder == mLLSDMessageBuilder) + { + LLSD message = mLLSDMessageBuilder->getMessage(); UntrustedCallback_t cb = NULL; if ((mSendReliable) && (mReliablePacketParams.mCallback)) @@ -1165,195 +1165,195 @@ S32 LLMessageSystem::sendMessage(const LLHost &host) } LLCoros::instance().launch("LLMessageSystem::sendUntrustedSimulatorMessageCoro", - boost::bind(&LLMessageSystem::sendUntrustedSimulatorMessageCoro, this, - host.getUntrustedSimulatorCap(), + boost::bind(&LLMessageSystem::sendUntrustedSimulatorMessageCoro, this, + host.getUntrustedSimulatorCap(), mLLSDMessageBuilder->getMessageName(), message, cb)); - mSendReliable = false; - mReliablePacketParams.clear(); - return 1; - } - - // zero out the flags and packetid. Subtract 1 here so that we do - // not overwrite the offset if it was set set in buildMessage(). - memset(mSendBuffer, 0, LL_PACKET_ID_SIZE - 1); - - // add the send id to the front of the message - cdp->nextPacketOutID(); - - // Packet ID size is always 4 - *((S32*)&mSendBuffer[PHL_PACKET_ID]) = htonl(cdp->getPacketOutID()); - - // Compress the message, which will usually reduce its size. - U8 * buf_ptr = (U8 *)mSendBuffer; - U32 buffer_length = mSendSize; - mMessageBuilder->compressMessage(buf_ptr, buffer_length); - - if (buffer_length > 1500) - { - if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate) - && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket)) - { - LL_WARNS("Messaging") << "sendMessage - Trying to send " - << ((buffer_length > 4000) ? "EXTRA " : "") - << "BIG message " << mMessageBuilder->getMessageName() << " - " - << buffer_length << LL_ENDL; - } - } - if (mSendReliable) - { - buf_ptr[0] |= LL_RELIABLE_FLAG; - - if (!cdp->getUnackedPacketCount()) - { - // We are adding the first packed onto the unacked packet list(s) - // Add this circuit to the list of circuits with unacked packets - mCircuitInfo.mUnackedCircuitMap[cdp->mHost] = cdp; - } - - cdp->addReliablePacket(mSocket,buf_ptr,buffer_length, &mReliablePacketParams); - mReliablePacketsOut++; - } - - // tack packet acks onto the end of this message - S32 space_left = (MTUBYTES - buffer_length) / sizeof(TPACKETID); // space left for packet ids - S32 ack_count = (S32)cdp->mAcks.size(); - bool is_ack_appended = false; - std::vector<TPACKETID> acks; - if((space_left > 0) && (ack_count > 0) && - (mMessageBuilder->getMessageName() != _PREHASH_PacketAck)) - { - buf_ptr[0] |= LL_ACK_FLAG; - S32 append_ack_count = llmin(space_left, ack_count); - const S32 MAX_ACKS = 250; - append_ack_count = llmin(append_ack_count, MAX_ACKS); - std::vector<TPACKETID>::iterator iter = cdp->mAcks.begin(); - std::vector<TPACKETID>::iterator last = cdp->mAcks.begin(); - last += append_ack_count; - TPACKETID packet_id; - for( ; iter != last ; ++iter) - { - // grab the next packet id. - packet_id = (*iter); - if(mVerboseLog) - { - acks.push_back(packet_id); - } - - // put it on the end of the buffer - packet_id = htonl(packet_id); - - if((S32)(buffer_length + sizeof(TPACKETID)) < MAX_BUFFER_SIZE) - { - memcpy(&buf_ptr[buffer_length], &packet_id, sizeof(TPACKETID)); /* Flawfinder: ignore */ - // Do the accounting - buffer_length += sizeof(TPACKETID); - } - else - { - // Just reporting error is likely not enough. Need to - // check how to abort or error out gracefully from - // this function. XXXTBD - // *NOTE: Actually hitting this error would indicate - // the calculation above for space_left, ack_count, - // append_acout_count is incorrect or that - // MAX_BUFFER_SIZE has fallen below MTU which is bad - // and probably programmer error. - LL_ERRS("Messaging") << "Buffer packing failed due to size.." << LL_ENDL; - } - } - - // clean up the source - cdp->mAcks.erase(cdp->mAcks.begin(), last); - - // tack the count in the final byte - U8 count = (U8)append_ack_count; - buf_ptr[buffer_length++] = count; - is_ack_appended = true; - } - - bool success; - success = mPacketRing.sendPacket(mSocket, (char *)buf_ptr, buffer_length, host); - - if (!success) - { - mSendPacketFailureCount++; - } - else - { - // mCircuitInfo already points to the correct circuit data - cdp->addBytesOut( (S32Bytes)buffer_length ); - } - - if(mVerboseLog) - { - std::ostringstream str; - str << "MSG: -> " << host; - std::string buffer; - buffer = llformat( "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID()); - str << buffer - << mMessageBuilder->getMessageName() - << (mSendReliable ? " reliable " : ""); - if(is_ack_appended) - { - str << "\tACKS:\t"; - std::ostream_iterator<TPACKETID> append(str, " "); - std::copy(acks.begin(), acks.end(), append); - } - LL_INFOS("Messaging") << str.str() << LL_ENDL; - } - - - mPacketsOut++; - mTotalBytesOut += buffer_length; - - mSendReliable = false; - mReliablePacketParams.clear(); - return buffer_length; + mSendReliable = false; + mReliablePacketParams.clear(); + return 1; + } + + // zero out the flags and packetid. Subtract 1 here so that we do + // not overwrite the offset if it was set set in buildMessage(). + memset(mSendBuffer, 0, LL_PACKET_ID_SIZE - 1); + + // add the send id to the front of the message + cdp->nextPacketOutID(); + + // Packet ID size is always 4 + *((S32*)&mSendBuffer[PHL_PACKET_ID]) = htonl(cdp->getPacketOutID()); + + // Compress the message, which will usually reduce its size. + U8 * buf_ptr = (U8 *)mSendBuffer; + U32 buffer_length = mSendSize; + mMessageBuilder->compressMessage(buf_ptr, buffer_length); + + if (buffer_length > 1500) + { + if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate) + && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket)) + { + LL_WARNS("Messaging") << "sendMessage - Trying to send " + << ((buffer_length > 4000) ? "EXTRA " : "") + << "BIG message " << mMessageBuilder->getMessageName() << " - " + << buffer_length << LL_ENDL; + } + } + if (mSendReliable) + { + buf_ptr[0] |= LL_RELIABLE_FLAG; + + if (!cdp->getUnackedPacketCount()) + { + // We are adding the first packed onto the unacked packet list(s) + // Add this circuit to the list of circuits with unacked packets + mCircuitInfo.mUnackedCircuitMap[cdp->mHost] = cdp; + } + + cdp->addReliablePacket(mSocket,buf_ptr,buffer_length, &mReliablePacketParams); + mReliablePacketsOut++; + } + + // tack packet acks onto the end of this message + S32 space_left = (MTUBYTES - buffer_length) / sizeof(TPACKETID); // space left for packet ids + S32 ack_count = (S32)cdp->mAcks.size(); + bool is_ack_appended = false; + std::vector<TPACKETID> acks; + if((space_left > 0) && (ack_count > 0) && + (mMessageBuilder->getMessageName() != _PREHASH_PacketAck)) + { + buf_ptr[0] |= LL_ACK_FLAG; + S32 append_ack_count = llmin(space_left, ack_count); + const S32 MAX_ACKS = 250; + append_ack_count = llmin(append_ack_count, MAX_ACKS); + std::vector<TPACKETID>::iterator iter = cdp->mAcks.begin(); + std::vector<TPACKETID>::iterator last = cdp->mAcks.begin(); + last += append_ack_count; + TPACKETID packet_id; + for( ; iter != last ; ++iter) + { + // grab the next packet id. + packet_id = (*iter); + if(mVerboseLog) + { + acks.push_back(packet_id); + } + + // put it on the end of the buffer + packet_id = htonl(packet_id); + + if((S32)(buffer_length + sizeof(TPACKETID)) < MAX_BUFFER_SIZE) + { + memcpy(&buf_ptr[buffer_length], &packet_id, sizeof(TPACKETID)); /* Flawfinder: ignore */ + // Do the accounting + buffer_length += sizeof(TPACKETID); + } + else + { + // Just reporting error is likely not enough. Need to + // check how to abort or error out gracefully from + // this function. XXXTBD + // *NOTE: Actually hitting this error would indicate + // the calculation above for space_left, ack_count, + // append_acout_count is incorrect or that + // MAX_BUFFER_SIZE has fallen below MTU which is bad + // and probably programmer error. + LL_ERRS("Messaging") << "Buffer packing failed due to size.." << LL_ENDL; + } + } + + // clean up the source + cdp->mAcks.erase(cdp->mAcks.begin(), last); + + // tack the count in the final byte + U8 count = (U8)append_ack_count; + buf_ptr[buffer_length++] = count; + is_ack_appended = true; + } + + bool success; + success = mPacketRing.sendPacket(mSocket, (char *)buf_ptr, buffer_length, host); + + if (!success) + { + mSendPacketFailureCount++; + } + else + { + // mCircuitInfo already points to the correct circuit data + cdp->addBytesOut( (S32Bytes)buffer_length ); + } + + if(mVerboseLog) + { + std::ostringstream str; + str << "MSG: -> " << host; + std::string buffer; + buffer = llformat( "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID()); + str << buffer + << mMessageBuilder->getMessageName() + << (mSendReliable ? " reliable " : ""); + if(is_ack_appended) + { + str << "\tACKS:\t"; + std::ostream_iterator<TPACKETID> append(str, " "); + std::copy(acks.begin(), acks.end(), append); + } + LL_INFOS("Messaging") << str.str() << LL_ENDL; + } + + + mPacketsOut++; + mTotalBytesOut += buffer_length; + + mSendReliable = false; + mReliablePacketParams.clear(); + return buffer_length; } void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, bool recv_reliable ) { - if(mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << host; - std::string buffer; - buffer = llformat( "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID); - str << buffer - << nullToEmpty(mMessageReader->getMessageName()) - << (recv_reliable ? " reliable" : "") - << " REJECTED"; - LL_INFOS("Messaging") << str.str() << LL_ENDL; - } - // nope! - // cout << "Rejecting unexpected message " << mCurrentMessageTemplate->mName << " from " << hex << ip << " , " << dec << port << endl; - - // Keep track of rejected messages as well - if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) - { - LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << LL_ENDL; - } - else - { - // TODO: babbage: work out if we need these - // mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; - mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize(); - mMessageCountList[mNumMessageCounts].mInvalid = true; - mNumMessageCounts++; - } + if(mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << host; + std::string buffer; + buffer = llformat( "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID); + str << buffer + << nullToEmpty(mMessageReader->getMessageName()) + << (recv_reliable ? " reliable" : "") + << " REJECTED"; + LL_INFOS("Messaging") << str.str() << LL_ENDL; + } + // nope! + // cout << "Rejecting unexpected message " << mCurrentMessageTemplate->mName << " from " << hex << ip << " , " << dec << port << endl; + + // Keep track of rejected messages as well + if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) + { + LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << LL_ENDL; + } + else + { + // TODO: babbage: work out if we need these + // mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; + mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize(); + mMessageCountList[mNumMessageCounts].mInvalid = true; + mNumMessageCounts++; + } } S32 LLMessageSystem::sendMessage( - const LLHost &host, - const char* name, - const LLSD& message) + const LLHost &host, + const char* name, + const LLSD& message) { - if (!(host.isOk())) - { - LL_WARNS("Messaging") << "trying to send message to invalid host" << LL_ENDL; - return 0; - } + if (!(host.isOk())) + { + LL_WARNS("Messaging") << "trying to send message to invalid host" << LL_ENDL; + return 0; + } UntrustedCallback_t cb = NULL; if ((mSendReliable) && (mReliablePacketParams.mCallback)) @@ -1369,363 +1369,363 @@ S32 LLMessageSystem::sendMessage( void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host ) { - // RequestTrustedCircuit is how we establish trust, so don't spam - // if it's received on a trusted circuit. JC - if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit")) - { - LL_WARNS("Messaging") << "Received trusted message on untrusted circuit. " - << "Will reply with deny. " - << "Message: " << nullToEmpty(mMessageReader->getMessageName()) - << " Host: " << host << LL_ENDL; - } - - if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) - { - LL_WARNS("Messaging") << "got more than " << MAX_MESSAGE_COUNT_NUM - << " packets without clearing counts" - << LL_ENDL; - } - else - { - // TODO: babbage: work out if we need these - //mMessageCountList[mNumMessageCounts].mMessageNum - // = mCurrentRMessageTemplate->mMessageNumber; - mMessageCountList[mNumMessageCounts].mMessageBytes - = mMessageReader->getMessageSize(); - mMessageCountList[mNumMessageCounts].mInvalid = true; - mNumMessageCounts++; - } + // RequestTrustedCircuit is how we establish trust, so don't spam + // if it's received on a trusted circuit. JC + if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit")) + { + LL_WARNS("Messaging") << "Received trusted message on untrusted circuit. " + << "Will reply with deny. " + << "Message: " << nullToEmpty(mMessageReader->getMessageName()) + << " Host: " << host << LL_ENDL; + } + + if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) + { + LL_WARNS("Messaging") << "got more than " << MAX_MESSAGE_COUNT_NUM + << " packets without clearing counts" + << LL_ENDL; + } + else + { + // TODO: babbage: work out if we need these + //mMessageCountList[mNumMessageCounts].mMessageNum + // = mCurrentRMessageTemplate->mMessageNumber; + mMessageCountList[mNumMessageCounts].mMessageBytes + = mMessageReader->getMessageSize(); + mMessageCountList[mNumMessageCounts].mInvalid = true; + mNumMessageCounts++; + } } void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, bool recv_reliable, bool recv_resent, bool recv_acks ) { - if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) - { - LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << LL_ENDL; - } - else - { - // TODO: babbage: work out if we need these - //mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; - mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize(); - mMessageCountList[mNumMessageCounts].mInvalid = false; - mNumMessageCounts++; - } - - if (cdp) - { - // update circuit packet ID tracking (missing/out of order packets) - cdp->checkPacketInID( mCurrentRecvPacketID, recv_resent ); - cdp->addBytesIn( (S32Bytes)mTrueReceiveSize ); - } - - if(mVerboseLog) - { - std::ostringstream str; - str << "MSG: <- " << host; - std::string buffer; - buffer = llformat( "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID); - str << buffer - << nullToEmpty(mMessageReader->getMessageName()) - << (recv_reliable ? " reliable" : "") - << (recv_resent ? " resent" : "") - << (recv_acks ? " acks" : ""); - LL_INFOS("Messaging") << str.str() << LL_ENDL; - } + if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) + { + LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << LL_ENDL; + } + else + { + // TODO: babbage: work out if we need these + //mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; + mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize(); + mMessageCountList[mNumMessageCounts].mInvalid = false; + mNumMessageCounts++; + } + + if (cdp) + { + // update circuit packet ID tracking (missing/out of order packets) + cdp->checkPacketInID( mCurrentRecvPacketID, recv_resent ); + cdp->addBytesIn( (S32Bytes)mTrueReceiveSize ); + } + + if(mVerboseLog) + { + std::ostringstream str; + str << "MSG: <- " << host; + std::string buffer; + buffer = llformat( "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID); + str << buffer + << nullToEmpty(mMessageReader->getMessageName()) + << (recv_reliable ? " reliable" : "") + << (recv_resent ? " resent" : "") + << (recv_acks ? " acks" : ""); + LL_INFOS("Messaging") << str.str() << LL_ENDL; + } } void LLMessageSystem::sanityCheck() { // TODO: babbage: reinstate -// if (!mCurrentRMessageData) -// { -// LL_ERRS("Messaging") << "mCurrentRMessageData is NULL" << LL_ENDL; -// } +// if (!mCurrentRMessageData) +// { +// LL_ERRS("Messaging") << "mCurrentRMessageData is NULL" << LL_ENDL; +// } -// if (!mCurrentRMessageTemplate) -// { -// LL_ERRS("Messaging") << "mCurrentRMessageTemplate is NULL" << LL_ENDL; -// } +// if (!mCurrentRMessageTemplate) +// { +// LL_ERRS("Messaging") << "mCurrentRMessageTemplate is NULL" << LL_ENDL; +// } -// if (!mCurrentRTemplateBlock) -// { -// LL_ERRS("Messaging") << "mCurrentRTemplateBlock is NULL" << LL_ENDL; -// } +// if (!mCurrentRTemplateBlock) +// { +// LL_ERRS("Messaging") << "mCurrentRTemplateBlock is NULL" << LL_ENDL; +// } -// if (!mCurrentRDataBlock) -// { -// LL_ERRS("Messaging") << "mCurrentRDataBlock is NULL" << LL_ENDL; -// } +// if (!mCurrentRDataBlock) +// { +// LL_ERRS("Messaging") << "mCurrentRDataBlock is NULL" << LL_ENDL; +// } -// if (!mCurrentSMessageData) -// { -// LL_ERRS("Messaging") << "mCurrentSMessageData is NULL" << LL_ENDL; -// } +// if (!mCurrentSMessageData) +// { +// LL_ERRS("Messaging") << "mCurrentSMessageData is NULL" << LL_ENDL; +// } -// if (!mCurrentSMessageTemplate) -// { -// LL_ERRS("Messaging") << "mCurrentSMessageTemplate is NULL" << LL_ENDL; -// } +// if (!mCurrentSMessageTemplate) +// { +// LL_ERRS("Messaging") << "mCurrentSMessageTemplate is NULL" << LL_ENDL; +// } -// if (!mCurrentSTemplateBlock) -// { -// LL_ERRS("Messaging") << "mCurrentSTemplateBlock is NULL" << LL_ENDL; -// } +// if (!mCurrentSTemplateBlock) +// { +// LL_ERRS("Messaging") << "mCurrentSTemplateBlock is NULL" << LL_ENDL; +// } -// if (!mCurrentSDataBlock) -// { -// LL_ERRS("Messaging") << "mCurrentSDataBlock is NULL" << LL_ENDL; -// } +// if (!mCurrentSDataBlock) +// { +// LL_ERRS("Messaging") << "mCurrentSDataBlock is NULL" << LL_ENDL; +// } } void LLMessageSystem::showCircuitInfo() { - LL_INFOS("Messaging") << mCircuitInfo << LL_ENDL; + LL_INFOS("Messaging") << mCircuitInfo << LL_ENDL; } void LLMessageSystem::dumpCircuitInfo() { - LL_DEBUGS("Messaging") << mCircuitInfo << LL_ENDL; + LL_DEBUGS("Messaging") << mCircuitInfo << LL_ENDL; } /* virtual */ U32 LLMessageSystem::getOurCircuitCode() { - return mOurCircuitCode; + return mOurCircuitCode; } void LLMessageSystem::getCircuitInfo(LLSD& info) const { - mCircuitInfo.getInfo(info); + mCircuitInfo.getInfo(info); } // returns whether the given host is on a trusted circuit bool LLMessageSystem::getCircuitTrust(const LLHost &host) { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - return cdp->getTrusted(); - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + return cdp->getTrusted(); + } - return false; + return false; } // Activate a circuit, and set its trust level (true if trusted, // false if not). void LLMessageSystem::enableCircuit(const LLHost &host, bool trusted) { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (!cdp) - { - cdp = mCircuitInfo.addCircuitData(host, 0); - } - else - { - cdp->setAlive(true); - } - cdp->setTrusted(trusted); + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (!cdp) + { + cdp = mCircuitInfo.addCircuitData(host, 0); + } + else + { + cdp->setAlive(true); + } + cdp->setTrusted(trusted); } void LLMessageSystem::disableCircuit(const LLHost &host) { - LL_INFOS("Messaging") << "LLMessageSystem::disableCircuit for " << host << LL_ENDL; - U32 code = gMessageSystem->findCircuitCode( host ); + LL_INFOS("Messaging") << "LLMessageSystem::disableCircuit for " << host << LL_ENDL; + U32 code = gMessageSystem->findCircuitCode( host ); - // Don't need to do this, as we're removing the circuit info anyway - djs 01/28/03 + // Don't need to do this, as we're removing the circuit info anyway - djs 01/28/03 - // don't clean up 0 circuit code entries - // because many hosts (neighbor sims, etc) can have the 0 circuit - if (code) - { - //if (mCircuitCodes.checkKey(code)) - code_session_map_t::iterator it = mCircuitCodes.find(code); - if(it != mCircuitCodes.end()) - { - LL_INFOS("Messaging") << "Circuit " << code << " removed from list" << LL_ENDL; - //mCircuitCodes.removeData(code); - mCircuitCodes.erase(it); - } + // don't clean up 0 circuit code entries + // because many hosts (neighbor sims, etc) can have the 0 circuit + if (code) + { + //if (mCircuitCodes.checkKey(code)) + code_session_map_t::iterator it = mCircuitCodes.find(code); + if(it != mCircuitCodes.end()) + { + LL_INFOS("Messaging") << "Circuit " << code << " removed from list" << LL_ENDL; + //mCircuitCodes.removeData(code); + mCircuitCodes.erase(it); + } + + U64 ip_port = 0; + std::map<U32, U64>::iterator iter = gMessageSystem->mCircuitCodeToIPPort.find(code); + if (iter != gMessageSystem->mCircuitCodeToIPPort.end()) + { + ip_port = iter->second; - U64 ip_port = 0; - std::map<U32, U64>::iterator iter = gMessageSystem->mCircuitCodeToIPPort.find(code); - if (iter != gMessageSystem->mCircuitCodeToIPPort.end()) - { - ip_port = iter->second; + gMessageSystem->mCircuitCodeToIPPort.erase(iter); - gMessageSystem->mCircuitCodeToIPPort.erase(iter); + U32 old_port = (U32)(ip_port & (U64)0xFFFFFFFF); + U32 old_ip = (U32)(ip_port >> 32); - U32 old_port = (U32)(ip_port & (U64)0xFFFFFFFF); - U32 old_ip = (U32)(ip_port >> 32); + LL_INFOS("Messaging") << "Host " << LLHost(old_ip, old_port) << " circuit " << code << " removed from lookup table" << LL_ENDL; + gMessageSystem->mIPPortToCircuitCode.erase(ip_port); + } + mCircuitInfo.removeCircuitData(host); + } + else + { + // Sigh, since we can open circuits which don't have circuit + // codes, it's possible for this to happen... - LL_INFOS("Messaging") << "Host " << LLHost(old_ip, old_port) << " circuit " << code << " removed from lookup table" << LL_ENDL; - gMessageSystem->mIPPortToCircuitCode.erase(ip_port); - } - mCircuitInfo.removeCircuitData(host); - } - else - { - // Sigh, since we can open circuits which don't have circuit - // codes, it's possible for this to happen... - - LL_WARNS("Messaging") << "Couldn't find circuit code for " << host << LL_ENDL; - } + LL_WARNS("Messaging") << "Couldn't find circuit code for " << host << LL_ENDL; + } } void LLMessageSystem::setCircuitAllowTimeout(const LLHost &host, bool allow) { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - cdp->setAllowTimeout(allow); - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + cdp->setAllowTimeout(allow); + } } void LLMessageSystem::setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost & host, void *user_data), void *user_data) { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - cdp->setTimeoutCallback(callback_func, user_data); - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + cdp->setTimeoutCallback(callback_func, user_data); + } } bool LLMessageSystem::checkCircuitBlocked(const U32 circuit) { - LLHost host = findHost(circuit); + LLHost host = findHost(circuit); - if (!host.isOk()) - { - LL_DEBUGS("Messaging") << "checkCircuitBlocked: Unknown circuit " << circuit << LL_ENDL; - return true; - } + if (!host.isOk()) + { + LL_DEBUGS("Messaging") << "checkCircuitBlocked: Unknown circuit " << circuit << LL_ENDL; + return true; + } - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - return cdp->isBlocked(); - } - else - { - LL_INFOS("Messaging") << "checkCircuitBlocked(circuit): Unknown host - " << host << LL_ENDL; - return false; - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + return cdp->isBlocked(); + } + else + { + LL_INFOS("Messaging") << "checkCircuitBlocked(circuit): Unknown host - " << host << LL_ENDL; + return false; + } } bool LLMessageSystem::checkCircuitAlive(const U32 circuit) { - LLHost host = findHost(circuit); + LLHost host = findHost(circuit); - if (!host.isOk()) - { - LL_DEBUGS("Messaging") << "checkCircuitAlive: Unknown circuit " << circuit << LL_ENDL; - return false; - } + if (!host.isOk()) + { + LL_DEBUGS("Messaging") << "checkCircuitAlive: Unknown circuit " << circuit << LL_ENDL; + return false; + } - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - return cdp->isAlive(); - } - else - { - LL_INFOS("Messaging") << "checkCircuitAlive(circuit): Unknown host - " << host << LL_ENDL; - return false; - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + return cdp->isAlive(); + } + else + { + LL_INFOS("Messaging") << "checkCircuitAlive(circuit): Unknown host - " << host << LL_ENDL; + return false; + } } bool LLMessageSystem::checkCircuitAlive(const LLHost &host) { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (cdp) - { - return cdp->isAlive(); - } - else - { - LL_DEBUGS("Messaging") << "checkCircuitAlive(host): Unknown host - " << host << LL_ENDL; - return false; - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (cdp) + { + return cdp->isAlive(); + } + else + { + LL_DEBUGS("Messaging") << "checkCircuitAlive(host): Unknown host - " << host << LL_ENDL; + return false; + } } void LLMessageSystem::setCircuitProtection(bool b_protect) { - mbProtected = b_protect; + mbProtected = b_protect; } U32 LLMessageSystem::findCircuitCode(const LLHost &host) { - U64 ip64 = (U64) host.getAddress(); - U64 port64 = (U64) host.getPort(); - U64 ip_port = (ip64 << 32) | port64; + U64 ip64 = (U64) host.getAddress(); + U64 port64 = (U64) host.getPort(); + U64 ip_port = (ip64 << 32) | port64; - return get_if_there(mIPPortToCircuitCode, ip_port, U32(0)); + return get_if_there(mIPPortToCircuitCode, ip_port, U32(0)); } LLHost LLMessageSystem::findHost(const U32 circuit_code) { - if (mCircuitCodeToIPPort.count(circuit_code) > 0) - { - return LLHost(mCircuitCodeToIPPort[circuit_code]); - } - else - { - return LLHost(); - } + if (mCircuitCodeToIPPort.count(circuit_code) > 0) + { + return LLHost(mCircuitCodeToIPPort[circuit_code]); + } + else + { + return LLHost(); + } } void LLMessageSystem::setMaxMessageTime(const F32 seconds) { - mMaxMessageTime = F32Seconds(seconds); + mMaxMessageTime = F32Seconds(seconds); } void LLMessageSystem::setMaxMessageCounts(const S32 num) { - mMaxMessageCounts = num; + mMaxMessageCounts = num; } std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg) { - U32 i; - if (msg.mbError) - { - s << "Message system not correctly initialized"; - } - else - { - s << "Message system open on port " << msg.mPort << " and socket " << msg.mSocket << "\n"; -// s << "Message template file " << msg.mName << " loaded\n"; - - s << "\nHigh frequency messages:\n"; - - for (i = 1; msg.mMessageNumbers[i] && (i < 255); i++) - { - s << *(msg.mMessageNumbers[i]); - } - - s << "\nMedium frequency messages:\n"; - - for (i = (255 << 8) + 1; msg.mMessageNumbers[i] && (i < (255 << 8) + 255); i++) - { - s << *msg.mMessageNumbers[i]; - } - - s << "\nLow frequency messages:\n"; - - for (i = (0xFFFF0000) + 1; msg.mMessageNumbers[i] && (i < 0xFFFFFFFF); i++) - { - s << *msg.mMessageNumbers[i]; - } - } - return s; + U32 i; + if (msg.mbError) + { + s << "Message system not correctly initialized"; + } + else + { + s << "Message system open on port " << msg.mPort << " and socket " << msg.mSocket << "\n"; +// s << "Message template file " << msg.mName << " loaded\n"; + + s << "\nHigh frequency messages:\n"; + + for (i = 1; msg.mMessageNumbers[i] && (i < 255); i++) + { + s << *(msg.mMessageNumbers[i]); + } + + s << "\nMedium frequency messages:\n"; + + for (i = (255 << 8) + 1; msg.mMessageNumbers[i] && (i < (255 << 8) + 255); i++) + { + s << *msg.mMessageNumbers[i]; + } + + s << "\nLow frequency messages:\n"; + + for (i = (0xFFFF0000) + 1; msg.mMessageNumbers[i] && (i < 0xFFFFFFFF); i++) + { + s << *msg.mMessageNumbers[i]; + } + } + return s; } // LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.) @@ -1733,2251 +1733,2251 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg) LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // update appropriate ping info -void process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) +void process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) { - U8 ping_id; - msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id); + U8 ping_id; + msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id); - LLCircuitData *cdp; - cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender()); + LLCircuitData *cdp; + cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender()); - // stop the appropriate timer - if (cdp) - { - cdp->pingTimerStop(ping_id); - } + // stop the appropriate timer + if (cdp) + { + cdp->pingTimerStop(ping_id); + } } -void process_start_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) +void process_start_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) { - U8 ping_id; - msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id); + U8 ping_id; + msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id); - LLCircuitData *cdp; - cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender()); - if (cdp) - { - // Grab the packet id of the oldest unacked packet - U32 packet_id; - msgsystem->getU32Fast(_PREHASH_PingID, _PREHASH_OldestUnacked, packet_id); - cdp->clearDuplicateList(packet_id); - } + LLCircuitData *cdp; + cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender()); + if (cdp) + { + // Grab the packet id of the oldest unacked packet + U32 packet_id; + msgsystem->getU32Fast(_PREHASH_PingID, _PREHASH_OldestUnacked, packet_id); + cdp->clearDuplicateList(packet_id); + } - // Send off the response - msgsystem->newMessageFast(_PREHASH_CompletePingCheck); - msgsystem->nextBlockFast(_PREHASH_PingID); - msgsystem->addU8(_PREHASH_PingID, ping_id); - msgsystem->sendMessage(msgsystem->getSender()); + // Send off the response + msgsystem->newMessageFast(_PREHASH_CompletePingCheck); + msgsystem->nextBlockFast(_PREHASH_PingID); + msgsystem->addU8(_PREHASH_PingID, ping_id); + msgsystem->sendMessage(msgsystem->getSender()); } // Note: this is currently unused. --mark -void open_circuit(LLMessageSystem *msgsystem, void** /*user_data*/) +void open_circuit(LLMessageSystem *msgsystem, void** /*user_data*/) { - U32 ip; - U16 port; + U32 ip; + U16 port; - msgsystem->getIPAddrFast(_PREHASH_CircuitInfo, _PREHASH_IP, ip); - msgsystem->getIPPortFast(_PREHASH_CircuitInfo, _PREHASH_Port, port); + msgsystem->getIPAddrFast(_PREHASH_CircuitInfo, _PREHASH_IP, ip); + msgsystem->getIPPortFast(_PREHASH_CircuitInfo, _PREHASH_Port, port); - // By default, OpenCircuit's are untrusted - msgsystem->enableCircuit(LLHost(ip, port), false); + // By default, OpenCircuit's are untrusted + msgsystem->enableCircuit(LLHost(ip, port), false); } -void close_circuit(LLMessageSystem *msgsystem, void** /*user_data*/) +void close_circuit(LLMessageSystem *msgsystem, void** /*user_data*/) { - msgsystem->disableCircuit(msgsystem->getSender()); + msgsystem->disableCircuit(msgsystem->getSender()); } // static /* void LLMessageSystem::processAssignCircuitCode(LLMessageSystem* msg, void**) { - // if we already have a circuit code, we can bail - if(msg->mOurCircuitCode) return; - LLUUID session_id; - msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id); - if(session_id != msg->getMySessionID()) - { - LL_WARNS("Messaging") << "AssignCircuitCode, bad session id. Expecting " - << msg->getMySessionID() << " but got " << session_id - << LL_ENDL; - return; - } - U32 code; - msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code); - if (!code) - { - LL_ERRS("Messaging") << "Assigning circuit code of zero!" << LL_ENDL; - } - - msg->mOurCircuitCode = code; - LL_INFOS("Messaging") << "Circuit code " << code << " assigned." << LL_ENDL; + // if we already have a circuit code, we can bail + if(msg->mOurCircuitCode) return; + LLUUID session_id; + msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id); + if(session_id != msg->getMySessionID()) + { + LL_WARNS("Messaging") << "AssignCircuitCode, bad session id. Expecting " + << msg->getMySessionID() << " but got " << session_id + << LL_ENDL; + return; + } + U32 code; + msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code); + if (!code) + { + LL_ERRS("Messaging") << "Assigning circuit code of zero!" << LL_ENDL; + } + + msg->mOurCircuitCode = code; + LL_INFOS("Messaging") << "Circuit code " << code << " assigned." << LL_ENDL; } */ // static void LLMessageSystem::processAddCircuitCode(LLMessageSystem* msg, void**) { - U32 code; - msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code); - LLUUID session_id; - msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id); - (void)msg->addCircuitCode(code, session_id); + U32 code; + msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code); + LLUUID session_id; + msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id); + (void)msg->addCircuitCode(code, session_id); - // Send the ack back - //msg->newMessageFast(_PREHASH_AckAddCircuitCode); - //msg->nextBlockFast(_PREHASH_CircuitCode); - //msg->addU32Fast(_PREHASH_Code, code); - //msg->sendMessage(msg->getSender()); + // Send the ack back + //msg->newMessageFast(_PREHASH_AckAddCircuitCode); + //msg->nextBlockFast(_PREHASH_CircuitCode); + //msg->addU32Fast(_PREHASH_Code, code); + //msg->sendMessage(msg->getSender()); } bool LLMessageSystem::addCircuitCode(U32 code, const LLUUID& session_id) { - if(!code) - { - LL_WARNS("Messaging") << "addCircuitCode: zero circuit code" << LL_ENDL; - return false; - } - code_session_map_t::iterator it = mCircuitCodes.find(code); - if(it == mCircuitCodes.end()) - { - LL_INFOS("Messaging") << "New circuit code " << code << " added" << LL_ENDL; - //msg->mCircuitCodes[circuit_code] = circuit_code; - - mCircuitCodes.insert(code_session_map_t::value_type(code, session_id)); - } - else - { - LL_INFOS("Messaging") << "Duplicate circuit code " << code << " added" << LL_ENDL; - } - return true; + if(!code) + { + LL_WARNS("Messaging") << "addCircuitCode: zero circuit code" << LL_ENDL; + return false; + } + code_session_map_t::iterator it = mCircuitCodes.find(code); + if(it == mCircuitCodes.end()) + { + LL_INFOS("Messaging") << "New circuit code " << code << " added" << LL_ENDL; + //msg->mCircuitCodes[circuit_code] = circuit_code; + + mCircuitCodes.insert(code_session_map_t::value_type(code, session_id)); + } + else + { + LL_INFOS("Messaging") << "Duplicate circuit code " << code << " added" << LL_ENDL; + } + return true; } //void ack_add_circuit_code(LLMessageSystem *msgsystem, void** /*user_data*/) //{ - // By default, we do nothing. This particular message is only handled by the spaceserver + // By default, we do nothing. This particular message is only handled by the spaceserver //} // static void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, - void** user) -{ - U32 circuit_code_in; - msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in); - - U32 ip = msg->getSenderIP(); - U32 port = msg->getSenderPort(); - - U64 ip64 = ip; - U64 port64 = port; - U64 ip_port_in = (ip64 << 32) | port64; - - if (circuit_code_in) - { - //if (!msg->mCircuitCodes.checkKey(circuit_code_in)) - code_session_map_t::iterator it; - it = msg->mCircuitCodes.find(circuit_code_in); - if(it == msg->mCircuitCodes.end()) - { - // Whoah, abort! We don't know anything about this circuit code. - LL_WARNS("Messaging") << "UseCircuitCode for " << circuit_code_in - << " received without AddCircuitCode message - aborting" - << LL_ENDL; - return; - } - - LLUUID id; - msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_ID, id); - LLUUID session_id; - msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id); - if(session_id != (*it).second) - { - LL_WARNS("Messaging") << "UseCircuitCode unmatched session id. Got " - << session_id << " but expected " << (*it).second - << LL_ENDL; - return; - } - - // Clean up previous references to this ip/port or circuit - U64 ip_port_old = get_if_there(msg->mCircuitCodeToIPPort, circuit_code_in, U64(0)); - U32 circuit_code_old = get_if_there(msg->mIPPortToCircuitCode, ip_port_in, U32(0)); - - if (ip_port_old) - { - if ((ip_port_old == ip_port_in) && (circuit_code_old == circuit_code_in)) - { - // Current information is the same as incoming info, ignore - LL_INFOS("Messaging") << "Got duplicate UseCircuitCode for circuit " << circuit_code_in << " to " << msg->getSender() << LL_ENDL; - return; - } - - // Hmm, got a different IP and port for the same circuit code. - U32 circut_code_old_ip_port = get_if_there(msg->mIPPortToCircuitCode, ip_port_old, U32(0)); - msg->mCircuitCodeToIPPort.erase(circut_code_old_ip_port); - msg->mIPPortToCircuitCode.erase(ip_port_old); - U32 old_port = (U32)(ip_port_old & (U64)0xFFFFFFFF); - U32 old_ip = (U32)(ip_port_old >> 32); - LL_INFOS("Messaging") << "Removing derelict lookup entry for circuit " << circuit_code_old << " to " << LLHost(old_ip, old_port) << LL_ENDL; - } - - if (circuit_code_old) - { - LLHost cur_host(ip, port); - - LL_WARNS("Messaging") << "Disabling existing circuit for " << cur_host << LL_ENDL; - msg->disableCircuit(cur_host); - if (circuit_code_old == circuit_code_in) - { - LL_WARNS("Messaging") << "Asymmetrical circuit to ip/port lookup!" << LL_ENDL; - LL_WARNS("Messaging") << "Multiple circuit codes for " << cur_host << " probably!" << LL_ENDL; - LL_WARNS("Messaging") << "Permanently disabling circuit" << LL_ENDL; - return; - } - else - { - LL_WARNS("Messaging") << "Circuit code changed for " << msg->getSender() - << " from " << circuit_code_old << " to " - << circuit_code_in << LL_ENDL; - } - } - - // Since this comes from the viewer, it's untrusted, but it - // passed the circuit code and session id check, so we will go - // ahead and persist the ID associated. - LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); - bool had_circuit_already = cdp != nullptr; - - msg->enableCircuit(msg->getSender(), false); - cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); - if(cdp) - { - cdp->setRemoteID(id); - cdp->setRemoteSessionID(session_id); - } - - if (!had_circuit_already) - { - // - // HACK HACK HACK HACK HACK! - // - // This would NORMALLY happen inside logValidMsg, but at the point that this happens - // inside logValidMsg, there's no circuit for this message yet. So the awful thing that - // we do here is do it inside this message handler immediately AFTER the message is - // handled. - // - // We COULD not do this, but then what happens is that some of the circuit bookkeeping - // gets broken, especially the packets in count. That causes some later packets to flush - // the RecentlyReceivedReliable list, resulting in an error in which UseCircuitCode - // doesn't get properly duplicate suppressed. Not a BIG deal, but it's somewhat confusing - // (and bad from a state point of view). DJS 9/23/04 - // - cdp->checkPacketInID(gMessageSystem->mCurrentRecvPacketID, false ); // Since this is the first message on the circuit, by definition it's not resent. - } - - msg->mIPPortToCircuitCode[ip_port_in] = circuit_code_in; - msg->mCircuitCodeToIPPort[circuit_code_in] = ip_port_in; - - LL_INFOS("Messaging") << "Circuit code " << circuit_code_in << " from " - << msg->getSender() << " for agent " << id << " in session " - << session_id << LL_ENDL; - - const LLUseCircuitCodeResponder* responder = - (const LLUseCircuitCodeResponder*) user; - if(responder) - { - responder->complete(msg->getSender(), id); - } - } - else - { - LL_WARNS("Messaging") << "Got zero circuit code in use_circuit_code" << LL_ENDL; - } + void** user) +{ + U32 circuit_code_in; + msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in); + + U32 ip = msg->getSenderIP(); + U32 port = msg->getSenderPort(); + + U64 ip64 = ip; + U64 port64 = port; + U64 ip_port_in = (ip64 << 32) | port64; + + if (circuit_code_in) + { + //if (!msg->mCircuitCodes.checkKey(circuit_code_in)) + code_session_map_t::iterator it; + it = msg->mCircuitCodes.find(circuit_code_in); + if(it == msg->mCircuitCodes.end()) + { + // Whoah, abort! We don't know anything about this circuit code. + LL_WARNS("Messaging") << "UseCircuitCode for " << circuit_code_in + << " received without AddCircuitCode message - aborting" + << LL_ENDL; + return; + } + + LLUUID id; + msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_ID, id); + LLUUID session_id; + msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id); + if(session_id != (*it).second) + { + LL_WARNS("Messaging") << "UseCircuitCode unmatched session id. Got " + << session_id << " but expected " << (*it).second + << LL_ENDL; + return; + } + + // Clean up previous references to this ip/port or circuit + U64 ip_port_old = get_if_there(msg->mCircuitCodeToIPPort, circuit_code_in, U64(0)); + U32 circuit_code_old = get_if_there(msg->mIPPortToCircuitCode, ip_port_in, U32(0)); + + if (ip_port_old) + { + if ((ip_port_old == ip_port_in) && (circuit_code_old == circuit_code_in)) + { + // Current information is the same as incoming info, ignore + LL_INFOS("Messaging") << "Got duplicate UseCircuitCode for circuit " << circuit_code_in << " to " << msg->getSender() << LL_ENDL; + return; + } + + // Hmm, got a different IP and port for the same circuit code. + U32 circut_code_old_ip_port = get_if_there(msg->mIPPortToCircuitCode, ip_port_old, U32(0)); + msg->mCircuitCodeToIPPort.erase(circut_code_old_ip_port); + msg->mIPPortToCircuitCode.erase(ip_port_old); + U32 old_port = (U32)(ip_port_old & (U64)0xFFFFFFFF); + U32 old_ip = (U32)(ip_port_old >> 32); + LL_INFOS("Messaging") << "Removing derelict lookup entry for circuit " << circuit_code_old << " to " << LLHost(old_ip, old_port) << LL_ENDL; + } + + if (circuit_code_old) + { + LLHost cur_host(ip, port); + + LL_WARNS("Messaging") << "Disabling existing circuit for " << cur_host << LL_ENDL; + msg->disableCircuit(cur_host); + if (circuit_code_old == circuit_code_in) + { + LL_WARNS("Messaging") << "Asymmetrical circuit to ip/port lookup!" << LL_ENDL; + LL_WARNS("Messaging") << "Multiple circuit codes for " << cur_host << " probably!" << LL_ENDL; + LL_WARNS("Messaging") << "Permanently disabling circuit" << LL_ENDL; + return; + } + else + { + LL_WARNS("Messaging") << "Circuit code changed for " << msg->getSender() + << " from " << circuit_code_old << " to " + << circuit_code_in << LL_ENDL; + } + } + + // Since this comes from the viewer, it's untrusted, but it + // passed the circuit code and session id check, so we will go + // ahead and persist the ID associated. + LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); + bool had_circuit_already = cdp != nullptr; + + msg->enableCircuit(msg->getSender(), false); + cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); + if(cdp) + { + cdp->setRemoteID(id); + cdp->setRemoteSessionID(session_id); + } + + if (!had_circuit_already) + { + // + // HACK HACK HACK HACK HACK! + // + // This would NORMALLY happen inside logValidMsg, but at the point that this happens + // inside logValidMsg, there's no circuit for this message yet. So the awful thing that + // we do here is do it inside this message handler immediately AFTER the message is + // handled. + // + // We COULD not do this, but then what happens is that some of the circuit bookkeeping + // gets broken, especially the packets in count. That causes some later packets to flush + // the RecentlyReceivedReliable list, resulting in an error in which UseCircuitCode + // doesn't get properly duplicate suppressed. Not a BIG deal, but it's somewhat confusing + // (and bad from a state point of view). DJS 9/23/04 + // + cdp->checkPacketInID(gMessageSystem->mCurrentRecvPacketID, false ); // Since this is the first message on the circuit, by definition it's not resent. + } + + msg->mIPPortToCircuitCode[ip_port_in] = circuit_code_in; + msg->mCircuitCodeToIPPort[circuit_code_in] = ip_port_in; + + LL_INFOS("Messaging") << "Circuit code " << circuit_code_in << " from " + << msg->getSender() << " for agent " << id << " in session " + << session_id << LL_ENDL; + + const LLUseCircuitCodeResponder* responder = + (const LLUseCircuitCodeResponder*) user; + if(responder) + { + responder->complete(msg->getSender(), id); + } + } + else + { + LL_WARNS("Messaging") << "Got zero circuit code in use_circuit_code" << LL_ENDL; + } } // static void LLMessageSystem::processError(LLMessageSystem* msg, void**) { - S32 error_code = 0; - msg->getS32("Data", "Code", error_code); - std::string error_token; - msg->getString("Data", "Token", error_token); + S32 error_code = 0; + msg->getS32("Data", "Code", error_code); + std::string error_token; + msg->getString("Data", "Token", error_token); - LLUUID error_id; - msg->getUUID("Data", "ID", error_id); - std::string error_system; - msg->getString("Data", "System", error_system); + LLUUID error_id; + msg->getUUID("Data", "ID", error_id); + std::string error_system; + msg->getString("Data", "System", error_system); - std::string error_message; - msg->getString("Data", "Message", error_message); + std::string error_message; + msg->getString("Data", "Message", error_message); - LL_WARNS("Messaging") << "Message error from " << msg->getSender() << " - " - << error_code << " " << error_token << " " << error_id << " \"" - << error_system << "\" \"" << error_message << "\"" << LL_ENDL; + LL_WARNS("Messaging") << "Message error from " << msg->getSender() << " - " + << error_code << " " << error_token << " " << error_id << " \"" + << error_system << "\" \"" << error_message << "\"" << LL_ENDL; } static LLHTTPNode& messageRootNode() { - static LLHTTPNode root_node; - static bool initialized = false; - if (!initialized) { - initialized = true; - LLHTTPRegistrar::buildAllServices(root_node); - } + static LLHTTPNode root_node; + static bool initialized = false; + if (!initialized) { + initialized = true; + LLHTTPRegistrar::buildAllServices(root_node); + } - return root_node; + return root_node; } //static void LLMessageSystem::dispatch( - const std::string& msg_name, - const LLSD& message) + const std::string& msg_name, + const LLSD& message) { - LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create(); - dispatch(msg_name, message, responsep); + LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create(); + dispatch(msg_name, message, responsep); } //static void LLMessageSystem::dispatch( - const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep) -{ - if ((gMessageSystem->mMessageTemplates.find - (LLMessageStringTable::getInstance()->getString(msg_name.c_str())) == - gMessageSystem->mMessageTemplates.end()) && - !LLMessageConfig::isValidMessage(msg_name)) - { - LL_WARNS("Messaging") << "Ignoring unknown message " << msg_name << LL_ENDL; - responsep->notFound("Invalid message name"); - return; - } - - std::string path = "/message/" + msg_name; - LLSD context; - const LLHTTPNode* handler = messageRootNode().traverse(path, context); - if (!handler) - { - LL_WARNS("Messaging") << "LLMessageService::dispatch > no handler for " - << path << LL_ENDL; - return; - } - // enable this for output of message names - LL_DEBUGS("Messaging") << "< \"" << msg_name << "\"" << LL_ENDL; - LL_DEBUGS("Messaging") << "context: " << context << LL_ENDL; - LL_DEBUGS("Messaging") << "message: " << message << LL_ENDL; - - handler->post(responsep, context, message); -} - -//static + const std::string& msg_name, + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) +{ + if ((gMessageSystem->mMessageTemplates.find + (LLMessageStringTable::getInstance()->getString(msg_name.c_str())) == + gMessageSystem->mMessageTemplates.end()) && + !LLMessageConfig::isValidMessage(msg_name)) + { + LL_WARNS("Messaging") << "Ignoring unknown message " << msg_name << LL_ENDL; + responsep->notFound("Invalid message name"); + return; + } + + std::string path = "/message/" + msg_name; + LLSD context; + const LLHTTPNode* handler = messageRootNode().traverse(path, context); + if (!handler) + { + LL_WARNS("Messaging") << "LLMessageService::dispatch > no handler for " + << path << LL_ENDL; + return; + } + // enable this for output of message names + LL_DEBUGS("Messaging") << "< \"" << msg_name << "\"" << LL_ENDL; + LL_DEBUGS("Messaging") << "context: " << context << LL_ENDL; + LL_DEBUGS("Messaging") << "message: " << message << LL_ENDL; + + handler->post(responsep, context, message); +} + +//static void LLMessageSystem::dispatchTemplate(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep) + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) { - LLTemplateMessageDispatcher dispatcher(*(gMessageSystem->mTemplateMessageReader)); - dispatcher.dispatch(msg_name, message, responsep); + LLTemplateMessageDispatcher dispatcher(*(gMessageSystem->mTemplateMessageReader)); + dispatcher.dispatch(msg_name, message, responsep); } static void check_for_unrecognized_messages( - const char* type, - const LLSD& map, - LLMessageSystem::message_template_name_map_t& templates) + const char* type, + const LLSD& map, + LLMessageSystem::message_template_name_map_t& templates) { - for (LLSD::map_const_iterator iter = map.beginMap(), - end = map.endMap(); - iter != end; ++iter) - { - const char* name = LLMessageStringTable::getInstance()->getString(iter->first.c_str()); + for (LLSD::map_const_iterator iter = map.beginMap(), + end = map.endMap(); + iter != end; ++iter) + { + const char* name = LLMessageStringTable::getInstance()->getString(iter->first.c_str()); - if (templates.find(name) == templates.end()) - { - LL_INFOS("AppInit") << " " << type - << " ban list contains unrecognized message " - << name << LL_ENDL; - } - } + if (templates.find(name) == templates.end()) + { + LL_INFOS("AppInit") << " " << type + << " ban list contains unrecognized message " + << name << LL_ENDL; + } + } } void LLMessageSystem::setMessageBans( - const LLSD& trusted, const LLSD& untrusted) + const LLSD& trusted, const LLSD& untrusted) { - LL_DEBUGS("AppInit") << "LLMessageSystem::setMessageBans:" << LL_ENDL; - bool any_set = false; + LL_DEBUGS("AppInit") << "LLMessageSystem::setMessageBans:" << LL_ENDL; + bool any_set = false; - for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), - end = mMessageTemplates.end(); - iter != end; ++iter) - { - LLMessageTemplate* mt = iter->second; + for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), + end = mMessageTemplates.end(); + iter != end; ++iter) + { + LLMessageTemplate* mt = iter->second; - std::string name(mt->mName); - bool ban_from_trusted - = trusted.has(name) && trusted.get(name).asBoolean(); - bool ban_from_untrusted - = untrusted.has(name) && untrusted.get(name).asBoolean(); + std::string name(mt->mName); + bool ban_from_trusted + = trusted.has(name) && trusted.get(name).asBoolean(); + bool ban_from_untrusted + = untrusted.has(name) && untrusted.get(name).asBoolean(); - mt->mBanFromTrusted = ban_from_trusted; - mt->mBanFromUntrusted = ban_from_untrusted; + mt->mBanFromTrusted = ban_from_trusted; + mt->mBanFromUntrusted = ban_from_untrusted; - if (ban_from_trusted || ban_from_untrusted) - { - LL_INFOS("AppInit") << " " << name << " banned from " - << (ban_from_trusted ? "TRUSTED " : " ") - << (ban_from_untrusted ? "UNTRUSTED " : " ") - << LL_ENDL; - any_set = true; - } - } + if (ban_from_trusted || ban_from_untrusted) + { + LL_INFOS("AppInit") << " " << name << " banned from " + << (ban_from_trusted ? "TRUSTED " : " ") + << (ban_from_untrusted ? "UNTRUSTED " : " ") + << LL_ENDL; + any_set = true; + } + } - if (!any_set) - { - LL_DEBUGS("AppInit") << " no messages banned" << LL_ENDL; - } + if (!any_set) + { + LL_DEBUGS("AppInit") << " no messages banned" << LL_ENDL; + } - check_for_unrecognized_messages("trusted", trusted, mMessageTemplates); - check_for_unrecognized_messages("untrusted", untrusted, mMessageTemplates); + check_for_unrecognized_messages("trusted", trusted, mMessageTemplates); + check_for_unrecognized_messages("untrusted", untrusted, mMessageTemplates); } S32 LLMessageSystem::sendError( - const LLHost& host, - const LLUUID& agent_id, - S32 code, - const std::string& token, - const LLUUID& id, - const std::string& system, - const std::string& message, - const LLSD& data) -{ - newMessage("Error"); - nextBlockFast(_PREHASH_AgentData); - addUUIDFast(_PREHASH_AgentID, agent_id); - nextBlockFast(_PREHASH_Data); - addS32("Code", code); - addString("Token", token); - addUUID("ID", id); - addString("System", system); - std::string temp; - temp = message; - if(temp.size() > (size_t)MTUBYTES) temp.resize((size_t)MTUBYTES); - addString("Message", message); - LLPointer<LLSDBinaryFormatter> formatter = new LLSDBinaryFormatter; - std::ostringstream ostr; - formatter->format(data, ostr); - temp = ostr.str(); - bool pack_data = true; - static const std::string ERROR_MESSAGE_NAME("Error"); - if (LLMessageConfig::getMessageFlavor(ERROR_MESSAGE_NAME) == - LLMessageConfig::TEMPLATE_FLAVOR) - { - S32 msg_size = temp.size() + mMessageBuilder->getMessageSize(); - if(msg_size >= ETHERNET_MTU_BYTES) - { - pack_data = false; - } - } - if(pack_data) - { - addBinaryData("Data", (void*)temp.c_str(), temp.size()); - } - else - { - LL_WARNS("Messaging") << "Data and message were too large -- data removed." - << LL_ENDL; - addBinaryData("Data", NULL, 0); - } - return sendReliable(host); -} - -void process_packet_ack(LLMessageSystem *msgsystem, void** /*user_data*/) -{ - TPACKETID packet_id; - - LLHost host = msgsystem->getSender(); - LLCircuitData *cdp = msgsystem->mCircuitInfo.findCircuit(host); - if (cdp) - { - - S32 ack_count = msgsystem->getNumberOfBlocksFast(_PREHASH_Packets); - - for (S32 i = 0; i < ack_count; i++) - { - msgsystem->getU32Fast(_PREHASH_Packets, _PREHASH_ID, packet_id, i); -// LL_DEBUGS("Messaging") << "ack recvd' from " << host << " for packet " << (TPACKETID)packet_id << LL_ENDL; - cdp->ackReliablePacket(packet_id); - } - if (!cdp->getUnackedPacketCount()) - { - // Remove this circuit from the list of circuits with unacked packets - gMessageSystem->mCircuitInfo.mUnackedCircuitMap.erase(host); - } - } + const LLHost& host, + const LLUUID& agent_id, + S32 code, + const std::string& token, + const LLUUID& id, + const std::string& system, + const std::string& message, + const LLSD& data) +{ + newMessage("Error"); + nextBlockFast(_PREHASH_AgentData); + addUUIDFast(_PREHASH_AgentID, agent_id); + nextBlockFast(_PREHASH_Data); + addS32("Code", code); + addString("Token", token); + addUUID("ID", id); + addString("System", system); + std::string temp; + temp = message; + if(temp.size() > (size_t)MTUBYTES) temp.resize((size_t)MTUBYTES); + addString("Message", message); + LLPointer<LLSDBinaryFormatter> formatter = new LLSDBinaryFormatter; + std::ostringstream ostr; + formatter->format(data, ostr); + temp = ostr.str(); + bool pack_data = true; + static const std::string ERROR_MESSAGE_NAME("Error"); + if (LLMessageConfig::getMessageFlavor(ERROR_MESSAGE_NAME) == + LLMessageConfig::TEMPLATE_FLAVOR) + { + S32 msg_size = temp.size() + mMessageBuilder->getMessageSize(); + if(msg_size >= ETHERNET_MTU_BYTES) + { + pack_data = false; + } + } + if(pack_data) + { + addBinaryData("Data", (void*)temp.c_str(), temp.size()); + } + else + { + LL_WARNS("Messaging") << "Data and message were too large -- data removed." + << LL_ENDL; + addBinaryData("Data", NULL, 0); + } + return sendReliable(host); +} + +void process_packet_ack(LLMessageSystem *msgsystem, void** /*user_data*/) +{ + TPACKETID packet_id; + + LLHost host = msgsystem->getSender(); + LLCircuitData *cdp = msgsystem->mCircuitInfo.findCircuit(host); + if (cdp) + { + + S32 ack_count = msgsystem->getNumberOfBlocksFast(_PREHASH_Packets); + + for (S32 i = 0; i < ack_count; i++) + { + msgsystem->getU32Fast(_PREHASH_Packets, _PREHASH_ID, packet_id, i); +// LL_DEBUGS("Messaging") << "ack recvd' from " << host << " for packet " << (TPACKETID)packet_id << LL_ENDL; + cdp->ackReliablePacket(packet_id); + } + if (!cdp->getUnackedPacketCount()) + { + // Remove this circuit from the list of circuits with unacked packets + gMessageSystem->mCircuitInfo.mUnackedCircuitMap.erase(host); + } + } } /* void process_log_messages(LLMessageSystem* msg, void**) { - U8 log_message; - - msg->getU8Fast(_PREHASH_Options, _PREHASH_Enable, log_message); - - if (log_message) - { - LL_INFOS("Messaging") << "Starting logging via message" << LL_ENDL; - msg->startLogging(); - } - else - { - LL_INFOS("Messaging") << "Stopping logging via message" << LL_ENDL; - msg->stopLogging(); - } + U8 log_message; + + msg->getU8Fast(_PREHASH_Options, _PREHASH_Enable, log_message); + + if (log_message) + { + LL_INFOS("Messaging") << "Starting logging via message" << LL_ENDL; + msg->startLogging(); + } + else + { + LL_INFOS("Messaging") << "Stopping logging via message" << LL_ENDL; + msg->stopLogging(); + } }*/ // Make circuit trusted if the MD5 Digest matches, otherwise // notify remote end that they are not trusted. void process_create_trusted_circuit(LLMessageSystem *msg, void **) { - // don't try to create trust on machines with no shared secret - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) return; - - LLUUID remote_id; - msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_EndPointID, remote_id); - - LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); - if (!cdp) - { - LL_WARNS("Messaging") << "Attempt to create trusted circuit without circuit data: " - << msg->getSender() << LL_ENDL; - return; - } - - LLUUID local_id; - local_id = cdp->getLocalEndPointID(); - if (remote_id == local_id) - { - // Don't respond to requests that use the same end point ID - return; - } - - U32 untrusted_interface = msg->getUntrustedInterface().getAddress(); - U32 last_interface = msg->getReceivingInterface().getAddress(); - if ( ( untrusted_interface != INVALID_HOST_IP_ADDRESS ) && ( untrusted_interface == last_interface ) ) - { - if( msg->getBlockUntrustedInterface() ) - { - LL_WARNS("Messaging") << "Ignoring CreateTrustedCircuit on public interface from host: " - << msg->getSender() << LL_ENDL; - return; - } - else - { - LL_WARNS("Messaging") << "Processing CreateTrustedCircuit on public interface from host: " - << msg->getSender() << LL_ENDL; - } - } - - char their_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ - S32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Digest); - if(size != MD5HEX_STR_BYTES) - { - // ignore requests which pack the wrong amount of data. - return; - } - msg->getBinaryDataFast(_PREHASH_DataBlock, _PREHASH_Digest, their_digest, MD5HEX_STR_BYTES); - their_digest[MD5HEX_STR_SIZE - 1] = '\0'; - if(msg->isMatchingDigestForWindowAndUUIDs(their_digest, TRUST_TIME_WINDOW, local_id, remote_id)) - { - cdp->setTrusted(true); - LL_INFOS("Messaging") << "Trusted digest from " << msg->getSender() << LL_ENDL; - return; - } - else if (cdp->getTrusted()) - { - // The digest is bad, but this circuit is already trusted. - // This means that this could just be the result of a stale deny sent from a while back, and - // the message system is being slow. Don't bother sending the deny, as it may continually - // ping-pong back and forth on a very hosed circuit. - LL_WARNS("Messaging") << "Ignoring bad digest from known trusted circuit: " << their_digest - << " host: " << msg->getSender() << LL_ENDL; - return; - } - else - { - LL_WARNS("Messaging") << "Bad digest from known circuit: " << their_digest - << " host: " << msg->getSender() << LL_ENDL; - msg->sendDenyTrustedCircuit(msg->getSender()); - return; - } -} + // don't try to create trust on machines with no shared secret + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) return; + + LLUUID remote_id; + msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_EndPointID, remote_id); + + LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); + if (!cdp) + { + LL_WARNS("Messaging") << "Attempt to create trusted circuit without circuit data: " + << msg->getSender() << LL_ENDL; + return; + } + + LLUUID local_id; + local_id = cdp->getLocalEndPointID(); + if (remote_id == local_id) + { + // Don't respond to requests that use the same end point ID + return; + } + + U32 untrusted_interface = msg->getUntrustedInterface().getAddress(); + U32 last_interface = msg->getReceivingInterface().getAddress(); + if ( ( untrusted_interface != INVALID_HOST_IP_ADDRESS ) && ( untrusted_interface == last_interface ) ) + { + if( msg->getBlockUntrustedInterface() ) + { + LL_WARNS("Messaging") << "Ignoring CreateTrustedCircuit on public interface from host: " + << msg->getSender() << LL_ENDL; + return; + } + else + { + LL_WARNS("Messaging") << "Processing CreateTrustedCircuit on public interface from host: " + << msg->getSender() << LL_ENDL; + } + } + + char their_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ + S32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Digest); + if(size != MD5HEX_STR_BYTES) + { + // ignore requests which pack the wrong amount of data. + return; + } + msg->getBinaryDataFast(_PREHASH_DataBlock, _PREHASH_Digest, their_digest, MD5HEX_STR_BYTES); + their_digest[MD5HEX_STR_SIZE - 1] = '\0'; + if(msg->isMatchingDigestForWindowAndUUIDs(their_digest, TRUST_TIME_WINDOW, local_id, remote_id)) + { + cdp->setTrusted(true); + LL_INFOS("Messaging") << "Trusted digest from " << msg->getSender() << LL_ENDL; + return; + } + else if (cdp->getTrusted()) + { + // The digest is bad, but this circuit is already trusted. + // This means that this could just be the result of a stale deny sent from a while back, and + // the message system is being slow. Don't bother sending the deny, as it may continually + // ping-pong back and forth on a very hosed circuit. + LL_WARNS("Messaging") << "Ignoring bad digest from known trusted circuit: " << their_digest + << " host: " << msg->getSender() << LL_ENDL; + return; + } + else + { + LL_WARNS("Messaging") << "Bad digest from known circuit: " << their_digest + << " host: " << msg->getSender() << LL_ENDL; + msg->sendDenyTrustedCircuit(msg->getSender()); + return; + } +} void process_deny_trusted_circuit(LLMessageSystem *msg, void **) { - // don't try to create trust on machines with no shared secret - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) return; - - LLUUID remote_id; - msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_EndPointID, remote_id); - - LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); - if (!cdp) - { - return; - } - - LLUUID local_id; - local_id = cdp->getLocalEndPointID(); - if (remote_id == local_id) - { - // Don't respond to requests that use the same end point ID - return; - } - - U32 untrusted_interface = msg->getUntrustedInterface().getAddress(); - U32 last_interface = msg->getReceivingInterface().getAddress(); - if ( ( untrusted_interface != INVALID_HOST_IP_ADDRESS ) && ( untrusted_interface == last_interface ) ) - { - if( msg->getBlockUntrustedInterface() ) - { - LL_WARNS("Messaging") << "Ignoring DenyTrustedCircuit on public interface from host: " - << msg->getSender() << LL_ENDL; - return; - } - else - { - LL_WARNS("Messaging") << "Processing DenyTrustedCircuit on public interface from host: " - << msg->getSender() << LL_ENDL; - } - } - - - // Assume that we require trust to proceed, so resend. - // This catches the case where a circuit that was trusted - // times out, and allows us to re-establish it, but does - // mean that if our shared_secret or clock is wrong, we'll - // spin. - // *TODO: probably should keep a count of number of resends - // per circuit, and stop resending after a while. - LL_INFOS("Messaging") << "Got DenyTrustedCircuit. Sending CreateTrustedCircuit to " - << msg->getSender() << LL_ENDL; - msg->sendCreateTrustedCircuit(msg->getSender(), local_id, remote_id); + // don't try to create trust on machines with no shared secret + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) return; + + LLUUID remote_id; + msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_EndPointID, remote_id); + + LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender()); + if (!cdp) + { + return; + } + + LLUUID local_id; + local_id = cdp->getLocalEndPointID(); + if (remote_id == local_id) + { + // Don't respond to requests that use the same end point ID + return; + } + + U32 untrusted_interface = msg->getUntrustedInterface().getAddress(); + U32 last_interface = msg->getReceivingInterface().getAddress(); + if ( ( untrusted_interface != INVALID_HOST_IP_ADDRESS ) && ( untrusted_interface == last_interface ) ) + { + if( msg->getBlockUntrustedInterface() ) + { + LL_WARNS("Messaging") << "Ignoring DenyTrustedCircuit on public interface from host: " + << msg->getSender() << LL_ENDL; + return; + } + else + { + LL_WARNS("Messaging") << "Processing DenyTrustedCircuit on public interface from host: " + << msg->getSender() << LL_ENDL; + } + } + + + // Assume that we require trust to proceed, so resend. + // This catches the case where a circuit that was trusted + // times out, and allows us to re-establish it, but does + // mean that if our shared_secret or clock is wrong, we'll + // spin. + // *TODO: probably should keep a count of number of resends + // per circuit, and stop resending after a while. + LL_INFOS("Messaging") << "Got DenyTrustedCircuit. Sending CreateTrustedCircuit to " + << msg->getSender() << LL_ENDL; + msg->sendCreateTrustedCircuit(msg->getSender(), local_id, remote_id); } void dump_prehash_files() { - U32 i; - std::string filename("../../indra/llmessage/message_prehash.h"); - LLFILE* fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */ - if (fp) - { - fprintf( - fp, - "/**\n" - " * @file message_prehash.h\n" - " * @brief header file of externs of prehashed variables plus defines.\n" - " *\n" - " * $LicenseInfo:firstyear=2003&license=viewerlgpl$" - " * $/LicenseInfo$" - " */\n\n" - "#ifndef LL_MESSAGE_PREHASH_H\n#define LL_MESSAGE_PREHASH_H\n\n"); - fprintf( - fp, - "/**\n" - " * Generated from message template version number %.3f\n" - " */\n", - gMessageSystem->mMessageFileVersionNumber); - fprintf(fp, "\n\nextern F32 const gPrehashVersionNumber;\n\n"); - for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) - { - if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.') - { - fprintf(fp, "extern char const* const _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]); - } - } - fprintf(fp, "\n\n#endif\n"); - fclose(fp); - } - filename = std::string("../../indra/llmessage/message_prehash.cpp"); - fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */ - if (fp) - { - fprintf( - fp, - "/**\n" - " * @file message_prehash.cpp\n" - " * @brief file of prehashed variables\n" - " *\n" - " * $LicenseInfo:firstyear=2003&license=viewerlgpl$" - " * $/LicenseInfo$" - " */\n\n" - "/**\n" - " * Generated from message template version number %.3f\n" - " */\n", - gMessageSystem->mMessageFileVersionNumber); - fprintf(fp, "#include \"linden_common.h\"\n"); - fprintf(fp, "#include \"message.h\"\n\n"); - fprintf(fp, "\n\nF32 const gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber); - for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) - { - if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.') - { - fprintf(fp, "char const* const _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]); - } - } - fclose(fp); - } + U32 i; + std::string filename("../../indra/llmessage/message_prehash.h"); + LLFILE* fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */ + if (fp) + { + fprintf( + fp, + "/**\n" + " * @file message_prehash.h\n" + " * @brief header file of externs of prehashed variables plus defines.\n" + " *\n" + " * $LicenseInfo:firstyear=2003&license=viewerlgpl$" + " * $/LicenseInfo$" + " */\n\n" + "#ifndef LL_MESSAGE_PREHASH_H\n#define LL_MESSAGE_PREHASH_H\n\n"); + fprintf( + fp, + "/**\n" + " * Generated from message template version number %.3f\n" + " */\n", + gMessageSystem->mMessageFileVersionNumber); + fprintf(fp, "\n\nextern F32 const gPrehashVersionNumber;\n\n"); + for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) + { + if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.') + { + fprintf(fp, "extern char const* const _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]); + } + } + fprintf(fp, "\n\n#endif\n"); + fclose(fp); + } + filename = std::string("../../indra/llmessage/message_prehash.cpp"); + fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */ + if (fp) + { + fprintf( + fp, + "/**\n" + " * @file message_prehash.cpp\n" + " * @brief file of prehashed variables\n" + " *\n" + " * $LicenseInfo:firstyear=2003&license=viewerlgpl$" + " * $/LicenseInfo$" + " */\n\n" + "/**\n" + " * Generated from message template version number %.3f\n" + " */\n", + gMessageSystem->mMessageFileVersionNumber); + fprintf(fp, "#include \"linden_common.h\"\n"); + fprintf(fp, "#include \"message.h\"\n\n"); + fprintf(fp, "\n\nF32 const gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber); + for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) + { + if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.') + { + fprintf(fp, "char const* const _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]); + } + } + fclose(fp); + } } bool start_messaging_system( - const std::string& template_name, - U32 port, - S32 version_major, - S32 version_minor, - S32 version_patch, - bool b_dump_prehash_file, - const std::string& secret, - const LLUseCircuitCodeResponder* responder, - bool failure_is_fatal, - const F32 circuit_heartbeat_interval, - const F32 circuit_timeout) -{ - gMessageSystem = new LLMessageSystem( - template_name, - port, - version_major, - version_minor, - version_patch, - failure_is_fatal, - circuit_heartbeat_interval, - circuit_timeout); - g_shared_secret.assign(secret); - - if (!gMessageSystem) - { - LL_ERRS("AppInit") << "Messaging system initialization failed." << LL_ENDL; - return false; - } - - // bail if system encountered an error. - if(!gMessageSystem->isOK()) - { - return false; - } - - if (b_dump_prehash_file) - { - dump_prehash_files(); - exit(0); - } - else - { - if (gMessageSystem->mMessageFileVersionNumber != gPrehashVersionNumber) - { - LL_INFOS("AppInit") << "Message template version does not match prehash version number" << LL_ENDL; - LL_INFOS("AppInit") << "Run simulator with -prehash command line option to rebuild prehash data" << LL_ENDL; - } - else - { - LL_DEBUGS("AppInit") << "Message template version matches prehash version number" << LL_ENDL; - } - } - - gMessageSystem->setHandlerFuncFast(_PREHASH_StartPingCheck, process_start_ping_check, NULL); - gMessageSystem->setHandlerFuncFast(_PREHASH_CompletePingCheck, process_complete_ping_check, NULL); - gMessageSystem->setHandlerFuncFast(_PREHASH_OpenCircuit, open_circuit, NULL); - gMessageSystem->setHandlerFuncFast(_PREHASH_CloseCircuit, close_circuit, NULL); - - //gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode); - gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode); - //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL); - gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder); - gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL); - //gMessageSystem->setHandlerFuncFast(_PREHASH_LogMessages, process_log_messages, NULL); - gMessageSystem->setHandlerFuncFast(_PREHASH_CreateTrustedCircuit, - process_create_trusted_circuit, - NULL); - gMessageSystem->setHandlerFuncFast(_PREHASH_DenyTrustedCircuit, - process_deny_trusted_circuit, - NULL); - gMessageSystem->setHandlerFunc("Error", LLMessageSystem::processError); - - // We can hand this to the null_message_callback since it is a - // trusted message, so it will automatically be denied if it isn't - // trusted and ignored if it is -- exactly what we want. - gMessageSystem->setHandlerFunc( - "RequestTrustedCircuit", - null_message_callback, - NULL); - - // Initialize the transfer manager - gTransferManager.init(); - - return true; + const std::string& template_name, + U32 port, + S32 version_major, + S32 version_minor, + S32 version_patch, + bool b_dump_prehash_file, + const std::string& secret, + const LLUseCircuitCodeResponder* responder, + bool failure_is_fatal, + const F32 circuit_heartbeat_interval, + const F32 circuit_timeout) +{ + gMessageSystem = new LLMessageSystem( + template_name, + port, + version_major, + version_minor, + version_patch, + failure_is_fatal, + circuit_heartbeat_interval, + circuit_timeout); + g_shared_secret.assign(secret); + + if (!gMessageSystem) + { + LL_ERRS("AppInit") << "Messaging system initialization failed." << LL_ENDL; + return false; + } + + // bail if system encountered an error. + if(!gMessageSystem->isOK()) + { + return false; + } + + if (b_dump_prehash_file) + { + dump_prehash_files(); + exit(0); + } + else + { + if (gMessageSystem->mMessageFileVersionNumber != gPrehashVersionNumber) + { + LL_INFOS("AppInit") << "Message template version does not match prehash version number" << LL_ENDL; + LL_INFOS("AppInit") << "Run simulator with -prehash command line option to rebuild prehash data" << LL_ENDL; + } + else + { + LL_DEBUGS("AppInit") << "Message template version matches prehash version number" << LL_ENDL; + } + } + + gMessageSystem->setHandlerFuncFast(_PREHASH_StartPingCheck, process_start_ping_check, NULL); + gMessageSystem->setHandlerFuncFast(_PREHASH_CompletePingCheck, process_complete_ping_check, NULL); + gMessageSystem->setHandlerFuncFast(_PREHASH_OpenCircuit, open_circuit, NULL); + gMessageSystem->setHandlerFuncFast(_PREHASH_CloseCircuit, close_circuit, NULL); + + //gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode); + gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode); + //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL); + gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder); + gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL); + //gMessageSystem->setHandlerFuncFast(_PREHASH_LogMessages, process_log_messages, NULL); + gMessageSystem->setHandlerFuncFast(_PREHASH_CreateTrustedCircuit, + process_create_trusted_circuit, + NULL); + gMessageSystem->setHandlerFuncFast(_PREHASH_DenyTrustedCircuit, + process_deny_trusted_circuit, + NULL); + gMessageSystem->setHandlerFunc("Error", LLMessageSystem::processError); + + // We can hand this to the null_message_callback since it is a + // trusted message, so it will automatically be denied if it isn't + // trusted and ignored if it is -- exactly what we want. + gMessageSystem->setHandlerFunc( + "RequestTrustedCircuit", + null_message_callback, + NULL); + + // Initialize the transfer manager + gTransferManager.init(); + + return true; } void LLMessageSystem::startLogging() { - mVerboseLog = true; - std::ostringstream str; - str << "START MESSAGE LOG" << std::endl; - str << "Legend:" << std::endl; - str << "\t<-\tincoming message" <<std::endl; - str << "\t->\toutgoing message" << std::endl; - str << " <> host size zero id name"; - LL_INFOS("Messaging") << str.str() << LL_ENDL; + mVerboseLog = true; + std::ostringstream str; + str << "START MESSAGE LOG" << std::endl; + str << "Legend:" << std::endl; + str << "\t<-\tincoming message" <<std::endl; + str << "\t->\toutgoing message" << std::endl; + str << " <> host size zero id name"; + LL_INFOS("Messaging") << str.str() << LL_ENDL; } void LLMessageSystem::stopLogging() { - if(mVerboseLog) - { - mVerboseLog = false; - LL_INFOS("Messaging") << "END MESSAGE LOG" << LL_ENDL; - } + if(mVerboseLog) + { + mVerboseLog = false; + LL_INFOS("Messaging") << "END MESSAGE LOG" << LL_ENDL; + } } void LLMessageSystem::summarizeLogs(std::ostream& str) { - std::string buffer; - std::string tmp_str; - F32 run_time = mMessageSystemTimer.getElapsedTimeF32(); - str << "START MESSAGE LOG SUMMARY" << std::endl; - buffer = llformat( "Run time: %12.3f seconds", run_time); - - // Incoming - str << buffer << std::endl << "Incoming:" << std::endl; - tmp_str = U64_to_str(mTotalBytesIn); - buffer = llformat( "Total bytes received: %20s (%5.2f kbits per second)", tmp_str.c_str(), ((F32)mTotalBytesIn * 0.008f) / run_time); - str << buffer << std::endl; - tmp_str = U64_to_str(mPacketsIn); - buffer = llformat( "Total packets received: %20s (%5.2f packets per second)", tmp_str.c_str(), ((F32) mPacketsIn / run_time)); - str << buffer << std::endl; - buffer = llformat( "Average packet size: %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn); - str << buffer << std::endl; - tmp_str = U64_to_str(mReliablePacketsIn); - buffer = llformat( "Total reliable packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mReliablePacketsIn)/((F32) mPacketsIn + 1)); - str << buffer << std::endl; - tmp_str = U64_to_str(mCompressedPacketsIn); - buffer = llformat( "Total compressed packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mCompressedPacketsIn)/((F32) mPacketsIn + 1)); - str << buffer << std::endl; - S64 savings = mUncompressedBytesIn - mCompressedBytesIn; - tmp_str = U64_to_str(savings); - buffer = llformat( "Total compression savings: %20s bytes", tmp_str.c_str()); - str << buffer << std::endl; - tmp_str = U64_to_str(savings/(mCompressedPacketsIn +1)); - buffer = llformat( "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mUncompressedBytesIn)/((F32) mCompressedBytesIn+1)); - str << buffer << std::endl; - tmp_str = U64_to_str(savings/(mPacketsIn+1)); - buffer = llformat( "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mTotalBytesIn + (F32) savings)/((F32) mTotalBytesIn + 1.f)); - - // Outgoing - str << buffer << std::endl << std::endl << "Outgoing:" << std::endl; - tmp_str = U64_to_str(mTotalBytesOut); - buffer = llformat( "Total bytes sent: %20s (%5.2f kbits per second)", tmp_str.c_str(), ((F32)mTotalBytesOut * 0.008f) / run_time ); - str << buffer << std::endl; - tmp_str = U64_to_str(mPacketsOut); - buffer = llformat( "Total packets sent: %20s (%5.2f packets per second)", tmp_str.c_str(), ((F32)mPacketsOut / run_time)); - str << buffer << std::endl; - buffer = llformat( "Average packet size: %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut); - str << buffer << std::endl; - tmp_str = U64_to_str(mReliablePacketsOut); - buffer = llformat( "Total reliable packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mReliablePacketsOut)/((F32) mPacketsOut + 1)); - str << buffer << std::endl; - tmp_str = U64_to_str(mCompressedPacketsOut); - buffer = llformat( "Total compressed packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mCompressedPacketsOut)/((F32) mPacketsOut + 1)); - str << buffer << std::endl; - savings = mUncompressedBytesOut - mCompressedBytesOut; - tmp_str = U64_to_str(savings); - buffer = llformat( "Total compression savings: %20s bytes", tmp_str.c_str()); - str << buffer << std::endl; - tmp_str = U64_to_str(savings/(mCompressedPacketsOut +1)); - buffer = llformat( "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mUncompressedBytesOut)/((F32) mCompressedBytesOut+1)); - str << buffer << std::endl; - tmp_str = U64_to_str(savings/(mPacketsOut+1)); - buffer = llformat( "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mTotalBytesOut + (F32) savings)/((F32) mTotalBytesOut + 1.f)); - str << buffer << std::endl << std::endl; - buffer = llformat( "SendPacket failures: %20d", mSendPacketFailureCount); - str << buffer << std::endl; - buffer = llformat( "Dropped packets: %20d", mDroppedPackets); - str << buffer << std::endl; - buffer = llformat( "Resent packets: %20d", mResentPackets); - str << buffer << std::endl; - buffer = llformat( "Failed reliable resends: %20d", mFailedResendPackets); - str << buffer << std::endl; - buffer = llformat( "Off-circuit rejected packets: %17d", mOffCircuitPackets); - str << buffer << std::endl; - buffer = llformat( "On-circuit invalid packets: %17d", mInvalidOnCircuitPackets); - str << buffer << std::endl << std::endl; - - str << "Decoding: " << std::endl; - buffer = llformat( "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); - str << buffer << std:: endl; - F32 avg; - for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(), - end = mMessageTemplates.end(); - iter != end; iter++) - { - const LLMessageTemplate* mt = iter->second; - if(mt->mTotalDecoded > 0) - { - avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded; - buffer = llformat( "%35s%10u%10f%10f%10f", mt->mName, mt->mTotalDecoded, mt->mTotalDecodeTime, mt->mMaxDecodeTimePerMsg, avg); - str << buffer << std::endl; - } - } - str << "END MESSAGE LOG SUMMARY" << std::endl; + std::string buffer; + std::string tmp_str; + F32 run_time = mMessageSystemTimer.getElapsedTimeF32(); + str << "START MESSAGE LOG SUMMARY" << std::endl; + buffer = llformat( "Run time: %12.3f seconds", run_time); + + // Incoming + str << buffer << std::endl << "Incoming:" << std::endl; + tmp_str = U64_to_str(mTotalBytesIn); + buffer = llformat( "Total bytes received: %20s (%5.2f kbits per second)", tmp_str.c_str(), ((F32)mTotalBytesIn * 0.008f) / run_time); + str << buffer << std::endl; + tmp_str = U64_to_str(mPacketsIn); + buffer = llformat( "Total packets received: %20s (%5.2f packets per second)", tmp_str.c_str(), ((F32) mPacketsIn / run_time)); + str << buffer << std::endl; + buffer = llformat( "Average packet size: %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn); + str << buffer << std::endl; + tmp_str = U64_to_str(mReliablePacketsIn); + buffer = llformat( "Total reliable packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mReliablePacketsIn)/((F32) mPacketsIn + 1)); + str << buffer << std::endl; + tmp_str = U64_to_str(mCompressedPacketsIn); + buffer = llformat( "Total compressed packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mCompressedPacketsIn)/((F32) mPacketsIn + 1)); + str << buffer << std::endl; + S64 savings = mUncompressedBytesIn - mCompressedBytesIn; + tmp_str = U64_to_str(savings); + buffer = llformat( "Total compression savings: %20s bytes", tmp_str.c_str()); + str << buffer << std::endl; + tmp_str = U64_to_str(savings/(mCompressedPacketsIn +1)); + buffer = llformat( "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mUncompressedBytesIn)/((F32) mCompressedBytesIn+1)); + str << buffer << std::endl; + tmp_str = U64_to_str(savings/(mPacketsIn+1)); + buffer = llformat( "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mTotalBytesIn + (F32) savings)/((F32) mTotalBytesIn + 1.f)); + + // Outgoing + str << buffer << std::endl << std::endl << "Outgoing:" << std::endl; + tmp_str = U64_to_str(mTotalBytesOut); + buffer = llformat( "Total bytes sent: %20s (%5.2f kbits per second)", tmp_str.c_str(), ((F32)mTotalBytesOut * 0.008f) / run_time ); + str << buffer << std::endl; + tmp_str = U64_to_str(mPacketsOut); + buffer = llformat( "Total packets sent: %20s (%5.2f packets per second)", tmp_str.c_str(), ((F32)mPacketsOut / run_time)); + str << buffer << std::endl; + buffer = llformat( "Average packet size: %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut); + str << buffer << std::endl; + tmp_str = U64_to_str(mReliablePacketsOut); + buffer = llformat( "Total reliable packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mReliablePacketsOut)/((F32) mPacketsOut + 1)); + str << buffer << std::endl; + tmp_str = U64_to_str(mCompressedPacketsOut); + buffer = llformat( "Total compressed packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mCompressedPacketsOut)/((F32) mPacketsOut + 1)); + str << buffer << std::endl; + savings = mUncompressedBytesOut - mCompressedBytesOut; + tmp_str = U64_to_str(savings); + buffer = llformat( "Total compression savings: %20s bytes", tmp_str.c_str()); + str << buffer << std::endl; + tmp_str = U64_to_str(savings/(mCompressedPacketsOut +1)); + buffer = llformat( "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mUncompressedBytesOut)/((F32) mCompressedBytesOut+1)); + str << buffer << std::endl; + tmp_str = U64_to_str(savings/(mPacketsOut+1)); + buffer = llformat( "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mTotalBytesOut + (F32) savings)/((F32) mTotalBytesOut + 1.f)); + str << buffer << std::endl << std::endl; + buffer = llformat( "SendPacket failures: %20d", mSendPacketFailureCount); + str << buffer << std::endl; + buffer = llformat( "Dropped packets: %20d", mDroppedPackets); + str << buffer << std::endl; + buffer = llformat( "Resent packets: %20d", mResentPackets); + str << buffer << std::endl; + buffer = llformat( "Failed reliable resends: %20d", mFailedResendPackets); + str << buffer << std::endl; + buffer = llformat( "Off-circuit rejected packets: %17d", mOffCircuitPackets); + str << buffer << std::endl; + buffer = llformat( "On-circuit invalid packets: %17d", mInvalidOnCircuitPackets); + str << buffer << std::endl << std::endl; + + str << "Decoding: " << std::endl; + buffer = llformat( "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); + str << buffer << std:: endl; + F32 avg; + for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(), + end = mMessageTemplates.end(); + iter != end; iter++) + { + const LLMessageTemplate* mt = iter->second; + if(mt->mTotalDecoded > 0) + { + avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded; + buffer = llformat( "%35s%10u%10f%10f%10f", mt->mName, mt->mTotalDecoded, mt->mTotalDecodeTime, mt->mMaxDecodeTimePerMsg, avg); + str << buffer << std::endl; + } + } + str << "END MESSAGE LOG SUMMARY" << std::endl; } void end_messaging_system(bool print_summary) { - gTransferManager.cleanup(); - LLTransferTargetVFile::updateQueue(true); // shutdown LLTransferTargetVFile - if (gMessageSystem) - { - gMessageSystem->stopLogging(); + gTransferManager.cleanup(); + LLTransferTargetVFile::updateQueue(true); // shutdown LLTransferTargetVFile + if (gMessageSystem) + { + gMessageSystem->stopLogging(); - if (print_summary) - { - std::ostringstream str; - gMessageSystem->summarizeLogs(str); - LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL; - } + if (print_summary) + { + std::ostringstream str; + gMessageSystem->summarizeLogs(str); + LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL; + } - delete static_cast<LLMessageSystem*>(gMessageSystem); - gMessageSystem = NULL; - } + delete static_cast<LLMessageSystem*>(gMessageSystem); + gMessageSystem = NULL; + } } void LLMessageSystem::resetReceiveCounts() { - mNumMessageCounts = 0; + mNumMessageCounts = 0; - for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), - end = mMessageTemplates.end(); - iter != end; iter++) - { - LLMessageTemplate* mt = iter->second; - mt->mDecodeTimeThisFrame = 0.f; - } + for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), + end = mMessageTemplates.end(); + iter != end; iter++) + { + LLMessageTemplate* mt = iter->second; + mt->mDecodeTimeThisFrame = 0.f; + } } void LLMessageSystem::dumpReceiveCounts() { - LLMessageTemplate *mt; - - for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), - end = mMessageTemplates.end(); - iter != end; iter++) - { - LLMessageTemplate* mt = iter->second; - mt->mReceiveCount = 0; - mt->mReceiveBytes = 0; - mt->mReceiveInvalid = 0; - } - - S32 i; - for (i = 0; i < mNumMessageCounts; i++) - { - mt = get_ptr_in_map(mMessageNumbers,mMessageCountList[i].mMessageNum); - if (mt) - { - mt->mReceiveCount++; - mt->mReceiveBytes += mMessageCountList[i].mMessageBytes; - if (mMessageCountList[i].mInvalid) - { - mt->mReceiveInvalid++; - } - } - } - - if(mNumMessageCounts > 0) - { - LL_DEBUGS("Messaging") << "Dump: " << mNumMessageCounts << " messages processed in " << mReceiveTime << " seconds" << LL_ENDL; - for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(), - end = mMessageTemplates.end(); - iter != end; iter++) - { - const LLMessageTemplate* mt = iter->second; - if (mt->mReceiveCount > 0) - { - LL_INFOS("Messaging") << "Num: " << std::setw(3) << mt->mReceiveCount << " Bytes: " << std::setw(6) << mt->mReceiveBytes - << " Invalid: " << std::setw(3) << mt->mReceiveInvalid << " " << mt->mName << " " << ll_round(100 * mt->mDecodeTimeThisFrame / mReceiveTime.value()) << "%" << LL_ENDL; - } - } - } + LLMessageTemplate *mt; + + for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), + end = mMessageTemplates.end(); + iter != end; iter++) + { + LLMessageTemplate* mt = iter->second; + mt->mReceiveCount = 0; + mt->mReceiveBytes = 0; + mt->mReceiveInvalid = 0; + } + + S32 i; + for (i = 0; i < mNumMessageCounts; i++) + { + mt = get_ptr_in_map(mMessageNumbers,mMessageCountList[i].mMessageNum); + if (mt) + { + mt->mReceiveCount++; + mt->mReceiveBytes += mMessageCountList[i].mMessageBytes; + if (mMessageCountList[i].mInvalid) + { + mt->mReceiveInvalid++; + } + } + } + + if(mNumMessageCounts > 0) + { + LL_DEBUGS("Messaging") << "Dump: " << mNumMessageCounts << " messages processed in " << mReceiveTime << " seconds" << LL_ENDL; + for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(), + end = mMessageTemplates.end(); + iter != end; iter++) + { + const LLMessageTemplate* mt = iter->second; + if (mt->mReceiveCount > 0) + { + LL_INFOS("Messaging") << "Num: " << std::setw(3) << mt->mReceiveCount << " Bytes: " << std::setw(6) << mt->mReceiveBytes + << " Invalid: " << std::setw(3) << mt->mReceiveInvalid << " " << mt->mName << " " << ll_round(100 * mt->mDecodeTimeThisFrame / mReceiveTime.value()) << "%" << LL_ENDL; + } + } + } } bool LLMessageSystem::isClear() const { - return mMessageBuilder->isClear(); + return mMessageBuilder->isClear(); } S32 LLMessageSystem::flush(const LLHost &host) { - if (mMessageBuilder->getMessageSize()) - { - S32 sentbytes = sendMessage(host); - clearMessage(); - return sentbytes; - } - else - { - return 0; - } + if (mMessageBuilder->getMessageSize()) + { + S32 sentbytes = sendMessage(host); + clearMessage(); + return sentbytes; + } + else + { + return 0; + } } U32 LLMessageSystem::getListenPort( void ) const { - return mPort; + return mPort; } // TODO: babbage: remove this horror! S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal() { - if(mMessageBuilder == mLLSDMessageBuilder) - { - // babbage: don't compress LLSD messages, so delta is 0 - return 0; - } - - if (! mMessageBuilder->isBuilt()) - { - mSendSize = mMessageBuilder->buildMessage( - mSendBuffer, - MAX_BUFFER_SIZE, - 0); - } - // TODO: babbage: remove this horror - mMessageBuilder->setBuilt(false); - - S32 count = mSendSize; - - S32 net_gain = 0; - U8 num_zeroes = 0; - - U8 *inptr = (U8 *)mSendBuffer; + if(mMessageBuilder == mLLSDMessageBuilder) + { + // babbage: don't compress LLSD messages, so delta is 0 + return 0; + } + + if (! mMessageBuilder->isBuilt()) + { + mSendSize = mMessageBuilder->buildMessage( + mSendBuffer, + MAX_BUFFER_SIZE, + 0); + } + // TODO: babbage: remove this horror + mMessageBuilder->setBuilt(false); + + S32 count = mSendSize; + + S32 net_gain = 0; + U8 num_zeroes = 0; + + U8 *inptr = (U8 *)mSendBuffer; // skip the packet id field - for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii) - { - count--; - inptr++; - } + for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii) + { + count--; + inptr++; + } // don't actually build, just test -// sequential zero bytes are encoded as 0 [U8 count] +// sequential zero bytes are encoded as 0 [U8 count] // with 0 0 [count] representing wrap (>256 zeroes) - while (count--) - { - if (!(*inptr)) // in a zero count - { - if (num_zeroes) - { - if (++num_zeroes > 254) - { - num_zeroes = 0; - } - net_gain--; // subseqent zeroes save one - } - else - { - net_gain++; // starting a zero count adds one - num_zeroes = 1; - } - inptr++; - } - else - { - if (num_zeroes) - { - num_zeroes = 0; - } - inptr++; - } - } - if (net_gain < 0) - { - return net_gain; - } - else - { - return 0; - } + while (count--) + { + if (!(*inptr)) // in a zero count + { + if (num_zeroes) + { + if (++num_zeroes > 254) + { + num_zeroes = 0; + } + net_gain--; // subseqent zeroes save one + } + else + { + net_gain++; // starting a zero count adds one + num_zeroes = 1; + } + inptr++; + } + else + { + if (num_zeroes) + { + num_zeroes = 0; + } + inptr++; + } + } + if (net_gain < 0) + { + return net_gain; + } + else + { + return 0; + } } S32 LLMessageSystem::zeroCodeExpand(U8** data, S32* data_size) { - if ((*data_size ) < LL_MINIMUM_VALID_PACKET_SIZE) - { - LL_WARNS("Messaging") << "zeroCodeExpand() called with data_size of " << *data_size - << LL_ENDL; - } + if ((*data_size ) < LL_MINIMUM_VALID_PACKET_SIZE) + { + LL_WARNS("Messaging") << "zeroCodeExpand() called with data_size of " << *data_size + << LL_ENDL; + } - mTotalBytesIn += *data_size; + mTotalBytesIn += *data_size; - // if we're not zero-coded, simply return. - if (!(*data[0] & LL_ZERO_CODE_FLAG)) - { - return 0; - } + // if we're not zero-coded, simply return. + if (!(*data[0] & LL_ZERO_CODE_FLAG)) + { + return 0; + } - S32 in_size = *data_size; - mCompressedPacketsIn++; - mCompressedBytesIn += *data_size; - - *data[0] &= (~LL_ZERO_CODE_FLAG); + S32 in_size = *data_size; + mCompressedPacketsIn++; + mCompressedBytesIn += *data_size; - S32 count = (*data_size); - - U8 *inptr = (U8 *)*data; - U8 *outptr = (U8 *)mEncodedRecvBuffer; + *data[0] &= (~LL_ZERO_CODE_FLAG); + + S32 count = (*data_size); + + U8 *inptr = (U8 *)*data; + U8 *outptr = (U8 *)mEncodedRecvBuffer; // skip the packet id field - for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii) - { - count--; - *outptr++ = *inptr++; - } + for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii) + { + count--; + *outptr++ = *inptr++; + } // reconstruct encoded packet, keeping track of net size gain -// sequential zero bytes are encoded as 0 [U8 count] +// sequential zero bytes are encoded as 0 [U8 count] // with 0 0 [count] representing wrap (>256 zeroes) - while (count--) - { - if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-1])) - { - LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 1" << LL_ENDL; - callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE); - outptr = mEncodedRecvBuffer; - break; - } - if (!((*outptr++ = *inptr++))) - { - while (((count--)) && (!(*inptr))) - { - *outptr++ = *inptr++; - if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-256])) - { - LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 2" << LL_ENDL; - callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE); - outptr = mEncodedRecvBuffer; - count = -1; - break; - } - memset(outptr,0,255); - outptr += 255; - } - - if (count < 0) - { - break; - } - - else - { - if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-(*inptr)])) - { - LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 3" << LL_ENDL; - callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE); - outptr = mEncodedRecvBuffer; - } - memset(outptr,0,(*inptr) - 1); - outptr += ((*inptr) - 1); - inptr++; - } - } - } - - *data = mEncodedRecvBuffer; - *data_size = (S32)(outptr - mEncodedRecvBuffer); - mUncompressedBytesIn += *data_size; - - return(in_size); + while (count--) + { + if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-1])) + { + LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 1" << LL_ENDL; + callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE); + outptr = mEncodedRecvBuffer; + break; + } + if (!((*outptr++ = *inptr++))) + { + while (((count--)) && (!(*inptr))) + { + *outptr++ = *inptr++; + if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-256])) + { + LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 2" << LL_ENDL; + callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE); + outptr = mEncodedRecvBuffer; + count = -1; + break; + } + memset(outptr,0,255); + outptr += 255; + } + + if (count < 0) + { + break; + } + + else + { + if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-(*inptr)])) + { + LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 3" << LL_ENDL; + callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE); + outptr = mEncodedRecvBuffer; + } + memset(outptr,0,(*inptr) - 1); + outptr += ((*inptr) - 1); + inptr++; + } + } + } + + *data = mEncodedRecvBuffer; + *data_size = (S32)(outptr - mEncodedRecvBuffer); + mUncompressedBytesIn += *data_size; + + return(in_size); } void LLMessageSystem::addTemplate(LLMessageTemplate *templatep) { - if (mMessageTemplates.count(templatep->mName) > 0) - { - LL_ERRS("Messaging") << templatep->mName << " already used as a template name!" - << LL_ENDL; - } - mMessageTemplates[templatep->mName] = templatep; - mMessageNumbers[templatep->mMessageNumber] = templatep; + if (mMessageTemplates.count(templatep->mName) > 0) + { + LL_ERRS("Messaging") << templatep->mName << " already used as a template name!" + << LL_ENDL; + } + mMessageTemplates[templatep->mName] = templatep; + mMessageNumbers[templatep->mMessageNumber] = templatep; } void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) { - LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name); - if (msgtemplate) - { - msgtemplate->setHandlerFunc(handler_func, user_data); - } - else - { - LL_ERRS("Messaging") << name << " is not a known message name!" << LL_ENDL; - } + LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name); + if (msgtemplate) + { + msgtemplate->setHandlerFunc(handler_func, user_data); + } + else + { + LL_ERRS("Messaging") << name << " is not a known message name!" << LL_ENDL; + } } bool LLMessageSystem::callHandler(const char *name, - bool trustedSource, LLMessageSystem* msg) + bool trustedSource, LLMessageSystem* msg) { - name = LLMessageStringTable::getInstance()->getString(name); - message_template_name_map_t::const_iterator iter; - iter = mMessageTemplates.find(name); - if(iter == mMessageTemplates.end()) - { - LL_WARNS("Messaging") << "LLMessageSystem::callHandler: unknown message " - << name << LL_ENDL; - return false; - } + name = LLMessageStringTable::getInstance()->getString(name); + message_template_name_map_t::const_iterator iter; + iter = mMessageTemplates.find(name); + if(iter == mMessageTemplates.end()) + { + LL_WARNS("Messaging") << "LLMessageSystem::callHandler: unknown message " + << name << LL_ENDL; + return false; + } - const LLMessageTemplate* msg_template = iter->second; - if (msg_template->isBanned(trustedSource)) - { - LL_WARNS("Messaging") << "LLMessageSystem::callHandler: banned message " - << name - << " from " - << (trustedSource ? "trusted " : "untrusted ") - << "source" << LL_ENDL; - return false; - } + const LLMessageTemplate* msg_template = iter->second; + if (msg_template->isBanned(trustedSource)) + { + LL_WARNS("Messaging") << "LLMessageSystem::callHandler: banned message " + << name + << " from " + << (trustedSource ? "trusted " : "untrusted ") + << "source" << LL_ENDL; + return false; + } - return msg_template->callHandlerFunc(msg); + return msg_template->callHandlerFunc(msg); } void LLMessageSystem::setExceptionFunc(EMessageException e, - msg_exception_callback func, - void* data) + msg_exception_callback func, + void* data) { - callbacks_t::iterator it = mExceptionCallbacks.find(e); - if(it != mExceptionCallbacks.end()) - { - mExceptionCallbacks.erase(it); - } - if(func) - { - mExceptionCallbacks.insert(callbacks_t::value_type(e, exception_t(func, data))); - } + callbacks_t::iterator it = mExceptionCallbacks.find(e); + if(it != mExceptionCallbacks.end()) + { + mExceptionCallbacks.erase(it); + } + if(func) + { + mExceptionCallbacks.insert(callbacks_t::value_type(e, exception_t(func, data))); + } } bool LLMessageSystem::callExceptionFunc(EMessageException exception) { - callbacks_t::iterator it = mExceptionCallbacks.find(exception); - if(it == mExceptionCallbacks.end()) - { - return false; - } + callbacks_t::iterator it = mExceptionCallbacks.find(exception); + if(it == mExceptionCallbacks.end()) + { + return false; + } - exception_t& ex = it->second; - msg_exception_callback ex_cb = ex.first; + exception_t& ex = it->second; + msg_exception_callback ex_cb = ex.first; - if (!ex_cb) - { - LL_WARNS("Messaging") << "LLMessageSystem::callExceptionFunc: bad message exception callback." << LL_ENDL; - return false; - } + if (!ex_cb) + { + LL_WARNS("Messaging") << "LLMessageSystem::callExceptionFunc: bad message exception callback." << LL_ENDL; + return false; + } - (ex_cb)(this, ex.second, exception); + (ex_cb)(this, ex.second, exception); - return true; + return true; } void LLMessageSystem::setTimingFunc(msg_timing_callback func, void* data) { - mTimingCallback = func; - mTimingCallbackData = data; + mTimingCallback = func; + mTimingCallbackData = data; } bool LLMessageSystem::isCircuitCodeKnown(U32 code) const { - if(mCircuitCodes.find(code) == mCircuitCodes.end()) - return false; - return true; + if(mCircuitCodes.find(code) == mCircuitCodes.end()) + return false; + return true; } bool LLMessageSystem::isMessageFast(const char *msg) { - return msg == mMessageReader->getMessageName(); + return msg == mMessageReader->getMessageName(); } char* LLMessageSystem::getMessageName() { - return const_cast<char*>(mMessageReader->getMessageName()); + return const_cast<char*>(mMessageReader->getMessageName()); } const LLUUID& LLMessageSystem::getSenderID() const { - LLCircuitData *cdp = mCircuitInfo.findCircuit(mLastSender); - if (cdp) - { - return (cdp->mRemoteID); - } + LLCircuitData *cdp = mCircuitInfo.findCircuit(mLastSender); + if (cdp) + { + return (cdp->mRemoteID); + } - return LLUUID::null; + return LLUUID::null; } const LLUUID& LLMessageSystem::getSenderSessionID() const { - LLCircuitData *cdp = mCircuitInfo.findCircuit(mLastSender); - if (cdp) - { - return (cdp->mRemoteSessionID); - } - return LLUUID::null; + LLCircuitData *cdp = mCircuitInfo.findCircuit(mLastSender); + if (cdp) + { + return (cdp->mRemoteSessionID); + } + return LLUUID::null; } bool LLMessageSystem::generateDigestForNumberAndUUIDs( - char* digest, - const U32 number, - const LLUUID& id1, - const LLUUID& id2) const -{ - // *NOTE: This method is needlessly inefficient. Instead of - // calling LLUUID::asString, it should just call - // LLUUID::toString(). - - const char *colon = ":"; - char tbuf[16]; /* Flawfinder: ignore */ - LLMD5 d; - std::string id1string = id1.asString(); - std::string id2string = id2.asString(); - std::string shared_secret = get_shared_secret(); - unsigned char * secret = (unsigned char*)shared_secret.c_str(); - unsigned char * id1str = (unsigned char*)id1string.c_str(); - unsigned char * id2str = (unsigned char*)id2string.c_str(); - - memset(digest, 0, MD5HEX_STR_SIZE); - - if( secret != NULL) - { - d.update(secret, (U32)strlen((char *) secret)); /* Flawfinder: ignore */ - } - - d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ - - snprintf(tbuf, sizeof(tbuf),"%i", number); /* Flawfinder: ignore */ - d.update((unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */ - - d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ - if( (char*) id1str != NULL) - { - d.update(id1str, (U32)strlen((char *) id1str)); /* Flawfinder: ignore */ - } - d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ - - if( (char*) id2str != NULL) - { - d.update(id2str, (U32)strlen((char *) id2str)); /* Flawfinder: ignore */ - } - - d.finalize(); - d.hex_digest(digest); - digest[MD5HEX_STR_SIZE - 1] = '\0'; - - return true; + char* digest, + const U32 number, + const LLUUID& id1, + const LLUUID& id2) const +{ + // *NOTE: This method is needlessly inefficient. Instead of + // calling LLUUID::asString, it should just call + // LLUUID::toString(). + + const char *colon = ":"; + char tbuf[16]; /* Flawfinder: ignore */ + LLMD5 d; + std::string id1string = id1.asString(); + std::string id2string = id2.asString(); + std::string shared_secret = get_shared_secret(); + unsigned char * secret = (unsigned char*)shared_secret.c_str(); + unsigned char * id1str = (unsigned char*)id1string.c_str(); + unsigned char * id2str = (unsigned char*)id2string.c_str(); + + memset(digest, 0, MD5HEX_STR_SIZE); + + if( secret != NULL) + { + d.update(secret, (U32)strlen((char *) secret)); /* Flawfinder: ignore */ + } + + d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ + + snprintf(tbuf, sizeof(tbuf),"%i", number); /* Flawfinder: ignore */ + d.update((unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */ + + d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ + if( (char*) id1str != NULL) + { + d.update(id1str, (U32)strlen((char *) id1str)); /* Flawfinder: ignore */ + } + d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ + + if( (char*) id2str != NULL) + { + d.update(id2str, (U32)strlen((char *) id2str)); /* Flawfinder: ignore */ + } + + d.finalize(); + d.hex_digest(digest); + digest[MD5HEX_STR_SIZE - 1] = '\0'; + + return true; } bool LLMessageSystem::generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const { - if(0 == window) return false; - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) - { - LL_ERRS("Messaging") << "Trying to generate complex digest on a machine without a shared secret!" << LL_ENDL; - } + if(0 == window) return false; + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) + { + LL_ERRS("Messaging") << "Trying to generate complex digest on a machine without a shared secret!" << LL_ENDL; + } - U32 now = (U32)time(NULL); + U32 now = (U32)time(NULL); - now /= window; + now /= window; - bool result = generateDigestForNumberAndUUIDs(digest, now, id1, id2); + bool result = generateDigestForNumberAndUUIDs(digest, now, id1, id2); - return result; + return result; } bool LLMessageSystem::isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const { - if(0 == window) return false; - - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) - { - LL_ERRS("Messaging") << "Trying to compare complex digests on a machine without a shared secret!" << LL_ENDL; - } - - char our_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ - U32 now = (U32)time(NULL); - - now /= window; - - // Check 1 window ago, now, and one window from now to catch edge - // conditions. Process them as current window, one window ago, and - // one window in the future to catch the edges. - const S32 WINDOW_BIN_COUNT = 3; - U32 window_bin[WINDOW_BIN_COUNT]; - window_bin[0] = now; - window_bin[1] = now - 1; - window_bin[2] = now + 1; - for(S32 i = 0; i < WINDOW_BIN_COUNT; ++i) - { - generateDigestForNumberAndUUIDs(our_digest, window_bin[i], id2, id1); - if(0 == strncmp(digest, our_digest, MD5HEX_STR_BYTES)) - { - return true; - } - } - return false; + if(0 == window) return false; + + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) + { + LL_ERRS("Messaging") << "Trying to compare complex digests on a machine without a shared secret!" << LL_ENDL; + } + + char our_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ + U32 now = (U32)time(NULL); + + now /= window; + + // Check 1 window ago, now, and one window from now to catch edge + // conditions. Process them as current window, one window ago, and + // one window in the future to catch the edges. + const S32 WINDOW_BIN_COUNT = 3; + U32 window_bin[WINDOW_BIN_COUNT]; + window_bin[0] = now; + window_bin[1] = now - 1; + window_bin[2] = now + 1; + for(S32 i = 0; i < WINDOW_BIN_COUNT; ++i) + { + generateDigestForNumberAndUUIDs(our_digest, window_bin[i], id2, id1); + if(0 == strncmp(digest, our_digest, MD5HEX_STR_BYTES)) + { + return true; + } + } + return false; } bool LLMessageSystem::generateDigestForNumber(char* digest, const U32 number) const { - memset(digest, 0, MD5HEX_STR_SIZE); + memset(digest, 0, MD5HEX_STR_SIZE); - LLMD5 d; - std::string shared_secret = get_shared_secret(); - d = LLMD5((const unsigned char *)shared_secret.c_str(), number); - d.hex_digest(digest); - digest[MD5HEX_STR_SIZE - 1] = '\0'; + LLMD5 d; + std::string shared_secret = get_shared_secret(); + d = LLMD5((const unsigned char *)shared_secret.c_str(), number); + d.hex_digest(digest); + digest[MD5HEX_STR_SIZE - 1] = '\0'; - return true; + return true; } bool LLMessageSystem::generateDigestForWindow(char* digest, const S32 window) const { - if(0 == window) return false; + if(0 == window) return false; - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) - { - LL_ERRS("Messaging") << "Trying to generate simple digest on a machine without a shared secret!" << LL_ENDL; - } + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) + { + LL_ERRS("Messaging") << "Trying to generate simple digest on a machine without a shared secret!" << LL_ENDL; + } - U32 now = (U32)time(NULL); + U32 now = (U32)time(NULL); - now /= window; + now /= window; - bool result = generateDigestForNumber(digest, now); + bool result = generateDigestForNumber(digest, now); - return result; + return result; } bool LLMessageSystem::isMatchingDigestForWindow(const char* digest, S32 const window) const { - if(0 == window) return false; - - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) - { - LL_ERRS("Messaging") << "Trying to compare simple digests on a machine without a shared secret!" << LL_ENDL; - } - - char our_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ - U32 now = (S32)time(NULL); - - now /= window; - - // Check 1 window ago, now, and one window from now to catch edge - // conditions. Process them as current window, one window ago, and - // one window in the future to catch the edges. - const S32 WINDOW_BIN_COUNT = 3; - U32 window_bin[WINDOW_BIN_COUNT]; - window_bin[0] = now; - window_bin[1] = now - 1; - window_bin[2] = now + 1; - for(S32 i = 0; i < WINDOW_BIN_COUNT; ++i) - { - generateDigestForNumber(our_digest, window_bin[i]); - if(0 == strncmp(digest, our_digest, MD5HEX_STR_BYTES)) - { - return true; - } - } - return false; + if(0 == window) return false; + + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) + { + LL_ERRS("Messaging") << "Trying to compare simple digests on a machine without a shared secret!" << LL_ENDL; + } + + char our_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ + U32 now = (S32)time(NULL); + + now /= window; + + // Check 1 window ago, now, and one window from now to catch edge + // conditions. Process them as current window, one window ago, and + // one window in the future to catch the edges. + const S32 WINDOW_BIN_COUNT = 3; + U32 window_bin[WINDOW_BIN_COUNT]; + window_bin[0] = now; + window_bin[1] = now - 1; + window_bin[2] = now + 1; + for(S32 i = 0; i < WINDOW_BIN_COUNT; ++i) + { + generateDigestForNumber(our_digest, window_bin[i]); + if(0 == strncmp(digest, our_digest, MD5HEX_STR_BYTES)) + { + return true; + } + } + return false; } void LLMessageSystem::sendCreateTrustedCircuit(const LLHost &host, const LLUUID & id1, const LLUUID & id2) { - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) return; - char digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ - if (id1.isNull()) - { - LL_WARNS("Messaging") << "Can't send CreateTrustedCircuit to " << host << " because we don't have the local end point ID" << LL_ENDL; - return; - } - if (id2.isNull()) - { - LL_WARNS("Messaging") << "Can't send CreateTrustedCircuit to " << host << " because we don't have the remote end point ID" << LL_ENDL; - return; - } - generateDigestForWindowAndUUIDs(digest, TRUST_TIME_WINDOW, id1, id2); - newMessageFast(_PREHASH_CreateTrustedCircuit); - nextBlockFast(_PREHASH_DataBlock); - addUUIDFast(_PREHASH_EndPointID, id1); - addBinaryDataFast(_PREHASH_Digest, digest, MD5HEX_STR_BYTES); - LL_INFOS("Messaging") << "xmitting digest: " << digest << " Host: " << host << LL_ENDL; - sendMessage(host); + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) return; + char digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ + if (id1.isNull()) + { + LL_WARNS("Messaging") << "Can't send CreateTrustedCircuit to " << host << " because we don't have the local end point ID" << LL_ENDL; + return; + } + if (id2.isNull()) + { + LL_WARNS("Messaging") << "Can't send CreateTrustedCircuit to " << host << " because we don't have the remote end point ID" << LL_ENDL; + return; + } + generateDigestForWindowAndUUIDs(digest, TRUST_TIME_WINDOW, id1, id2); + newMessageFast(_PREHASH_CreateTrustedCircuit); + nextBlockFast(_PREHASH_DataBlock); + addUUIDFast(_PREHASH_EndPointID, id1); + addBinaryDataFast(_PREHASH_Digest, digest, MD5HEX_STR_BYTES); + LL_INFOS("Messaging") << "xmitting digest: " << digest << " Host: " << host << LL_ENDL; + sendMessage(host); } void LLMessageSystem::sendDenyTrustedCircuit(const LLHost &host) { - mDenyTrustedCircuitSet.insert(host); + mDenyTrustedCircuitSet.insert(host); } void LLMessageSystem::reallySendDenyTrustedCircuit(const LLHost &host) { - LLCircuitData *cdp = mCircuitInfo.findCircuit(host); - if (!cdp) - { - LL_WARNS("Messaging") << "Not sending DenyTrustedCircuit to host without a circuit." << LL_ENDL; - return; - } - LL_INFOS("Messaging") << "Sending DenyTrustedCircuit to " << host << LL_ENDL; - newMessageFast(_PREHASH_DenyTrustedCircuit); - nextBlockFast(_PREHASH_DataBlock); - addUUIDFast(_PREHASH_EndPointID, cdp->getLocalEndPointID()); - sendMessage(host); + LLCircuitData *cdp = mCircuitInfo.findCircuit(host); + if (!cdp) + { + LL_WARNS("Messaging") << "Not sending DenyTrustedCircuit to host without a circuit." << LL_ENDL; + return; + } + LL_INFOS("Messaging") << "Sending DenyTrustedCircuit to " << host << LL_ENDL; + newMessageFast(_PREHASH_DenyTrustedCircuit); + nextBlockFast(_PREHASH_DataBlock); + addUUIDFast(_PREHASH_EndPointID, cdp->getLocalEndPointID()); + sendMessage(host); } void null_message_callback(LLMessageSystem *msg, void **data) { - // Nothing should ever go here, but we use this to register messages - // that we are expecting to see (and spinning on) at startup. - return; + // Nothing should ever go here, but we use this to register messages + // that we are expecting to see (and spinning on) at startup. + return; } // Try to establish a bidirectional trust metric by pinging a host until it's // up, and then sending auth messages. void LLMessageSystem::establishBidirectionalTrust(const LLHost &host, S64 frame_count ) { - LockMessageChecker lmc(this); - - std::string shared_secret = get_shared_secret(); - if(shared_secret.empty()) - { - LL_ERRS("Messaging") << "Trying to establish bidirectional trust on a machine without a shared secret!" << LL_ENDL; - } - LLTimer timeout; - - timeout.setTimerExpirySec(20.0); - setHandlerFuncFast(_PREHASH_StartPingCheck, null_message_callback, NULL); - setHandlerFuncFast(_PREHASH_CompletePingCheck, null_message_callback, - NULL); - - while (! timeout.hasExpired()) - { - newMessageFast(_PREHASH_StartPingCheck); - nextBlockFast(_PREHASH_PingID); - addU8Fast(_PREHASH_PingID, 0); - addU32Fast(_PREHASH_OldestUnacked, 0); - sendMessage(host); - if (lmc.checkMessages( frame_count )) - { - if (isMessageFast(_PREHASH_CompletePingCheck) && - (getSender() == host)) - { - break; - } - } - lmc.processAcks(); - ms_sleep(1); - } - - // Send a request, a deny, and give the host 2 seconds to complete - // the trust handshake. - newMessage("RequestTrustedCircuit"); - sendMessage(host); - reallySendDenyTrustedCircuit(host); - setHandlerFuncFast(_PREHASH_StartPingCheck, process_start_ping_check, NULL); - setHandlerFuncFast(_PREHASH_CompletePingCheck, process_complete_ping_check, NULL); - - timeout.setTimerExpirySec(2.0); - LLCircuitData* cdp = NULL; - while(!timeout.hasExpired()) - { - cdp = mCircuitInfo.findCircuit(host); - if(!cdp) break; // no circuit anymore, no point continuing. - if(cdp->getTrusted()) break; // circuit is trusted. - lmc.checkMessages(frame_count); - lmc.processAcks(); - ms_sleep(1); - } + LockMessageChecker lmc(this); + + std::string shared_secret = get_shared_secret(); + if(shared_secret.empty()) + { + LL_ERRS("Messaging") << "Trying to establish bidirectional trust on a machine without a shared secret!" << LL_ENDL; + } + LLTimer timeout; + + timeout.setTimerExpirySec(20.0); + setHandlerFuncFast(_PREHASH_StartPingCheck, null_message_callback, NULL); + setHandlerFuncFast(_PREHASH_CompletePingCheck, null_message_callback, + NULL); + + while (! timeout.hasExpired()) + { + newMessageFast(_PREHASH_StartPingCheck); + nextBlockFast(_PREHASH_PingID); + addU8Fast(_PREHASH_PingID, 0); + addU32Fast(_PREHASH_OldestUnacked, 0); + sendMessage(host); + if (lmc.checkMessages( frame_count )) + { + if (isMessageFast(_PREHASH_CompletePingCheck) && + (getSender() == host)) + { + break; + } + } + lmc.processAcks(); + ms_sleep(1); + } + + // Send a request, a deny, and give the host 2 seconds to complete + // the trust handshake. + newMessage("RequestTrustedCircuit"); + sendMessage(host); + reallySendDenyTrustedCircuit(host); + setHandlerFuncFast(_PREHASH_StartPingCheck, process_start_ping_check, NULL); + setHandlerFuncFast(_PREHASH_CompletePingCheck, process_complete_ping_check, NULL); + + timeout.setTimerExpirySec(2.0); + LLCircuitData* cdp = NULL; + while(!timeout.hasExpired()) + { + cdp = mCircuitInfo.findCircuit(host); + if(!cdp) break; // no circuit anymore, no point continuing. + if(cdp->getTrusted()) break; // circuit is trusted. + lmc.checkMessages(frame_count); + lmc.processAcks(); + ms_sleep(1); + } } void LLMessageSystem::dumpPacketToLog() { - LL_WARNS("Messaging") << "Packet Dump from:" << mPacketRing.getLastSender() << LL_ENDL; - LL_WARNS("Messaging") << "Packet Size:" << mTrueReceiveSize << LL_ENDL; - char line_buffer[256]; /* Flawfinder: ignore */ - S32 i; - S32 cur_line_pos = 0; - S32 cur_line = 0; - - for (i = 0; i < mTrueReceiveSize; i++) - { - S32 offset = cur_line_pos * 3; - snprintf(line_buffer + offset, sizeof(line_buffer) - offset, - "%02x ", mTrueReceiveBuffer[i]); /* Flawfinder: ignore */ - cur_line_pos++; - if (cur_line_pos >= 16) - { - cur_line_pos = 0; - LL_WARNS("Messaging") << "PD:" << cur_line << "PD:" << line_buffer << LL_ENDL; - cur_line++; - } - } - if (cur_line_pos) - { - LL_WARNS("Messaging") << "PD:" << cur_line << "PD:" << line_buffer << LL_ENDL; - } + LL_WARNS("Messaging") << "Packet Dump from:" << mPacketRing.getLastSender() << LL_ENDL; + LL_WARNS("Messaging") << "Packet Size:" << mTrueReceiveSize << LL_ENDL; + char line_buffer[256]; /* Flawfinder: ignore */ + S32 i; + S32 cur_line_pos = 0; + S32 cur_line = 0; + + for (i = 0; i < mTrueReceiveSize; i++) + { + S32 offset = cur_line_pos * 3; + snprintf(line_buffer + offset, sizeof(line_buffer) - offset, + "%02x ", mTrueReceiveBuffer[i]); /* Flawfinder: ignore */ + cur_line_pos++; + if (cur_line_pos >= 16) + { + cur_line_pos = 0; + LL_WARNS("Messaging") << "PD:" << cur_line << "PD:" << line_buffer << LL_ENDL; + cur_line++; + } + } + if (cur_line_pos) + { + LL_WARNS("Messaging") << "PD:" << cur_line << "PD:" << line_buffer << LL_ENDL; + } } //static U64Microseconds LLMessageSystem::getMessageTimeUsecs(const bool update) { - if (gMessageSystem) - { - if (update) - { - gMessageSystem->mCurrentMessageTime = totalTime(); - } - return gMessageSystem->mCurrentMessageTime; - } - else - { - return totalTime(); - } + if (gMessageSystem) + { + if (update) + { + gMessageSystem->mCurrentMessageTime = totalTime(); + } + return gMessageSystem->mCurrentMessageTime; + } + else + { + return totalTime(); + } } //static F64Seconds LLMessageSystem::getMessageTimeSeconds(const bool update) { - if (gMessageSystem) - { - if (update) - { - gMessageSystem->mCurrentMessageTime = totalTime(); - } - return gMessageSystem->mCurrentMessageTime; - } - else - { - return F64Seconds(totalTime()); - } + if (gMessageSystem) + { + if (update) + { + gMessageSystem->mCurrentMessageTime = totalTime(); + } + return gMessageSystem->mCurrentMessageTime; + } + else + { + return F64Seconds(totalTime()); + } } std::string get_shared_secret() { - static const std::string SHARED_SECRET_KEY("shared_secret"); - if(g_shared_secret.empty()) - { - LLApp* app = LLApp::instance(); - if(app) return app->getOption(SHARED_SECRET_KEY); - } - return g_shared_secret; + static const std::string SHARED_SECRET_KEY("shared_secret"); + if(g_shared_secret.empty()) + { + LLApp* app = LLApp::instance(); + if(app) return app->getOption(SHARED_SECRET_KEY); + } + return g_shared_secret; } typedef std::map<const char*, LLMessageBuilder*> BuilderMap; void LLMessageSystem::newMessageFast(const char *name) { - //LL_DEBUGS("Messaging") << "creating new message: " << name << LL_ENDL; - LLMessageConfig::Flavor message_flavor = - LLMessageConfig::getMessageFlavor(name); - LLMessageConfig::Flavor server_flavor = - LLMessageConfig::getServerDefaultFlavor(); - - if(message_flavor == LLMessageConfig::TEMPLATE_FLAVOR) - { - mMessageBuilder = mTemplateMessageBuilder; - } - else if (message_flavor == LLMessageConfig::LLSD_FLAVOR) - { - mMessageBuilder = mLLSDMessageBuilder; - } - // NO_FLAVOR - else - { - if (server_flavor == LLMessageConfig::LLSD_FLAVOR) - { - mMessageBuilder = mLLSDMessageBuilder; - } - // TEMPLATE_FLAVOR or NO_FLAVOR - else - { - mMessageBuilder = mTemplateMessageBuilder; - } - } - mSendReliable = false; - mMessageBuilder->newMessage(name); -} - + //LL_DEBUGS("Messaging") << "creating new message: " << name << LL_ENDL; + LLMessageConfig::Flavor message_flavor = + LLMessageConfig::getMessageFlavor(name); + LLMessageConfig::Flavor server_flavor = + LLMessageConfig::getServerDefaultFlavor(); + + if(message_flavor == LLMessageConfig::TEMPLATE_FLAVOR) + { + mMessageBuilder = mTemplateMessageBuilder; + } + else if (message_flavor == LLMessageConfig::LLSD_FLAVOR) + { + mMessageBuilder = mLLSDMessageBuilder; + } + // NO_FLAVOR + else + { + if (server_flavor == LLMessageConfig::LLSD_FLAVOR) + { + mMessageBuilder = mLLSDMessageBuilder; + } + // TEMPLATE_FLAVOR or NO_FLAVOR + else + { + mMessageBuilder = mTemplateMessageBuilder; + } + } + mSendReliable = false; + mMessageBuilder->newMessage(name); +} + void LLMessageSystem::newMessage(const char *name) { - newMessageFast(LLMessageStringTable::getInstance()->getString(name)); + newMessageFast(LLMessageStringTable::getInstance()->getString(name)); } void LLMessageSystem::addBinaryDataFast(const char *varname, const void *data, S32 size) { - mMessageBuilder->addBinaryData(varname, data, size); + mMessageBuilder->addBinaryData(varname, data, size); } void LLMessageSystem::addBinaryData(const char *varname, const void *data, S32 size) { - mMessageBuilder->addBinaryData(LLMessageStringTable::getInstance()->getString(varname),data, size); + mMessageBuilder->addBinaryData(LLMessageStringTable::getInstance()->getString(varname),data, size); } void LLMessageSystem::addS8Fast(const char *varname, S8 v) { - mMessageBuilder->addS8(varname, v); + mMessageBuilder->addS8(varname, v); } void LLMessageSystem::addS8(const char *varname, S8 v) { - mMessageBuilder->addS8(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addS8(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addU8Fast(const char *varname, U8 v) { - mMessageBuilder->addU8(varname, v); + mMessageBuilder->addU8(varname, v); } void LLMessageSystem::addU8(const char *varname, U8 v) { - mMessageBuilder->addU8(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addU8(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addS16Fast(const char *varname, S16 v) { - mMessageBuilder->addS16(varname, v); + mMessageBuilder->addS16(varname, v); } void LLMessageSystem::addS16(const char *varname, S16 v) { - mMessageBuilder->addS16(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addS16(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addU16Fast(const char *varname, U16 v) { - mMessageBuilder->addU16(varname, v); + mMessageBuilder->addU16(varname, v); } void LLMessageSystem::addU16(const char *varname, U16 v) { - mMessageBuilder->addU16(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addU16(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addF32Fast(const char *varname, F32 v) { - mMessageBuilder->addF32(varname, v); + mMessageBuilder->addF32(varname, v); } void LLMessageSystem::addF32(const char *varname, F32 v) { - mMessageBuilder->addF32(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addF32(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addS32Fast(const char *varname, S32 v) { - mMessageBuilder->addS32(varname, v); + mMessageBuilder->addS32(varname, v); } void LLMessageSystem::addS32(const char *varname, S32 v) { - mMessageBuilder->addS32(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addS32(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addU32Fast(const char *varname, U32 v) { - mMessageBuilder->addU32(varname, v); + mMessageBuilder->addU32(varname, v); } void LLMessageSystem::addU32(const char *varname, U32 v) { - mMessageBuilder->addU32(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addU32(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addU64Fast(const char *varname, U64 v) { - mMessageBuilder->addU64(varname, v); + mMessageBuilder->addU64(varname, v); } void LLMessageSystem::addU64(const char *varname, U64 v) { - mMessageBuilder->addU64(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addU64(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addF64Fast(const char *varname, F64 v) { - mMessageBuilder->addF64(varname, v); + mMessageBuilder->addF64(varname, v); } void LLMessageSystem::addF64(const char *varname, F64 v) { - mMessageBuilder->addF64(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addF64(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addIPAddrFast(const char *varname, U32 v) { - mMessageBuilder->addIPAddr(varname, v); + mMessageBuilder->addIPAddr(varname, v); } void LLMessageSystem::addIPAddr(const char *varname, U32 v) { - mMessageBuilder->addIPAddr(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addIPAddr(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addIPPortFast(const char *varname, U16 v) { - mMessageBuilder->addIPPort(varname, v); + mMessageBuilder->addIPPort(varname, v); } void LLMessageSystem::addIPPort(const char *varname, U16 v) { - mMessageBuilder->addIPPort(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addIPPort(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addBOOLFast(const char* varname, bool v) { - mMessageBuilder->addBOOL(varname, v); + mMessageBuilder->addBOOL(varname, v); } void LLMessageSystem::addBOOL(const char* varname, bool v) { - mMessageBuilder->addBOOL(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addBOOL(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addStringFast(const char* varname, const char* v) { - mMessageBuilder->addString(varname, v); + mMessageBuilder->addString(varname, v); } void LLMessageSystem::addString(const char* varname, const char* v) { - mMessageBuilder->addString(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addString(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addStringFast(const char* varname, const std::string& v) { - mMessageBuilder->addString(varname, v); + mMessageBuilder->addString(varname, v); } void LLMessageSystem::addString(const char* varname, const std::string& v) { - mMessageBuilder->addString(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addString(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& v) { - mMessageBuilder->addVector3(varname, v); + mMessageBuilder->addVector3(varname, v); } void LLMessageSystem::addVector3(const char *varname, const LLVector3& v) { - mMessageBuilder->addVector3(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addVector3(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& v) { - mMessageBuilder->addVector4(varname, v); + mMessageBuilder->addVector4(varname, v); } void LLMessageSystem::addVector4(const char *varname, const LLVector4& v) { - mMessageBuilder->addVector4(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addVector4(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& v) { - mMessageBuilder->addVector3d(varname, v); + mMessageBuilder->addVector3d(varname, v); } void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& v) { - mMessageBuilder->addVector3d(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addVector3d(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& v) { - mMessageBuilder->addQuat(varname, v); + mMessageBuilder->addQuat(varname, v); } void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& v) { - mMessageBuilder->addQuat(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addQuat(LLMessageStringTable::getInstance()->getString(varname), v); } void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& v) { - mMessageBuilder->addUUID(varname, v); + mMessageBuilder->addUUID(varname, v); } void LLMessageSystem::addUUID(const char *varname, const LLUUID& v) { - mMessageBuilder->addUUID(LLMessageStringTable::getInstance()->getString(varname), v); + mMessageBuilder->addUUID(LLMessageStringTable::getInstance()->getString(varname), v); } S32 LLMessageSystem::getCurrentSendTotal() const { - return mMessageBuilder->getMessageSize(); + return mMessageBuilder->getMessageSize(); } -void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u, - S32 blocknum) +void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u, + S32 blocknum) { - mMessageReader->getS8(block, var, u, blocknum); + mMessageReader->getS8(block, var, u, blocknum); } -void LLMessageSystem::getS8(const char *block, const char *var, S8 &u, - S32 blocknum) +void LLMessageSystem::getS8(const char *block, const char *var, S8 &u, + S32 blocknum) { - getS8Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), u, blocknum); + getS8Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), u, blocknum); } -void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u, - S32 blocknum) +void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u, + S32 blocknum) { - mMessageReader->getU8(block, var, u, blocknum); + mMessageReader->getU8(block, var, u, blocknum); } -void LLMessageSystem::getU8(const char *block, const char *var, U8 &u, - S32 blocknum) +void LLMessageSystem::getU8(const char *block, const char *var, U8 &u, + S32 blocknum) { - getU8Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), u, blocknum); + getU8Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), u, blocknum); } void LLMessageSystem::getBOOLFast(const char *block, const char *var, bool &b, - S32 blocknum) + S32 blocknum) { - mMessageReader->getBOOL(block, var, b, blocknum); + mMessageReader->getBOOL(block, var, b, blocknum); } void LLMessageSystem::getBOOL(const char *block, const char *var, bool &b, - S32 blocknum) + S32 blocknum) { - getBOOLFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), b, blocknum); + getBOOLFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), b, blocknum); } -void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d, - S32 blocknum) +void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d, + S32 blocknum) { - mMessageReader->getS16(block, var, d, blocknum); + mMessageReader->getS16(block, var, d, blocknum); } -void LLMessageSystem::getS16(const char *block, const char *var, S16 &d, - S32 blocknum) +void LLMessageSystem::getS16(const char *block, const char *var, S16 &d, + S32 blocknum) { - getS16Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + getS16Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d, - S32 blocknum) +void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d, + S32 blocknum) { - mMessageReader->getU16(block, var, d, blocknum); + mMessageReader->getU16(block, var, d, blocknum); } -void LLMessageSystem::getU16(const char *block, const char *var, U16 &d, - S32 blocknum) +void LLMessageSystem::getU16(const char *block, const char *var, U16 &d, + S32 blocknum) { - getU16Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + getU16Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d, - S32 blocknum) +void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d, + S32 blocknum) { - mMessageReader->getS32(block, var, d, blocknum); + mMessageReader->getS32(block, var, d, blocknum); } -void LLMessageSystem::getS32(const char *block, const char *var, S32 &d, - S32 blocknum) +void LLMessageSystem::getS32(const char *block, const char *var, S32 &d, + S32 blocknum) { - getS32Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + getS32Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d, - S32 blocknum) +void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d, + S32 blocknum) { - mMessageReader->getU32(block, var, d, blocknum); + mMessageReader->getU32(block, var, d, blocknum); } -void LLMessageSystem::getU32(const char *block, const char *var, U32 &d, - S32 blocknum) +void LLMessageSystem::getU32(const char *block, const char *var, U32 &d, + S32 blocknum) { - getU32Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + getU32Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d, - S32 blocknum) +void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d, + S32 blocknum) { - mMessageReader->getU64(block, var, d, blocknum); + mMessageReader->getU64(block, var, d, blocknum); } -void LLMessageSystem::getU64(const char *block, const char *var, U64 &d, - S32 blocknum) +void LLMessageSystem::getU64(const char *block, const char *var, U64 &d, + S32 blocknum) { - - getU64Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + + getU64Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getBinaryDataFast(const char *blockname, - const char *varname, - void *datap, S32 size, - S32 blocknum, S32 max_size) +void LLMessageSystem::getBinaryDataFast(const char *blockname, + const char *varname, + void *datap, S32 size, + S32 blocknum, S32 max_size) { - mMessageReader->getBinaryData(blockname, varname, datap, size, blocknum, - max_size); + mMessageReader->getBinaryData(blockname, varname, datap, size, blocknum, + max_size); } -void LLMessageSystem::getBinaryData(const char *blockname, - const char *varname, - void *datap, S32 size, - S32 blocknum, S32 max_size) +void LLMessageSystem::getBinaryData(const char *blockname, + const char *varname, + void *datap, S32 size, + S32 blocknum, S32 max_size) { - getBinaryDataFast(LLMessageStringTable::getInstance()->getString(blockname), - LLMessageStringTable::getInstance()->getString(varname), - datap, size, blocknum, max_size); + getBinaryDataFast(LLMessageStringTable::getInstance()->getString(blockname), + LLMessageStringTable::getInstance()->getString(varname), + datap, size, blocknum, max_size); } -void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d, - S32 blocknum) +void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d, + S32 blocknum) { - mMessageReader->getF32(block, var, d, blocknum); + mMessageReader->getF32(block, var, d, blocknum); } -void LLMessageSystem::getF32(const char *block, const char *var, F32 &d, - S32 blocknum) +void LLMessageSystem::getF32(const char *block, const char *var, F32 &d, + S32 blocknum) { - getF32Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + getF32Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d, - S32 blocknum) +void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d, + S32 blocknum) { - mMessageReader->getF64(block, var, d, blocknum); + mMessageReader->getF64(block, var, d, blocknum); } -void LLMessageSystem::getF64(const char *block, const char *var, F64 &d, - S32 blocknum) +void LLMessageSystem::getF64(const char *block, const char *var, F64 &d, + S32 blocknum) { - getF64Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), d, blocknum); + getF64Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), d, blocknum); } -void LLMessageSystem::getVector3Fast(const char *block, const char *var, - LLVector3 &v, S32 blocknum ) +void LLMessageSystem::getVector3Fast(const char *block, const char *var, + LLVector3 &v, S32 blocknum ) { - mMessageReader->getVector3(block, var, v, blocknum); + mMessageReader->getVector3(block, var, v, blocknum); } -void LLMessageSystem::getVector3(const char *block, const char *var, - LLVector3 &v, S32 blocknum ) +void LLMessageSystem::getVector3(const char *block, const char *var, + LLVector3 &v, S32 blocknum ) { - getVector3Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), v, blocknum); + getVector3Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), v, blocknum); } -void LLMessageSystem::getVector4Fast(const char *block, const char *var, - LLVector4 &v, S32 blocknum ) +void LLMessageSystem::getVector4Fast(const char *block, const char *var, + LLVector4 &v, S32 blocknum ) { - mMessageReader->getVector4(block, var, v, blocknum); + mMessageReader->getVector4(block, var, v, blocknum); } -void LLMessageSystem::getVector4(const char *block, const char *var, - LLVector4 &v, S32 blocknum ) +void LLMessageSystem::getVector4(const char *block, const char *var, + LLVector4 &v, S32 blocknum ) { - getVector4Fast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), v, blocknum); + getVector4Fast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), v, blocknum); } -void LLMessageSystem::getVector3dFast(const char *block, const char *var, - LLVector3d &v, S32 blocknum ) +void LLMessageSystem::getVector3dFast(const char *block, const char *var, + LLVector3d &v, S32 blocknum ) { - mMessageReader->getVector3d(block, var, v, blocknum); + mMessageReader->getVector3d(block, var, v, blocknum); } -void LLMessageSystem::getVector3d(const char *block, const char *var, - LLVector3d &v, S32 blocknum ) +void LLMessageSystem::getVector3d(const char *block, const char *var, + LLVector3d &v, S32 blocknum ) { - getVector3dFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), v, blocknum); + getVector3dFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), v, blocknum); } -void LLMessageSystem::getQuatFast(const char *block, const char *var, - LLQuaternion &q, S32 blocknum ) +void LLMessageSystem::getQuatFast(const char *block, const char *var, + LLQuaternion &q, S32 blocknum ) { - mMessageReader->getQuat(block, var, q, blocknum); + mMessageReader->getQuat(block, var, q, blocknum); } -void LLMessageSystem::getQuat(const char *block, const char *var, - LLQuaternion &q, S32 blocknum) +void LLMessageSystem::getQuat(const char *block, const char *var, + LLQuaternion &q, S32 blocknum) { - getQuatFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), q, blocknum); + getQuatFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), q, blocknum); } -void LLMessageSystem::getUUIDFast(const char *block, const char *var, - LLUUID &u, S32 blocknum ) +void LLMessageSystem::getUUIDFast(const char *block, const char *var, + LLUUID &u, S32 blocknum ) { - mMessageReader->getUUID(block, var, u, blocknum); + mMessageReader->getUUID(block, var, u, blocknum); } -void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u, - S32 blocknum ) +void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u, + S32 blocknum ) { - getUUIDFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), u, blocknum); + getUUIDFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), u, blocknum); } -void LLMessageSystem::getIPAddrFast(const char *block, const char *var, - U32 &u, S32 blocknum) +void LLMessageSystem::getIPAddrFast(const char *block, const char *var, + U32 &u, S32 blocknum) { - mMessageReader->getIPAddr(block, var, u, blocknum); + mMessageReader->getIPAddr(block, var, u, blocknum); } -void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u, - S32 blocknum) +void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u, + S32 blocknum) { - getIPAddrFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), u, blocknum); + getIPAddrFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), u, blocknum); } -void LLMessageSystem::getIPPortFast(const char *block, const char *var, - U16 &u, S32 blocknum) +void LLMessageSystem::getIPPortFast(const char *block, const char *var, + U16 &u, S32 blocknum) { - mMessageReader->getIPPort(block, var, u, blocknum); + mMessageReader->getIPPort(block, var, u, blocknum); } -void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u, - S32 blocknum) +void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u, + S32 blocknum) { - getIPPortFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), u, - blocknum); + getIPPortFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), u, + blocknum); } -void LLMessageSystem::getStringFast(const char *block, const char *var, - S32 buffer_size, char *s, S32 blocknum) +void LLMessageSystem::getStringFast(const char *block, const char *var, + S32 buffer_size, char *s, S32 blocknum) { - if(buffer_size <= 0) - { - LL_WARNS("Messaging") << "buffer_size <= 0" << LL_ENDL; - } - mMessageReader->getString(block, var, buffer_size, s, blocknum); + if(buffer_size <= 0) + { + LL_WARNS("Messaging") << "buffer_size <= 0" << LL_ENDL; + } + mMessageReader->getString(block, var, buffer_size, s, blocknum); } -void LLMessageSystem::getString(const char *block, const char *var, - S32 buffer_size, char *s, S32 blocknum ) +void LLMessageSystem::getString(const char *block, const char *var, + S32 buffer_size, char *s, S32 blocknum ) { - getStringFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), buffer_size, s, - blocknum); + getStringFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), buffer_size, s, + blocknum); } -void LLMessageSystem::getStringFast(const char *block, const char *var, - std::string& outstr, S32 blocknum) +void LLMessageSystem::getStringFast(const char *block, const char *var, + std::string& outstr, S32 blocknum) { - mMessageReader->getString(block, var, outstr, blocknum); + mMessageReader->getString(block, var, outstr, blocknum); } -void LLMessageSystem::getString(const char *block, const char *var, - std::string& outstr, S32 blocknum ) +void LLMessageSystem::getString(const char *block, const char *var, + std::string& outstr, S32 blocknum ) { - getStringFast(LLMessageStringTable::getInstance()->getString(block), - LLMessageStringTable::getInstance()->getString(var), outstr, - blocknum); + getStringFast(LLMessageStringTable::getInstance()->getString(block), + LLMessageStringTable::getInstance()->getString(var), outstr, + blocknum); } -bool LLMessageSystem::has(const char *blockname) const +bool LLMessageSystem::has(const char *blockname) const { - return getNumberOfBlocks(blockname) > 0; + return getNumberOfBlocks(blockname) > 0; } -S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname) const +S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname) const { - return mMessageReader->getNumberOfBlocks(blockname); + return mMessageReader->getNumberOfBlocks(blockname); } -S32 LLMessageSystem::getNumberOfBlocks(const char *blockname) const +S32 LLMessageSystem::getNumberOfBlocks(const char *blockname) const { - return getNumberOfBlocksFast(LLMessageStringTable::getInstance()->getString(blockname)); + return getNumberOfBlocksFast(LLMessageStringTable::getInstance()->getString(blockname)); } - -S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname) const + +S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname) const { - return mMessageReader->getSize(blockname, varname); + return mMessageReader->getSize(blockname, varname); } -S32 LLMessageSystem::getSize(const char *blockname, const char *varname) const +S32 LLMessageSystem::getSize(const char *blockname, const char *varname) const { - return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), - LLMessageStringTable::getInstance()->getString(varname)); + return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), + LLMessageStringTable::getInstance()->getString(varname)); } - + // size in bytes of variable length data -S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, - const char *varname) const +S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, + const char *varname) const { - return mMessageReader->getSize(blockname, blocknum, varname); + return mMessageReader->getSize(blockname, blocknum, varname); } - -S32 LLMessageSystem::getSize(const char *blockname, S32 blocknum, - const char *varname) const + +S32 LLMessageSystem::getSize(const char *blockname, S32 blocknum, + const char *varname) const { - return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), blocknum, - LLMessageStringTable::getInstance()->getString(varname)); + return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), blocknum, + LLMessageStringTable::getInstance()->getString(varname)); } S32 LLMessageSystem::getReceiveSize() const { - return mMessageReader->getMessageSize(); + return mMessageReader->getMessageSize(); } -//static +//static void LLMessageSystem::setTimeDecodes( bool b ) { - LLMessageReader::setTimeDecodes(b); + LLMessageReader::setTimeDecodes(b); } - -//static + +//static void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds ) -{ - LLMessageReader::setTimeDecodesSpamThreshold(seconds); +{ + LLMessageReader::setTimeDecodesSpamThreshold(seconds); } LockMessageChecker::LockMessageChecker(LLMessageSystem* msgsystem): @@ -3991,33 +3991,33 @@ LockMessageChecker::LockMessageChecker(LLMessageSystem* msgsystem): // TODO: babbage: move gServicePump in to LLMessageSystem? bool LLMessageSystem::checkAllMessages(LockMessageChecker& lmc, S64 frame_count, LLPumpIO* http_pump) { - if(lmc.checkMessages(frame_count)) - { - return true; - } - U32 packetsIn = mPacketsIn; - http_pump->pump(); - http_pump->callback(); - return (mPacketsIn - packetsIn) > 0; + if(lmc.checkMessages(frame_count)) + { + return true; + } + U32 packetsIn = mPacketsIn; + http_pump->pump(); + http_pump->callback(); + return (mPacketsIn - packetsIn) > 0; } void LLMessageSystem::banUdpMessage(const std::string& name) { - message_template_name_map_t::iterator itt = mMessageTemplates.find( - LLMessageStringTable::getInstance()->getString(name.c_str()) - ); - if(itt != mMessageTemplates.end()) - { - itt->second->banUdp(); - } - else - { - LL_WARNS() << "Attempted to ban an unknown message: " << name << "." << LL_ENDL; - } + message_template_name_map_t::iterator itt = mMessageTemplates.find( + LLMessageStringTable::getInstance()->getString(name.c_str()) + ); + if(itt != mMessageTemplates.end()) + { + itt->second->banUdp(); + } + else + { + LL_WARNS() << "Attempted to ban an unknown message: " << name << "." << LL_ENDL; + } } const LLHost& LLMessageSystem::getSender() const { - return mLastSender; + return mLastSender; } void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::string message, LLSD body, UntrustedCallback_t callback) @@ -4051,5 +4051,5 @@ void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::st LLHTTPRegistration<LLHTTPNodeAdapter<LLTrustedMessageService> > - gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); + gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 65c1e07a68..b4b0d94021 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -1,25 +1,25 @@ -/** +/** * @file message.h * @brief LLMessageSystem class header file * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -67,54 +67,54 @@ const S32 MESSAGE_MAX_PER_FRAME = 400; class LLMessageStringTable : public LLSingleton<LLMessageStringTable> { - LLSINGLETON(LLMessageStringTable); - ~LLMessageStringTable(); + LLSINGLETON(LLMessageStringTable); + ~LLMessageStringTable(); public: - char *getString(const char *str); + char *getString(const char *str); - U32 mUsed; - bool mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS]; - char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH]; /* Flawfinder: ignore */ + U32 mUsed; + bool mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS]; + char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH]; /* Flawfinder: ignore */ }; // Individual Messages are described with the following format // Note that to ease parsing, keywords are used // -// // Comment (Comment like a C++ single line comment) -// Comments can only be placed between Messages +// // Comment (Comment like a C++ single line comment) +// Comments can only be placed between Messages // { -// MessageName (same naming restrictions as C variable) -// Frequency ("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits -- -// there can 254 messages in the first 2 groups, 32K in the last group) -// (A message can be made up only of the Name if it is only a signal) -// Trust ("Trusted", "NotTrusted" - determines if a message will be accepted -// on a circuit. "Trusted" messages are not accepted from NotTrusted circuits -// while NotTrusted messages are accepted on any circuit. An example of a -// NotTrusted circuit is any circuit from the viewer.) -// Encoding ("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of -// zeros, but if there is no space win, it discards the compression and goes unencoded) -// { -// Block Name (same naming restrictions as C variable) -// Block Type ("Single", "Multiple", or "Variable" - determines if the block is coded once, -// a known number of times, or has a 8 bit argument encoded to tell the decoder -// how many times the group is repeated) -// Block Repeat Number (Optional - used only with the "Multiple" type - tells how many times the field is repeated -// { -// Variable 1 Name (same naming restrictions as C variable) -// Variable Type ("Fixed" or "Variable" - determines if the variable is of fixed size or needs to -// encode an argument describing the size in bytes) -// Variable Size (In bytes, either of the "Fixed" variable itself or of the size argument) +// MessageName (same naming restrictions as C variable) +// Frequency ("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits -- +// there can 254 messages in the first 2 groups, 32K in the last group) +// (A message can be made up only of the Name if it is only a signal) +// Trust ("Trusted", "NotTrusted" - determines if a message will be accepted +// on a circuit. "Trusted" messages are not accepted from NotTrusted circuits +// while NotTrusted messages are accepted on any circuit. An example of a +// NotTrusted circuit is any circuit from the viewer.) +// Encoding ("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of +// zeros, but if there is no space win, it discards the compression and goes unencoded) +// { +// Block Name (same naming restrictions as C variable) +// Block Type ("Single", "Multiple", or "Variable" - determines if the block is coded once, +// a known number of times, or has a 8 bit argument encoded to tell the decoder +// how many times the group is repeated) +// Block Repeat Number (Optional - used only with the "Multiple" type - tells how many times the field is repeated +// { +// Variable 1 Name (same naming restrictions as C variable) +// Variable Type ("Fixed" or "Variable" - determines if the variable is of fixed size or needs to +// encode an argument describing the size in bytes) +// Variable Size (In bytes, either of the "Fixed" variable itself or of the size argument) // -// repeat variables +// repeat variables // -// } +// } // -// Repeat for number of variables in block -// } +// Repeat for number of variables in block +// } // -// Repeat for number of blocks in message +// Repeat for number of blocks in message // } // Repeat for number of messages in file // @@ -133,10 +133,10 @@ const U8 LL_ACK_FLAG = 0x10; const S32 LL_MINIMUM_VALID_PACKET_SIZE = LL_PACKET_ID_SIZE + 1; enum EPacketHeaderLayout { - PHL_FLAGS = 0, - PHL_PACKET_ID = 1, - PHL_OFFSET = 5, - PHL_NAME = 6 + PHL_FLAGS = 0, + PHL_PACKET_ID = 1, + PHL_OFFSET = 5, + PHL_NAME = 6 }; @@ -145,10 +145,10 @@ const F32Seconds LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS(1.f); const F32Seconds LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS(1.f); const F32Seconds LL_PING_BASED_TIMEOUT_DUMMY(0.0f); -const F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR = 5.f; // averaged ping -const F32 LL_RELIABLE_TIMEOUT_FACTOR = 5.f; // averaged ping -const F32 LL_LOST_TIMEOUT_FACTOR = 16.f; // averaged ping for marking packets "Lost" -const F32Seconds LL_MAX_LOST_TIMEOUT(5.f); // Maximum amount of time before considering something "lost" +const F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR = 5.f; // averaged ping +const F32 LL_RELIABLE_TIMEOUT_FACTOR = 5.f; // averaged ping +const F32 LL_LOST_TIMEOUT_FACTOR = 16.f; // averaged ping for marking packets "Lost" +const F32Seconds LL_MAX_LOST_TIMEOUT(5.f); // Maximum amount of time before considering something "lost" const S32 MAX_MESSAGE_COUNT_NUM = 1024; @@ -165,10 +165,10 @@ class LLPumpIO; // message system exceptional condition handlers. enum EMessageException { - MX_UNREGISTERED_MESSAGE, // message number not part of template - MX_PACKET_TOO_SHORT, // invalid packet, shorter than minimum packet size - MX_RAN_OFF_END_OF_PACKET, // ran off the end of the packet during decode - MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand + MX_UNREGISTERED_MESSAGE, // message number not part of template + MX_PACKET_TOO_SHORT, // invalid packet, shorter than minimum packet size + MX_RAN_OFF_END_OF_PACKET, // ran off the end of the packet during decode + MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand }; typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException); @@ -190,11 +190,11 @@ class LLSDMessageReader; class LLUseCircuitCodeResponder { - LOG_CLASS(LLMessageSystem); - + LOG_CLASS(LLMessageSystem); + public: - virtual ~LLUseCircuitCodeResponder(); - virtual void complete(const LLHost& host, const LLUUID& agent) const = 0; + virtual ~LLUseCircuitCodeResponder(); + virtual void complete(const LLHost& host, const LLUUID& agent) const = 0; }; /** @@ -285,634 +285,634 @@ class LockMessageChecker; class LLMessageSystem : public LLMessageSenderInterface { private: - U8 mSendBuffer[MAX_BUFFER_SIZE]; - S32 mSendSize; + U8 mSendBuffer[MAX_BUFFER_SIZE]; + S32 mSendSize; - bool mBlockUntrustedInterface; - LLHost mUntrustedInterface; + bool mBlockUntrustedInterface; + LLHost mUntrustedInterface; public: - LLPacketRing mPacketRing; - LLReliablePacketParams mReliablePacketParams; + LLPacketRing mPacketRing; + LLReliablePacketParams mReliablePacketParams; - // Set this flag to true when you want *very* verbose logs. - bool mVerboseLog; + // Set this flag to true when you want *very* verbose logs. + bool mVerboseLog; - F32 mMessageFileVersionNumber; + F32 mMessageFileVersionNumber; - typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; - typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; + typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; + typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; private: - message_template_name_map_t mMessageTemplates; - message_template_number_map_t mMessageNumbers; + message_template_name_map_t mMessageTemplates; + message_template_number_map_t mMessageNumbers; public: - S32 mSystemVersionMajor; - S32 mSystemVersionMinor; - S32 mSystemVersionPatch; - S32 mSystemVersionServer; - U32 mVersionFlags; - - bool mbProtected; - - U32 mNumberHighFreqMessages; - U32 mNumberMediumFreqMessages; - U32 mNumberLowFreqMessages; - S32 mPort; - S32 mSocket; - - U32 mPacketsIn; // total packets in, including compressed and uncompressed - U32 mPacketsOut; // total packets out, including compressed and uncompressed - - U64 mBytesIn; // total bytes in, including compressed and uncompressed - U64 mBytesOut; // total bytes out, including compressed and uncompressed - - U32 mCompressedPacketsIn; // total compressed packets in - U32 mCompressedPacketsOut; // total compressed packets out - - U32 mReliablePacketsIn; // total reliable packets in - U32 mReliablePacketsOut; // total reliable packets out - - U32 mDroppedPackets; // total dropped packets in - U32 mResentPackets; // total resent packets out - U32 mFailedResendPackets; // total resend failure packets out - U32 mOffCircuitPackets; // total # of off-circuit packets rejected - U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected - - S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in - S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out - S64 mCompressedBytesIn; // total compressed size of compressed packets in - S64 mCompressedBytesOut; // total compressed size of compressed packets out - S64 mTotalBytesIn; // total size of all uncompressed packets in - S64 mTotalBytesOut; // total size of all uncompressed packets out - - bool mSendReliable; // does the outgoing message require a pos ack? - - LLCircuit mCircuitInfo; - F64Seconds mCircuitPrintTime; // used to print circuit debug info every couple minutes - F32Seconds mCircuitPrintFreq; - - std::map<U64, U32> mIPPortToCircuitCode; - std::map<U32, U64> mCircuitCodeToIPPort; - U32 mOurCircuitCode; - S32 mSendPacketFailureCount; - S32 mUnackedListDepth; - S32 mUnackedListSize; - S32 mDSMaxListDepth; + S32 mSystemVersionMajor; + S32 mSystemVersionMinor; + S32 mSystemVersionPatch; + S32 mSystemVersionServer; + U32 mVersionFlags; + + bool mbProtected; + + U32 mNumberHighFreqMessages; + U32 mNumberMediumFreqMessages; + U32 mNumberLowFreqMessages; + S32 mPort; + S32 mSocket; + + U32 mPacketsIn; // total packets in, including compressed and uncompressed + U32 mPacketsOut; // total packets out, including compressed and uncompressed + + U64 mBytesIn; // total bytes in, including compressed and uncompressed + U64 mBytesOut; // total bytes out, including compressed and uncompressed + + U32 mCompressedPacketsIn; // total compressed packets in + U32 mCompressedPacketsOut; // total compressed packets out + + U32 mReliablePacketsIn; // total reliable packets in + U32 mReliablePacketsOut; // total reliable packets out + + U32 mDroppedPackets; // total dropped packets in + U32 mResentPackets; // total resent packets out + U32 mFailedResendPackets; // total resend failure packets out + U32 mOffCircuitPackets; // total # of off-circuit packets rejected + U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected + + S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in + S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out + S64 mCompressedBytesIn; // total compressed size of compressed packets in + S64 mCompressedBytesOut; // total compressed size of compressed packets out + S64 mTotalBytesIn; // total size of all uncompressed packets in + S64 mTotalBytesOut; // total size of all uncompressed packets out + + bool mSendReliable; // does the outgoing message require a pos ack? + + LLCircuit mCircuitInfo; + F64Seconds mCircuitPrintTime; // used to print circuit debug info every couple minutes + F32Seconds mCircuitPrintFreq; + + std::map<U64, U32> mIPPortToCircuitCode; + std::map<U32, U64> mCircuitCodeToIPPort; + U32 mOurCircuitCode; + S32 mSendPacketFailureCount; + S32 mUnackedListDepth; + S32 mUnackedListSize; + S32 mDSMaxListDepth; public: - // Read file and build message templates - LLMessageSystem(const std::string& filename, U32 port, S32 version_major, - S32 version_minor, S32 version_patch, - bool failure_is_fatal, - const F32 circuit_heartbeat_interval, const F32 circuit_timeout); - - ~LLMessageSystem(); - - bool isOK() const { return !mbError; } - S32 getErrorCode() const { return mErrorCode; } - - // Read file and build message templates filename must point to a - // valid string which specifies the path of a valid linden - // template. - void loadTemplateFile(const std::string& filename, bool failure_is_fatal); - - - // methods for building, sending, receiving, and handling messages - void setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL); - void setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL) - { - setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data); - } - - // Set a callback function for a message system exception. - void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL); - // Call the specified exception func, and return true if a - // function was found and called. Otherwise return false. - bool callExceptionFunc(EMessageException exception); - - // Set a function that will be called once per packet processed with the - // hashed message name and the time spent in the processing handler function - // measured in seconds. JC - typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data); - void setTimingFunc(msg_timing_callback func, void* data = NULL); - msg_timing_callback getTimingCallback() - { - return mTimingCallback; - } - void* getTimingCallbackData() - { - return mTimingCallbackData; - } - - // This method returns true if the code is in the circuit codes map. - bool isCircuitCodeKnown(U32 code) const; - - // usually called in response to an AddCircuitCode message, but - // may also be called by the login process. - bool addCircuitCode(U32 code, const LLUUID& session_id); - - bool poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received - bool checkMessages(LockMessageChecker&, S64 frame_count = 0 ); - void processAcks(LockMessageChecker&, F32 collect_time = 0.f); - - bool isMessageFast(const char *msg); - bool isMessage(const char *msg) - { - return isMessageFast(LLMessageStringTable::getInstance()->getString(msg)); - } - - void dumpPacketToLog(); - - char *getMessageName(); - - const LLHost& getSender() const; - U32 getSenderIP() const; // getSender() is preferred - U32 getSenderPort() const; // getSender() is preferred - - const LLHost& getReceivingInterface() const; - - // This method returns the uuid associated with the sender. The - // UUID will be null if it is not yet known or is a server - // circuit. - const LLUUID& getSenderID() const; - - // This method returns the session id associated with the last - // sender. - const LLUUID& getSenderSessionID() const; - - // set & get the session id (useful for viewers for now.) - void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; } - const LLUUID& getMySessionID() { return mSessionID; } - - void newMessageFast(const char *name); - void newMessage(const char *name); + // Read file and build message templates + LLMessageSystem(const std::string& filename, U32 port, S32 version_major, + S32 version_minor, S32 version_patch, + bool failure_is_fatal, + const F32 circuit_heartbeat_interval, const F32 circuit_timeout); + + ~LLMessageSystem(); + + bool isOK() const { return !mbError; } + S32 getErrorCode() const { return mErrorCode; } + + // Read file and build message templates filename must point to a + // valid string which specifies the path of a valid linden + // template. + void loadTemplateFile(const std::string& filename, bool failure_is_fatal); + + + // methods for building, sending, receiving, and handling messages + void setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL); + void setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL) + { + setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data); + } + + // Set a callback function for a message system exception. + void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL); + // Call the specified exception func, and return true if a + // function was found and called. Otherwise return false. + bool callExceptionFunc(EMessageException exception); + + // Set a function that will be called once per packet processed with the + // hashed message name and the time spent in the processing handler function + // measured in seconds. JC + typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data); + void setTimingFunc(msg_timing_callback func, void* data = NULL); + msg_timing_callback getTimingCallback() + { + return mTimingCallback; + } + void* getTimingCallbackData() + { + return mTimingCallbackData; + } + + // This method returns true if the code is in the circuit codes map. + bool isCircuitCodeKnown(U32 code) const; + + // usually called in response to an AddCircuitCode message, but + // may also be called by the login process. + bool addCircuitCode(U32 code, const LLUUID& session_id); + + bool poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received + bool checkMessages(LockMessageChecker&, S64 frame_count = 0 ); + void processAcks(LockMessageChecker&, F32 collect_time = 0.f); + + bool isMessageFast(const char *msg); + bool isMessage(const char *msg) + { + return isMessageFast(LLMessageStringTable::getInstance()->getString(msg)); + } + + void dumpPacketToLog(); + + char *getMessageName(); + + const LLHost& getSender() const; + U32 getSenderIP() const; // getSender() is preferred + U32 getSenderPort() const; // getSender() is preferred + + const LLHost& getReceivingInterface() const; + + // This method returns the uuid associated with the sender. The + // UUID will be null if it is not yet known or is a server + // circuit. + const LLUUID& getSenderID() const; + + // This method returns the session id associated with the last + // sender. + const LLUUID& getSenderSessionID() const; + + // set & get the session id (useful for viewers for now.) + void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; } + const LLUUID& getMySessionID() { return mSessionID; } + + void newMessageFast(const char *name); + void newMessage(const char *name); public: - LLStoredMessagePtr getReceivedMessage() const; - LLStoredMessagePtr getBuiltMessage() const; - S32 sendMessage(const LLHost &host, LLStoredMessagePtr message); + LLStoredMessagePtr getReceivedMessage() const; + LLStoredMessagePtr getBuiltMessage() const; + S32 sendMessage(const LLHost &host, LLStoredMessagePtr message); private: - LLSD getReceivedMessageLLSD() const; - LLSD getBuiltMessageLLSD() const; - - // NOTE: babbage: Only use to support legacy misuse of the - // LLMessageSystem API where values are dangerously written - // as one type and read as another. LLSD does not support - // dangerous conversions and so converting the message to an - // LLSD would result in the reads failing. All code which - // misuses the message system in this way should be made safe - // but while the unsafe code is run in old processes, this - // method should be used to forward unsafe messages. - LLSD wrapReceivedTemplateData() const; - LLSD wrapBuiltTemplateData() const; + LLSD getReceivedMessageLLSD() const; + LLSD getBuiltMessageLLSD() const; + + // NOTE: babbage: Only use to support legacy misuse of the + // LLMessageSystem API where values are dangerously written + // as one type and read as another. LLSD does not support + // dangerous conversions and so converting the message to an + // LLSD would result in the reads failing. All code which + // misuses the message system in this way should be made safe + // but while the unsafe code is run in old processes, this + // method should be used to forward unsafe messages. + LLSD wrapReceivedTemplateData() const; + LLSD wrapBuiltTemplateData() const; public: - void copyMessageReceivedToSend(); - void clearMessage(); + void copyMessageReceivedToSend(); + void clearMessage(); - void nextBlockFast(const char *blockname); - void nextBlock(const char *blockname); + void nextBlockFast(const char *blockname); + void nextBlock(const char *blockname); public: - void addBinaryDataFast(const char *varname, const void *data, S32 size); - void addBinaryData(const char *varname, const void *data, S32 size); - - void addBOOLFast( const char* varname, bool b); // typed, checks storage space - void addBOOL( const char* varname, bool b); // typed, checks storage space - void addS8Fast( const char *varname, S8 s); // typed, checks storage space - void addS8( const char *varname, S8 s); // typed, checks storage space - void addU8Fast( const char *varname, U8 u); // typed, checks storage space - void addU8( const char *varname, U8 u); // typed, checks storage space - void addS16Fast( const char *varname, S16 i); // typed, checks storage space - void addS16( const char *varname, S16 i); // typed, checks storage space - void addU16Fast( const char *varname, U16 i); // typed, checks storage space - void addU16( const char *varname, U16 i); // typed, checks storage space - void addF32Fast( const char *varname, F32 f); // typed, checks storage space - void addF32( const char *varname, F32 f); // typed, checks storage space - void addS32Fast( const char *varname, S32 s); // typed, checks storage space - void addS32( const char *varname, S32 s); // typed, checks storage space - void addU32Fast( const char *varname, U32 u); // typed, checks storage space - void addU32( const char *varname, U32 u); // typed, checks storage space - void addU64Fast( const char *varname, U64 lu); // typed, checks storage space - void addU64( const char *varname, U64 lu); // typed, checks storage space - void addF64Fast( const char *varname, F64 d); // typed, checks storage space - void addF64( const char *varname, F64 d); // typed, checks storage space - void addVector3Fast( const char *varname, const LLVector3& vec); // typed, checks storage space - void addVector3( const char *varname, const LLVector3& vec); // typed, checks storage space - void addVector4Fast( const char *varname, const LLVector4& vec); // typed, checks storage space - void addVector4( const char *varname, const LLVector4& vec); // typed, checks storage space - void addVector3dFast( const char *varname, const LLVector3d& vec); // typed, checks storage space - void addVector3d( const char *varname, const LLVector3d& vec); // typed, checks storage space - void addQuatFast( const char *varname, const LLQuaternion& quat); // typed, checks storage space - void addQuat( const char *varname, const LLQuaternion& quat); // typed, checks storage space - void addUUIDFast( const char *varname, const LLUUID& uuid); // typed, checks storage space - void addUUID( const char *varname, const LLUUID& uuid); // typed, checks storage space - void addIPAddrFast( const char *varname, const U32 ip); // typed, checks storage space - void addIPAddr( const char *varname, const U32 ip); // typed, checks storage space - void addIPPortFast( const char *varname, const U16 port); // typed, checks storage space - void addIPPort( const char *varname, const U16 port); // typed, checks storage space - void addStringFast( const char* varname, const char* s); // typed, checks storage space - void addString( const char* varname, const char* s); // typed, checks storage space - void addStringFast( const char* varname, const std::string& s); // typed, checks storage space - void addString( const char* varname, const std::string& s); // typed, checks storage space - - S32 getCurrentSendTotal() const; - TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; } - - // This method checks for current send total and returns true if - // you need to go to the next block type or need to start a new - // message. Specify the current blockname to check block counts, - // otherwise the method only checks against MTU. - bool isSendFull(const char* blockname = NULL); - bool isSendFullFast(const char* blockname = NULL); - - bool removeLastBlock(); - - //void buildMessage(); - - S32 zeroCode(U8 **data, S32 *data_size); - S32 zeroCodeExpand(U8 **data, S32 *data_size); - S32 zeroCodeAdjustCurrentSendTotal(); - - // Uses ping-based retry - S32 sendReliable(const LLHost &host); - - // Uses ping-based retry - S32 sendReliable(const U32 circuit) { return sendReliable(findHost(circuit)); } - - // Use this one if you DON'T want automatic ping-based retry. - S32 sendReliable( const LLHost &host, - S32 retries, - bool ping_based_retries, - F32Seconds timeout, - void (*callback)(void **,S32), - void ** callback_data); - - S32 sendSemiReliable( const LLHost &host, - void (*callback)(void **,S32), void ** callback_data); - - // flush sends a message only if data's been pushed on it. - S32 flushSemiReliable( const LLHost &host, - void (*callback)(void **,S32), void ** callback_data); - - S32 flushReliable( const LLHost &host ); - - void forwardMessage(const LLHost &host); - void forwardReliable(const LLHost &host); - void forwardReliable(const U32 circuit_code); - S32 forwardReliable( - const LLHost &host, - S32 retries, - bool ping_based_timeout, - F32Seconds timeout, - void (*callback)(void **,S32), - void ** callback_data); - - S32 sendMessage(const LLHost &host); - S32 sendMessage(const U32 circuit); + void addBinaryDataFast(const char *varname, const void *data, S32 size); + void addBinaryData(const char *varname, const void *data, S32 size); + + void addBOOLFast( const char* varname, bool b); // typed, checks storage space + void addBOOL( const char* varname, bool b); // typed, checks storage space + void addS8Fast( const char *varname, S8 s); // typed, checks storage space + void addS8( const char *varname, S8 s); // typed, checks storage space + void addU8Fast( const char *varname, U8 u); // typed, checks storage space + void addU8( const char *varname, U8 u); // typed, checks storage space + void addS16Fast( const char *varname, S16 i); // typed, checks storage space + void addS16( const char *varname, S16 i); // typed, checks storage space + void addU16Fast( const char *varname, U16 i); // typed, checks storage space + void addU16( const char *varname, U16 i); // typed, checks storage space + void addF32Fast( const char *varname, F32 f); // typed, checks storage space + void addF32( const char *varname, F32 f); // typed, checks storage space + void addS32Fast( const char *varname, S32 s); // typed, checks storage space + void addS32( const char *varname, S32 s); // typed, checks storage space + void addU32Fast( const char *varname, U32 u); // typed, checks storage space + void addU32( const char *varname, U32 u); // typed, checks storage space + void addU64Fast( const char *varname, U64 lu); // typed, checks storage space + void addU64( const char *varname, U64 lu); // typed, checks storage space + void addF64Fast( const char *varname, F64 d); // typed, checks storage space + void addF64( const char *varname, F64 d); // typed, checks storage space + void addVector3Fast( const char *varname, const LLVector3& vec); // typed, checks storage space + void addVector3( const char *varname, const LLVector3& vec); // typed, checks storage space + void addVector4Fast( const char *varname, const LLVector4& vec); // typed, checks storage space + void addVector4( const char *varname, const LLVector4& vec); // typed, checks storage space + void addVector3dFast( const char *varname, const LLVector3d& vec); // typed, checks storage space + void addVector3d( const char *varname, const LLVector3d& vec); // typed, checks storage space + void addQuatFast( const char *varname, const LLQuaternion& quat); // typed, checks storage space + void addQuat( const char *varname, const LLQuaternion& quat); // typed, checks storage space + void addUUIDFast( const char *varname, const LLUUID& uuid); // typed, checks storage space + void addUUID( const char *varname, const LLUUID& uuid); // typed, checks storage space + void addIPAddrFast( const char *varname, const U32 ip); // typed, checks storage space + void addIPAddr( const char *varname, const U32 ip); // typed, checks storage space + void addIPPortFast( const char *varname, const U16 port); // typed, checks storage space + void addIPPort( const char *varname, const U16 port); // typed, checks storage space + void addStringFast( const char* varname, const char* s); // typed, checks storage space + void addString( const char* varname, const char* s); // typed, checks storage space + void addStringFast( const char* varname, const std::string& s); // typed, checks storage space + void addString( const char* varname, const std::string& s); // typed, checks storage space + + S32 getCurrentSendTotal() const; + TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; } + + // This method checks for current send total and returns true if + // you need to go to the next block type or need to start a new + // message. Specify the current blockname to check block counts, + // otherwise the method only checks against MTU. + bool isSendFull(const char* blockname = NULL); + bool isSendFullFast(const char* blockname = NULL); + + bool removeLastBlock(); + + //void buildMessage(); + + S32 zeroCode(U8 **data, S32 *data_size); + S32 zeroCodeExpand(U8 **data, S32 *data_size); + S32 zeroCodeAdjustCurrentSendTotal(); + + // Uses ping-based retry + S32 sendReliable(const LLHost &host); + + // Uses ping-based retry + S32 sendReliable(const U32 circuit) { return sendReliable(findHost(circuit)); } + + // Use this one if you DON'T want automatic ping-based retry. + S32 sendReliable( const LLHost &host, + S32 retries, + bool ping_based_retries, + F32Seconds timeout, + void (*callback)(void **,S32), + void ** callback_data); + + S32 sendSemiReliable( const LLHost &host, + void (*callback)(void **,S32), void ** callback_data); + + // flush sends a message only if data's been pushed on it. + S32 flushSemiReliable( const LLHost &host, + void (*callback)(void **,S32), void ** callback_data); + + S32 flushReliable( const LLHost &host ); + + void forwardMessage(const LLHost &host); + void forwardReliable(const LLHost &host); + void forwardReliable(const U32 circuit_code); + S32 forwardReliable( + const LLHost &host, + S32 retries, + bool ping_based_timeout, + F32Seconds timeout, + void (*callback)(void **,S32), + void ** callback_data); + + S32 sendMessage(const LLHost &host); + S32 sendMessage(const U32 circuit); private: - S32 sendMessage(const LLHost &host, const char* name, - const LLSD& message); + S32 sendMessage(const LLHost &host, const char* name, + const LLSD& message); public: - // bool decodeData(const U8 *buffer, const LLHost &host); - - /** - gets binary data from the current message. - - @param blockname the name of the block in the message (from the message template) - - @param varname - - @param datap - - @param size expected size - set to zero to get any amount of data up to max_size. - Make sure max_size is set in that case! - - @param blocknum - - @param max_size the max number of bytes to read - */ - void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); - void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); - void getBOOLFast( const char *block, const char *var, bool &data, S32 blocknum = 0); - void getBOOL( const char *block, const char *var, bool &data, S32 blocknum = 0); - void getS8Fast( const char *block, const char *var, S8 &data, S32 blocknum = 0); - void getS8( const char *block, const char *var, S8 &data, S32 blocknum = 0); - void getU8Fast( const char *block, const char *var, U8 &data, S32 blocknum = 0); - void getU8( const char *block, const char *var, U8 &data, S32 blocknum = 0); - void getS16Fast( const char *block, const char *var, S16 &data, S32 blocknum = 0); - void getS16( const char *block, const char *var, S16 &data, S32 blocknum = 0); - void getU16Fast( const char *block, const char *var, U16 &data, S32 blocknum = 0); - void getU16( const char *block, const char *var, U16 &data, S32 blocknum = 0); - void getS32Fast( const char *block, const char *var, S32 &data, S32 blocknum = 0); - void getS32( const char *block, const char *var, S32 &data, S32 blocknum = 0); - void getF32Fast( const char *block, const char *var, F32 &data, S32 blocknum = 0); - void getF32( const char *block, const char *var, F32 &data, S32 blocknum = 0); - void getU32Fast( const char *block, const char *var, U32 &data, S32 blocknum = 0); - void getU32( const char *block, const char *var, U32 &data, S32 blocknum = 0); - void getU64Fast( const char *block, const char *var, U64 &data, S32 blocknum = 0); - void getU64( const char *block, const char *var, U64 &data, S32 blocknum = 0); - void getF64Fast( const char *block, const char *var, F64 &data, S32 blocknum = 0); - void getF64( const char *block, const char *var, F64 &data, S32 blocknum = 0); - void getVector3Fast( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0); - void getVector3( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0); - void getVector4Fast( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0); - void getVector4( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0); - void getVector3dFast(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0); - void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0); - void getQuatFast( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0); - void getQuat( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0); - void getUUIDFast( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0); - void getUUID( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0); - void getIPAddrFast( const char *block, const char *var, U32 &ip, S32 blocknum = 0); - void getIPAddr( const char *block, const char *var, U32 &ip, S32 blocknum = 0); - void getIPPortFast( const char *block, const char *var, U16 &port, S32 blocknum = 0); - void getIPPort( const char *block, const char *var, U16 &port, S32 blocknum = 0); - void getStringFast( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0); - void getString( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0); - void getStringFast( const char *block, const char *var, std::string& outstr, S32 blocknum = 0); - void getString( const char *block, const char *var, std::string& outstr, S32 blocknum = 0); - - - // Utility functions to generate a replay-resistant digest check - // against the shared secret. The window specifies how much of a - // time window is allowed - 1 second is good for tight - // connections, but multi-process windows might want to be upwards - // of 5 seconds. For generateDigest, you want to pass in a - // character array of at least MD5HEX_STR_SIZE so that the hex - // digest and null termination will fit. - bool generateDigestForNumberAndUUIDs(char* digest, const U32 number, const LLUUID &id1, const LLUUID &id2) const; - bool generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const; - bool isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const; - - bool generateDigestForNumber(char* digest, const U32 number) const; - bool generateDigestForWindow(char* digest, const S32 window) const; - bool isMatchingDigestForWindow(const char* digest, const S32 window) const; - - void showCircuitInfo(); - void getCircuitInfo(LLSD& info) const; - - U32 getOurCircuitCode(); - - void enableCircuit(const LLHost &host, bool trusted); - void disableCircuit(const LLHost &host); - - // Use this to establish trust on startup and in response to - // DenyTrustedCircuit. - void sendCreateTrustedCircuit(const LLHost& host, const LLUUID & id1, const LLUUID & id2); - - // Use this to inform a peer that they aren't currently trusted... - // This now enqueues the request so that we can ensure that we only send - // one deny per circuit per message loop so that this doesn't become a DoS. - // The actual sending is done by reallySendDenyTrustedCircuit() - void sendDenyTrustedCircuit(const LLHost &host); - - /** Return false if host is unknown or untrusted */ - // Note:DaveH/Babbage some trusted messages can be received without a circuit - bool isTrustedSender(const LLHost& host) const; - - /** Return true if current message is from trusted source */ - bool isTrustedSender() const; - - /** Return false true if name is unknown or untrusted */ - bool isTrustedMessage(const std::string& name) const; - - /** Return false true if name is unknown or trusted */ - bool isUntrustedMessage(const std::string& name) const; - - // Mark an interface ineligible for trust - void setUntrustedInterface( const LLHost host ) { mUntrustedInterface = host; } - LLHost getUntrustedInterface() const { return mUntrustedInterface; } - void setBlockUntrustedInterface( bool block ) { mBlockUntrustedInterface = block; } // Throw a switch to allow, sending warnings only - bool getBlockUntrustedInterface() const { return mBlockUntrustedInterface; } - - // Change this message to be UDP black listed. - void banUdpMessage(const std::string& name); + // bool decodeData(const U8 *buffer, const LLHost &host); + + /** + gets binary data from the current message. + + @param blockname the name of the block in the message (from the message template) + + @param varname + + @param datap + + @param size expected size - set to zero to get any amount of data up to max_size. + Make sure max_size is set in that case! + + @param blocknum + + @param max_size the max number of bytes to read + */ + void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); + void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); + void getBOOLFast( const char *block, const char *var, bool &data, S32 blocknum = 0); + void getBOOL( const char *block, const char *var, bool &data, S32 blocknum = 0); + void getS8Fast( const char *block, const char *var, S8 &data, S32 blocknum = 0); + void getS8( const char *block, const char *var, S8 &data, S32 blocknum = 0); + void getU8Fast( const char *block, const char *var, U8 &data, S32 blocknum = 0); + void getU8( const char *block, const char *var, U8 &data, S32 blocknum = 0); + void getS16Fast( const char *block, const char *var, S16 &data, S32 blocknum = 0); + void getS16( const char *block, const char *var, S16 &data, S32 blocknum = 0); + void getU16Fast( const char *block, const char *var, U16 &data, S32 blocknum = 0); + void getU16( const char *block, const char *var, U16 &data, S32 blocknum = 0); + void getS32Fast( const char *block, const char *var, S32 &data, S32 blocknum = 0); + void getS32( const char *block, const char *var, S32 &data, S32 blocknum = 0); + void getF32Fast( const char *block, const char *var, F32 &data, S32 blocknum = 0); + void getF32( const char *block, const char *var, F32 &data, S32 blocknum = 0); + void getU32Fast( const char *block, const char *var, U32 &data, S32 blocknum = 0); + void getU32( const char *block, const char *var, U32 &data, S32 blocknum = 0); + void getU64Fast( const char *block, const char *var, U64 &data, S32 blocknum = 0); + void getU64( const char *block, const char *var, U64 &data, S32 blocknum = 0); + void getF64Fast( const char *block, const char *var, F64 &data, S32 blocknum = 0); + void getF64( const char *block, const char *var, F64 &data, S32 blocknum = 0); + void getVector3Fast( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0); + void getVector3( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0); + void getVector4Fast( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0); + void getVector4( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0); + void getVector3dFast(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0); + void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0); + void getQuatFast( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0); + void getQuat( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0); + void getUUIDFast( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0); + void getUUID( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0); + void getIPAddrFast( const char *block, const char *var, U32 &ip, S32 blocknum = 0); + void getIPAddr( const char *block, const char *var, U32 &ip, S32 blocknum = 0); + void getIPPortFast( const char *block, const char *var, U16 &port, S32 blocknum = 0); + void getIPPort( const char *block, const char *var, U16 &port, S32 blocknum = 0); + void getStringFast( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0); + void getString( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0); + void getStringFast( const char *block, const char *var, std::string& outstr, S32 blocknum = 0); + void getString( const char *block, const char *var, std::string& outstr, S32 blocknum = 0); + + + // Utility functions to generate a replay-resistant digest check + // against the shared secret. The window specifies how much of a + // time window is allowed - 1 second is good for tight + // connections, but multi-process windows might want to be upwards + // of 5 seconds. For generateDigest, you want to pass in a + // character array of at least MD5HEX_STR_SIZE so that the hex + // digest and null termination will fit. + bool generateDigestForNumberAndUUIDs(char* digest, const U32 number, const LLUUID &id1, const LLUUID &id2) const; + bool generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const; + bool isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const; + + bool generateDigestForNumber(char* digest, const U32 number) const; + bool generateDigestForWindow(char* digest, const S32 window) const; + bool isMatchingDigestForWindow(const char* digest, const S32 window) const; + + void showCircuitInfo(); + void getCircuitInfo(LLSD& info) const; + + U32 getOurCircuitCode(); + + void enableCircuit(const LLHost &host, bool trusted); + void disableCircuit(const LLHost &host); + + // Use this to establish trust on startup and in response to + // DenyTrustedCircuit. + void sendCreateTrustedCircuit(const LLHost& host, const LLUUID & id1, const LLUUID & id2); + + // Use this to inform a peer that they aren't currently trusted... + // This now enqueues the request so that we can ensure that we only send + // one deny per circuit per message loop so that this doesn't become a DoS. + // The actual sending is done by reallySendDenyTrustedCircuit() + void sendDenyTrustedCircuit(const LLHost &host); + + /** Return false if host is unknown or untrusted */ + // Note:DaveH/Babbage some trusted messages can be received without a circuit + bool isTrustedSender(const LLHost& host) const; + + /** Return true if current message is from trusted source */ + bool isTrustedSender() const; + + /** Return false true if name is unknown or untrusted */ + bool isTrustedMessage(const std::string& name) const; + + /** Return false true if name is unknown or trusted */ + bool isUntrustedMessage(const std::string& name) const; + + // Mark an interface ineligible for trust + void setUntrustedInterface( const LLHost host ) { mUntrustedInterface = host; } + LLHost getUntrustedInterface() const { return mUntrustedInterface; } + void setBlockUntrustedInterface( bool block ) { mBlockUntrustedInterface = block; } // Throw a switch to allow, sending warnings only + bool getBlockUntrustedInterface() const { return mBlockUntrustedInterface; } + + // Change this message to be UDP black listed. + void banUdpMessage(const std::string& name); private: - // A list of the circuits that need to be sent DenyTrustedCircuit messages. - typedef std::set<LLHost> host_set_t; - host_set_t mDenyTrustedCircuitSet; + // A list of the circuits that need to be sent DenyTrustedCircuit messages. + typedef std::set<LLHost> host_set_t; + host_set_t mDenyTrustedCircuitSet; - // Really sends the DenyTrustedCircuit message to a given host - // related to sendDenyTrustedCircuit() - void reallySendDenyTrustedCircuit(const LLHost &host); + // Really sends the DenyTrustedCircuit message to a given host + // related to sendDenyTrustedCircuit() + void reallySendDenyTrustedCircuit(const LLHost &host); public: - // Use this to establish trust to and from a host. This blocks - // until trust has been established, and probably should only be - // used on startup. - void establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0); - - // returns whether the given host is on a trusted circuit - // Note:DaveH/Babbage some trusted messages can be received without a circuit - bool getCircuitTrust(const LLHost &host); - - void setCircuitAllowTimeout(const LLHost &host, bool allow); - void setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost &host, void *user_data), void *user_data); - - bool checkCircuitBlocked(const U32 circuit); - bool checkCircuitAlive(const U32 circuit); - bool checkCircuitAlive(const LLHost &host); - void setCircuitProtection(bool b_protect); - U32 findCircuitCode(const LLHost &host); - LLHost findHost(const U32 circuit_code); - void sanityCheck(); - - bool has(const char *blockname) const; - S32 getNumberOfBlocksFast(const char *blockname) const; - S32 getNumberOfBlocks(const char *blockname) const; - S32 getSizeFast(const char *blockname, const char *varname) const; - S32 getSize(const char *blockname, const char *varname) const; - S32 getSizeFast(const char *blockname, S32 blocknum, - const char *varname) const; // size in bytes of data - S32 getSize(const char *blockname, S32 blocknum, const char *varname) const; - - void resetReceiveCounts(); // resets receive counts for all message types to 0 - void dumpReceiveCounts(); // dumps receive count for each message type to LL_INFOS() - void dumpCircuitInfo(); // Circuit information to LL_INFOS() - - bool isClear() const; // returns mbSClear; - S32 flush(const LLHost &host); - - U32 getListenPort( void ) const; - - void startLogging(); // start verbose logging - void stopLogging(); // flush and close file - void summarizeLogs(std::ostream& str); // log statistics - - S32 getReceiveSize() const; - S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; } - S32 getReceiveBytes() const; - - S32 getUnackedListSize() const { return mUnackedListSize; } - - //const char* getCurrentSMessageName() const { return mCurrentSMessageName; } - //const char* getCurrentSBlockName() const { return mCurrentSBlockName; } - - // friends - friend std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg); - - void setMaxMessageTime(const F32 seconds); // Max time to process messages before warning and dumping (neg to disable) - void setMaxMessageCounts(const S32 num); // Max number of messages before dumping (neg to disable) - - static U64Microseconds getMessageTimeUsecs(const bool update = false); // Get the current message system time in microseconds - static F64Seconds getMessageTimeSeconds(const bool update = false); // Get the current message system time in seconds - - static void setTimeDecodes(bool b); - static void setTimeDecodesSpamThreshold(F32 seconds); - - // message handlers internal to the message systesm - //static void processAssignCircuitCode(LLMessageSystem* msg, void**); - static void processAddCircuitCode(LLMessageSystem* msg, void**); - static void processUseCircuitCode(LLMessageSystem* msg, void**); - static void processError(LLMessageSystem* msg, void**); - - // dispatch llsd message to http node tree - static void dispatch(const std::string& msg_name, - const LLSD& message); - static void dispatch(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep); - - // this is added to support specific legacy messages and is - // ***not intended for general use*** Si, Gabriel, 2009 - static void dispatchTemplate(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep); - - void setMessageBans(const LLSD& trusted, const LLSD& untrusted); - - /** - * @brief send an error message to the host. This is a helper method. - * - * @param host Destination host. - * @param agent_id Destination agent id (may be null) - * @param code An HTTP status compatible error code. - * @param token A specific short string based message - * @param id The transactionid/uniqueid/sessionid whatever. - * @param system The hierarchical path to the system (255 bytes) - * @param message Human readable message (1200 bytes) - * @param data Extra info. - * @return Returns value returned from sendReliable(). - */ - S32 sendError( - const LLHost& host, - const LLUUID& agent_id, - S32 code, - const std::string& token, - const LLUUID& id, - const std::string& system, - const std::string& message, - const LLSD& data); - - // Check UDP messages and pump http_pump to receive HTTP messages. - bool checkAllMessages(LockMessageChecker&, S64 frame_count, LLPumpIO* http_pump); - - // Moved to allow access from LLTemplateMessageDispatcher - void clearReceiveState(); - - // This will cause all trust queries to return true until the next message - // is read: use with caution! - void receivedMessageFromTrustedSender(); - + // Use this to establish trust to and from a host. This blocks + // until trust has been established, and probably should only be + // used on startup. + void establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0); + + // returns whether the given host is on a trusted circuit + // Note:DaveH/Babbage some trusted messages can be received without a circuit + bool getCircuitTrust(const LLHost &host); + + void setCircuitAllowTimeout(const LLHost &host, bool allow); + void setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost &host, void *user_data), void *user_data); + + bool checkCircuitBlocked(const U32 circuit); + bool checkCircuitAlive(const U32 circuit); + bool checkCircuitAlive(const LLHost &host); + void setCircuitProtection(bool b_protect); + U32 findCircuitCode(const LLHost &host); + LLHost findHost(const U32 circuit_code); + void sanityCheck(); + + bool has(const char *blockname) const; + S32 getNumberOfBlocksFast(const char *blockname) const; + S32 getNumberOfBlocks(const char *blockname) const; + S32 getSizeFast(const char *blockname, const char *varname) const; + S32 getSize(const char *blockname, const char *varname) const; + S32 getSizeFast(const char *blockname, S32 blocknum, + const char *varname) const; // size in bytes of data + S32 getSize(const char *blockname, S32 blocknum, const char *varname) const; + + void resetReceiveCounts(); // resets receive counts for all message types to 0 + void dumpReceiveCounts(); // dumps receive count for each message type to LL_INFOS() + void dumpCircuitInfo(); // Circuit information to LL_INFOS() + + bool isClear() const; // returns mbSClear; + S32 flush(const LLHost &host); + + U32 getListenPort( void ) const; + + void startLogging(); // start verbose logging + void stopLogging(); // flush and close file + void summarizeLogs(std::ostream& str); // log statistics + + S32 getReceiveSize() const; + S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; } + S32 getReceiveBytes() const; + + S32 getUnackedListSize() const { return mUnackedListSize; } + + //const char* getCurrentSMessageName() const { return mCurrentSMessageName; } + //const char* getCurrentSBlockName() const { return mCurrentSBlockName; } + + // friends + friend std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg); + + void setMaxMessageTime(const F32 seconds); // Max time to process messages before warning and dumping (neg to disable) + void setMaxMessageCounts(const S32 num); // Max number of messages before dumping (neg to disable) + + static U64Microseconds getMessageTimeUsecs(const bool update = false); // Get the current message system time in microseconds + static F64Seconds getMessageTimeSeconds(const bool update = false); // Get the current message system time in seconds + + static void setTimeDecodes(bool b); + static void setTimeDecodesSpamThreshold(F32 seconds); + + // message handlers internal to the message systesm + //static void processAssignCircuitCode(LLMessageSystem* msg, void**); + static void processAddCircuitCode(LLMessageSystem* msg, void**); + static void processUseCircuitCode(LLMessageSystem* msg, void**); + static void processError(LLMessageSystem* msg, void**); + + // dispatch llsd message to http node tree + static void dispatch(const std::string& msg_name, + const LLSD& message); + static void dispatch(const std::string& msg_name, + const LLSD& message, + LLHTTPNode::ResponsePtr responsep); + + // this is added to support specific legacy messages and is + // ***not intended for general use*** Si, Gabriel, 2009 + static void dispatchTemplate(const std::string& msg_name, + const LLSD& message, + LLHTTPNode::ResponsePtr responsep); + + void setMessageBans(const LLSD& trusted, const LLSD& untrusted); + + /** + * @brief send an error message to the host. This is a helper method. + * + * @param host Destination host. + * @param agent_id Destination agent id (may be null) + * @param code An HTTP status compatible error code. + * @param token A specific short string based message + * @param id The transactionid/uniqueid/sessionid whatever. + * @param system The hierarchical path to the system (255 bytes) + * @param message Human readable message (1200 bytes) + * @param data Extra info. + * @return Returns value returned from sendReliable(). + */ + S32 sendError( + const LLHost& host, + const LLUUID& agent_id, + S32 code, + const std::string& token, + const LLUUID& id, + const std::string& system, + const std::string& message, + const LLSD& data); + + // Check UDP messages and pump http_pump to receive HTTP messages. + bool checkAllMessages(LockMessageChecker&, S64 frame_count, LLPumpIO* http_pump); + + // Moved to allow access from LLTemplateMessageDispatcher + void clearReceiveState(); + + // This will cause all trust queries to return true until the next message + // is read: use with caution! + void receivedMessageFromTrustedSender(); + private: typedef boost::function<void(S32)> UntrustedCallback_t; void sendUntrustedSimulatorMessageCoro(std::string url, std::string message, LLSD body, UntrustedCallback_t callback); - bool mLastMessageFromTrustedMessageService; - - // The mCircuitCodes is a map from circuit codes to session - // ids. This allows us to verify sessions on connect. - typedef std::map<U32, LLUUID> code_session_map_t; - code_session_map_t mCircuitCodes; + bool mLastMessageFromTrustedMessageService; - // Viewers need to track a process session in order to make sure - // that no one gives them a bad circuit code. - LLUUID mSessionID; - - void addTemplate(LLMessageTemplate *templatep); - bool decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template ); + // The mCircuitCodes is a map from circuit codes to session + // ids. This allows us to verify sessions on connect. + typedef std::map<U32, LLUUID> code_session_map_t; + code_session_map_t mCircuitCodes; - void logMsgFromInvalidCircuit( const LLHost& sender, bool recv_reliable ); - void logTrustedMsgFromUntrustedCircuit( const LLHost& sender ); - void logValidMsg(LLCircuitData *cdp, const LLHost& sender, bool recv_reliable, bool recv_resent, bool recv_acks ); - void logRanOffEndOfPacket( const LLHost& sender ); + // Viewers need to track a process session in order to make sure + // that no one gives them a bad circuit code. + LLUUID mSessionID; - class LLMessageCountInfo - { - public: - U32 mMessageNum; - U32 mMessageBytes; - bool mInvalid; - }; + void addTemplate(LLMessageTemplate *templatep); + bool decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template ); - LLMessagePollInfo *mPollInfop; + void logMsgFromInvalidCircuit( const LLHost& sender, bool recv_reliable ); + void logTrustedMsgFromUntrustedCircuit( const LLHost& sender ); + void logValidMsg(LLCircuitData *cdp, const LLHost& sender, bool recv_reliable, bool recv_resent, bool recv_acks ); + void logRanOffEndOfPacket( const LLHost& sender ); + + class LLMessageCountInfo + { + public: + U32 mMessageNum; + U32 mMessageBytes; + bool mInvalid; + }; - U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE]; - U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE]; - S32 mTrueReceiveSize; + LLMessagePollInfo *mPollInfop; - // Must be valid during decode - - bool mbError; - S32 mErrorCode; + U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE]; + U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE]; + S32 mTrueReceiveSize; - F64Seconds mResendDumpTime; // The last time we dumped resends + // Must be valid during decode - LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM]; - S32 mNumMessageCounts; - F32Seconds mReceiveTime; - F32Seconds mMaxMessageTime; // Max number of seconds for processing messages - S32 mMaxMessageCounts; // Max number of messages to process before dumping. - F64Seconds mMessageCountTime; + bool mbError; + S32 mErrorCode; - F64Seconds mCurrentMessageTime; // The current "message system time" (updated the first call to checkMessages after a resetReceiveCount + F64Seconds mResendDumpTime; // The last time we dumped resends - // message system exceptions - typedef std::pair<msg_exception_callback, void*> exception_t; - typedef std::map<EMessageException, exception_t> callbacks_t; - callbacks_t mExceptionCallbacks; + LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM]; + S32 mNumMessageCounts; + F32Seconds mReceiveTime; + F32Seconds mMaxMessageTime; // Max number of seconds for processing messages + S32 mMaxMessageCounts; // Max number of messages to process before dumping. + F64Seconds mMessageCountTime; - // stuff for logging - LLTimer mMessageSystemTimer; + F64Seconds mCurrentMessageTime; // The current "message system time" (updated the first call to checkMessages after a resetReceiveCount - static F32 mTimeDecodesSpamThreshold; // If mTimeDecodes is on, all this many seconds for each msg decode before spamming - static bool mTimeDecodes; // Measure time for all message decodes if true; + // message system exceptions + typedef std::pair<msg_exception_callback, void*> exception_t; + typedef std::map<EMessageException, exception_t> callbacks_t; + callbacks_t mExceptionCallbacks; - msg_timing_callback mTimingCallback; - void* mTimingCallbackData; + // stuff for logging + LLTimer mMessageSystemTimer; - void init(); // ctor shared initialisation. + static F32 mTimeDecodesSpamThreshold; // If mTimeDecodes is on, all this many seconds for each msg decode before spamming + static bool mTimeDecodes; // Measure time for all message decodes if true; - LLHost mLastSender; - LLHost mLastReceivingIF; - S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.) - TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting) + msg_timing_callback mTimingCallback; + void* mTimingCallbackData; - LLMessageBuilder* mMessageBuilder; - LLTemplateMessageBuilder* mTemplateMessageBuilder; - LLSDMessageBuilder* mLLSDMessageBuilder; - LLMessageReaderPointer mMessageReader; - LLTemplateMessageReader* mTemplateMessageReader; - LLSDMessageReader* mLLSDMessageReader; + void init(); // ctor shared initialisation. - friend class LLMessageHandlerBridge; - friend class LockMessageChecker; + LLHost mLastSender; + LLHost mLastReceivingIF; + S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.) + TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting) - bool callHandler(const char *name, bool trustedSource, - LLMessageSystem* msg); + LLMessageBuilder* mMessageBuilder; + LLTemplateMessageBuilder* mTemplateMessageBuilder; + LLSDMessageBuilder* mLLSDMessageBuilder; + LLMessageReaderPointer mMessageReader; + LLTemplateMessageReader* mTemplateMessageReader; + LLSDMessageReader* mLLSDMessageReader; + friend class LLMessageHandlerBridge; + friend class LockMessageChecker; - /** Find, create or revive circuit for host as needed */ - LLCircuitData* findCircuit(const LLHost& host, bool resetPacketId); + bool callHandler(const char *name, bool trustedSource, + LLMessageSystem* msg); + + + /** Find, create or revive circuit for host as needed */ + LLCircuitData* findCircuit(const LLHost& host, bool resetPacketId); }; @@ -957,17 +957,17 @@ private: // if a patch is available in the message template checksum verification. // Return true if able to initialize system. bool start_messaging_system( - const std::string& template_name, - U32 port, - S32 version_major, - S32 version_minor, - S32 version_patch, - bool b_dump_prehash_file, - const std::string& secret, - const LLUseCircuitCodeResponder* responder, - bool failure_is_fatal, - const F32 circuit_heartbeat_interval, - const F32 circuit_timeout); + const std::string& template_name, + U32 port, + S32 version_major, + S32 version_minor, + S32 version_patch, + bool b_dump_prehash_file, + const std::string& secret, + const LLUseCircuitCodeResponder* responder, + bool failure_is_fatal, + const F32 circuit_heartbeat_interval, + const F32 circuit_timeout); void end_messaging_system(bool print_summary = true); @@ -983,179 +983,179 @@ void null_message_callback(LLMessageSystem *msg, void **data); static inline void *htolememcpy(void *vs, const void *vct, EMsgVariableType type, size_t n) { - char *s = (char *)vs; - const char *ct = (const char *)vct; + char *s = (char *)vs; + const char *ct = (const char *)vct; #ifdef LL_BIG_ENDIAN - S32 i, length; + S32 i, length; #endif - switch(type) - { - case MVT_FIXED: - case MVT_VARIABLE: - case MVT_U8: - case MVT_S8: - case MVT_BOOL: - case MVT_LLUUID: - case MVT_IP_ADDR: // these two are swizzled in the getters and setters - case MVT_IP_PORT: // these two are swizzled in the getters and setters - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ - - case MVT_U16: - case MVT_S16: - if (n != 2) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + switch(type) + { + case MVT_FIXED: + case MVT_VARIABLE: + case MVT_U8: + case MVT_S8: + case MVT_BOOL: + case MVT_LLUUID: + case MVT_IP_ADDR: // these two are swizzled in the getters and setters + case MVT_IP_PORT: // these two are swizzled in the getters and setters + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + + case MVT_U16: + case MVT_S16: + if (n != 2) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - *(s + 1) = *(ct); - *(s) = *(ct + 1); - return(vs); + *(s + 1) = *(ct); + *(s) = *(ct + 1); + return(vs); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_U32: - case MVT_S32: - case MVT_F32: - if (n != 4) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_U32: + case MVT_S32: + case MVT_F32: + if (n != 4) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - *(s + 3) = *(ct); - *(s + 2) = *(ct + 1); - *(s + 1) = *(ct + 2); - *(s) = *(ct + 3); - return(vs); + *(s + 3) = *(ct); + *(s + 2) = *(ct + 1); + *(s + 1) = *(ct + 2); + *(s) = *(ct + 3); + return(vs); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_U64: - case MVT_S64: - case MVT_F64: - if (n != 8) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_U64: + case MVT_S64: + case MVT_F64: + if (n != 8) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - *(s + 7) = *(ct); - *(s + 6) = *(ct + 1); - *(s + 5) = *(ct + 2); - *(s + 4) = *(ct + 3); - *(s + 3) = *(ct + 4); - *(s + 2) = *(ct + 5); - *(s + 1) = *(ct + 6); - *(s) = *(ct + 7); - return(vs); + *(s + 7) = *(ct); + *(s + 6) = *(ct + 1); + *(s + 5) = *(ct + 2); + *(s + 4) = *(ct + 3); + *(s + 3) = *(ct + 4); + *(s + 2) = *(ct + 5); + *(s + 1) = *(ct + 6); + *(s) = *(ct + 7); + return(vs); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_LLVector3: - case MVT_LLQuaternion: // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0) - if (n != 12) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_LLVector3: + case MVT_LLQuaternion: // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0) + if (n != 12) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - htolememcpy(s + 8, ct + 8, MVT_F32, 4); - htolememcpy(s + 4, ct + 4, MVT_F32, 4); - return(htolememcpy(s, ct, MVT_F32, 4)); + htolememcpy(s + 8, ct + 8, MVT_F32, 4); + htolememcpy(s + 4, ct + 4, MVT_F32, 4); + return(htolememcpy(s, ct, MVT_F32, 4)); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_LLVector3d: - if (n != 24) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_LLVector3d: + if (n != 24) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - htolememcpy(s + 16, ct + 16, MVT_F64, 8); - htolememcpy(s + 8, ct + 8, MVT_F64, 8); - return(htolememcpy(s, ct, MVT_F64, 8)); + htolememcpy(s + 16, ct + 16, MVT_F64, 8); + htolememcpy(s + 8, ct + 8, MVT_F64, 8); + return(htolememcpy(s, ct, MVT_F64, 8)); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_LLVector4: - if (n != 16) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_LLVector4: + if (n != 16) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - htolememcpy(s + 12, ct + 12, MVT_F32, 4); - htolememcpy(s + 8, ct + 8, MVT_F32, 4); - htolememcpy(s + 4, ct + 4, MVT_F32, 4); - return(htolememcpy(s, ct, MVT_F32, 4)); + htolememcpy(s + 12, ct + 12, MVT_F32, 4); + htolememcpy(s + 8, ct + 8, MVT_F32, 4); + htolememcpy(s + 4, ct + 4, MVT_F32, 4); + return(htolememcpy(s, ct, MVT_F32, 4)); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_U16Vec3: - if (n != 6) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_U16Vec3: + if (n != 6) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - htolememcpy(s + 4, ct + 4, MVT_U16, 2); - htolememcpy(s + 2, ct + 2, MVT_U16, 2); - return(htolememcpy(s, ct, MVT_U16, 2)); + htolememcpy(s + 4, ct + 4, MVT_U16, 2); + htolememcpy(s + 2, ct + 2, MVT_U16, 2); + return(htolememcpy(s, ct, MVT_U16, 2)); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_U16Quat: - if (n != 8) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_U16Quat: + if (n != 8) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - htolememcpy(s + 6, ct + 6, MVT_U16, 2); - htolememcpy(s + 4, ct + 4, MVT_U16, 2); - htolememcpy(s + 2, ct + 2, MVT_U16, 2); - return(htolememcpy(s, ct, MVT_U16, 2)); + htolememcpy(s + 6, ct + 6, MVT_U16, 2); + htolememcpy(s + 4, ct + 4, MVT_U16, 2); + htolememcpy(s + 2, ct + 2, MVT_U16, 2); + return(htolememcpy(s, ct, MVT_U16, 2)); #else - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ #endif - case MVT_S16Array: - if (n % 2) - { - LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; - } + case MVT_S16Array: + if (n % 2) + { + LL_ERRS() << "Size argument passed to htolememcpy doesn't match swizzle type size" << LL_ENDL; + } #ifdef LL_BIG_ENDIAN - length = n % 2; - for (i = 1; i < length; i++) - { - htolememcpy(s + i*2, ct + i*2, MVT_S16, 2); - } - return(htolememcpy(s, ct, MVT_S16, 2)); + length = n % 2; + for (i = 1; i < length; i++) + { + htolememcpy(s + i*2, ct + i*2, MVT_S16, 2); + } + return(htolememcpy(s, ct, MVT_S16, 2)); #else - return(memcpy(s,ct,n)); + return(memcpy(s,ct,n)); #endif - default: - return(memcpy(s,ct,n)); /* Flawfinder: ignore */ - } + default: + return(memcpy(s,ct,n)); /* Flawfinder: ignore */ + } } inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n) { - return(htolememcpy(s,ct,type, n)); + return(htolememcpy(s,ct,type, n)); } inline const LLHost& LLMessageSystem::getReceivingInterface() const {return mLastReceivingIF;} -inline U32 LLMessageSystem::getSenderIP() const +inline U32 LLMessageSystem::getSenderIP() const { - return mLastSender.getAddress(); + return mLastSender.getAddress(); } inline U32 LLMessageSystem::getSenderPort() const { - return mLastSender.getPort(); + return mLastSender.getPort(); } @@ -1165,7 +1165,7 @@ inline U32 LLMessageSystem::getSenderPort() const inline S32 LLMessageSystem::sendMessage(const U32 circuit) { - return sendMessage(findHost(circuit)); + return sendMessage(findHost(circuit)); } #endif diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 4dccacb889..c264a9f086 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -412,7 +412,7 @@ char const* const _PREHASH_GlobalX = LLMessageStringTable::getInstance()->getStr char const* const _PREHASH_GlobalY = LLMessageStringTable::getInstance()->getString("GlobalY"); char const* const _PREHASH_CopyRotates = LLMessageStringTable::getInstance()->getString("CopyRotates"); char const* const _PREHASH_KickUserAck = LLMessageStringTable::getInstance()->getString("KickUserAck"); -char const* const _PREHASH_TopPick = LLMessageStringTable::getInstance()->getString("TopPick"); //legacy var need to be deleted -angela +char const* const _PREHASH_TopPick = LLMessageStringTable::getInstance()->getString("TopPick"); //legacy var need to be deleted -angela char const* const _PREHASH_SessionID = LLMessageStringTable::getInstance()->getString("SessionID"); char const* const _PREHASH_GlobalZ = LLMessageStringTable::getInstance()->getString("GlobalZ"); char const* const _PREHASH_DeclineFriendship = LLMessageStringTable::getInstance()->getString("DeclineFriendship"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index a393bbabb2..1d30b69b67 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/message_string_table.cpp b/indra/llmessage/message_string_table.cpp index 8bcc452e3f..6d2157eec9 100644 --- a/indra/llmessage/message_string_table.cpp +++ b/indra/llmessage/message_string_table.cpp @@ -1,25 +1,25 @@ -/** +/** * @file message_string_table.cpp * @brief static string table for message template * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,27 +29,27 @@ #include "llerror.h" #include "message.h" -inline U32 message_hash_my_string(const char *str) +inline U32 message_hash_my_string(const char *str) { - U32 retval = 0; - while (*str++) - { - retval += *str; - retval <<= 1; - } - return (retval % MESSAGE_NUMBER_OF_HASH_BUCKETS); + U32 retval = 0; + while (*str++) + { + retval += *str; + retval <<= 1; + } + return (retval % MESSAGE_NUMBER_OF_HASH_BUCKETS); } LLMessageStringTable::LLMessageStringTable() -: mUsed(0) +: mUsed(0) { - for (U32 i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) - { - mEmpty[i] = true; - mString[i][0] = 0; - } + for (U32 i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) + { + mEmpty[i] = true; + mString[i][0] = 0; + } } @@ -59,33 +59,33 @@ LLMessageStringTable::~LLMessageStringTable() char* LLMessageStringTable::getString(const char *str) { - U32 hash_value = message_hash_my_string(str); - while (!mEmpty[hash_value]) - { - if (!strncmp(str, mString[hash_value], MESSAGE_MAX_STRINGS_LENGTH)) - { - return mString[hash_value]; - } - else - { - hash_value++; - hash_value %= MESSAGE_NUMBER_OF_HASH_BUCKETS; - } - } - // not found, so add! - strncpy(mString[hash_value], str, MESSAGE_MAX_STRINGS_LENGTH); /* Flawfinder: ignore */ - mString[hash_value][MESSAGE_MAX_STRINGS_LENGTH - 1] = 0; - mEmpty[hash_value] = false; - mUsed++; - if (mUsed >= MESSAGE_NUMBER_OF_HASH_BUCKETS - 1) - { - U32 i; - LL_INFOS() << "Dumping string table before crashing on HashTable full!" << LL_ENDL; - for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) - { - LL_INFOS() << "Entry #" << i << ": " << mString[i] << LL_ENDL; - } - } - return mString[hash_value]; + U32 hash_value = message_hash_my_string(str); + while (!mEmpty[hash_value]) + { + if (!strncmp(str, mString[hash_value], MESSAGE_MAX_STRINGS_LENGTH)) + { + return mString[hash_value]; + } + else + { + hash_value++; + hash_value %= MESSAGE_NUMBER_OF_HASH_BUCKETS; + } + } + // not found, so add! + strncpy(mString[hash_value], str, MESSAGE_MAX_STRINGS_LENGTH); /* Flawfinder: ignore */ + mString[hash_value][MESSAGE_MAX_STRINGS_LENGTH - 1] = 0; + mEmpty[hash_value] = false; + mUsed++; + if (mUsed >= MESSAGE_NUMBER_OF_HASH_BUCKETS - 1) + { + U32 i; + LL_INFOS() << "Dumping string table before crashing on HashTable full!" << LL_ENDL; + for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) + { + LL_INFOS() << "Entry #" << i << ": " << mString[i] << LL_ENDL; + } + } + return mString[hash_value]; } diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index 443303e45a..1c49f9be36 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -1,25 +1,25 @@ -/** +/** * @file net.cpp * @brief Cross-platform routines for sending and receiving packets. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,12 +34,12 @@ #if LL_WINDOWS #include "llwin32headerslean.h" #else - #include <sys/types.h> - #include <sys/socket.h> - #include <netinet/in.h> - #include <arpa/inet.h> - #include <fcntl.h> - #include <errno.h> + #include <sys/types.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + #include <fcntl.h> + #include <errno.h> #endif // linden library includes @@ -77,106 +77,106 @@ const char* LOOPBACK_ADDRESS_STRING = "127.0.0.1"; const char* BROADCAST_ADDRESS_STRING = "255.255.255.255"; #if LL_DARWIN - // macOS returns an error when trying to set these to 400000. Smaller values succeed. - const int SEND_BUFFER_SIZE = 200000; - const int RECEIVE_BUFFER_SIZE = 200000; + // macOS returns an error when trying to set these to 400000. Smaller values succeed. + const int SEND_BUFFER_SIZE = 200000; + const int RECEIVE_BUFFER_SIZE = 200000; #else // LL_DARWIN - const int SEND_BUFFER_SIZE = 400000; - const int RECEIVE_BUFFER_SIZE = 400000; + const int SEND_BUFFER_SIZE = 400000; + const int RECEIVE_BUFFER_SIZE = 400000; #endif // LL_DARWIN // universal functions (cross-platform) LLHost get_sender() { - return LLHost(stSrcAddr.sin_addr.s_addr, ntohs(stSrcAddr.sin_port)); + return LLHost(stSrcAddr.sin_addr.s_addr, ntohs(stSrcAddr.sin_port)); } -U32 get_sender_ip(void) +U32 get_sender_ip(void) { - return stSrcAddr.sin_addr.s_addr; + return stSrcAddr.sin_addr.s_addr; } -U32 get_sender_port() +U32 get_sender_port() { - return ntohs(stSrcAddr.sin_port); + return ntohs(stSrcAddr.sin_port); } LLHost get_receiving_interface() { - return LLHost(gsnReceivingIFAddr, INVALID_PORT); + return LLHost(gsnReceivingIFAddr, INVALID_PORT); } U32 get_receiving_interface_ip(void) { - return gsnReceivingIFAddr; + return gsnReceivingIFAddr; } const char* u32_to_ip_string(U32 ip) { - static char buffer[MAXADDRSTR]; /* Flawfinder: ignore */ - - // Convert the IP address into a string - in_addr in; - in.s_addr = ip; - char* result = inet_ntoa(in); - - // NULL indicates error in conversion - if (result != NULL) - { - strncpy( buffer, result, MAXADDRSTR ); /* Flawfinder: ignore */ - buffer[MAXADDRSTR-1] = '\0'; - return buffer; - } - else - { - return "(bad IP addr)"; - } + static char buffer[MAXADDRSTR]; /* Flawfinder: ignore */ + + // Convert the IP address into a string + in_addr in; + in.s_addr = ip; + char* result = inet_ntoa(in); + + // NULL indicates error in conversion + if (result != NULL) + { + strncpy( buffer, result, MAXADDRSTR ); /* Flawfinder: ignore */ + buffer[MAXADDRSTR-1] = '\0'; + return buffer; + } + else + { + return "(bad IP addr)"; + } } // Returns ip_string if successful, NULL if not. Copies into ip_string char *u32_to_ip_string(U32 ip, char *ip_string) { - char *result; - in_addr in; - - // Convert the IP address into a string - in.s_addr = ip; - result = inet_ntoa(in); - - // NULL indicates error in conversion - if (result != NULL) - { - //the function signature needs to change to pass in the lengfth of first and last. - strcpy(ip_string, result); /*Flawfinder: ignore*/ - return ip_string; - } - else - { - return NULL; - } + char *result; + in_addr in; + + // Convert the IP address into a string + in.s_addr = ip; + result = inet_ntoa(in); + + // NULL indicates error in conversion + if (result != NULL) + { + //the function signature needs to change to pass in the lengfth of first and last. + strcpy(ip_string, result); /*Flawfinder: ignore*/ + return ip_string; + } + else + { + return NULL; + } } // Wrapper for inet_addr() U32 ip_string_to_u32(const char* ip_string) { - // *NOTE: Windows doesn't support inet_aton(), so we are using - // inet_addr(). Unfortunately, INADDR_NONE == INADDR_BROADCAST, so - // we have to check whether the input is a broadcast address before - // deciding that @ip_string is invalid. - // - // Also, our definition of INVALID_HOST_IP_ADDRESS doesn't allow us to - // use wildcard addresses. -Ambroff - U32 ip = inet_addr(ip_string); - if (ip == INADDR_NONE - && strncmp(ip_string, BROADCAST_ADDRESS_STRING, MAXADDRSTR) != 0) - { - LL_WARNS() << "ip_string_to_u32() failed, Error: Invalid IP string '" << ip_string << "'" << LL_ENDL; - return INVALID_HOST_IP_ADDRESS; - } - return ip; + // *NOTE: Windows doesn't support inet_aton(), so we are using + // inet_addr(). Unfortunately, INADDR_NONE == INADDR_BROADCAST, so + // we have to check whether the input is a broadcast address before + // deciding that @ip_string is invalid. + // + // Also, our definition of INVALID_HOST_IP_ADDRESS doesn't allow us to + // use wildcard addresses. -Ambroff + U32 ip = inet_addr(ip_string); + if (ip == INADDR_NONE + && strncmp(ip_string, BROADCAST_ADDRESS_STRING, MAXADDRSTR) != 0) + { + LL_WARNS() << "ip_string_to_u32() failed, Error: Invalid IP string '" << ip_string << "'" << LL_ENDL; + return INVALID_HOST_IP_ADDRESS; + } + return ip; } @@ -186,194 +186,194 @@ U32 ip_string_to_u32(const char* ip_string) #if LL_WINDOWS -S32 start_net(S32& socket_out, int& nPort) -{ - // Create socket, make non-blocking - // Init WinSock - int nRet; - int hSocket; - - int snd_size = SEND_BUFFER_SIZE; - int rec_size = RECEIVE_BUFFER_SIZE; - int buff_size = 4; - - // Initialize windows specific stuff - if (WSAStartup(0x0202, &stWSAData)) - { - S32 err = WSAGetLastError(); - WSACleanup(); - LL_WARNS("AppInit") << "Windows Sockets initialization failed, err " << err << LL_ENDL; - return 1; - } - - // Get a datagram socket - hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0); - if (hSocket == INVALID_SOCKET) - { - S32 err = WSAGetLastError(); - WSACleanup(); - LL_WARNS("AppInit") << "socket() failed, err " << err << LL_ENDL; - return 2; - } - - // Name the socket (assign the local port number to receive on) - stLclAddr.sin_family = AF_INET; - stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); - stLclAddr.sin_port = htons(nPort); - - S32 attempt_port = nPort; - LL_DEBUGS("AppInit") << "attempting to connect on port " << attempt_port << LL_ENDL; - nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); - - if (nRet == SOCKET_ERROR) - { - // If we got an address in use error... - if (WSAGetLastError() == WSAEADDRINUSE) - { - // Try all ports from PORT_DISCOVERY_RANGE_MIN to PORT_DISCOVERY_RANGE_MAX - for(attempt_port = PORT_DISCOVERY_RANGE_MIN; - attempt_port <= PORT_DISCOVERY_RANGE_MAX; - attempt_port++) - { - stLclAddr.sin_port = htons(attempt_port); - LL_DEBUGS("AppInit") << "trying port " << attempt_port << LL_ENDL; - nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); - - if (!(nRet == SOCKET_ERROR && - WSAGetLastError() == WSAEADDRINUSE)) - { - break; - } - } - - if (nRet == SOCKET_ERROR) - { - LL_WARNS("AppInit") << "startNet() : Couldn't find available network port." << LL_ENDL; - // Fail gracefully here in release - return 3; - } - } - else - // Some other socket error - { - LL_WARNS("AppInit") << llformat("bind() port: %d failed, Err: %d\n", nPort, WSAGetLastError()) << LL_ENDL; - // Fail gracefully in release. - return 4; - } - } - - sockaddr_in socket_address; - S32 socket_address_size = sizeof(socket_address); - getsockname(hSocket, (SOCKADDR*) &socket_address, &socket_address_size); - attempt_port = ntohs(socket_address.sin_port); - - LL_INFOS("AppInit") << "connected on port " << attempt_port << LL_ENDL; - nPort = attempt_port; - - // Set socket to be non-blocking - unsigned long argp = 1; - nRet = ioctlsocket (hSocket, FIONBIO, &argp); - if (nRet == SOCKET_ERROR) - { - printf("Failed to set socket non-blocking, Err: %d\n", - WSAGetLastError()); - } - - // set a large receive buffer - nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size); - if (nRet) - { - LL_INFOS("AppInit") << "Can't set receive buffer size!" << LL_ENDL; - } - - nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size); - if (nRet) - { - LL_INFOS("AppInit") << "Can't set send buffer size!" << LL_ENDL; - } - - getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size); - getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size); - - LL_DEBUGS("AppInit") << "startNet - receive buffer size : " << rec_size << LL_ENDL; - LL_DEBUGS("AppInit") << "startNet - send buffer size : " << snd_size << LL_ENDL; - - // Setup a destination address - stDstAddr.sin_family = AF_INET; - stDstAddr.sin_addr.s_addr = INVALID_HOST_IP_ADDRESS; - stDstAddr.sin_port = htons(nPort); - - socket_out = hSocket; - return 0; +S32 start_net(S32& socket_out, int& nPort) +{ + // Create socket, make non-blocking + // Init WinSock + int nRet; + int hSocket; + + int snd_size = SEND_BUFFER_SIZE; + int rec_size = RECEIVE_BUFFER_SIZE; + int buff_size = 4; + + // Initialize windows specific stuff + if (WSAStartup(0x0202, &stWSAData)) + { + S32 err = WSAGetLastError(); + WSACleanup(); + LL_WARNS("AppInit") << "Windows Sockets initialization failed, err " << err << LL_ENDL; + return 1; + } + + // Get a datagram socket + hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0); + if (hSocket == INVALID_SOCKET) + { + S32 err = WSAGetLastError(); + WSACleanup(); + LL_WARNS("AppInit") << "socket() failed, err " << err << LL_ENDL; + return 2; + } + + // Name the socket (assign the local port number to receive on) + stLclAddr.sin_family = AF_INET; + stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); + stLclAddr.sin_port = htons(nPort); + + S32 attempt_port = nPort; + LL_DEBUGS("AppInit") << "attempting to connect on port " << attempt_port << LL_ENDL; + nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); + + if (nRet == SOCKET_ERROR) + { + // If we got an address in use error... + if (WSAGetLastError() == WSAEADDRINUSE) + { + // Try all ports from PORT_DISCOVERY_RANGE_MIN to PORT_DISCOVERY_RANGE_MAX + for(attempt_port = PORT_DISCOVERY_RANGE_MIN; + attempt_port <= PORT_DISCOVERY_RANGE_MAX; + attempt_port++) + { + stLclAddr.sin_port = htons(attempt_port); + LL_DEBUGS("AppInit") << "trying port " << attempt_port << LL_ENDL; + nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); + + if (!(nRet == SOCKET_ERROR && + WSAGetLastError() == WSAEADDRINUSE)) + { + break; + } + } + + if (nRet == SOCKET_ERROR) + { + LL_WARNS("AppInit") << "startNet() : Couldn't find available network port." << LL_ENDL; + // Fail gracefully here in release + return 3; + } + } + else + // Some other socket error + { + LL_WARNS("AppInit") << llformat("bind() port: %d failed, Err: %d\n", nPort, WSAGetLastError()) << LL_ENDL; + // Fail gracefully in release. + return 4; + } + } + + sockaddr_in socket_address; + S32 socket_address_size = sizeof(socket_address); + getsockname(hSocket, (SOCKADDR*) &socket_address, &socket_address_size); + attempt_port = ntohs(socket_address.sin_port); + + LL_INFOS("AppInit") << "connected on port " << attempt_port << LL_ENDL; + nPort = attempt_port; + + // Set socket to be non-blocking + unsigned long argp = 1; + nRet = ioctlsocket (hSocket, FIONBIO, &argp); + if (nRet == SOCKET_ERROR) + { + printf("Failed to set socket non-blocking, Err: %d\n", + WSAGetLastError()); + } + + // set a large receive buffer + nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size); + if (nRet) + { + LL_INFOS("AppInit") << "Can't set receive buffer size!" << LL_ENDL; + } + + nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size); + if (nRet) + { + LL_INFOS("AppInit") << "Can't set send buffer size!" << LL_ENDL; + } + + getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size); + getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size); + + LL_DEBUGS("AppInit") << "startNet - receive buffer size : " << rec_size << LL_ENDL; + LL_DEBUGS("AppInit") << "startNet - send buffer size : " << snd_size << LL_ENDL; + + // Setup a destination address + stDstAddr.sin_family = AF_INET; + stDstAddr.sin_addr.s_addr = INVALID_HOST_IP_ADDRESS; + stDstAddr.sin_port = htons(nPort); + + socket_out = hSocket; + return 0; } void end_net(S32& socket_out) { - if (socket_out >= 0) - { - shutdown(socket_out, SD_BOTH); - closesocket(socket_out); - } - WSACleanup(); + if (socket_out >= 0) + { + shutdown(socket_out, SD_BOTH); + closesocket(socket_out); + } + WSACleanup(); } S32 receive_packet(int hSocket, char * receiveBuffer) { - // Receives data asynchronously from the socket set by initNet(). - // Returns the number of bytes received into dataReceived, or zero - // if there is no data received. - int nRet; - int addr_size = sizeof(struct sockaddr_in); - - nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, 0, (struct sockaddr*)&stSrcAddr, &addr_size); - if (nRet == SOCKET_ERROR ) - { - if (WSAEWOULDBLOCK == WSAGetLastError()) - return 0; - if (WSAECONNRESET == WSAGetLastError()) - return 0; - LL_INFOS() << "receivePacket() failed, Error: " << WSAGetLastError() << LL_ENDL; - } - - return nRet; + // Receives data asynchronously from the socket set by initNet(). + // Returns the number of bytes received into dataReceived, or zero + // if there is no data received. + int nRet; + int addr_size = sizeof(struct sockaddr_in); + + nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, 0, (struct sockaddr*)&stSrcAddr, &addr_size); + if (nRet == SOCKET_ERROR ) + { + if (WSAEWOULDBLOCK == WSAGetLastError()) + return 0; + if (WSAECONNRESET == WSAGetLastError()) + return 0; + LL_INFOS() << "receivePacket() failed, Error: " << WSAGetLastError() << LL_ENDL; + } + + return nRet; } // Returns true on success. bool send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort) { - // Sends a packet to the address set in initNet - // - int nRet = 0; - U32 last_error = 0; - - stDstAddr.sin_addr.s_addr = recipient; - stDstAddr.sin_port = htons(nPort); - do - { - nRet = sendto(hSocket, sendBuffer, size, 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr)); - - if (nRet == SOCKET_ERROR ) - { - last_error = WSAGetLastError(); - if (last_error != WSAEWOULDBLOCK) - { - // WSAECONNRESET - I think this is caused by an ICMP "connection refused" - // message being sent back from a Linux box... I'm not finding helpful - // documentation or web pages on this. The question is whether the packet - // actually got sent or not. Based on the structure of this code, I would - // assume it is. JNC 2002.01.18 - if (WSAECONNRESET == WSAGetLastError()) - { - return true; - } - LL_INFOS() << "sendto() failed to " << u32_to_ip_string(recipient) << ":" << nPort - << ", Error " << last_error << LL_ENDL; - } - } - } while ( (nRet == SOCKET_ERROR) - &&(last_error == WSAEWOULDBLOCK)); - - return (nRet != SOCKET_ERROR); + // Sends a packet to the address set in initNet + // + int nRet = 0; + U32 last_error = 0; + + stDstAddr.sin_addr.s_addr = recipient; + stDstAddr.sin_port = htons(nPort); + do + { + nRet = sendto(hSocket, sendBuffer, size, 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr)); + + if (nRet == SOCKET_ERROR ) + { + last_error = WSAGetLastError(); + if (last_error != WSAEWOULDBLOCK) + { + // WSAECONNRESET - I think this is caused by an ICMP "connection refused" + // message being sent back from a Linux box... I'm not finding helpful + // documentation or web pages on this. The question is whether the packet + // actually got sent or not. Based on the structure of this code, I would + // assume it is. JNC 2002.01.18 + if (WSAECONNRESET == WSAGetLastError()) + { + return true; + } + LL_INFOS() << "sendto() failed to " << u32_to_ip_string(recipient) << ":" << nPort + << ", Error " << last_error << LL_ENDL; + } + } + } while ( (nRet == SOCKET_ERROR) + &&(last_error == WSAEWOULDBLOCK)); + + return (nRet != SOCKET_ERROR); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -385,277 +385,277 @@ bool send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i // Create socket, make non-blocking S32 start_net(S32& socket_out, int& nPort) { - int hSocket, nRet; - int snd_size = SEND_BUFFER_SIZE; - int rec_size = RECEIVE_BUFFER_SIZE; - - socklen_t buff_size = 4; - - // Create socket - hSocket = socket(AF_INET, SOCK_DGRAM, 0); - if (hSocket < 0) - { - LL_WARNS() << "socket() failed" << LL_ENDL; - return 1; - } - - if (NET_USE_OS_ASSIGNED_PORT == nPort) - { - // Although bind is not required it will tell us which port we were - // assigned to. - stLclAddr.sin_family = AF_INET; - stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); - stLclAddr.sin_port = htons(0); - LL_INFOS() << "attempting to connect on OS assigned port" << LL_ENDL; - nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); - if (nRet < 0) - { - LL_WARNS() << "Failed to bind on an OS assigned port error: " - << nRet << LL_ENDL; - } - else - { - sockaddr_in socket_info; - socklen_t len = sizeof(sockaddr_in); - int err = getsockname(hSocket, (sockaddr*)&socket_info, &len); - LL_INFOS() << "Get socket returned: " << err << " length " << len << LL_ENDL; - nPort = ntohs(socket_info.sin_port); - LL_INFOS() << "Assigned port: " << nPort << LL_ENDL; - - } - } - else - { - // Name the socket (assign the local port number to receive on) - stLclAddr.sin_family = AF_INET; - stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); - stLclAddr.sin_port = htons(nPort); - U32 attempt_port = nPort; - LL_INFOS() << "attempting to connect on port " << attempt_port << LL_ENDL; - - nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); - if (nRet < 0) - { - // If we got an address in use error... - if (errno == EADDRINUSE) - { - // Try all ports from PORT_DISCOVERY_RANGE_MIN to PORT_DISCOVERY_RANGE_MAX - for(attempt_port = PORT_DISCOVERY_RANGE_MIN; - attempt_port <= PORT_DISCOVERY_RANGE_MAX; - attempt_port++) - { - stLclAddr.sin_port = htons(attempt_port); - LL_INFOS() << "trying port " << attempt_port << LL_ENDL; - nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); - if (!((nRet < 0) && (errno == EADDRINUSE))) - { - break; - } - } - if (nRet < 0) - { - LL_WARNS() << "startNet() : Couldn't find available network port." << LL_ENDL; - // Fail gracefully in release. - return 3; - } - } - // Some other socket error - else - { - LL_WARNS() << llformat ("bind() port: %d failed, Err: %s\n", nPort, strerror(errno)) << LL_ENDL; - // Fail gracefully in release. - return 4; - } - } - LL_INFOS() << "connected on port " << attempt_port << LL_ENDL; - nPort = attempt_port; - } - // Set socket to be non-blocking - fcntl(hSocket, F_SETFL, O_NONBLOCK); - // set a large receive buffer - nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size); - if (nRet) - { - LL_INFOS() << "Can't set receive size!" << LL_ENDL; - } - nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size); - if (nRet) - { - LL_INFOS() << "Can't set send size!" << LL_ENDL; - } - getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size); - getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size); - - LL_INFOS() << "startNet - receive buffer size : " << rec_size << LL_ENDL; - LL_INFOS() << "startNet - send buffer size : " << snd_size << LL_ENDL; + int hSocket, nRet; + int snd_size = SEND_BUFFER_SIZE; + int rec_size = RECEIVE_BUFFER_SIZE; + + socklen_t buff_size = 4; + + // Create socket + hSocket = socket(AF_INET, SOCK_DGRAM, 0); + if (hSocket < 0) + { + LL_WARNS() << "socket() failed" << LL_ENDL; + return 1; + } + + if (NET_USE_OS_ASSIGNED_PORT == nPort) + { + // Although bind is not required it will tell us which port we were + // assigned to. + stLclAddr.sin_family = AF_INET; + stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); + stLclAddr.sin_port = htons(0); + LL_INFOS() << "attempting to connect on OS assigned port" << LL_ENDL; + nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); + if (nRet < 0) + { + LL_WARNS() << "Failed to bind on an OS assigned port error: " + << nRet << LL_ENDL; + } + else + { + sockaddr_in socket_info; + socklen_t len = sizeof(sockaddr_in); + int err = getsockname(hSocket, (sockaddr*)&socket_info, &len); + LL_INFOS() << "Get socket returned: " << err << " length " << len << LL_ENDL; + nPort = ntohs(socket_info.sin_port); + LL_INFOS() << "Assigned port: " << nPort << LL_ENDL; + + } + } + else + { + // Name the socket (assign the local port number to receive on) + stLclAddr.sin_family = AF_INET; + stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); + stLclAddr.sin_port = htons(nPort); + U32 attempt_port = nPort; + LL_INFOS() << "attempting to connect on port " << attempt_port << LL_ENDL; + + nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); + if (nRet < 0) + { + // If we got an address in use error... + if (errno == EADDRINUSE) + { + // Try all ports from PORT_DISCOVERY_RANGE_MIN to PORT_DISCOVERY_RANGE_MAX + for(attempt_port = PORT_DISCOVERY_RANGE_MIN; + attempt_port <= PORT_DISCOVERY_RANGE_MAX; + attempt_port++) + { + stLclAddr.sin_port = htons(attempt_port); + LL_INFOS() << "trying port " << attempt_port << LL_ENDL; + nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); + if (!((nRet < 0) && (errno == EADDRINUSE))) + { + break; + } + } + if (nRet < 0) + { + LL_WARNS() << "startNet() : Couldn't find available network port." << LL_ENDL; + // Fail gracefully in release. + return 3; + } + } + // Some other socket error + else + { + LL_WARNS() << llformat ("bind() port: %d failed, Err: %s\n", nPort, strerror(errno)) << LL_ENDL; + // Fail gracefully in release. + return 4; + } + } + LL_INFOS() << "connected on port " << attempt_port << LL_ENDL; + nPort = attempt_port; + } + // Set socket to be non-blocking + fcntl(hSocket, F_SETFL, O_NONBLOCK); + // set a large receive buffer + nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size); + if (nRet) + { + LL_INFOS() << "Can't set receive size!" << LL_ENDL; + } + nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size); + if (nRet) + { + LL_INFOS() << "Can't set send size!" << LL_ENDL; + } + getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size); + getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size); + + LL_INFOS() << "startNet - receive buffer size : " << rec_size << LL_ENDL; + LL_INFOS() << "startNet - send buffer size : " << snd_size << LL_ENDL; #if LL_LINUX - // Turn on recipient address tracking - { - int use_pktinfo = 1; - if( setsockopt( hSocket, SOL_IP, IP_PKTINFO, &use_pktinfo, sizeof(use_pktinfo) ) == -1 ) - { - LL_WARNS() << "No IP_PKTINFO available" << LL_ENDL; - } - else - { - LL_INFOS() << "IP_PKKTINFO enabled" << LL_ENDL; - } - } + // Turn on recipient address tracking + { + int use_pktinfo = 1; + if( setsockopt( hSocket, SOL_IP, IP_PKTINFO, &use_pktinfo, sizeof(use_pktinfo) ) == -1 ) + { + LL_WARNS() << "No IP_PKTINFO available" << LL_ENDL; + } + else + { + LL_INFOS() << "IP_PKKTINFO enabled" << LL_ENDL; + } + } #endif - // Setup a destination address - char achMCAddr[MAXADDRSTR] = "127.0.0.1"; /* Flawfinder: ignore */ - stDstAddr.sin_family = AF_INET; - stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr); - stDstAddr.sin_port = htons(nPort); + // Setup a destination address + char achMCAddr[MAXADDRSTR] = "127.0.0.1"; /* Flawfinder: ignore */ + stDstAddr.sin_family = AF_INET; + stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr); + stDstAddr.sin_port = htons(nPort); - socket_out = hSocket; - return 0; + socket_out = hSocket; + return 0; } void end_net(S32& socket_out) { - if (socket_out >= 0) - { - close(socket_out); - } + if (socket_out >= 0) + { + close(socket_out); + } } #if LL_LINUX static int recvfrom_destip( int socket, void *buf, int len, struct sockaddr *from, socklen_t *fromlen, U32 *dstip ) { - int size; - struct iovec iov[1]; - char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))]; - struct cmsghdr *cmsgptr; - struct msghdr msg = {0}; - - iov[0].iov_base = buf; - iov[0].iov_len = len; - - memset(&msg, 0, sizeof msg); - msg.msg_name = from; - msg.msg_namelen = *fromlen; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = &cmsg; - msg.msg_controllen = sizeof(cmsg); - - size = recvmsg(socket, &msg, 0); - - if (size == -1) - { - return -1; - } - - for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr)) - { - if( cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO ) - { - in_pktinfo *pktinfo = (in_pktinfo *)CMSG_DATA(cmsgptr); - if( pktinfo ) - { - // Two choices. routed and specified. ipi_addr is routed, ipi_spec_dst is - // routed. We should stay with specified until we go to multiple - // interfaces - *dstip = pktinfo->ipi_spec_dst.s_addr; - } - } - } - - return size; + int size; + struct iovec iov[1]; + char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))]; + struct cmsghdr *cmsgptr; + struct msghdr msg = {0}; + + iov[0].iov_base = buf; + iov[0].iov_len = len; + + memset(&msg, 0, sizeof msg); + msg.msg_name = from; + msg.msg_namelen = *fromlen; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = &cmsg; + msg.msg_controllen = sizeof(cmsg); + + size = recvmsg(socket, &msg, 0); + + if (size == -1) + { + return -1; + } + + for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr)) + { + if( cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO ) + { + in_pktinfo *pktinfo = (in_pktinfo *)CMSG_DATA(cmsgptr); + if( pktinfo ) + { + // Two choices. routed and specified. ipi_addr is routed, ipi_spec_dst is + // routed. We should stay with specified until we go to multiple + // interfaces + *dstip = pktinfo->ipi_spec_dst.s_addr; + } + } + } + + return size; } #endif int receive_packet(int hSocket, char * receiveBuffer) { - // Receives data asynchronously from the socket set by initNet(). - // Returns the number of bytes received into dataReceived, or zero - // if there is no data received. - // or -1 if an error occured! - int nRet; - socklen_t addr_size = sizeof(struct sockaddr_in); + // Receives data asynchronously from the socket set by initNet(). + // Returns the number of bytes received into dataReceived, or zero + // if there is no data received. + // or -1 if an error occured! + int nRet; + socklen_t addr_size = sizeof(struct sockaddr_in); - gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS; + gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS; #if LL_LINUX - nRet = recvfrom_destip(hSocket, receiveBuffer, NET_BUFFER_SIZE, (struct sockaddr*)&stSrcAddr, &addr_size, &gsnReceivingIFAddr); -#else - int recv_flags = 0; - nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, recv_flags, (struct sockaddr*)&stSrcAddr, &addr_size); + nRet = recvfrom_destip(hSocket, receiveBuffer, NET_BUFFER_SIZE, (struct sockaddr*)&stSrcAddr, &addr_size, &gsnReceivingIFAddr); +#else + int recv_flags = 0; + nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, recv_flags, (struct sockaddr*)&stSrcAddr, &addr_size); #endif - if (nRet == -1) - { - // To maintain consistency with the Windows implementation, return a zero for size on error. - return 0; - } + if (nRet == -1) + { + // To maintain consistency with the Windows implementation, return a zero for size on error. + return 0; + } - // Uncomment for testing if/when implementing for Mac or Windows: - // LL_INFOS() << "Received datagram to in addr " << u32_to_ip_string(get_receiving_interface_ip()) << LL_ENDL; + // Uncomment for testing if/when implementing for Mac or Windows: + // LL_INFOS() << "Received datagram to in addr " << u32_to_ip_string(get_receiving_interface_ip()) << LL_ENDL; - return nRet; + return nRet; } bool send_packet(int hSocket, const char * sendBuffer, int size, U32 recipient, int nPort) { - int ret; - bool success; - bool resend; - S32 send_attempts = 0; - - stDstAddr.sin_addr.s_addr = recipient; - stDstAddr.sin_port = htons(nPort); - - do - { - ret = sendto(hSocket, sendBuffer, size, 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr)); - send_attempts++; - - if (ret >= 0) - { - // successful send - success = true; - resend = false; - } - else - { - // send failed, check to see if we should resend - success = false; - - if (errno == EAGAIN) - { - // say nothing, just repeat send - LL_INFOS() << "sendto() reported buffer full, resending (attempt " << send_attempts << ")" << LL_ENDL; - LL_INFOS() << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << LL_ENDL; - resend = true; - } - else if (errno == ECONNREFUSED) - { - // response to ICMP connection refused message on earlier send - LL_INFOS() << "sendto() reported connection refused, resending (attempt " << send_attempts << ")" << LL_ENDL; - LL_INFOS() << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << LL_ENDL; - resend = true; - } - else - { - // some other error - LL_INFOS() << "sendto() failed: " << errno << ", " << strerror(errno) << LL_ENDL; - LL_INFOS() << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << LL_ENDL; - resend = false; - } - } - } - while (resend && send_attempts < 3); - - if (send_attempts >= 3) - { - LL_INFOS() << "sendPacket() bailed out of send!" << LL_ENDL; - return false; - } - - return success; + int ret; + bool success; + bool resend; + S32 send_attempts = 0; + + stDstAddr.sin_addr.s_addr = recipient; + stDstAddr.sin_port = htons(nPort); + + do + { + ret = sendto(hSocket, sendBuffer, size, 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr)); + send_attempts++; + + if (ret >= 0) + { + // successful send + success = true; + resend = false; + } + else + { + // send failed, check to see if we should resend + success = false; + + if (errno == EAGAIN) + { + // say nothing, just repeat send + LL_INFOS() << "sendto() reported buffer full, resending (attempt " << send_attempts << ")" << LL_ENDL; + LL_INFOS() << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << LL_ENDL; + resend = true; + } + else if (errno == ECONNREFUSED) + { + // response to ICMP connection refused message on earlier send + LL_INFOS() << "sendto() reported connection refused, resending (attempt " << send_attempts << ")" << LL_ENDL; + LL_INFOS() << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << LL_ENDL; + resend = true; + } + else + { + // some other error + LL_INFOS() << "sendto() failed: " << errno << ", " << strerror(errno) << LL_ENDL; + LL_INFOS() << inet_ntoa(stDstAddr.sin_addr) << ":" << nPort << LL_ENDL; + resend = false; + } + } + } + while (resend && send_attempts < 3); + + if (send_attempts >= 3) + { + LL_INFOS() << "sendPacket() bailed out of send!" << LL_ENDL; + return false; + } + + return success; } #endif diff --git a/indra/llmessage/net.h b/indra/llmessage/net.h index a873026fa4..c41f3bb89f 100644 --- a/indra/llmessage/net.h +++ b/indra/llmessage/net.h @@ -1,30 +1,30 @@ -/** +/** * @file net.h * @brief Cross platform UDP network code. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef LL_NET_H +#ifndef LL_NET_H #define LL_NET_H class LLTimer; @@ -37,24 +37,24 @@ class LLHost; // Returns 0 on success, non-zero on error. // Sets socket handler/descriptor, changes nPort if port requested is unavailable. -S32 start_net(S32& socket_out, int& nPort); -void end_net(S32& socket_out); +S32 start_net(S32& socket_out, int& nPort); +void end_net(S32& socket_out); // returns size of packet or -1 in case of error -S32 receive_packet(int hSocket, char * receiveBuffer); +S32 receive_packet(int hSocket, char * receiveBuffer); -bool send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort); // Returns true on success. +bool send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort); // Returns true on success. -//void get_sender(char * tmp); -LLHost get_sender(); -U32 get_sender_port(); -U32 get_sender_ip(void); -LLHost get_receiving_interface(); -U32 get_receiving_interface_ip(void); +//void get_sender(char * tmp); +LLHost get_sender(); +U32 get_sender_port(); +U32 get_sender_ip(void); +LLHost get_receiving_interface(); +U32 get_receiving_interface_ip(void); -const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls -char* u32_to_ip_string(U32 ip, char *ip_string); // NULL on failure, ip_string on success, you must allocate at least MAXADDRSTR chars -U32 ip_string_to_u32(const char* ip_string); // Wrapper for inet_addr() +const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls +char* u32_to_ip_string(U32 ip, char *ip_string); // NULL on failure, ip_string on success, you must allocate at least MAXADDRSTR chars +U32 ip_string_to_u32(const char* ip_string); // Wrapper for inet_addr() extern const char* LOOPBACK_ADDRESS_STRING; extern const char* BROADCAST_ADDRESS_STRING; @@ -62,13 +62,13 @@ extern const char* BROADCAST_ADDRESS_STRING; // useful MTU consts -const S32 MTUBYTES = 1200; // 1500 = standard Ethernet MTU -const S32 ETHERNET_MTU_BYTES = 1500; -const S32 MTUBITS = MTUBYTES*8; -const S32 MTUU32S = MTUBITS/32; +const S32 MTUBYTES = 1200; // 1500 = standard Ethernet MTU +const S32 ETHERNET_MTU_BYTES = 1500; +const S32 MTUBITS = MTUBYTES*8; +const S32 MTUU32S = MTUBITS/32; // For automatic port discovery when running multiple viewers on one host -const U32 PORT_DISCOVERY_RANGE_MIN = 13000; -const U32 PORT_DISCOVERY_RANGE_MAX = PORT_DISCOVERY_RANGE_MIN + 50; +const U32 PORT_DISCOVERY_RANGE_MIN = 13000; +const U32 PORT_DISCOVERY_RANGE_MAX = PORT_DISCOVERY_RANGE_MIN + 50; #endif diff --git a/indra/llmessage/partsyspacket.cpp b/indra/llmessage/partsyspacket.cpp index 846b11a5d0..6113adbfcf 100644 --- a/indra/llmessage/partsyspacket.cpp +++ b/indra/llmessage/partsyspacket.cpp @@ -1,4 +1,4 @@ -/** +/** * @file partsyspacket.cpp * @brief Object for packing particle system initialization parameters * before sending them over the network. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,911 +33,911 @@ // this function is global void gSetInitDataDefaults(LLPartInitData *setMe) { - U32 i; - - //for(i = 0; i < 18; i++) - //{ - // setMe->k[i] = 0.0f; - //} - - //setMe->kill_p[0] = setMe->kill_p[1] = setMe->kill_p[2] = 0.0f; - //setMe->kill_p[3] = -0.2f; // time parameter, die when t= 5.0f - //setMe->kill_p[4] = 1.0f; - //setMe->kill_p[5] = -0.5f; // or radius == 2 (contracting) - - //setMe->bounce_p[0] = setMe->bounce_p[1] = - // setMe->bounce_p[2] = setMe->bounce_p[3] = 0.0f; - //setMe->bounce_p[4] = 1.0f; - - setMe->bounce_b = 1.0f; - // i just changed the meaning of bounce_b - // its now the attenuation from revlecting your velocity across the normal - // set by bounce_p - - //setMe->pos_ranges[0] = setMe->pos_ranges[2] = setMe->pos_ranges[4] = -1.0f; - //setMe->pos_ranges[1] = setMe->pos_ranges[3] = setMe->pos_ranges[5] = 1.0f; - - //setMe->vel_ranges[0] = setMe->vel_ranges[2] = setMe->vel_ranges[4] = -1.0f; - //setMe->vel_ranges[1] = setMe->vel_ranges[3] = setMe->vel_ranges[5] = 1.0f; - - for(i = 0; i < 3; i++) - { - setMe->diffEqAlpha[i] = 0.0f; - setMe->diffEqScale[i] = 0.0f; - } - - setMe->scale_range[0] = 1.00f; - setMe->scale_range[1] = 5.00f; - setMe->scale_range[2] = setMe->scale_range[3] = 0.0f; - - setMe->alpha_range[0] = setMe->alpha_range[1] = 1.0f; - setMe->alpha_range[2] = setMe->alpha_range[3] = 0.0f; - - setMe->vel_offset[0] = 0.0f; - setMe->vel_offset[1] = 0.0f; - setMe->vel_offset[2] = 0.0f; - - // start dropping particles when I'm more then one sim away - setMe->mDistBeginFadeout = 256.0f; - setMe->mDistEndFadeout = 1.414f * 512.0f; - // stop displaying particles when I'm more then two sim diagonals away - - setMe->mImageUuid = IMG_SHOT; - - for(i = 0; i < 8; i++) - { - setMe->mFlags[i] = 0x00; - } - - setMe->createMe = true; - - setMe->maxParticles = 25; - setMe->initialParticles = 25; - - //These defaults are for an explosion - a short lived set of debris affected by gravity. - //Action flags default to PART_SYS_AFFECTED_BY_WIND + PART_SYS_AFFECTED_BY_GRAVITY + PART_SYS_DISTANCE_DEATH - setMe->mFlags[PART_SYS_ACTION_BYTE] = PART_SYS_AFFECTED_BY_WIND | PART_SYS_AFFECTED_BY_GRAVITY | PART_SYS_DISTANCE_DEATH; - setMe->mFlags[PART_SYS_KILL_BYTE] = PART_SYS_DISTANCE_DEATH + PART_SYS_TIME_DEATH; - - setMe->killPlaneNormal[0] = 0.0f;setMe->killPlaneNormal[1] = 0.0f;setMe->killPlaneNormal[2] = 1.0f; //Straight up - setMe->killPlaneZ = 0.0f; //get local ground z as an approximation if turn on PART_SYS_KILL_PLANE - setMe->bouncePlaneNormal[0] = 0.0f;setMe->bouncePlaneNormal[1] = 0.0f;setMe->bouncePlaneNormal[2] = 1.0f; //Straight up - setMe->bouncePlaneZ = 0.0f; //get local ground z as an approximation if turn on PART_SYS_BOUNCE - setMe->spawnRange = 1.0f; - setMe->spawnFrequency = 0.0f; //Create the instant one dies - setMe->spawnFreqencyRange = 0.0f; - setMe->spawnDirection[0] = 0.0f;setMe->spawnDirection[1] = 0.0f;setMe->spawnDirection[2] = 1.0f; //Straight up - setMe->spawnDirectionRange = 1.0f; //global scattering - setMe->spawnVelocity = 0.75f; - setMe->spawnVelocityRange = 0.25f; //velocity +/- 0.25 - setMe->speedLimit = 1.0f; - - setMe->windWeight = 0.5f; //0.0f means looks like a heavy object (if gravity is on), 1.0f means light and fluffy - setMe->currentGravity[0] = 0.0f;setMe->currentGravity[1] = 0.0f;setMe->currentGravity[2] = -9.81f; - //This has to be constant to allow for compression - - setMe->gravityWeight = 0.5f; //0.0f means boyed by air, 1.0f means it's a lead weight - setMe->globalLifetime = 0.0f; //Arbitrary, but default is no global die, so doesn't matter - setMe->individualLifetime = 5.0f; - setMe->individualLifetimeRange = 1.0f; //Particles last 5 secs +/- 1 - setMe->alphaDecay = 1.0f; //normal alpha fadeout - setMe->scaleDecay = 0.0f; //no scale decay - setMe->distanceDeath = 10.0f; //die if hit unit radius - setMe->dampMotionFactor = 0.0f; - - setMe->windDiffusionFactor[0] = 0.0f; - setMe->windDiffusionFactor[1] = 0.0f; - setMe->windDiffusionFactor[2] = 0.0f; + U32 i; + + //for(i = 0; i < 18; i++) + //{ + // setMe->k[i] = 0.0f; + //} + + //setMe->kill_p[0] = setMe->kill_p[1] = setMe->kill_p[2] = 0.0f; + //setMe->kill_p[3] = -0.2f; // time parameter, die when t= 5.0f + //setMe->kill_p[4] = 1.0f; + //setMe->kill_p[5] = -0.5f; // or radius == 2 (contracting) + + //setMe->bounce_p[0] = setMe->bounce_p[1] = + // setMe->bounce_p[2] = setMe->bounce_p[3] = 0.0f; + //setMe->bounce_p[4] = 1.0f; + + setMe->bounce_b = 1.0f; + // i just changed the meaning of bounce_b + // its now the attenuation from revlecting your velocity across the normal + // set by bounce_p + + //setMe->pos_ranges[0] = setMe->pos_ranges[2] = setMe->pos_ranges[4] = -1.0f; + //setMe->pos_ranges[1] = setMe->pos_ranges[3] = setMe->pos_ranges[5] = 1.0f; + + //setMe->vel_ranges[0] = setMe->vel_ranges[2] = setMe->vel_ranges[4] = -1.0f; + //setMe->vel_ranges[1] = setMe->vel_ranges[3] = setMe->vel_ranges[5] = 1.0f; + + for(i = 0; i < 3; i++) + { + setMe->diffEqAlpha[i] = 0.0f; + setMe->diffEqScale[i] = 0.0f; + } + + setMe->scale_range[0] = 1.00f; + setMe->scale_range[1] = 5.00f; + setMe->scale_range[2] = setMe->scale_range[3] = 0.0f; + + setMe->alpha_range[0] = setMe->alpha_range[1] = 1.0f; + setMe->alpha_range[2] = setMe->alpha_range[3] = 0.0f; + + setMe->vel_offset[0] = 0.0f; + setMe->vel_offset[1] = 0.0f; + setMe->vel_offset[2] = 0.0f; + + // start dropping particles when I'm more then one sim away + setMe->mDistBeginFadeout = 256.0f; + setMe->mDistEndFadeout = 1.414f * 512.0f; + // stop displaying particles when I'm more then two sim diagonals away + + setMe->mImageUuid = IMG_SHOT; + + for(i = 0; i < 8; i++) + { + setMe->mFlags[i] = 0x00; + } + + setMe->createMe = true; + + setMe->maxParticles = 25; + setMe->initialParticles = 25; + + //These defaults are for an explosion - a short lived set of debris affected by gravity. + //Action flags default to PART_SYS_AFFECTED_BY_WIND + PART_SYS_AFFECTED_BY_GRAVITY + PART_SYS_DISTANCE_DEATH + setMe->mFlags[PART_SYS_ACTION_BYTE] = PART_SYS_AFFECTED_BY_WIND | PART_SYS_AFFECTED_BY_GRAVITY | PART_SYS_DISTANCE_DEATH; + setMe->mFlags[PART_SYS_KILL_BYTE] = PART_SYS_DISTANCE_DEATH + PART_SYS_TIME_DEATH; + + setMe->killPlaneNormal[0] = 0.0f;setMe->killPlaneNormal[1] = 0.0f;setMe->killPlaneNormal[2] = 1.0f; //Straight up + setMe->killPlaneZ = 0.0f; //get local ground z as an approximation if turn on PART_SYS_KILL_PLANE + setMe->bouncePlaneNormal[0] = 0.0f;setMe->bouncePlaneNormal[1] = 0.0f;setMe->bouncePlaneNormal[2] = 1.0f; //Straight up + setMe->bouncePlaneZ = 0.0f; //get local ground z as an approximation if turn on PART_SYS_BOUNCE + setMe->spawnRange = 1.0f; + setMe->spawnFrequency = 0.0f; //Create the instant one dies + setMe->spawnFreqencyRange = 0.0f; + setMe->spawnDirection[0] = 0.0f;setMe->spawnDirection[1] = 0.0f;setMe->spawnDirection[2] = 1.0f; //Straight up + setMe->spawnDirectionRange = 1.0f; //global scattering + setMe->spawnVelocity = 0.75f; + setMe->spawnVelocityRange = 0.25f; //velocity +/- 0.25 + setMe->speedLimit = 1.0f; + + setMe->windWeight = 0.5f; //0.0f means looks like a heavy object (if gravity is on), 1.0f means light and fluffy + setMe->currentGravity[0] = 0.0f;setMe->currentGravity[1] = 0.0f;setMe->currentGravity[2] = -9.81f; + //This has to be constant to allow for compression + + setMe->gravityWeight = 0.5f; //0.0f means boyed by air, 1.0f means it's a lead weight + setMe->globalLifetime = 0.0f; //Arbitrary, but default is no global die, so doesn't matter + setMe->individualLifetime = 5.0f; + setMe->individualLifetimeRange = 1.0f; //Particles last 5 secs +/- 1 + setMe->alphaDecay = 1.0f; //normal alpha fadeout + setMe->scaleDecay = 0.0f; //no scale decay + setMe->distanceDeath = 10.0f; //die if hit unit radius + setMe->dampMotionFactor = 0.0f; + + setMe->windDiffusionFactor[0] = 0.0f; + setMe->windDiffusionFactor[1] = 0.0f; + setMe->windDiffusionFactor[2] = 0.0f; } LLPartSysCompressedPacket::LLPartSysCompressedPacket() { - // default constructor for mDefaults called implicitly/automatically here - for(int i = 0; i < MAX_PART_SYS_PACKET_SIZE; i++) - { - mData[i] = '\0'; - } + // default constructor for mDefaults called implicitly/automatically here + for(int i = 0; i < MAX_PART_SYS_PACKET_SIZE; i++) + { + mData[i] = '\0'; + } - mNumBytes = 0; + mNumBytes = 0; - gSetInitDataDefaults(&mDefaults); + gSetInitDataDefaults(&mDefaults); } LLPartSysCompressedPacket::~LLPartSysCompressedPacket() { - // no dynamic data is stored by this class, do nothing. + // no dynamic data is stored by this class, do nothing. } void LLPartSysCompressedPacket::writeFlagByte(LLPartInitData *in) { - mData[0] = mData[1] = mData[2] = '\0'; - - U32 i; - //for(i = 1; i < 18; i++) { - // if(in->k[i] != mDefaults.k[i]) - // { - // mData[0] |= PART_SYS_K_MASK; - // break; - // } - //} - - if(in->killPlaneZ != mDefaults.killPlaneZ || - in->killPlaneNormal[0] != mDefaults.killPlaneNormal[0] || - in->killPlaneNormal[1] != mDefaults.killPlaneNormal[1] || - in->killPlaneNormal[2] != mDefaults.killPlaneNormal[2] || - in->distanceDeath != mDefaults.distanceDeath) - { - mData[0] |= PART_SYS_KILL_P_MASK; - } - - - - if(in->bouncePlaneZ != mDefaults.bouncePlaneZ || - in->bouncePlaneNormal[0] != mDefaults.bouncePlaneNormal[0] || - in->bouncePlaneNormal[1] != mDefaults.bouncePlaneNormal[1] || - in->bouncePlaneNormal[2] != mDefaults.bouncePlaneNormal[2]) - { - mData[0] |= PART_SYS_BOUNCE_P_MASK; - } - - if(in->bounce_b != mDefaults.bounce_b) - { - mData[0] |= PART_SYS_BOUNCE_B_MASK; - } - - - //if(in->pos_ranges[0] != mDefaults.pos_ranges[0] || in->pos_ranges[1] != mDefaults.pos_ranges[1] || - // in->pos_ranges[2] != mDefaults.pos_ranges[2] || in->pos_ranges[3] != mDefaults.pos_ranges[3] || - // in->pos_ranges[4] != mDefaults.pos_ranges[4] || in->pos_ranges[5] != mDefaults.pos_ranges[5]) - //{ - // mData[0] |= PART_SYS_POS_RANGES_MASK; - //} - - //if(in->vel_ranges[0] != mDefaults.vel_ranges[0] || in->vel_ranges[1] != mDefaults.vel_ranges[1] || - // in->vel_ranges[2] != mDefaults.vel_ranges[2] || in->vel_ranges[3] != mDefaults.vel_ranges[3] || - // in->vel_ranges[4] != mDefaults.vel_ranges[4] || in->vel_ranges[5] != mDefaults.vel_ranges[5]) - //{ -// mData[0] |= PART_SYS_VEL_RANGES_MASK; - //} - - - if(in->diffEqAlpha[0] != mDefaults.diffEqAlpha[0] || - in->diffEqAlpha[1] != mDefaults.diffEqAlpha[1] || - in->diffEqAlpha[2] != mDefaults.diffEqAlpha[2] || - in->diffEqScale[0] != mDefaults.diffEqScale[0] || - in->diffEqScale[1] != mDefaults.diffEqScale[1] || - in->diffEqScale[2] != mDefaults.diffEqScale[2]) - { - mData[0] |= PART_SYS_ALPHA_SCALE_DIFF_MASK; - } - - - if(in->scale_range[0] != mDefaults.scale_range[0] || - in->scale_range[1] != mDefaults.scale_range[1] || - in->scale_range[2] != mDefaults.scale_range[2] || - in->scale_range[3] != mDefaults.scale_range[3]) - { - mData[0] |= PART_SYS_SCALE_RANGE_MASK; - } - - - if(in->alpha_range[0] != mDefaults.alpha_range[0] || - in->alpha_range[1] != mDefaults.alpha_range[1] || - in->alpha_range[2] != mDefaults.alpha_range[2] || - in->alpha_range[3] != mDefaults.alpha_range[3]) - { - mData[2] |= PART_SYS_BYTE_3_ALPHA_MASK; - } - - if(in->vel_offset[0] != mDefaults.vel_offset[0] || - in->vel_offset[1] != mDefaults.vel_offset[1] || - in->vel_offset[2] != mDefaults.vel_offset[2]) - { - mData[0] |= PART_SYS_VEL_OFFSET_MASK; - } - - - if(in->mImageUuid != mDefaults.mImageUuid) - { - mData[0] |= PART_SYS_M_IMAGE_UUID_MASK; - } - - for( i = 0; i < 8; i++) - { - if(in->mFlags[i]) - { - mData[1] |= 1<<i; -// llprintline("Flag \"%x\" gets byte \"%x\"\n", i<<i, in->mFlags[i]); - } - } - - - if(in->spawnRange != mDefaults.spawnRange || - in->spawnFrequency != mDefaults.spawnFrequency || - in->spawnFreqencyRange != mDefaults.spawnFreqencyRange || - in->spawnDirection[0] != mDefaults.spawnDirection[0] || - in->spawnDirection[1] != mDefaults.spawnDirection[1] || - in->spawnDirection[2] != mDefaults.spawnDirection[2] || - in->spawnDirectionRange != mDefaults.spawnDirectionRange || - in->spawnVelocity != mDefaults.spawnVelocity || - in->spawnVelocityRange != mDefaults.spawnVelocityRange) - { - mData[3] |= PART_SYS_BYTE_SPAWN_MASK; - } - - - if(in->windWeight != mDefaults.windWeight || - in->currentGravity[0] != mDefaults.currentGravity[0] || - in->currentGravity[1] != mDefaults.currentGravity[1] || - in->currentGravity[2] != mDefaults.currentGravity[2] || - in->gravityWeight != mDefaults.gravityWeight) - { - mData[3] |= PART_SYS_BYTE_ENVIRONMENT_MASK; - } - - - if(in->globalLifetime != mDefaults.globalLifetime || - in->individualLifetime != mDefaults.individualLifetime || - in->individualLifetimeRange != mDefaults.individualLifetimeRange) - { - mData[3] |= PART_SYS_BYTE_LIFESPAN_MASK; - } - - - if(in->speedLimit != mDefaults.speedLimit || - in->alphaDecay != mDefaults.alphaDecay || - in->scaleDecay != mDefaults.scaleDecay || - in->dampMotionFactor != mDefaults.dampMotionFactor) - { - mData[3] |= PART_SYS_BYTE_DECAY_DAMP_MASK; - } - - if(in->windDiffusionFactor[0] != mDefaults.windDiffusionFactor[0] || - in->windDiffusionFactor[1] != mDefaults.windDiffusionFactor[1] || - in->windDiffusionFactor[2] != mDefaults.windDiffusionFactor[2]) - { - mData[3] |= PART_SYS_BYTE_WIND_DIFF_MASK; - } + mData[0] = mData[1] = mData[2] = '\0'; + + U32 i; + //for(i = 1; i < 18; i++) { + // if(in->k[i] != mDefaults.k[i]) + // { + // mData[0] |= PART_SYS_K_MASK; + // break; + // } + //} + + if(in->killPlaneZ != mDefaults.killPlaneZ || + in->killPlaneNormal[0] != mDefaults.killPlaneNormal[0] || + in->killPlaneNormal[1] != mDefaults.killPlaneNormal[1] || + in->killPlaneNormal[2] != mDefaults.killPlaneNormal[2] || + in->distanceDeath != mDefaults.distanceDeath) + { + mData[0] |= PART_SYS_KILL_P_MASK; + } + + + + if(in->bouncePlaneZ != mDefaults.bouncePlaneZ || + in->bouncePlaneNormal[0] != mDefaults.bouncePlaneNormal[0] || + in->bouncePlaneNormal[1] != mDefaults.bouncePlaneNormal[1] || + in->bouncePlaneNormal[2] != mDefaults.bouncePlaneNormal[2]) + { + mData[0] |= PART_SYS_BOUNCE_P_MASK; + } + + if(in->bounce_b != mDefaults.bounce_b) + { + mData[0] |= PART_SYS_BOUNCE_B_MASK; + } + + + //if(in->pos_ranges[0] != mDefaults.pos_ranges[0] || in->pos_ranges[1] != mDefaults.pos_ranges[1] || + // in->pos_ranges[2] != mDefaults.pos_ranges[2] || in->pos_ranges[3] != mDefaults.pos_ranges[3] || + // in->pos_ranges[4] != mDefaults.pos_ranges[4] || in->pos_ranges[5] != mDefaults.pos_ranges[5]) + //{ + // mData[0] |= PART_SYS_POS_RANGES_MASK; + //} + + //if(in->vel_ranges[0] != mDefaults.vel_ranges[0] || in->vel_ranges[1] != mDefaults.vel_ranges[1] || + // in->vel_ranges[2] != mDefaults.vel_ranges[2] || in->vel_ranges[3] != mDefaults.vel_ranges[3] || + // in->vel_ranges[4] != mDefaults.vel_ranges[4] || in->vel_ranges[5] != mDefaults.vel_ranges[5]) + //{ +// mData[0] |= PART_SYS_VEL_RANGES_MASK; + //} + + + if(in->diffEqAlpha[0] != mDefaults.diffEqAlpha[0] || + in->diffEqAlpha[1] != mDefaults.diffEqAlpha[1] || + in->diffEqAlpha[2] != mDefaults.diffEqAlpha[2] || + in->diffEqScale[0] != mDefaults.diffEqScale[0] || + in->diffEqScale[1] != mDefaults.diffEqScale[1] || + in->diffEqScale[2] != mDefaults.diffEqScale[2]) + { + mData[0] |= PART_SYS_ALPHA_SCALE_DIFF_MASK; + } + + + if(in->scale_range[0] != mDefaults.scale_range[0] || + in->scale_range[1] != mDefaults.scale_range[1] || + in->scale_range[2] != mDefaults.scale_range[2] || + in->scale_range[3] != mDefaults.scale_range[3]) + { + mData[0] |= PART_SYS_SCALE_RANGE_MASK; + } + + + if(in->alpha_range[0] != mDefaults.alpha_range[0] || + in->alpha_range[1] != mDefaults.alpha_range[1] || + in->alpha_range[2] != mDefaults.alpha_range[2] || + in->alpha_range[3] != mDefaults.alpha_range[3]) + { + mData[2] |= PART_SYS_BYTE_3_ALPHA_MASK; + } + + if(in->vel_offset[0] != mDefaults.vel_offset[0] || + in->vel_offset[1] != mDefaults.vel_offset[1] || + in->vel_offset[2] != mDefaults.vel_offset[2]) + { + mData[0] |= PART_SYS_VEL_OFFSET_MASK; + } + + + if(in->mImageUuid != mDefaults.mImageUuid) + { + mData[0] |= PART_SYS_M_IMAGE_UUID_MASK; + } + + for( i = 0; i < 8; i++) + { + if(in->mFlags[i]) + { + mData[1] |= 1<<i; +// llprintline("Flag \"%x\" gets byte \"%x\"\n", i<<i, in->mFlags[i]); + } + } + + + if(in->spawnRange != mDefaults.spawnRange || + in->spawnFrequency != mDefaults.spawnFrequency || + in->spawnFreqencyRange != mDefaults.spawnFreqencyRange || + in->spawnDirection[0] != mDefaults.spawnDirection[0] || + in->spawnDirection[1] != mDefaults.spawnDirection[1] || + in->spawnDirection[2] != mDefaults.spawnDirection[2] || + in->spawnDirectionRange != mDefaults.spawnDirectionRange || + in->spawnVelocity != mDefaults.spawnVelocity || + in->spawnVelocityRange != mDefaults.spawnVelocityRange) + { + mData[3] |= PART_SYS_BYTE_SPAWN_MASK; + } + + + if(in->windWeight != mDefaults.windWeight || + in->currentGravity[0] != mDefaults.currentGravity[0] || + in->currentGravity[1] != mDefaults.currentGravity[1] || + in->currentGravity[2] != mDefaults.currentGravity[2] || + in->gravityWeight != mDefaults.gravityWeight) + { + mData[3] |= PART_SYS_BYTE_ENVIRONMENT_MASK; + } + + + if(in->globalLifetime != mDefaults.globalLifetime || + in->individualLifetime != mDefaults.individualLifetime || + in->individualLifetimeRange != mDefaults.individualLifetimeRange) + { + mData[3] |= PART_SYS_BYTE_LIFESPAN_MASK; + } + + + if(in->speedLimit != mDefaults.speedLimit || + in->alphaDecay != mDefaults.alphaDecay || + in->scaleDecay != mDefaults.scaleDecay || + in->dampMotionFactor != mDefaults.dampMotionFactor) + { + mData[3] |= PART_SYS_BYTE_DECAY_DAMP_MASK; + } + + if(in->windDiffusionFactor[0] != mDefaults.windDiffusionFactor[0] || + in->windDiffusionFactor[1] != mDefaults.windDiffusionFactor[1] || + in->windDiffusionFactor[2] != mDefaults.windDiffusionFactor[2]) + { + mData[3] |= PART_SYS_BYTE_WIND_DIFF_MASK; + } } F32 floatFromTwoBytes(S8 bMant, S8 bExp) { - F32 result = bMant; - while(bExp > 0) - { - result *= 2.0f; - bExp--; - } - while(bExp < 0) - { - result *= 0.5f; - bExp++; - } - return result; + F32 result = bMant; + while(bExp > 0) + { + result *= 2.0f; + bExp--; + } + while(bExp < 0) + { + result *= 0.5f; + bExp++; + } + return result; } void twoBytesFromFloat(F32 fIn, S8 &bMant, S8 &bExp) { - bExp = 0; - if(fIn > 127.0f) - { - fIn = 127.0f; - } - if(fIn < -127.0f) - { - fIn = -127.0f; - } - while(fIn < 64 && fIn > -64 && bExp > -127) - { - fIn *= 2.0f; - bExp--; - } - while((fIn > 128 || fIn < -128) && bExp < 127) - { - fIn *= 0.5f; - bExp++; - } - bMant = (S8)fIn; + bExp = 0; + if(fIn > 127.0f) + { + fIn = 127.0f; + } + if(fIn < -127.0f) + { + fIn = -127.0f; + } + while(fIn < 64 && fIn > -64 && bExp > -127) + { + fIn *= 2.0f; + bExp--; + } + while((fIn > 128 || fIn < -128) && bExp < 127) + { + fIn *= 0.5f; + bExp++; + } + bMant = (S8)fIn; } - + /* U32 LLPartSysCompressedPacket::writeK(LLPartInitData *in, U32 startByte) { - U32 i, kFlag, i_mod_eight; - S8 bMant, bExp; - - kFlag = startByte; - - startByte += 3; // 3 bytes contain enough room for 18 flag bits - mData[kFlag] = 0x00; -// llprintline("In the writeK\n"); - - i_mod_eight = 0; - for(i = 0; i < 18; i++) - { - if(in->k[i] != mDefaults.k[i]) - { - - mData[kFlag] |= 1<<i_mod_eight; - twoBytesFromFloat(in->k[i], bMant, bExp); - - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - i_mod_eight++; - while(i_mod_eight >= 8) - { - kFlag++; - i_mod_eight -= 8; - } - } - - return startByte; + U32 i, kFlag, i_mod_eight; + S8 bMant, bExp; + + kFlag = startByte; + + startByte += 3; // 3 bytes contain enough room for 18 flag bits + mData[kFlag] = 0x00; +// llprintline("In the writeK\n"); + + i_mod_eight = 0; + for(i = 0; i < 18; i++) + { + if(in->k[i] != mDefaults.k[i]) + { + + mData[kFlag] |= 1<<i_mod_eight; + twoBytesFromFloat(in->k[i], bMant, bExp); + + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + i_mod_eight++; + while(i_mod_eight >= 8) + { + kFlag++; + i_mod_eight -= 8; + } + } + + return startByte; }*/ U32 LLPartSysCompressedPacket::writeKill_p(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - - twoBytesFromFloat(in->killPlaneNormal[0], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->killPlaneNormal[1], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->killPlaneNormal[2], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - twoBytesFromFloat(in->killPlaneZ, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->distanceDeath, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - return startByte; + S8 bMant, bExp; + + twoBytesFromFloat(in->killPlaneNormal[0], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->killPlaneNormal[1], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->killPlaneNormal[2], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + twoBytesFromFloat(in->killPlaneZ, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->distanceDeath, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + return startByte; } U32 LLPartSysCompressedPacket::writeBounce_p(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - - twoBytesFromFloat(in->bouncePlaneNormal[0], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->bouncePlaneNormal[1], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->bouncePlaneNormal[2], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - - twoBytesFromFloat(in->bouncePlaneZ, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - return startByte; + S8 bMant, bExp; + + twoBytesFromFloat(in->bouncePlaneNormal[0], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->bouncePlaneNormal[1], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->bouncePlaneNormal[2], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + + twoBytesFromFloat(in->bouncePlaneZ, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + return startByte; } U32 LLPartSysCompressedPacket::writeBounce_b(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - twoBytesFromFloat(in->bounce_b, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - return startByte; + S8 bMant, bExp; + twoBytesFromFloat(in->bounce_b, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + return startByte; } //U32 LLPartSysCompressedPacket::writePos_ranges(LLPartInitData *in, U32 startByte) //{ -// S8 tmp; -// int i; -// for(i = 0; i < 6; i++) -// { -// tmp = (S8) in->pos_ranges[i]; // float to int conversion (keep the sign) -// mData[startByte++] = (U8)tmp; // signed to unsigned typecast -// } -// return startByte; +// S8 tmp; +// int i; +// for(i = 0; i < 6; i++) +// { +// tmp = (S8) in->pos_ranges[i]; // float to int conversion (keep the sign) +// mData[startByte++] = (U8)tmp; // signed to unsigned typecast +// } +// return startByte; //} //U32 LLPartSysCompressedPacket::writeVel_ranges(LLPartInitData *in, U32 startByte) //{ -// S8 tmp; -// int i; -// for(i = 0; i < 6; i++) -// { -// tmp = (S8) in->vel_ranges[i]; // float to int conversion (keep the sign) -// mData[startByte++] = (U8)tmp; // signed to unsigned typecast -// } -// return startByte; +// S8 tmp; +// int i; +// for(i = 0; i < 6; i++) +// { +// tmp = (S8) in->vel_ranges[i]; // float to int conversion (keep the sign) +// mData[startByte++] = (U8)tmp; // signed to unsigned typecast +// } +// return startByte; //} U32 LLPartSysCompressedPacket::writeAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; - int i; - for(i = 0; i < 3; i++) - { - twoBytesFromFloat(in->diffEqAlpha[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - for(i = 0; i < 3; i++) - { - twoBytesFromFloat(in->diffEqScale[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - return startByte; + S8 bExp, bMant; + int i; + for(i = 0; i < 3; i++) + { + twoBytesFromFloat(in->diffEqAlpha[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + for(i = 0; i < 3; i++) + { + twoBytesFromFloat(in->diffEqScale[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + return startByte; } U32 LLPartSysCompressedPacket::writeScale_range(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; - int i; - for(i = 0; i < 4; i++) - { - twoBytesFromFloat(in->scale_range[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - return startByte; + S8 bExp, bMant; + int i; + for(i = 0; i < 4; i++) + { + twoBytesFromFloat(in->scale_range[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + return startByte; } U32 LLPartSysCompressedPacket::writeAlpha_range(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; - int i; - for(i = 0; i < 4; i++) - { - twoBytesFromFloat(in->alpha_range[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - return startByte; + S8 bExp, bMant; + int i; + for(i = 0; i < 4; i++) + { + twoBytesFromFloat(in->alpha_range[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + return startByte; } U32 LLPartSysCompressedPacket::writeVelocityOffset(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; - int i; - for(i = 0; i < 3; i++) - { - twoBytesFromFloat(in->vel_offset[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - return startByte; + S8 bExp, bMant; + int i; + for(i = 0; i < 3; i++) + { + twoBytesFromFloat(in->vel_offset[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + return startByte; } U32 LLPartSysCompressedPacket::writeUUID(LLPartInitData *in, U32 startByte) { - U8 * bufPtr = mData + startByte; - if(in->mImageUuid == IMG_SHOT) { - mData[startByte++] = 0x01; - return startByte; - } - - if(in->mImageUuid == IMG_SPARK) { - mData[startByte++] = 0x02; - return startByte; - } - - - if(in->mImageUuid == IMG_BIG_EXPLOSION_1) { - mData[startByte++] = 0x03; - return startByte; - } - - if(in->mImageUuid == IMG_BIG_EXPLOSION_2) { - mData[startByte++] = 0x04; - return startByte; - } - - - if(in->mImageUuid == IMG_SMOKE_POOF) { - mData[startByte++] = 0x05; - return startByte; - } - - if(in->mImageUuid == IMG_FIRE) { - mData[startByte++] = 0x06; - return startByte; - } - - - if(in->mImageUuid == IMG_EXPLOSION) { - mData[startByte++] = 0x07; - return startByte; - } - - if(in->mImageUuid == IMG_EXPLOSION_2) { - mData[startByte++] = 0x08; - return startByte; - } - - - if(in->mImageUuid == IMG_EXPLOSION_3) { - mData[startByte++] = 0x09; - return startByte; - } - - if(in->mImageUuid == IMG_EXPLOSION_4) { - mData[startByte++] = 0x0A; - return startByte; - } - - mData[startByte++] = 0x00; // flag for "read whole UUID" - - memcpy(bufPtr, in->mImageUuid.mData, 16); /* Flawfinder: ignore */ - return (startByte+16); + U8 * bufPtr = mData + startByte; + if(in->mImageUuid == IMG_SHOT) { + mData[startByte++] = 0x01; + return startByte; + } + + if(in->mImageUuid == IMG_SPARK) { + mData[startByte++] = 0x02; + return startByte; + } + + + if(in->mImageUuid == IMG_BIG_EXPLOSION_1) { + mData[startByte++] = 0x03; + return startByte; + } + + if(in->mImageUuid == IMG_BIG_EXPLOSION_2) { + mData[startByte++] = 0x04; + return startByte; + } + + + if(in->mImageUuid == IMG_SMOKE_POOF) { + mData[startByte++] = 0x05; + return startByte; + } + + if(in->mImageUuid == IMG_FIRE) { + mData[startByte++] = 0x06; + return startByte; + } + + + if(in->mImageUuid == IMG_EXPLOSION) { + mData[startByte++] = 0x07; + return startByte; + } + + if(in->mImageUuid == IMG_EXPLOSION_2) { + mData[startByte++] = 0x08; + return startByte; + } + + + if(in->mImageUuid == IMG_EXPLOSION_3) { + mData[startByte++] = 0x09; + return startByte; + } + + if(in->mImageUuid == IMG_EXPLOSION_4) { + mData[startByte++] = 0x0A; + return startByte; + } + + mData[startByte++] = 0x00; // flag for "read whole UUID" + + memcpy(bufPtr, in->mImageUuid.mData, 16); /* Flawfinder: ignore */ + return (startByte+16); } U32 LLPartSysCompressedPacket::writeSpawn(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; - int i; - - twoBytesFromFloat(in->spawnRange, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->spawnFrequency, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->spawnFreqencyRange, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - - - for(i = 0; i < 3; i++) - { - twoBytesFromFloat(in->spawnDirection[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - - twoBytesFromFloat(in->spawnDirectionRange, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->spawnVelocity, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - twoBytesFromFloat(in->spawnVelocityRange, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - return startByte; + S8 bExp, bMant; + int i; + + twoBytesFromFloat(in->spawnRange, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->spawnFrequency, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->spawnFreqencyRange, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + + + for(i = 0; i < 3; i++) + { + twoBytesFromFloat(in->spawnDirection[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + + twoBytesFromFloat(in->spawnDirectionRange, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->spawnVelocity, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + twoBytesFromFloat(in->spawnVelocityRange, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + return startByte; } U32 LLPartSysCompressedPacket::writeEnvironment(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; - int i; - - twoBytesFromFloat(in->windWeight, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - - for(i = 0; i < 3; i++) - { - twoBytesFromFloat(in->currentGravity[i], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - } - - twoBytesFromFloat(in->gravityWeight, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; - return startByte; -} - + S8 bExp, bMant; + int i; + + twoBytesFromFloat(in->windWeight, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + + for(i = 0; i < 3; i++) + { + twoBytesFromFloat(in->currentGravity[i], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + } + + twoBytesFromFloat(in->gravityWeight, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; + return startByte; +} + U32 LLPartSysCompressedPacket::writeLifespan(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; + S8 bExp, bMant; - twoBytesFromFloat(in->globalLifetime, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->globalLifetime, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->individualLifetime, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->individualLifetime, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->individualLifetimeRange, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->individualLifetimeRange, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - return startByte; + return startByte; } - + U32 LLPartSysCompressedPacket::writeDecayDamp(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; + S8 bExp, bMant; - twoBytesFromFloat(in->speedLimit, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->speedLimit, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->alphaDecay, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->alphaDecay, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->scaleDecay, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->scaleDecay, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->dampMotionFactor, bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->dampMotionFactor, bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - return startByte; + return startByte; } U32 LLPartSysCompressedPacket::writeWindDiffusionFactor(LLPartInitData *in, U32 startByte) { - S8 bExp, bMant; + S8 bExp, bMant; - twoBytesFromFloat(in->windDiffusionFactor[0], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->windDiffusionFactor[0], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->windDiffusionFactor[1], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->windDiffusionFactor[1], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - twoBytesFromFloat(in->windDiffusionFactor[2], bMant, bExp); - mData[startByte++] = bMant; - mData[startByte++] = bExp; + twoBytesFromFloat(in->windDiffusionFactor[2], bMant, bExp); + mData[startByte++] = bMant; + mData[startByte++] = bExp; - return startByte; + return startByte; } - + /* U32 LLPartSysCompressedPacket::readK(LLPartInitData *in, U32 startByte) { - U32 i, i_mod_eight, kFlag; - S8 bMant, bExp; // 1 bytes mantissa and exponent for a float - kFlag = startByte; - startByte += 3; // 3 bytes has enough room for 18 bits - - i_mod_eight = 0; - for(i = 0; i < 18; i++) - { - if(mData[kFlag]&(1<<i_mod_eight)) - { - - - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - - - in->k[i] = floatFromTwoBytes(bMant, bExp); // much tighter platform-independent - // way to ship floats - - } - i_mod_eight++; - if(i_mod_eight >= 8) - { - i_mod_eight -= 8; - kFlag++; - } - } - - return startByte; + U32 i, i_mod_eight, kFlag; + S8 bMant, bExp; // 1 bytes mantissa and exponent for a float + kFlag = startByte; + startByte += 3; // 3 bytes has enough room for 18 bits + + i_mod_eight = 0; + for(i = 0; i < 18; i++) + { + if(mData[kFlag]&(1<<i_mod_eight)) + { + + + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + + + in->k[i] = floatFromTwoBytes(bMant, bExp); // much tighter platform-independent + // way to ship floats + + } + i_mod_eight++; + if(i_mod_eight >= 8) + { + i_mod_eight -= 8; + kFlag++; + } + } + + return startByte; } */ U32 LLPartSysCompressedPacket::readKill_p(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->killPlaneNormal[0] = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->killPlaneNormal[1] = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->killPlaneNormal[2] = floatFromTwoBytes(bMant, bExp); - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->killPlaneZ = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->distanceDeath = floatFromTwoBytes(bMant, bExp); - - return startByte; + S8 bMant, bExp; + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->killPlaneNormal[0] = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->killPlaneNormal[1] = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->killPlaneNormal[2] = floatFromTwoBytes(bMant, bExp); + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->killPlaneZ = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->distanceDeath = floatFromTwoBytes(bMant, bExp); + + return startByte; } U32 LLPartSysCompressedPacket::readBounce_p(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; + S8 bMant, bExp; - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->bouncePlaneNormal[0] = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->bouncePlaneNormal[1] = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->bouncePlaneNormal[2] = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->bouncePlaneNormal[0] = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->bouncePlaneNormal[1] = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->bouncePlaneNormal[2] = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->bouncePlaneZ = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->bouncePlaneZ = floatFromTwoBytes(bMant, bExp); - return startByte; + return startByte; } U32 LLPartSysCompressedPacket::readBounce_b(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->bounce_b = floatFromTwoBytes(bMant, bExp); - return startByte; + S8 bMant, bExp; + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->bounce_b = floatFromTwoBytes(bMant, bExp); + return startByte; } //U32 LLPartSysCompressedPacket::readPos_ranges(LLPartInitData *in, U32 startByte) //{ -// S8 tmp; -// int i; -// for(i = 0; i < 6; i++) -// { -// tmp = (S8)mData[startByte++]; -// in->pos_ranges[i] = tmp; -// } -// return startByte; +// S8 tmp; +// int i; +// for(i = 0; i < 6; i++) +// { +// tmp = (S8)mData[startByte++]; +// in->pos_ranges[i] = tmp; +// } +// return startByte; //} //U32 LLPartSysCompressedPacket::readVel_ranges(LLPartInitData *in, U32 startByte) //{ -// S8 tmp; -// int i; -// for(i = 0; i < 6; i++) -// { -// tmp = (S8)mData[startByte++]; -// in->vel_ranges[i] = tmp; -// } -// return startByte; +// S8 tmp; +// int i; +// for(i = 0; i < 6; i++) +// { +// tmp = (S8)mData[startByte++]; +// in->vel_ranges[i] = tmp; +// } +// return startByte; //} U32 LLPartSysCompressedPacket::readAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte) { - int i; - S8 bMant, bExp; - for(i = 0; i < 3; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->diffEqAlpha[i] = floatFromTwoBytes(bMant, bExp); - } - for(i = 0; i < 3; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->diffEqScale[i] = floatFromTwoBytes(bMant, bExp); - } - return startByte; + int i; + S8 bMant, bExp; + for(i = 0; i < 3; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->diffEqAlpha[i] = floatFromTwoBytes(bMant, bExp); + } + for(i = 0; i < 3; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->diffEqScale[i] = floatFromTwoBytes(bMant, bExp); + } + return startByte; } U32 LLPartSysCompressedPacket::readAlpha_range(LLPartInitData *in, U32 startByte) { - int i; - S8 bMant, bExp; - for(i = 0; i < 4; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->alpha_range[i] = floatFromTwoBytes(bMant, bExp); - } - return startByte; + int i; + S8 bMant, bExp; + for(i = 0; i < 4; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->alpha_range[i] = floatFromTwoBytes(bMant, bExp); + } + return startByte; } U32 LLPartSysCompressedPacket::readScale_range(LLPartInitData *in, U32 startByte) { - int i; - S8 bMant, bExp; - for(i = 0; i < 4; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->scale_range[i] = floatFromTwoBytes(bMant, bExp); - } - return startByte; + int i; + S8 bMant, bExp; + for(i = 0; i < 4; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->scale_range[i] = floatFromTwoBytes(bMant, bExp); + } + return startByte; } U32 LLPartSysCompressedPacket::readVelocityOffset(LLPartInitData *in, U32 startByte) { - int i; - S8 bMant, bExp; - for(i = 0; i < 3; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->vel_offset[i] = floatFromTwoBytes(bMant, bExp); - } - return startByte; + int i; + S8 bMant, bExp; + for(i = 0; i < 3; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->vel_offset[i] = floatFromTwoBytes(bMant, bExp); + } + return startByte; } U32 LLPartSysCompressedPacket::readUUID(LLPartInitData *in, U32 startByte) { - U8 * bufPtr = mData + startByte; - - if(mData[startByte] == 0x01) - { - in->mImageUuid = IMG_SHOT; - return startByte+1; - } - if(mData[startByte] == 0x02) - { - in->mImageUuid = IMG_SPARK; - return startByte+1; - } - if(mData[startByte] == 0x03) - { - in->mImageUuid = IMG_BIG_EXPLOSION_1; - return startByte+1; - } - if(mData[startByte] == 0x04) - { - in->mImageUuid = IMG_BIG_EXPLOSION_2; - return startByte+1; - } - if(mData[startByte] == 0x05) - { - in->mImageUuid = IMG_SMOKE_POOF; - return startByte+1; - } - if(mData[startByte] == 0x06) - { - in->mImageUuid = IMG_FIRE; - return startByte+1; - } - if(mData[startByte] == 0x07) - { - in->mImageUuid = IMG_EXPLOSION; - return startByte+1; - } - if(mData[startByte] == 0x08) - { - in->mImageUuid = IMG_EXPLOSION_2; - return startByte+1; - } - if(mData[startByte] == 0x09) - { - in->mImageUuid = IMG_EXPLOSION_3; - return startByte+1; - } - if(mData[startByte] == 0x0A) - { - in->mImageUuid = IMG_EXPLOSION_4; - return startByte+1; - } - - startByte++; // cause we actually have to read the UUID now. - memcpy(in->mImageUuid.mData, bufPtr, 16); /* Flawfinder: ignore */ - return (startByte+16); + U8 * bufPtr = mData + startByte; + + if(mData[startByte] == 0x01) + { + in->mImageUuid = IMG_SHOT; + return startByte+1; + } + if(mData[startByte] == 0x02) + { + in->mImageUuid = IMG_SPARK; + return startByte+1; + } + if(mData[startByte] == 0x03) + { + in->mImageUuid = IMG_BIG_EXPLOSION_1; + return startByte+1; + } + if(mData[startByte] == 0x04) + { + in->mImageUuid = IMG_BIG_EXPLOSION_2; + return startByte+1; + } + if(mData[startByte] == 0x05) + { + in->mImageUuid = IMG_SMOKE_POOF; + return startByte+1; + } + if(mData[startByte] == 0x06) + { + in->mImageUuid = IMG_FIRE; + return startByte+1; + } + if(mData[startByte] == 0x07) + { + in->mImageUuid = IMG_EXPLOSION; + return startByte+1; + } + if(mData[startByte] == 0x08) + { + in->mImageUuid = IMG_EXPLOSION_2; + return startByte+1; + } + if(mData[startByte] == 0x09) + { + in->mImageUuid = IMG_EXPLOSION_3; + return startByte+1; + } + if(mData[startByte] == 0x0A) + { + in->mImageUuid = IMG_EXPLOSION_4; + return startByte+1; + } + + startByte++; // cause we actually have to read the UUID now. + memcpy(in->mImageUuid.mData, bufPtr, 16); /* Flawfinder: ignore */ + return (startByte+16); } @@ -945,353 +945,353 @@ U32 LLPartSysCompressedPacket::readUUID(LLPartInitData *in, U32 startByte) U32 LLPartSysCompressedPacket::readSpawn(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - U32 i; - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnRange = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnFrequency = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnFreqencyRange = floatFromTwoBytes(bMant, bExp); - - for(i = 0; i < 3; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnDirection[i] = floatFromTwoBytes(bMant, bExp); - } - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnDirectionRange = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnVelocity = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->spawnVelocityRange = floatFromTwoBytes(bMant, bExp); - - return startByte; + S8 bMant, bExp; + U32 i; + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnRange = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnFrequency = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnFreqencyRange = floatFromTwoBytes(bMant, bExp); + + for(i = 0; i < 3; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnDirection[i] = floatFromTwoBytes(bMant, bExp); + } + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnDirectionRange = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnVelocity = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->spawnVelocityRange = floatFromTwoBytes(bMant, bExp); + + return startByte; } U32 LLPartSysCompressedPacket::readEnvironment(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - U32 i; + S8 bMant, bExp; + U32 i; - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->windWeight = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->windWeight = floatFromTwoBytes(bMant, bExp); - for(i = 0; i < 3; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->currentGravity[i] = floatFromTwoBytes(bMant, bExp); - } + for(i = 0; i < 3; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->currentGravity[i] = floatFromTwoBytes(bMant, bExp); + } - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->gravityWeight = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->gravityWeight = floatFromTwoBytes(bMant, bExp); - return startByte; + return startByte; } U32 LLPartSysCompressedPacket::readLifespan(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->globalLifetime = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->individualLifetime = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->individualLifetimeRange = floatFromTwoBytes(bMant, bExp); - - return startByte; + S8 bMant, bExp; + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->globalLifetime = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->individualLifetime = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->individualLifetimeRange = floatFromTwoBytes(bMant, bExp); + + return startByte; } U32 LLPartSysCompressedPacket::readDecayDamp(LLPartInitData *in, U32 startByte) { - S8 bMant, bExp; - - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->speedLimit = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->alphaDecay = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->scaleDecay = floatFromTwoBytes(bMant, bExp); - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->dampMotionFactor = floatFromTwoBytes(bMant, bExp); - - return startByte; + S8 bMant, bExp; + + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->speedLimit = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->alphaDecay = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->scaleDecay = floatFromTwoBytes(bMant, bExp); + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->dampMotionFactor = floatFromTwoBytes(bMant, bExp); + + return startByte; } U32 LLPartSysCompressedPacket::readWindDiffusionFactor(LLPartInitData *in, U32 startByte) { - int i; - S8 bMant, bExp; - for(i = 0; i < 3; i++) - { - bMant = mData[startByte++]; - bExp = mData[startByte++]; - in->windDiffusionFactor[i] = floatFromTwoBytes(bMant, bExp); - } - return startByte; + int i; + S8 bMant, bExp; + for(i = 0; i < 3; i++) + { + bMant = mData[startByte++]; + bExp = mData[startByte++]; + in->windDiffusionFactor[i] = floatFromTwoBytes(bMant, bExp); + } + return startByte; } bool LLPartSysCompressedPacket::fromLLPartInitData(LLPartInitData *in, U32 &bytesUsed) { - writeFlagByte(in); - U32 currByte = 4; - -// llprintline("calling \"fromLLPartInitData\"\n"); - - //if(mData[0] & PART_SYS_K_MASK) - //{ - // currByte = writeK(in, 3); // first 3 bytes are reserved for header data - //} - - - - if(mData[0] & PART_SYS_KILL_P_MASK) - { - currByte = writeKill_p(in, currByte); - } - - if(mData[0] & PART_SYS_BOUNCE_P_MASK) - { - currByte = writeBounce_p(in, currByte); - } - - if(mData[0] & PART_SYS_BOUNCE_B_MASK) - { - currByte = writeBounce_b(in, currByte); - } - - //if(mData[0] & PART_SYS_POS_RANGES_MASK) - //{ - // currByte = writePos_ranges(in, currByte); - //} - - //if(mData[0] & PART_SYS_VEL_RANGES_MASK) - //{ - // currByte = writeVel_ranges(in, currByte); - //} - - if(mData[0] & PART_SYS_ALPHA_SCALE_DIFF_MASK) - { - currByte = writeAlphaScaleDiffEqn_range(in, currByte); - } - - if(mData[0] & PART_SYS_SCALE_RANGE_MASK) - { - currByte = writeScale_range(in, currByte); - } - - if(mData[0] & PART_SYS_VEL_OFFSET_MASK) - { - currByte = writeVelocityOffset(in, currByte); - } - - if(mData[0] & PART_SYS_M_IMAGE_UUID_MASK) - { - currByte = writeUUID(in, currByte); - } - - - if(mData[3] & PART_SYS_BYTE_SPAWN_MASK) - { - currByte = writeSpawn(in, currByte); - } - - if(mData[3] & PART_SYS_BYTE_ENVIRONMENT_MASK) - { - currByte = writeEnvironment(in, currByte); - } - - if(mData[3] & PART_SYS_BYTE_LIFESPAN_MASK) - { - currByte = writeLifespan(in, currByte); - } - - if(mData[3] & PART_SYS_BYTE_DECAY_DAMP_MASK) - { - currByte = writeDecayDamp(in, currByte); - } - - if(mData[3] & PART_SYS_BYTE_WIND_DIFF_MASK) - { - currByte = writeWindDiffusionFactor(in, currByte); - } - - - if(mData[2] & PART_SYS_BYTE_3_ALPHA_MASK) - { - currByte = writeAlpha_range(in, currByte); - } - - mData[currByte++] = (U8)in->maxParticles; - mData[currByte++] = (U8)in->initialParticles; - - - U32 flagFlag = 1; // flag indicating which flag bytes are non-zero - // yeah, I know, the name sounds funny - for(U32 i = 0; i < 8; i++) - { - -// llprintline("Flag \"%x\" gets byte \"%x\"\n", flagFlag, in->mFlags[i]); - if(mData[1] & flagFlag) - { - mData[currByte++] = in->mFlags[i]; -// llprintline("and is valid...\n"); - } - flagFlag <<= 1; - } - - bytesUsed = mNumBytes = currByte; - - - -// llprintline("returning from \"fromLLPartInitData\" with %d bytes\n", bytesUsed); - - return true; + writeFlagByte(in); + U32 currByte = 4; + +// llprintline("calling \"fromLLPartInitData\"\n"); + + //if(mData[0] & PART_SYS_K_MASK) + //{ + // currByte = writeK(in, 3); // first 3 bytes are reserved for header data + //} + + + + if(mData[0] & PART_SYS_KILL_P_MASK) + { + currByte = writeKill_p(in, currByte); + } + + if(mData[0] & PART_SYS_BOUNCE_P_MASK) + { + currByte = writeBounce_p(in, currByte); + } + + if(mData[0] & PART_SYS_BOUNCE_B_MASK) + { + currByte = writeBounce_b(in, currByte); + } + + //if(mData[0] & PART_SYS_POS_RANGES_MASK) + //{ + // currByte = writePos_ranges(in, currByte); + //} + + //if(mData[0] & PART_SYS_VEL_RANGES_MASK) + //{ + // currByte = writeVel_ranges(in, currByte); + //} + + if(mData[0] & PART_SYS_ALPHA_SCALE_DIFF_MASK) + { + currByte = writeAlphaScaleDiffEqn_range(in, currByte); + } + + if(mData[0] & PART_SYS_SCALE_RANGE_MASK) + { + currByte = writeScale_range(in, currByte); + } + + if(mData[0] & PART_SYS_VEL_OFFSET_MASK) + { + currByte = writeVelocityOffset(in, currByte); + } + + if(mData[0] & PART_SYS_M_IMAGE_UUID_MASK) + { + currByte = writeUUID(in, currByte); + } + + + if(mData[3] & PART_SYS_BYTE_SPAWN_MASK) + { + currByte = writeSpawn(in, currByte); + } + + if(mData[3] & PART_SYS_BYTE_ENVIRONMENT_MASK) + { + currByte = writeEnvironment(in, currByte); + } + + if(mData[3] & PART_SYS_BYTE_LIFESPAN_MASK) + { + currByte = writeLifespan(in, currByte); + } + + if(mData[3] & PART_SYS_BYTE_DECAY_DAMP_MASK) + { + currByte = writeDecayDamp(in, currByte); + } + + if(mData[3] & PART_SYS_BYTE_WIND_DIFF_MASK) + { + currByte = writeWindDiffusionFactor(in, currByte); + } + + + if(mData[2] & PART_SYS_BYTE_3_ALPHA_MASK) + { + currByte = writeAlpha_range(in, currByte); + } + + mData[currByte++] = (U8)in->maxParticles; + mData[currByte++] = (U8)in->initialParticles; + + + U32 flagFlag = 1; // flag indicating which flag bytes are non-zero + // yeah, I know, the name sounds funny + for(U32 i = 0; i < 8; i++) + { + +// llprintline("Flag \"%x\" gets byte \"%x\"\n", flagFlag, in->mFlags[i]); + if(mData[1] & flagFlag) + { + mData[currByte++] = in->mFlags[i]; +// llprintline("and is valid...\n"); + } + flagFlag <<= 1; + } + + bytesUsed = mNumBytes = currByte; + + + +// llprintline("returning from \"fromLLPartInitData\" with %d bytes\n", bytesUsed); + + return true; } bool LLPartSysCompressedPacket::toLLPartInitData(LLPartInitData *out, U32 *bytesUsed) { - U32 currByte = 4; - - gSetInitDataDefaults(out); - - if(mData[0] & PART_SYS_KILL_P_MASK) - { - currByte = readKill_p(out, currByte); - } - - if(mData[0] & PART_SYS_BOUNCE_P_MASK) - { - currByte = readBounce_p(out, currByte); - } - - if(mData[0] & PART_SYS_BOUNCE_B_MASK) - { - currByte = readBounce_b(out, currByte); - } - - if(mData[0] & PART_SYS_ALPHA_SCALE_DIFF_MASK) - { - currByte = readAlphaScaleDiffEqn_range(out, currByte); - } - - if(mData[0] & PART_SYS_SCALE_RANGE_MASK) - { - currByte = readScale_range(out, currByte); - } - - if(mData[0] & PART_SYS_VEL_OFFSET_MASK) - { - currByte = readVelocityOffset(out, currByte); - } - - if(mData[0] & PART_SYS_M_IMAGE_UUID_MASK) - { - currByte = readUUID(out, currByte); - } - - - if(mData[3] & PART_SYS_BYTE_SPAWN_MASK) - { - currByte = readSpawn(out, currByte); - } - - if(mData[3] & PART_SYS_BYTE_ENVIRONMENT_MASK) - { - currByte = readEnvironment(out, currByte); - } - - if(mData[3] & PART_SYS_BYTE_LIFESPAN_MASK) - { - currByte = readLifespan(out, currByte); - } - - if(mData[3] & PART_SYS_BYTE_DECAY_DAMP_MASK) - { - currByte = readDecayDamp(out, currByte); - } - - if(mData[3] & PART_SYS_BYTE_WIND_DIFF_MASK) - { - currByte = readWindDiffusionFactor(out, currByte); - } - - if(mData[2] & PART_SYS_BYTE_3_ALPHA_MASK) - { - currByte = readAlpha_range(out, currByte); - } - - out->maxParticles = mData[currByte++]; - out->initialParticles = mData[currByte++]; - - U32 flagFlag = 1; // flag indicating which flag bytes are non-zero - // yeah, I know, the name sounds funny - for(U32 i = 0; i < 8; i++) - { - flagFlag = 1<<i; - - if((mData[1] & flagFlag)) - { - out->mFlags[i] = mData[currByte++]; - } - } - - *bytesUsed = currByte; - return true; + U32 currByte = 4; + + gSetInitDataDefaults(out); + + if(mData[0] & PART_SYS_KILL_P_MASK) + { + currByte = readKill_p(out, currByte); + } + + if(mData[0] & PART_SYS_BOUNCE_P_MASK) + { + currByte = readBounce_p(out, currByte); + } + + if(mData[0] & PART_SYS_BOUNCE_B_MASK) + { + currByte = readBounce_b(out, currByte); + } + + if(mData[0] & PART_SYS_ALPHA_SCALE_DIFF_MASK) + { + currByte = readAlphaScaleDiffEqn_range(out, currByte); + } + + if(mData[0] & PART_SYS_SCALE_RANGE_MASK) + { + currByte = readScale_range(out, currByte); + } + + if(mData[0] & PART_SYS_VEL_OFFSET_MASK) + { + currByte = readVelocityOffset(out, currByte); + } + + if(mData[0] & PART_SYS_M_IMAGE_UUID_MASK) + { + currByte = readUUID(out, currByte); + } + + + if(mData[3] & PART_SYS_BYTE_SPAWN_MASK) + { + currByte = readSpawn(out, currByte); + } + + if(mData[3] & PART_SYS_BYTE_ENVIRONMENT_MASK) + { + currByte = readEnvironment(out, currByte); + } + + if(mData[3] & PART_SYS_BYTE_LIFESPAN_MASK) + { + currByte = readLifespan(out, currByte); + } + + if(mData[3] & PART_SYS_BYTE_DECAY_DAMP_MASK) + { + currByte = readDecayDamp(out, currByte); + } + + if(mData[3] & PART_SYS_BYTE_WIND_DIFF_MASK) + { + currByte = readWindDiffusionFactor(out, currByte); + } + + if(mData[2] & PART_SYS_BYTE_3_ALPHA_MASK) + { + currByte = readAlpha_range(out, currByte); + } + + out->maxParticles = mData[currByte++]; + out->initialParticles = mData[currByte++]; + + U32 flagFlag = 1; // flag indicating which flag bytes are non-zero + // yeah, I know, the name sounds funny + for(U32 i = 0; i < 8; i++) + { + flagFlag = 1<<i; + + if((mData[1] & flagFlag)) + { + out->mFlags[i] = mData[currByte++]; + } + } + + *bytesUsed = currByte; + return true; } bool LLPartSysCompressedPacket::fromUnsignedBytes(U8 *in, U32 bytesUsed) { - if ((in != NULL) && (bytesUsed <= sizeof(mData))) - { - memcpy(mData, in, bytesUsed); /* Flawfinder: ignore */ - mNumBytes = bytesUsed; - return true; - } - else - { - LL_ERRS() << "NULL input data or number of bytes exceed mData size" << LL_ENDL; - return false; - } -} - + if ((in != NULL) && (bytesUsed <= sizeof(mData))) + { + memcpy(mData, in, bytesUsed); /* Flawfinder: ignore */ + mNumBytes = bytesUsed; + return true; + } + else + { + LL_ERRS() << "NULL input data or number of bytes exceed mData size" << LL_ENDL; + return false; + } +} + U32 LLPartSysCompressedPacket::bufferSize() { - return mNumBytes; + return mNumBytes; } bool LLPartSysCompressedPacket::toUnsignedBytes(U8 *out) { - memcpy(out, mData, mNumBytes); /* Flawfinder: ignore */ - return true; + memcpy(out, mData, mNumBytes); /* Flawfinder: ignore */ + return true; } U8 * LLPartSysCompressedPacket::getBytePtr() { - return mData; + return mData; } diff --git a/indra/llmessage/partsyspacket.h b/indra/llmessage/partsyspacket.h index 76c6b3e202..23307f3409 100644 --- a/indra/llmessage/partsyspacket.h +++ b/indra/llmessage/partsyspacket.h @@ -1,4 +1,4 @@ -/** +/** * @file partsyspacket.h * @brief Object for packing particle system initialization parameters * before sending them over the network @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,97 +35,97 @@ const U64 PART_SYS_MAX_TIME_IN_USEC = 1000000; // 1 second, die not quite near instantaneously -// this struct is for particle system initialization parameters +// this struct is for particle system initialization parameters // I'm breaking some rules here, but I need a storage structure to hold initialization data -// for these things. Sorry guys, they're not simple enough (yet) to avoid this cleanly +// for these things. Sorry guys, they're not simple enough (yet) to avoid this cleanly struct LLPartInitData { - // please do not add functions to this class -- data only! - //F32 k[18]; // first 9 --> x,y,z last 9 --> scale, alpha, rot - //F32 kill_p[6]; // last one is for particles that die when they reach a spherical bounding radius - //F32 kill_plane[3]; - //F32 bounce_p[5]; - F32 bounce_b; // recently changed - // no need to store orientation and position here, as they're sent over seperately - //F32 pos_ranges[6]; - //F32 vel_ranges[6]; - F32 scale_range[4]; - F32 alpha_range[4]; - F32 vel_offset[3]; //new - more understandable! - - F32 mDistBeginFadeout; // for fadeout LOD optimization - F32 mDistEndFadeout; - - LLUUID mImageUuid; - //U8 n; // number of particles - U8 mFlags[8]; // for miscellaneous data --> its interpretation can change at my whim! - U8 createMe; // do I need to be created? or has the work allready been done? - //ActionFlag is now mFlags[PART_SYS_ACTION_BYTE] - //Spawn point is initially object creation center - - F32 diffEqAlpha[3]; - F32 diffEqScale[3]; - - U8 maxParticles; - //How many particles exist at any time within the system? - U8 initialParticles; - //How many particles exist when the system is created? - F32 killPlaneZ; - //For simplicity assume the XY plane, so this sets an altitude at which to die - F32 killPlaneNormal[3]; - //Normal if not planar XY - F32 bouncePlaneZ; - //For simplicity assume the XY plane, so this sets an altitude at which to bounce - F32 bouncePlaneNormal[3]; - //Normal if not planar XY - F32 spawnRange; - //Range of emission points about the mSpawnPoint - F32 spawnFrequency; - //Required if the system is to spawn new particles. - //This variable determines the time after a particle dies when it is respawned. - F32 spawnFreqencyRange; - //Determines the random range of time until a new particle is spawned. - F32 spawnDirection[3]; - //Direction vector giving the mean direction in which particles are spawned - F32 spawnDirectionRange; - //Direction limiting the angular range of emissions about the mean direction. 1.0f means everywhere, 0.0f means uni-directional - F32 spawnVelocity; - //The mean speed at which particles are emitted - F32 spawnVelocityRange; - //The range of speeds about the mean at which particles are emitted. - F32 speedLimit; - //Used to constrain particle maximum velocity - F32 windWeight; - //How much of an effect does wind have - F32 currentGravity[3]; - //Gravity direction used in update calculations - F32 gravityWeight; - //How much of an effect does gravity have - F32 globalLifetime; - //If particles re-spawn, a system can exist forever. - //If (ActionFlags & PART_SYS_GLOBAL_DIE) is true this variable is used to determine how long the system lasts. - F32 individualLifetime; - //How long does each particle last if nothing else happens to it - F32 individualLifetimeRange; - //Range of variation in individual lifetimes - F32 alphaDecay; - //By what factor does alpha decrease as the lifetime of a particle is approached. - F32 scaleDecay; - //By what factor does scale decrease as the lifetime of a particle is approached. - F32 distanceDeath; - //With the increased functionality, particle systems can expand to indefinite size - //(e.g. wind can chaotically move particles into a wide spread). - //To avoid particles exceeding normal object size constraints, - //set the PART_SYS_DISTANCE_DEATH flag, and set a distance value here, representing a radius around the spawn point. - F32 dampMotionFactor; - //How much to damp motion - F32 windDiffusionFactor[3]; - //Change the size and alpha of particles as wind speed increases (scale gets bigger, alpha smaller) + // please do not add functions to this class -- data only! + //F32 k[18]; // first 9 --> x,y,z last 9 --> scale, alpha, rot + //F32 kill_p[6]; // last one is for particles that die when they reach a spherical bounding radius + //F32 kill_plane[3]; + //F32 bounce_p[5]; + F32 bounce_b; // recently changed + // no need to store orientation and position here, as they're sent over seperately + //F32 pos_ranges[6]; + //F32 vel_ranges[6]; + F32 scale_range[4]; + F32 alpha_range[4]; + F32 vel_offset[3]; //new - more understandable! + + F32 mDistBeginFadeout; // for fadeout LOD optimization + F32 mDistEndFadeout; + + LLUUID mImageUuid; + //U8 n; // number of particles + U8 mFlags[8]; // for miscellaneous data --> its interpretation can change at my whim! + U8 createMe; // do I need to be created? or has the work allready been done? + //ActionFlag is now mFlags[PART_SYS_ACTION_BYTE] + //Spawn point is initially object creation center + + F32 diffEqAlpha[3]; + F32 diffEqScale[3]; + + U8 maxParticles; + //How many particles exist at any time within the system? + U8 initialParticles; + //How many particles exist when the system is created? + F32 killPlaneZ; + //For simplicity assume the XY plane, so this sets an altitude at which to die + F32 killPlaneNormal[3]; + //Normal if not planar XY + F32 bouncePlaneZ; + //For simplicity assume the XY plane, so this sets an altitude at which to bounce + F32 bouncePlaneNormal[3]; + //Normal if not planar XY + F32 spawnRange; + //Range of emission points about the mSpawnPoint + F32 spawnFrequency; + //Required if the system is to spawn new particles. + //This variable determines the time after a particle dies when it is respawned. + F32 spawnFreqencyRange; + //Determines the random range of time until a new particle is spawned. + F32 spawnDirection[3]; + //Direction vector giving the mean direction in which particles are spawned + F32 spawnDirectionRange; + //Direction limiting the angular range of emissions about the mean direction. 1.0f means everywhere, 0.0f means uni-directional + F32 spawnVelocity; + //The mean speed at which particles are emitted + F32 spawnVelocityRange; + //The range of speeds about the mean at which particles are emitted. + F32 speedLimit; + //Used to constrain particle maximum velocity + F32 windWeight; + //How much of an effect does wind have + F32 currentGravity[3]; + //Gravity direction used in update calculations + F32 gravityWeight; + //How much of an effect does gravity have + F32 globalLifetime; + //If particles re-spawn, a system can exist forever. + //If (ActionFlags & PART_SYS_GLOBAL_DIE) is true this variable is used to determine how long the system lasts. + F32 individualLifetime; + //How long does each particle last if nothing else happens to it + F32 individualLifetimeRange; + //Range of variation in individual lifetimes + F32 alphaDecay; + //By what factor does alpha decrease as the lifetime of a particle is approached. + F32 scaleDecay; + //By what factor does scale decrease as the lifetime of a particle is approached. + F32 distanceDeath; + //With the increased functionality, particle systems can expand to indefinite size + //(e.g. wind can chaotically move particles into a wide spread). + //To avoid particles exceeding normal object size constraints, + //set the PART_SYS_DISTANCE_DEATH flag, and set a distance value here, representing a radius around the spawn point. + F32 dampMotionFactor; + //How much to damp motion + F32 windDiffusionFactor[3]; + //Change the size and alpha of particles as wind speed increases (scale gets bigger, alpha smaller) }; // constants for setting flag values // BYTES are in range 0-8, bits are in range 2^0 - 2^8 and can only be powers of two const int PART_SYS_NO_Z_BUFFER_BYTE = 0; // option to turn off z-buffer when rendering -const int PART_SYS_NO_Z_BUFFER_BIT = 2; // particle systems -- +const int PART_SYS_NO_Z_BUFFER_BIT = 2; // particle systems -- // I advise against using this, as it looks bad in every case I've tried const int PART_SYS_SLOW_ANIM_BYTE = 0; // slow animation down by a factor of 10 @@ -138,7 +138,7 @@ const int PART_SYS_IS_LIGHT_BYTE = 0; // indicates whether a particular partic const int PART_SYS_IS_LIGHT_BIT = 8; // is also a light object -- for andrew // should deprecate this once there is a general method for setting light properties of objects -const int PART_SYS_SPAWN_COPY_BYTE = 0; // indicates whether to spawn baby particle systems on +const int PART_SYS_SPAWN_COPY_BYTE = 0; // indicates whether to spawn baby particle systems on const int PART_SYS_SPAWN_COPY_BIT = 0x10; // particle death -- intended for smoke trails const int PART_SYS_COPY_VEL_BYTE = 0; // indicates whether baby particle systems inherit parents vel @@ -155,41 +155,41 @@ const int PART_SYS_ADAPT_TO_FRAMERATE_BIT = 0x80; // to how far we are below 60 //const U16 MAX_PART_SYS_PACKET_SIZE = 180; const U16 MAX_PART_SYS_PACKET_SIZE = 256; -//const U8 PART_SYS_K_MASK = 0x01; -const U8 PART_SYS_KILL_P_MASK = 0x02; -const U8 PART_SYS_BOUNCE_P_MASK = 0x04; -const U8 PART_SYS_BOUNCE_B_MASK = 0x08; -//const U8 PART_SYS_POS_RANGES_MASK = 0x10; -//const U8 PART_SYS_VEL_RANGES_MASK = 0x20; -const U8 PART_SYS_VEL_OFFSET_MASK = 0x10; //re-use one of the original slots now commented out -const U8 PART_SYS_ALPHA_SCALE_DIFF_MASK = 0x20; //re-use one of the original slots now commented out -const U8 PART_SYS_SCALE_RANGE_MASK = 0x40; -const U8 PART_SYS_M_IMAGE_UUID_MASK = 0x80; -const U8 PART_SYS_BYTE_3_ALPHA_MASK = 0x01; // wrapped around, didn't we? - -const U8 PART_SYS_BYTE_SPAWN_MASK = 0x01; -const U8 PART_SYS_BYTE_ENVIRONMENT_MASK = 0x02; -const U8 PART_SYS_BYTE_LIFESPAN_MASK = 0x04; -const U8 PART_SYS_BYTE_DECAY_DAMP_MASK = 0x08; -const U8 PART_SYS_BYTE_WIND_DIFF_MASK = 0x10; +//const U8 PART_SYS_K_MASK = 0x01; +const U8 PART_SYS_KILL_P_MASK = 0x02; +const U8 PART_SYS_BOUNCE_P_MASK = 0x04; +const U8 PART_SYS_BOUNCE_B_MASK = 0x08; +//const U8 PART_SYS_POS_RANGES_MASK = 0x10; +//const U8 PART_SYS_VEL_RANGES_MASK = 0x20; +const U8 PART_SYS_VEL_OFFSET_MASK = 0x10; //re-use one of the original slots now commented out +const U8 PART_SYS_ALPHA_SCALE_DIFF_MASK = 0x20; //re-use one of the original slots now commented out +const U8 PART_SYS_SCALE_RANGE_MASK = 0x40; +const U8 PART_SYS_M_IMAGE_UUID_MASK = 0x80; +const U8 PART_SYS_BYTE_3_ALPHA_MASK = 0x01; // wrapped around, didn't we? + +const U8 PART_SYS_BYTE_SPAWN_MASK = 0x01; +const U8 PART_SYS_BYTE_ENVIRONMENT_MASK = 0x02; +const U8 PART_SYS_BYTE_LIFESPAN_MASK = 0x04; +const U8 PART_SYS_BYTE_DECAY_DAMP_MASK = 0x08; +const U8 PART_SYS_BYTE_WIND_DIFF_MASK = 0x10; // 26 September 2001 - new constants for mActionFlags const int PART_SYS_ACTION_BYTE = 1; -const U8 PART_SYS_SPAWN = 0x01; -const U8 PART_SYS_BOUNCE = 0x02; -const U8 PART_SYS_AFFECTED_BY_WIND = 0x04; -const U8 PART_SYS_AFFECTED_BY_GRAVITY = 0x08; -const U8 PART_SYS_EVALUATE_WIND_PER_PARTICLE = 0x10; -const U8 PART_SYS_DAMP_MOTION = 0x20; -const U8 PART_SYS_WIND_DIFFUSION = 0x40; +const U8 PART_SYS_SPAWN = 0x01; +const U8 PART_SYS_BOUNCE = 0x02; +const U8 PART_SYS_AFFECTED_BY_WIND = 0x04; +const U8 PART_SYS_AFFECTED_BY_GRAVITY = 0x08; +const U8 PART_SYS_EVALUATE_WIND_PER_PARTICLE = 0x10; +const U8 PART_SYS_DAMP_MOTION = 0x20; +const U8 PART_SYS_WIND_DIFFUSION = 0x40; // 26 September 2001 - new constants for mKillFlags const int PART_SYS_KILL_BYTE = 2; -const U8 PART_SYS_KILL_PLANE = 0x01; -const U8 PART_SYS_GLOBAL_DIE = 0x02; -const U8 PART_SYS_DISTANCE_DEATH = 0x04; -const U8 PART_SYS_TIME_DEATH = 0x08; +const U8 PART_SYS_KILL_PLANE = 0x01; +const U8 PART_SYS_GLOBAL_DIE = 0x02; +const U8 PART_SYS_DISTANCE_DEATH = 0x04; +const U8 PART_SYS_TIME_DEATH = 0x08; // global, because the sim-side also calls it in the LLPartInitDataFactory @@ -200,61 +200,61 @@ void gSetInitDataDefaults(LLPartInitData *setMe); class LLPartSysCompressedPacket { public: - LLPartSysCompressedPacket(); - ~LLPartSysCompressedPacket(); - bool fromLLPartInitData(LLPartInitData *in, U32 &bytesUsed); - bool toLLPartInitData(LLPartInitData *out, U32 *bytesUsed); - bool fromUnsignedBytes(U8 *in, U32 bytesUsed); - bool toUnsignedBytes(U8 *out); - U32 bufferSize(); - U8 *getBytePtr(); + LLPartSysCompressedPacket(); + ~LLPartSysCompressedPacket(); + bool fromLLPartInitData(LLPartInitData *in, U32 &bytesUsed); + bool toLLPartInitData(LLPartInitData *out, U32 *bytesUsed); + bool fromUnsignedBytes(U8 *in, U32 bytesUsed); + bool toUnsignedBytes(U8 *out); + U32 bufferSize(); + U8 *getBytePtr(); protected: - U8 mData[MAX_PART_SYS_PACKET_SIZE]; - U32 mNumBytes; - LLPartInitData mDefaults; // this is intended to hold default LLPartInitData values - // please do not modify it - LLPartInitData mWorkingCopy; // uncompressed data I'm working with + U8 mData[MAX_PART_SYS_PACKET_SIZE]; + U32 mNumBytes; + LLPartInitData mDefaults; // this is intended to hold default LLPartInitData values + // please do not modify it + LLPartInitData mWorkingCopy; // uncompressed data I'm working with protected: - // private functions (used only to break up code) - void writeFlagByte(LLPartInitData *in); - //U32 writeK(LLPartInitData *in, U32 startByte); - U32 writeKill_p(LLPartInitData *in, U32 startByte); - U32 writeBounce_p(LLPartInitData *in, U32 startByte); - U32 writeBounce_b(LLPartInitData *in, U32 startByte); - //U32 writePos_ranges(LLPartInitData *in, U32 startByte); - //U32 writeVel_ranges(LLPartInitData *in, U32 startByte); - U32 writeAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte); - U32 writeScale_range(LLPartInitData *in, U32 startByte); - U32 writeAlpha_range(LLPartInitData *in, U32 startByte); - U32 writeUUID(LLPartInitData *in, U32 startByte); - - U32 writeVelocityOffset(LLPartInitData *in, U32 startByte); - U32 writeSpawn(LLPartInitData *in, U32 startByte); //all spawn data - U32 writeEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity - U32 writeLifespan(LLPartInitData *in, U32 startByte); //lifespan data - individual and global - U32 writeDecayDamp(LLPartInitData *in, U32 startByte); //alpha and scale, and motion damp - U32 writeWindDiffusionFactor(LLPartInitData *in, U32 startByte); - - - //U32 readK(LLPartInitData *in, U32 startByte); - U32 readKill_p(LLPartInitData *in, U32 startByte); - U32 readBounce_p(LLPartInitData *in, U32 startByte); - U32 readBounce_b(LLPartInitData *in, U32 startByte); - //U32 readPos_ranges(LLPartInitData *in, U32 startByte); - //U32 readVel_ranges(LLPartInitData *in, U32 startByte); - U32 readAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte); - U32 readScale_range(LLPartInitData *in, U32 startByte); - U32 readAlpha_range(LLPartInitData *in, U32 startByte); - U32 readUUID(LLPartInitData *in, U32 startByte); - - U32 readVelocityOffset(LLPartInitData *in, U32 startByte); - U32 readSpawn(LLPartInitData *in, U32 startByte); //all spawn data - U32 readEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity - U32 readLifespan(LLPartInitData *in, U32 startByte); //lifespan data - individual and global - U32 readDecayDamp(LLPartInitData *in, U32 startByte); //alpha and scale, and motion damp - U32 readWindDiffusionFactor(LLPartInitData *in, U32 startByte); + // private functions (used only to break up code) + void writeFlagByte(LLPartInitData *in); + //U32 writeK(LLPartInitData *in, U32 startByte); + U32 writeKill_p(LLPartInitData *in, U32 startByte); + U32 writeBounce_p(LLPartInitData *in, U32 startByte); + U32 writeBounce_b(LLPartInitData *in, U32 startByte); + //U32 writePos_ranges(LLPartInitData *in, U32 startByte); + //U32 writeVel_ranges(LLPartInitData *in, U32 startByte); + U32 writeAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte); + U32 writeScale_range(LLPartInitData *in, U32 startByte); + U32 writeAlpha_range(LLPartInitData *in, U32 startByte); + U32 writeUUID(LLPartInitData *in, U32 startByte); + + U32 writeVelocityOffset(LLPartInitData *in, U32 startByte); + U32 writeSpawn(LLPartInitData *in, U32 startByte); //all spawn data + U32 writeEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity + U32 writeLifespan(LLPartInitData *in, U32 startByte); //lifespan data - individual and global + U32 writeDecayDamp(LLPartInitData *in, U32 startByte); //alpha and scale, and motion damp + U32 writeWindDiffusionFactor(LLPartInitData *in, U32 startByte); + + + //U32 readK(LLPartInitData *in, U32 startByte); + U32 readKill_p(LLPartInitData *in, U32 startByte); + U32 readBounce_p(LLPartInitData *in, U32 startByte); + U32 readBounce_b(LLPartInitData *in, U32 startByte); + //U32 readPos_ranges(LLPartInitData *in, U32 startByte); + //U32 readVel_ranges(LLPartInitData *in, U32 startByte); + U32 readAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte); + U32 readScale_range(LLPartInitData *in, U32 startByte); + U32 readAlpha_range(LLPartInitData *in, U32 startByte); + U32 readUUID(LLPartInitData *in, U32 startByte); + + U32 readVelocityOffset(LLPartInitData *in, U32 startByte); + U32 readSpawn(LLPartInitData *in, U32 startByte); //all spawn data + U32 readEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity + U32 readLifespan(LLPartInitData *in, U32 startByte); //lifespan data - individual and global + U32 readDecayDamp(LLPartInitData *in, U32 startByte); //alpha and scale, and motion damp + U32 readWindDiffusionFactor(LLPartInitData *in, U32 startByte); }; #endif diff --git a/indra/llmessage/patch_code.cpp b/indra/llmessage/patch_code.cpp index c3c3e2b3b3..489b6ce6a6 100644 --- a/indra/llmessage/patch_code.cpp +++ b/indra/llmessage/patch_code.cpp @@ -1,25 +1,25 @@ -/** +/** * @file patch_code.cpp * @brief Encode patch DCT data into bitcode. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,374 +35,374 @@ U32 gPatchSize, gWordBits; -void init_patch_coding(LLBitPack &bitpack) +void init_patch_coding(LLBitPack &bitpack) { - bitpack.resetBitPacking(); + bitpack.resetBitPacking(); } -void code_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp) +void code_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp) { #ifdef LL_BIG_ENDIAN - U8 *stride = (U8 *)&gopp->stride; - bitpack.bitPack(&(stride[1]), 8); - bitpack.bitPack(&(stride[0]), 8); + U8 *stride = (U8 *)&gopp->stride; + bitpack.bitPack(&(stride[1]), 8); + bitpack.bitPack(&(stride[0]), 8); #else - bitpack.bitPack((U8 *)&gopp->stride, 16); + bitpack.bitPack((U8 *)&gopp->stride, 16); #endif - bitpack.bitPack((U8 *)&gopp->patch_size, 8); - bitpack.bitPack((U8 *)&gopp->layer_type, 8); + bitpack.bitPack((U8 *)&gopp->patch_size, 8); + bitpack.bitPack((U8 *)&gopp->layer_type, 8); - gPatchSize = gopp->patch_size; + gPatchSize = gopp->patch_size; } -void code_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, S32 *patch) +void code_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, S32 *patch) { - S32 i, j, temp, patch_size = gPatchSize, wbits = (ph->quant_wbits & 0xf) + 2; - U32 max_wbits = wbits + 5, min_wbits = wbits>>1; - - wbits = min_wbits; - - for (i = 0; i < (int) patch_size*patch_size; i++) - { - temp = patch[i]; - if (temp) - { - if (temp < 0) - temp *= -1; - for (j = max_wbits; j > (int) min_wbits; j--) - { - if (temp & (1<<j)) - { - if (j > wbits) - wbits = j; - break; - } - } - } - } - - wbits += 1; - - ph->quant_wbits &= 0xf0; - - if ( (wbits > 17) - ||(wbits < 2)) - { - LL_ERRS() << "Bits needed per word in code_patch_header out of legal range. Adjust compression quatization." << LL_ENDL; - } - - ph->quant_wbits |= (wbits - 2); - - bitpack.bitPack((U8 *)&ph->quant_wbits, 8); + S32 i, j, temp, patch_size = gPatchSize, wbits = (ph->quant_wbits & 0xf) + 2; + U32 max_wbits = wbits + 5, min_wbits = wbits>>1; + + wbits = min_wbits; + + for (i = 0; i < (int) patch_size*patch_size; i++) + { + temp = patch[i]; + if (temp) + { + if (temp < 0) + temp *= -1; + for (j = max_wbits; j > (int) min_wbits; j--) + { + if (temp & (1<<j)) + { + if (j > wbits) + wbits = j; + break; + } + } + } + } + + wbits += 1; + + ph->quant_wbits &= 0xf0; + + if ( (wbits > 17) + ||(wbits < 2)) + { + LL_ERRS() << "Bits needed per word in code_patch_header out of legal range. Adjust compression quatization." << LL_ENDL; + } + + ph->quant_wbits |= (wbits - 2); + + bitpack.bitPack((U8 *)&ph->quant_wbits, 8); #ifdef LL_BIG_ENDIAN - U8 *offset = (U8 *)&ph->dc_offset; - bitpack.bitPack(&(offset[3]), 8); - bitpack.bitPack(&(offset[2]), 8); - bitpack.bitPack(&(offset[1]), 8); - bitpack.bitPack(&(offset[0]), 8); + U8 *offset = (U8 *)&ph->dc_offset; + bitpack.bitPack(&(offset[3]), 8); + bitpack.bitPack(&(offset[2]), 8); + bitpack.bitPack(&(offset[1]), 8); + bitpack.bitPack(&(offset[0]), 8); #else - bitpack.bitPack((U8 *)&ph->dc_offset, 32); + bitpack.bitPack((U8 *)&ph->dc_offset, 32); #endif #ifdef LL_BIG_ENDIAN - U8 *range = (U8 *)&ph->range; - bitpack.bitPack(&(range[1]), 8); - bitpack.bitPack(&(range[0]), 8); + U8 *range = (U8 *)&ph->range; + bitpack.bitPack(&(range[1]), 8); + bitpack.bitPack(&(range[0]), 8); #else - bitpack.bitPack((U8 *)&ph->range, 16); + bitpack.bitPack((U8 *)&ph->range, 16); #endif #ifdef LL_BIG_ENDIAN - U8 *ids = (U8 *)&ph->patchids; - bitpack.bitPack(&(ids[1]), 8); - bitpack.bitPack(&(ids[0]), 2); + U8 *ids = (U8 *)&ph->patchids; + bitpack.bitPack(&(ids[1]), 8); + bitpack.bitPack(&(ids[0]), 2); #else - bitpack.bitPack((U8 *)&ph->patchids, 10); + bitpack.bitPack((U8 *)&ph->patchids, 10); #endif - gWordBits = wbits; + gWordBits = wbits; } -void code_end_of_data(LLBitPack &bitpack) +void code_end_of_data(LLBitPack &bitpack) { - bitpack.bitPack((U8 *)&END_OF_PATCHES, 8); + bitpack.bitPack((U8 *)&END_OF_PATCHES, 8); } void code_patch(LLBitPack &bitpack, S32 *patch, S32 postquant) { - S32 i, j, patch_size = gPatchSize, wbits = gWordBits; - S32 temp; - bool b_eob; - - if ( (postquant > patch_size*patch_size) - ||(postquant < 0)) - { - LL_ERRS() << "Bad postquant in code_patch!" << LL_ENDL; - } - - if (postquant) - patch[patch_size*patch_size - postquant] = 0; - - for (i = 0; i < patch_size*patch_size; i++) - { - b_eob = false; - temp = patch[i]; - if (!temp) - { - b_eob = true; - for (j = i; j < patch_size*patch_size - postquant; j++) - { - if (patch[j]) - { - b_eob = false; - break; - } - } - if (b_eob) - { - bitpack.bitPack((U8 *)&ZERO_EOB, 2); - return; - } - else - { - bitpack.bitPack((U8 *)&ZERO_CODE, 1); - } - } - else - { - if (temp < 0) - { - temp *= -1; - if (temp > (1<<wbits)) - { - temp = (1<<wbits); -// printf("patch quatization exceeding allowable bits!"); - } - bitpack.bitPack((U8 *)&NEGATIVE_VALUE, 3); - bitpack.bitPack((U8 *)&temp, wbits); - } - else - { - if (temp > (1<<wbits)) - { - temp = (1<<wbits); -// printf("patch quatization exceeding allowable bits!"); - } - bitpack.bitPack((U8 *)&POSITIVE_VALUE, 3); - bitpack.bitPack((U8 *)&temp, wbits); - } - } - } + S32 i, j, patch_size = gPatchSize, wbits = gWordBits; + S32 temp; + bool b_eob; + + if ( (postquant > patch_size*patch_size) + ||(postquant < 0)) + { + LL_ERRS() << "Bad postquant in code_patch!" << LL_ENDL; + } + + if (postquant) + patch[patch_size*patch_size - postquant] = 0; + + for (i = 0; i < patch_size*patch_size; i++) + { + b_eob = false; + temp = patch[i]; + if (!temp) + { + b_eob = true; + for (j = i; j < patch_size*patch_size - postquant; j++) + { + if (patch[j]) + { + b_eob = false; + break; + } + } + if (b_eob) + { + bitpack.bitPack((U8 *)&ZERO_EOB, 2); + return; + } + else + { + bitpack.bitPack((U8 *)&ZERO_CODE, 1); + } + } + else + { + if (temp < 0) + { + temp *= -1; + if (temp > (1<<wbits)) + { + temp = (1<<wbits); +// printf("patch quatization exceeding allowable bits!"); + } + bitpack.bitPack((U8 *)&NEGATIVE_VALUE, 3); + bitpack.bitPack((U8 *)&temp, wbits); + } + else + { + if (temp > (1<<wbits)) + { + temp = (1<<wbits); +// printf("patch quatization exceeding allowable bits!"); + } + bitpack.bitPack((U8 *)&POSITIVE_VALUE, 3); + bitpack.bitPack((U8 *)&temp, wbits); + } + } + } } -void end_patch_coding(LLBitPack &bitpack) +void end_patch_coding(LLBitPack &bitpack) { - bitpack.flushBitPack(); + bitpack.flushBitPack(); } -void init_patch_decoding(LLBitPack &bitpack) +void init_patch_decoding(LLBitPack &bitpack) { - bitpack.resetBitPacking(); + bitpack.resetBitPacking(); } -void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp) +void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp) { - U16 retvalu16; + U16 retvalu16; - retvalu16 = 0; + retvalu16 = 0; #ifdef LL_BIG_ENDIAN - U8 *ret = (U8 *)&retvalu16; - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), 8); + U8 *ret = (U8 *)&retvalu16; + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), 8); #else - bitpack.bitUnpack((U8 *)&retvalu16, 16); + bitpack.bitUnpack((U8 *)&retvalu16, 16); #endif - gopp->stride = retvalu16; + gopp->stride = retvalu16; - U8 retvalu8 = 0; - bitpack.bitUnpack(&retvalu8, 8); - gopp->patch_size = retvalu8; + U8 retvalu8 = 0; + bitpack.bitUnpack(&retvalu8, 8); + gopp->patch_size = retvalu8; - retvalu8 = 0; - bitpack.bitUnpack(&retvalu8, 8); - gopp->layer_type = retvalu8; + retvalu8 = 0; + bitpack.bitUnpack(&retvalu8, 8); + gopp->layer_type = retvalu8; - gPatchSize = gopp->patch_size; + gPatchSize = gopp->patch_size; } -void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph) +void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph) { - U8 retvalu8; - - retvalu8 = 0; - bitpack.bitUnpack(&retvalu8, 8); - ph->quant_wbits = retvalu8; - - if (END_OF_PATCHES == ph->quant_wbits) - { - // End of data, blitz the rest. - ph->dc_offset = 0; - ph->range = 0; - ph->patchids = 0; - return; - } - - U32 retvalu32 = 0; + U8 retvalu8; + + retvalu8 = 0; + bitpack.bitUnpack(&retvalu8, 8); + ph->quant_wbits = retvalu8; + + if (END_OF_PATCHES == ph->quant_wbits) + { + // End of data, blitz the rest. + ph->dc_offset = 0; + ph->range = 0; + ph->patchids = 0; + return; + } + + U32 retvalu32 = 0; #ifdef LL_BIG_ENDIAN - U8 *ret = (U8 *)&retvalu32; - bitpack.bitUnpack(&(ret[3]), 8); - bitpack.bitUnpack(&(ret[2]), 8); - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), 8); + U8 *ret = (U8 *)&retvalu32; + bitpack.bitUnpack(&(ret[3]), 8); + bitpack.bitUnpack(&(ret[2]), 8); + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), 8); #else - bitpack.bitUnpack((U8 *)&retvalu32, 32); + bitpack.bitUnpack((U8 *)&retvalu32, 32); #endif - ph->dc_offset = *(F32 *)&retvalu32; + ph->dc_offset = *(F32 *)&retvalu32; - U16 retvalu16 = 0; + U16 retvalu16 = 0; #ifdef LL_BIG_ENDIAN - ret = (U8 *)&retvalu16; - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), 8); + ret = (U8 *)&retvalu16; + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), 8); #else - bitpack.bitUnpack((U8 *)&retvalu16, 16); + bitpack.bitUnpack((U8 *)&retvalu16, 16); #endif - ph->range = retvalu16; + ph->range = retvalu16; - retvalu16 = 0; + retvalu16 = 0; #ifdef LL_BIG_ENDIAN - ret = (U8 *)&retvalu16; - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), 2); + ret = (U8 *)&retvalu16; + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), 2); #else - bitpack.bitUnpack((U8 *)&retvalu16, 10); + bitpack.bitUnpack((U8 *)&retvalu16, 10); #endif - ph->patchids = retvalu16; + ph->patchids = retvalu16; - gWordBits = (ph->quant_wbits & 0xf) + 2; + gWordBits = (ph->quant_wbits & 0xf) + 2; } -void decode_patch(LLBitPack &bitpack, S32 *patches) +void decode_patch(LLBitPack &bitpack, S32 *patches) { #ifdef LL_BIG_ENDIAN - S32 i, j, patch_size = gPatchSize, wbits = gWordBits; - U8 tempu8; - U16 tempu16; - U32 tempu32; - for (i = 0; i < patch_size*patch_size; i++) - { - bitpack.bitUnpack((U8 *)&tempu8, 1); - if (tempu8) - { - // either 0 EOB or Value - bitpack.bitUnpack((U8 *)&tempu8, 1); - if (tempu8) - { - // value - bitpack.bitUnpack((U8 *)&tempu8, 1); - if (tempu8) - { - // negative - patches[i] = -1; - } - else - { - // positive - patches[i] = 1; - } - if (wbits <= 8) - { - bitpack.bitUnpack((U8 *)&tempu8, wbits); - patches[i] *= tempu8; - } - else if (wbits <= 16) - { - tempu16 = 0; - U8 *ret = (U8 *)&tempu16; - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), wbits - 8); - patches[i] *= tempu16; - } - else if (wbits <= 24) - { - tempu32 = 0; - U8 *ret = (U8 *)&tempu32; - bitpack.bitUnpack(&(ret[2]), 8); - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), wbits - 16); - patches[i] *= tempu32; - } - else if (wbits <= 32) - { - tempu32 = 0; - U8 *ret = (U8 *)&tempu32; - bitpack.bitUnpack(&(ret[3]), 8); - bitpack.bitUnpack(&(ret[2]), 8); - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), wbits - 24); - patches[i] *= tempu32; - } - } - else - { - for (j = i; j < patch_size*patch_size; j++) - { - patches[j] = 0; - } - return; - } - } - else - { - patches[i] = 0; - } - } + S32 i, j, patch_size = gPatchSize, wbits = gWordBits; + U8 tempu8; + U16 tempu16; + U32 tempu32; + for (i = 0; i < patch_size*patch_size; i++) + { + bitpack.bitUnpack((U8 *)&tempu8, 1); + if (tempu8) + { + // either 0 EOB or Value + bitpack.bitUnpack((U8 *)&tempu8, 1); + if (tempu8) + { + // value + bitpack.bitUnpack((U8 *)&tempu8, 1); + if (tempu8) + { + // negative + patches[i] = -1; + } + else + { + // positive + patches[i] = 1; + } + if (wbits <= 8) + { + bitpack.bitUnpack((U8 *)&tempu8, wbits); + patches[i] *= tempu8; + } + else if (wbits <= 16) + { + tempu16 = 0; + U8 *ret = (U8 *)&tempu16; + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), wbits - 8); + patches[i] *= tempu16; + } + else if (wbits <= 24) + { + tempu32 = 0; + U8 *ret = (U8 *)&tempu32; + bitpack.bitUnpack(&(ret[2]), 8); + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), wbits - 16); + patches[i] *= tempu32; + } + else if (wbits <= 32) + { + tempu32 = 0; + U8 *ret = (U8 *)&tempu32; + bitpack.bitUnpack(&(ret[3]), 8); + bitpack.bitUnpack(&(ret[2]), 8); + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), wbits - 24); + patches[i] *= tempu32; + } + } + else + { + for (j = i; j < patch_size*patch_size; j++) + { + patches[j] = 0; + } + return; + } + } + else + { + patches[i] = 0; + } + } #else - S32 i, j, patch_size = gPatchSize, wbits = gWordBits; - U32 temp; - for (i = 0; i < patch_size*patch_size; i++) - { - temp = 0; - bitpack.bitUnpack((U8 *)&temp, 1); - if (temp) - { - // either 0 EOB or Value - temp = 0; - bitpack.bitUnpack((U8 *)&temp, 1); - if (temp) - { - // value - temp = 0; - bitpack.bitUnpack((U8 *)&temp, 1); - if (temp) - { - // negative - temp = 0; - bitpack.bitUnpack((U8 *)&temp, wbits); - patches[i] = temp; - patches[i] *= -1; - } - else - { - // positive - temp = 0; - bitpack.bitUnpack((U8 *)&temp, wbits); - patches[i] = temp; - } - } - else - { - for (j = i; j < patch_size*patch_size; j++) - { - patches[j] = 0; - } - return; - } - } - else - { - patches[i] = 0; - } - } + S32 i, j, patch_size = gPatchSize, wbits = gWordBits; + U32 temp; + for (i = 0; i < patch_size*patch_size; i++) + { + temp = 0; + bitpack.bitUnpack((U8 *)&temp, 1); + if (temp) + { + // either 0 EOB or Value + temp = 0; + bitpack.bitUnpack((U8 *)&temp, 1); + if (temp) + { + // value + temp = 0; + bitpack.bitUnpack((U8 *)&temp, 1); + if (temp) + { + // negative + temp = 0; + bitpack.bitUnpack((U8 *)&temp, wbits); + patches[i] = temp; + patches[i] *= -1; + } + else + { + // positive + temp = 0; + bitpack.bitUnpack((U8 *)&temp, wbits); + patches[i] = temp; + } + } + else + { + for (j = i; j < patch_size*patch_size; j++) + { + patches[j] = 0; + } + return; + } + } + else + { + patches[i] = 0; + } + } #endif } diff --git a/indra/llmessage/patch_code.h b/indra/llmessage/patch_code.h index 4c87c9808a..ee8bd58844 100644 --- a/indra/llmessage/patch_code.h +++ b/indra/llmessage/patch_code.h @@ -1,25 +1,25 @@ -/** +/** * @file patch_code.h * @brief Function declarations for encoding and decoding patches. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,16 +31,16 @@ class LLBitPack; class LLGroupHeader; class LLPatchHeader; -void init_patch_coding(LLBitPack &bitpack); -void code_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp); -void code_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, S32 *patch); -void code_end_of_data(LLBitPack &bitpack); -void code_patch(LLBitPack &bitpack, S32 *patch, S32 postquant); -void end_patch_coding(LLBitPack &bitpack); +void init_patch_coding(LLBitPack &bitpack); +void code_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp); +void code_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, S32 *patch); +void code_end_of_data(LLBitPack &bitpack); +void code_patch(LLBitPack &bitpack, S32 *patch, S32 postquant); +void end_patch_coding(LLBitPack &bitpack); -void init_patch_decoding(LLBitPack &bitpack); -void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp); -void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph); -void decode_patch(LLBitPack &bitpack, S32 *patches); +void init_patch_decoding(LLBitPack &bitpack); +void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp); +void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph); +void decode_patch(LLBitPack &bitpack, S32 *patches); #endif diff --git a/indra/llmessage/patch_dct.cpp b/indra/llmessage/patch_dct.cpp index 2144b4e712..728fe84537 100644 --- a/indra/llmessage/patch_dct.cpp +++ b/indra/llmessage/patch_dct.cpp @@ -1,25 +1,25 @@ -/** +/** * @file patch_dct.cpp * @brief DCT patch. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,737 +33,737 @@ typedef struct s_patch_compress_global_data { - S32 patch_size; - S32 patch_stride; - U32 charptr; - S32 layer_type; + S32 patch_size; + S32 patch_stride; + U32 charptr; + S32 layer_type; } PCGD; -PCGD gPatchCompressGlobalData; +PCGD gPatchCompressGlobalData; void reset_patch_compressor(void) { - PCGD *pcp = &gPatchCompressGlobalData; + PCGD *pcp = &gPatchCompressGlobalData; - pcp->charptr = 0; + pcp->charptr = 0; } -S32 gCurrentSize = 0; +S32 gCurrentSize = 0; F32 gPatchQuantizeTable[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; void build_patch_quantize_table(S32 size) { - S32 i, j; - for (j = 0; j < size; j++) - { - for (i = 0; i < size; i++) - { - gPatchQuantizeTable[j*size + i] = 1.f/(1.f + 2.f*(i+j)); - } - } + S32 i, j; + for (j = 0; j < size; j++) + { + for (i = 0; i < size; i++) + { + gPatchQuantizeTable[j*size + i] = 1.f/(1.f + 2.f*(i+j)); + } + } } -F32 gPatchCosines[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; +F32 gPatchCosines[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; void setup_patch_cosines(S32 size) { - S32 n, u; - F32 oosob = F_PI*0.5f/size; - - for (u = 0; u < size; u++) - { - for (n = 0; n < size; n++) - { - gPatchCosines[u*size+n] = cosf((2.f*n+1.f)*u*oosob); - } - } + S32 n, u; + F32 oosob = F_PI*0.5f/size; + + for (u = 0; u < size; u++) + { + for (n = 0; n < size; n++) + { + gPatchCosines[u*size+n] = cosf((2.f*n+1.f)*u*oosob); + } + } } -S32 gCopyMatrix[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; +S32 gCopyMatrix[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; void build_copy_matrix(S32 size) { - S32 i, j, count; - bool b_diag = false; - bool b_right = true; - - i = 0; - j = 0; - count = 0; - - while ( (i < size) - &&(j < size)) - { - gCopyMatrix[j*size + i] = count; - - count++; - - if (!b_diag) - { - if (b_right) - { - if (i < size - 1) - i++; - else - j++; - b_right = false; - b_diag = true; - } - else - { - if (j < size - 1) - j++; - else - i++; - b_right = true; - b_diag = true; - } - } - else - { - if (b_right) - { - i++; - j--; - if ( (i == size - 1) - ||(j == 0)) - { - b_diag = false; - } - } - else - { - i--; - j++; - if ( (i == 0) - ||(j == size - 1)) - { - b_diag = false; - } - } - } - } + S32 i, j, count; + bool b_diag = false; + bool b_right = true; + + i = 0; + j = 0; + count = 0; + + while ( (i < size) + &&(j < size)) + { + gCopyMatrix[j*size + i] = count; + + count++; + + if (!b_diag) + { + if (b_right) + { + if (i < size - 1) + i++; + else + j++; + b_right = false; + b_diag = true; + } + else + { + if (j < size - 1) + j++; + else + i++; + b_right = true; + b_diag = true; + } + } + else + { + if (b_right) + { + i++; + j--; + if ( (i == size - 1) + ||(j == 0)) + { + b_diag = false; + } + } + else + { + i--; + j++; + if ( (i == 0) + ||(j == size - 1)) + { + b_diag = false; + } + } + } + } } void init_patch_compressor(S32 patch_size, S32 patch_stride, S32 layer_type) { - PCGD *pcp = &gPatchCompressGlobalData; + PCGD *pcp = &gPatchCompressGlobalData; - pcp->charptr = 0; + pcp->charptr = 0; - pcp->patch_size = patch_size; - pcp->patch_stride = patch_stride; - pcp->layer_type = layer_type; + pcp->patch_size = patch_size; + pcp->patch_stride = patch_stride; + pcp->layer_type = layer_type; - if (patch_size != gCurrentSize) - { - gCurrentSize = patch_size; - build_patch_quantize_table(patch_size); - setup_patch_cosines(patch_size); - build_copy_matrix(patch_size); - } + if (patch_size != gCurrentSize) + { + gCurrentSize = patch_size; + build_patch_quantize_table(patch_size); + setup_patch_cosines(patch_size); + build_copy_matrix(patch_size); + } } void prescan_patch(F32 *patch, LLPatchHeader *php, F32 &zmax, F32 &zmin) { - S32 i, j; - PCGD *pcp = &gPatchCompressGlobalData; - S32 stride = pcp->patch_stride; - S32 size = pcp->patch_size; - S32 jstride; - - zmax = -99999999.f; - zmin = 99999999.f; - - for (j = 0; j < size; j++) - { - jstride = j*stride; - for (i = 0; i < size; i++) - { - if (*(patch + jstride + i) > zmax) - { - zmax = *(patch + jstride + i); - } - if (*(patch + jstride + i) < zmin) - { - zmin = *(patch + jstride + i); - } - } - } - - php->dc_offset = zmin; - php->range = (U16) ((zmax - zmin) + 1.f); + S32 i, j; + PCGD *pcp = &gPatchCompressGlobalData; + S32 stride = pcp->patch_stride; + S32 size = pcp->patch_size; + S32 jstride; + + zmax = -99999999.f; + zmin = 99999999.f; + + for (j = 0; j < size; j++) + { + jstride = j*stride; + for (i = 0; i < size; i++) + { + if (*(patch + jstride + i) > zmax) + { + zmax = *(patch + jstride + i); + } + if (*(patch + jstride + i) < zmin) + { + zmin = *(patch + jstride + i); + } + } + } + + php->dc_offset = zmin; + php->range = (U16) ((zmax - zmin) + 1.f); } void dct_line(F32 *linein, F32 *lineout, S32 line) { - S32 u; - F32 total; - F32 *pcp = gPatchCosines; - S32 line_size = line*NORMAL_PATCH_SIZE; + S32 u; + F32 total; + F32 *pcp = gPatchCosines; + S32 line_size = line*NORMAL_PATCH_SIZE; #ifdef _PATCH_SIZE_16_AND_32_ONLY - F32 *tlinein, *tpcp; - - tlinein = linein + line_size; - - total = *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein); - - *(lineout + line_size) = OO_SQRT2*total; - - for (u = 1; u < NORMAL_PATCH_SIZE; u++) - { - tlinein = linein + line_size; - tpcp = pcp + (u<<4); - - total = *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein)*(*tpcp); - - *(lineout + line_size + u) = total; - } + F32 *tlinein, *tpcp; + + tlinein = linein + line_size; + + total = *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein); + + *(lineout + line_size) = OO_SQRT2*total; + + for (u = 1; u < NORMAL_PATCH_SIZE; u++) + { + tlinein = linein + line_size; + tpcp = pcp + (u<<4); + + total = *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein)*(*tpcp); + + *(lineout + line_size + u) = total; + } #else - S32 n; - S32 size = gPatchCompressGlobalData.patch_size; - total = 0.f; - for (n = 0; n < size; n++) - { - total += linein[line_size + n]; - } - lineout[line_size] = OO_SQRT2*total; - - for (u = 1; u < size; u++) - { - total = 0.f; - for (n = 0; n < size; n++) - { - total += linein[line_size + n]*pcp[u*size+n]; - } - lineout[line_size + u] = total; - } + S32 n; + S32 size = gPatchCompressGlobalData.patch_size; + total = 0.f; + for (n = 0; n < size; n++) + { + total += linein[line_size + n]; + } + lineout[line_size] = OO_SQRT2*total; + + for (u = 1; u < size; u++) + { + total = 0.f; + for (n = 0; n < size; n++) + { + total += linein[line_size + n]*pcp[u*size+n]; + } + lineout[line_size + u] = total; + } #endif } void dct_line_large(F32 *linein, F32 *lineout, S32 line) { - S32 u; - F32 total; - F32 *pcp = gPatchCosines; - S32 line_size = line*LARGE_PATCH_SIZE; - - F32 *tlinein, *tpcp; - - tlinein = linein + line_size; - - total = *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein++); - total += *(tlinein); - - *(lineout + line_size) = OO_SQRT2*total; - - for (u = 1; u < LARGE_PATCH_SIZE; u++) - { - tlinein = linein + line_size; - tpcp = pcp + (u<<5); - - total = *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein++)*(*(tpcp++)); - total += *(tlinein)*(*tpcp); - - *(lineout + line_size + u) = total; - } + S32 u; + F32 total; + F32 *pcp = gPatchCosines; + S32 line_size = line*LARGE_PATCH_SIZE; + + F32 *tlinein, *tpcp; + + tlinein = linein + line_size; + + total = *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein++); + total += *(tlinein); + + *(lineout + line_size) = OO_SQRT2*total; + + for (u = 1; u < LARGE_PATCH_SIZE; u++) + { + tlinein = linein + line_size; + tpcp = pcp + (u<<5); + + total = *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein++)*(*(tpcp++)); + total += *(tlinein)*(*tpcp); + + *(lineout + line_size + u) = total; + } } inline void dct_column(F32 *linein, S32 *lineout, S32 column) { - S32 u; - F32 total; - F32 oosob = 2.f/16.f; - F32 *pcp = gPatchCosines; - S32 *copy_matrix = gCopyMatrix; - F32 *qt = gPatchQuantizeTable; + S32 u; + F32 total; + F32 oosob = 2.f/16.f; + F32 *pcp = gPatchCosines; + S32 *copy_matrix = gCopyMatrix; + F32 *qt = gPatchQuantizeTable; #ifdef _PATCH_SIZE_16_AND_32_ONLY - F32 *tlinein, *tpcp; - S32 sizeu; - - tlinein = linein + column; - - total = *(tlinein); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - total += *(tlinein += NORMAL_PATCH_SIZE); - - *(lineout + *(copy_matrix + column)) = (S32)(OO_SQRT2*total*oosob*(*(qt + column))); - - for (u = 1; u < NORMAL_PATCH_SIZE; u++) - { - tlinein = linein + column; - tpcp = pcp + (u<<4); - - total = *(tlinein)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp)); - - sizeu = NORMAL_PATCH_SIZE*u + column; - - *(lineout + *(copy_matrix + sizeu)) = (S32)(total*oosob*(*(qt+sizeu))); - } + F32 *tlinein, *tpcp; + S32 sizeu; + + tlinein = linein + column; + + total = *(tlinein); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + total += *(tlinein += NORMAL_PATCH_SIZE); + + *(lineout + *(copy_matrix + column)) = (S32)(OO_SQRT2*total*oosob*(*(qt + column))); + + for (u = 1; u < NORMAL_PATCH_SIZE; u++) + { + tlinein = linein + column; + tpcp = pcp + (u<<4); + + total = *(tlinein)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp)); + + sizeu = NORMAL_PATCH_SIZE*u + column; + + *(lineout + *(copy_matrix + sizeu)) = (S32)(total*oosob*(*(qt+sizeu))); + } #else - S32 size = gPatchCompressGlobalData.patch_size; - F32 oosob = 2.f/size; - S32 n; - total = 0.f; - for (n = 0; n < size; n++) - { - total += linein[size*n + column]; - } - lineout[copy_matrix[column]] = OO_SQRT2*total*oosob*qt[column]; - - for (u = 1; u < size; u++) - { - total = 0.f; - for (n = 0; n < size; n++) - { - total += linein[size*n + column]*pcp[u*size+n]; - } - lineout[copy_matrix[size*u + column]] = total*oosob*qt[size*u + column]; - } + S32 size = gPatchCompressGlobalData.patch_size; + F32 oosob = 2.f/size; + S32 n; + total = 0.f; + for (n = 0; n < size; n++) + { + total += linein[size*n + column]; + } + lineout[copy_matrix[column]] = OO_SQRT2*total*oosob*qt[column]; + + for (u = 1; u < size; u++) + { + total = 0.f; + for (n = 0; n < size; n++) + { + total += linein[size*n + column]*pcp[u*size+n]; + } + lineout[copy_matrix[size*u + column]] = total*oosob*qt[size*u + column]; + } #endif } inline void dct_column_large(F32 *linein, S32 *lineout, S32 column) { - S32 u; - F32 total; - F32 oosob = 2.f/32.f; - F32 *pcp = gPatchCosines; - S32 *copy_matrix = gCopyMatrix; - F32 *qt = gPatchQuantizeTable; - - F32 *tlinein, *tpcp; - S32 sizeu; - - tlinein = linein + column; - - total = *(tlinein); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - total += *(tlinein += LARGE_PATCH_SIZE); - - *(lineout + *(copy_matrix + column)) = (S32)(OO_SQRT2*total*oosob*(*(qt + column))); - - for (u = 1; u < LARGE_PATCH_SIZE; u++) - { - tlinein = linein + column; - tpcp = pcp + (u<<5); - - total = *(tlinein)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp)); - - sizeu = LARGE_PATCH_SIZE*u + column; - - *(lineout + *(copy_matrix + sizeu)) = (S32)(total*oosob*(*(qt+sizeu))); - } + S32 u; + F32 total; + F32 oosob = 2.f/32.f; + F32 *pcp = gPatchCosines; + S32 *copy_matrix = gCopyMatrix; + F32 *qt = gPatchQuantizeTable; + + F32 *tlinein, *tpcp; + S32 sizeu; + + tlinein = linein + column; + + total = *(tlinein); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + total += *(tlinein += LARGE_PATCH_SIZE); + + *(lineout + *(copy_matrix + column)) = (S32)(OO_SQRT2*total*oosob*(*(qt + column))); + + for (u = 1; u < LARGE_PATCH_SIZE; u++) + { + tlinein = linein + column; + tpcp = pcp + (u<<5); + + total = *(tlinein)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp++)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp)); + + sizeu = LARGE_PATCH_SIZE*u + column; + + *(lineout + *(copy_matrix + sizeu)) = (S32)(total*oosob*(*(qt+sizeu))); + } } inline void dct_patch(F32 *block, S32 *cpatch) { - F32 temp[NORMAL_PATCH_SIZE*NORMAL_PATCH_SIZE]; + F32 temp[NORMAL_PATCH_SIZE*NORMAL_PATCH_SIZE]; #ifdef _PATCH_SIZE_16_AND_32_ONLY - dct_line(block, temp, 0); - dct_line(block, temp, 1); - dct_line(block, temp, 2); - dct_line(block, temp, 3); - - dct_line(block, temp, 4); - dct_line(block, temp, 5); - dct_line(block, temp, 6); - dct_line(block, temp, 7); - - dct_line(block, temp, 8); - dct_line(block, temp, 9); - dct_line(block, temp, 10); - dct_line(block, temp, 11); - - dct_line(block, temp, 12); - dct_line(block, temp, 13); - dct_line(block, temp, 14); - dct_line(block, temp, 15); - - dct_column(temp, cpatch, 0); - dct_column(temp, cpatch, 1); - dct_column(temp, cpatch, 2); - dct_column(temp, cpatch, 3); - - dct_column(temp, cpatch, 4); - dct_column(temp, cpatch, 5); - dct_column(temp, cpatch, 6); - dct_column(temp, cpatch, 7); - - dct_column(temp, cpatch, 8); - dct_column(temp, cpatch, 9); - dct_column(temp, cpatch, 10); - dct_column(temp, cpatch, 11); - - dct_column(temp, cpatch, 12); - dct_column(temp, cpatch, 13); - dct_column(temp, cpatch, 14); - dct_column(temp, cpatch, 15); + dct_line(block, temp, 0); + dct_line(block, temp, 1); + dct_line(block, temp, 2); + dct_line(block, temp, 3); + + dct_line(block, temp, 4); + dct_line(block, temp, 5); + dct_line(block, temp, 6); + dct_line(block, temp, 7); + + dct_line(block, temp, 8); + dct_line(block, temp, 9); + dct_line(block, temp, 10); + dct_line(block, temp, 11); + + dct_line(block, temp, 12); + dct_line(block, temp, 13); + dct_line(block, temp, 14); + dct_line(block, temp, 15); + + dct_column(temp, cpatch, 0); + dct_column(temp, cpatch, 1); + dct_column(temp, cpatch, 2); + dct_column(temp, cpatch, 3); + + dct_column(temp, cpatch, 4); + dct_column(temp, cpatch, 5); + dct_column(temp, cpatch, 6); + dct_column(temp, cpatch, 7); + + dct_column(temp, cpatch, 8); + dct_column(temp, cpatch, 9); + dct_column(temp, cpatch, 10); + dct_column(temp, cpatch, 11); + + dct_column(temp, cpatch, 12); + dct_column(temp, cpatch, 13); + dct_column(temp, cpatch, 14); + dct_column(temp, cpatch, 15); #else - S32 i; - S32 size = gPatchCompressGlobalData.patch_size; - for (i = 0; i < size; i++) - { - dct_line(block, temp, i); - } - for (i = 0; i < size; i++) - { - dct_column(temp, cpatch, i); - } + S32 i; + S32 size = gPatchCompressGlobalData.patch_size; + for (i = 0; i < size; i++) + { + dct_line(block, temp, i); + } + for (i = 0; i < size; i++) + { + dct_column(temp, cpatch, i); + } #endif } inline void dct_patch_large(F32 *block, S32 *cpatch) { - F32 temp[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; - - dct_line_large(block, temp, 0); - dct_line_large(block, temp, 1); - dct_line_large(block, temp, 2); - dct_line_large(block, temp, 3); - - dct_line_large(block, temp, 4); - dct_line_large(block, temp, 5); - dct_line_large(block, temp, 6); - dct_line_large(block, temp, 7); - - dct_line_large(block, temp, 8); - dct_line_large(block, temp, 9); - dct_line_large(block, temp, 10); - dct_line_large(block, temp, 11); - - dct_line_large(block, temp, 12); - dct_line_large(block, temp, 13); - dct_line_large(block, temp, 14); - dct_line_large(block, temp, 15); - - dct_line_large(block, temp, 16); - dct_line_large(block, temp, 17); - dct_line_large(block, temp, 18); - dct_line_large(block, temp, 19); - - dct_line_large(block, temp, 20); - dct_line_large(block, temp, 21); - dct_line_large(block, temp, 22); - dct_line_large(block, temp, 23); - - dct_line_large(block, temp, 24); - dct_line_large(block, temp, 25); - dct_line_large(block, temp, 26); - dct_line_large(block, temp, 27); - - dct_line_large(block, temp, 28); - dct_line_large(block, temp, 29); - dct_line_large(block, temp, 30); - dct_line_large(block, temp, 31); - - dct_column_large(temp, cpatch, 0); - dct_column_large(temp, cpatch, 1); - dct_column_large(temp, cpatch, 2); - dct_column_large(temp, cpatch, 3); - - dct_column_large(temp, cpatch, 4); - dct_column_large(temp, cpatch, 5); - dct_column_large(temp, cpatch, 6); - dct_column_large(temp, cpatch, 7); - - dct_column_large(temp, cpatch, 8); - dct_column_large(temp, cpatch, 9); - dct_column_large(temp, cpatch, 10); - dct_column_large(temp, cpatch, 11); - - dct_column_large(temp, cpatch, 12); - dct_column_large(temp, cpatch, 13); - dct_column_large(temp, cpatch, 14); - dct_column_large(temp, cpatch, 15); - - dct_column_large(temp, cpatch, 16); - dct_column_large(temp, cpatch, 17); - dct_column_large(temp, cpatch, 18); - dct_column_large(temp, cpatch, 19); - - dct_column_large(temp, cpatch, 20); - dct_column_large(temp, cpatch, 21); - dct_column_large(temp, cpatch, 22); - dct_column_large(temp, cpatch, 23); - - dct_column_large(temp, cpatch, 24); - dct_column_large(temp, cpatch, 25); - dct_column_large(temp, cpatch, 26); - dct_column_large(temp, cpatch, 27); - - dct_column_large(temp, cpatch, 28); - dct_column_large(temp, cpatch, 29); - dct_column_large(temp, cpatch, 30); - dct_column_large(temp, cpatch, 31); + F32 temp[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; + + dct_line_large(block, temp, 0); + dct_line_large(block, temp, 1); + dct_line_large(block, temp, 2); + dct_line_large(block, temp, 3); + + dct_line_large(block, temp, 4); + dct_line_large(block, temp, 5); + dct_line_large(block, temp, 6); + dct_line_large(block, temp, 7); + + dct_line_large(block, temp, 8); + dct_line_large(block, temp, 9); + dct_line_large(block, temp, 10); + dct_line_large(block, temp, 11); + + dct_line_large(block, temp, 12); + dct_line_large(block, temp, 13); + dct_line_large(block, temp, 14); + dct_line_large(block, temp, 15); + + dct_line_large(block, temp, 16); + dct_line_large(block, temp, 17); + dct_line_large(block, temp, 18); + dct_line_large(block, temp, 19); + + dct_line_large(block, temp, 20); + dct_line_large(block, temp, 21); + dct_line_large(block, temp, 22); + dct_line_large(block, temp, 23); + + dct_line_large(block, temp, 24); + dct_line_large(block, temp, 25); + dct_line_large(block, temp, 26); + dct_line_large(block, temp, 27); + + dct_line_large(block, temp, 28); + dct_line_large(block, temp, 29); + dct_line_large(block, temp, 30); + dct_line_large(block, temp, 31); + + dct_column_large(temp, cpatch, 0); + dct_column_large(temp, cpatch, 1); + dct_column_large(temp, cpatch, 2); + dct_column_large(temp, cpatch, 3); + + dct_column_large(temp, cpatch, 4); + dct_column_large(temp, cpatch, 5); + dct_column_large(temp, cpatch, 6); + dct_column_large(temp, cpatch, 7); + + dct_column_large(temp, cpatch, 8); + dct_column_large(temp, cpatch, 9); + dct_column_large(temp, cpatch, 10); + dct_column_large(temp, cpatch, 11); + + dct_column_large(temp, cpatch, 12); + dct_column_large(temp, cpatch, 13); + dct_column_large(temp, cpatch, 14); + dct_column_large(temp, cpatch, 15); + + dct_column_large(temp, cpatch, 16); + dct_column_large(temp, cpatch, 17); + dct_column_large(temp, cpatch, 18); + dct_column_large(temp, cpatch, 19); + + dct_column_large(temp, cpatch, 20); + dct_column_large(temp, cpatch, 21); + dct_column_large(temp, cpatch, 22); + dct_column_large(temp, cpatch, 23); + + dct_column_large(temp, cpatch, 24); + dct_column_large(temp, cpatch, 25); + dct_column_large(temp, cpatch, 26); + dct_column_large(temp, cpatch, 27); + + dct_column_large(temp, cpatch, 28); + dct_column_large(temp, cpatch, 29); + dct_column_large(temp, cpatch, 30); + dct_column_large(temp, cpatch, 31); } void compress_patch(F32 *patch, S32 *cpatch, LLPatchHeader *php, S32 prequant) { - S32 i, j; - PCGD *pcp = &gPatchCompressGlobalData; - S32 stride = pcp->patch_stride; - S32 size = pcp->patch_size; - F32 block[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE], *tblock; - F32 *tpatch; - - S32 wordsize = prequant; - F32 oozrange = 1.f/php->range; - - F32 dc = php->dc_offset; - - S32 range = (1<<prequant); - F32 premult = oozrange*range; -// F32 sub = (F32)(1<<(prequant - 1)); - F32 sub = (F32)(1<<(prequant - 1)) + dc*premult; - - php->quant_wbits = wordsize - 2; - php->quant_wbits |= (prequant - 2)<<4; - - for (j = 0; j < size; j++) - { - tblock = block + j*size; - tpatch = patch + j*stride; - for (i = 0; i < size; i++) - { -// block[j*size + i] = (patch[j*stride + i] - dc)*premult - sub; - *(tblock++) = *(tpatch++)*premult - sub; - } - } - - if (size == 16) - dct_patch(block, cpatch); - else - dct_patch_large(block, cpatch); + S32 i, j; + PCGD *pcp = &gPatchCompressGlobalData; + S32 stride = pcp->patch_stride; + S32 size = pcp->patch_size; + F32 block[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE], *tblock; + F32 *tpatch; + + S32 wordsize = prequant; + F32 oozrange = 1.f/php->range; + + F32 dc = php->dc_offset; + + S32 range = (1<<prequant); + F32 premult = oozrange*range; +// F32 sub = (F32)(1<<(prequant - 1)); + F32 sub = (F32)(1<<(prequant - 1)) + dc*premult; + + php->quant_wbits = wordsize - 2; + php->quant_wbits |= (prequant - 2)<<4; + + for (j = 0; j < size; j++) + { + tblock = block + j*size; + tpatch = patch + j*stride; + for (i = 0; i < size; i++) + { +// block[j*size + i] = (patch[j*stride + i] - dc)*premult - sub; + *(tblock++) = *(tpatch++)*premult - sub; + } + } + + if (size == 16) + dct_patch(block, cpatch); + else + dct_patch_large(block, cpatch); } void get_patch_group_header(LLGroupHeader *gopp) { - PCGD *pcp = &gPatchCompressGlobalData; - gopp->stride = pcp->patch_stride; - gopp->patch_size = pcp->patch_size; - gopp->layer_type = pcp->layer_type; + PCGD *pcp = &gPatchCompressGlobalData; + gopp->stride = pcp->patch_stride; + gopp->patch_size = pcp->patch_size; + gopp->layer_type = pcp->layer_type; } diff --git a/indra/llmessage/patch_dct.h b/indra/llmessage/patch_dct.h index 101231ec84..8c270d99bf 100644 --- a/indra/llmessage/patch_dct.h +++ b/indra/llmessage/patch_dct.h @@ -1,25 +1,25 @@ -/** +/** * @file patch_dct.h * @brief Function declarations for DCT and IDCT routines * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,12 +30,12 @@ class LLVector3; // Code Values -const U8 ZERO_CODE = 0x0; +const U8 ZERO_CODE = 0x0; const U8 ZERO_EOB = 0x2; const U8 POSITIVE_VALUE = 0x6; const U8 NEGATIVE_VALUE = 0x7; -const S8 NORMAL_PATCH_SIZE = 16; +const S8 NORMAL_PATCH_SIZE = 16; const S8 LARGE_PATCH_SIZE = 32; const U8 END_OF_PATCHES = 97; @@ -45,35 +45,35 @@ const U8 END_OF_PATCHES = 97; // Top level header for group of headers //typedef struct LL_Group_Header //{ -// U16 stride; // 2 = 2 -// U8 patch_size; // 1 = 3 -// U8 layer_type; // 1 = 4 +// U16 stride; // 2 = 2 +// U8 patch_size; // 1 = 3 +// U8 layer_type; // 1 = 4 //} LLGroupHeader; class LLGroupHeader { public: - U16 stride; // 2 = 2 - U8 patch_size; // 1 = 3 - U8 layer_type; // 1 = 4 + U16 stride; // 2 = 2 + U8 patch_size; // 1 = 3 + U8 layer_type; // 1 = 4 }; // Individual patch header //typedef struct LL_Patch_Header //{ -// F32 dc_offset; // 4 bytes -// U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch) -// U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2) -// U16 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) +// F32 dc_offset; // 4 bytes +// U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch) +// U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2) +// U16 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) //} LLPatchHeader; class LLPatchHeader { public: - F32 dc_offset; // 4 bytes - U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch) - U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2) - U16 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) + F32 dc_offset; // 4 bytes + U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch) + U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2) + U16 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) }; // Compression routines diff --git a/indra/llmessage/patch_idct.cpp b/indra/llmessage/patch_idct.cpp index 687c1734c5..5483cf98c0 100644 --- a/indra/llmessage/patch_idct.cpp +++ b/indra/llmessage/patch_idct.cpp @@ -1,25 +1,25 @@ -/** +/** * @file patch_idct.cpp * @brief IDCT patch. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,654 +31,654 @@ #include "v3math.h" #include "patch_dct.h" -LLGroupHeader *gGOPP; +LLGroupHeader *gGOPP; void set_group_of_patch_header(LLGroupHeader *gopp) { - gGOPP = gopp; + gGOPP = gopp; } F32 gPatchDequantizeTable[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; void build_patch_dequantize_table(S32 size) { - S32 i, j; - for (j = 0; j < size; j++) - { - for (i = 0; i < size; i++) - { - gPatchDequantizeTable[j*size + i] = (1.f + 2.f*(i+j)); - } - } + S32 i, j; + for (j = 0; j < size; j++) + { + for (i = 0; i < size; i++) + { + gPatchDequantizeTable[j*size + i] = (1.f + 2.f*(i+j)); + } + } } -S32 gCurrentDeSize = 0; +S32 gCurrentDeSize = 0; -F32 gPatchICosines[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; +F32 gPatchICosines[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; void setup_patch_icosines(S32 size) { - S32 n, u; - F32 oosob = F_PI*0.5f/size; - - for (u = 0; u < size; u++) - { - for (n = 0; n < size; n++) - { - gPatchICosines[u*size+n] = cosf((2.f*n+1.f)*u*oosob); - } - } + S32 n, u; + F32 oosob = F_PI*0.5f/size; + + for (u = 0; u < size; u++) + { + for (n = 0; n < size; n++) + { + gPatchICosines[u*size+n] = cosf((2.f*n+1.f)*u*oosob); + } + } } -S32 gDeCopyMatrix[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; +S32 gDeCopyMatrix[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; void build_decopy_matrix(S32 size) { - S32 i, j, count; - bool b_diag = false; - bool b_right = true; - - i = 0; - j = 0; - count = 0; - - while ( (i < size) - &&(j < size)) - { - gDeCopyMatrix[j*size + i] = count; - - count++; - - if (!b_diag) - { - if (b_right) - { - if (i < size - 1) - i++; - else - j++; - b_right = false; - b_diag = true; - } - else - { - if (j < size - 1) - j++; - else - i++; - b_right = true; - b_diag = true; - } - } - else - { - if (b_right) - { - i++; - j--; - if ( (i == size - 1) - ||(j == 0)) - { - b_diag = false; - } - } - else - { - i--; - j++; - if ( (i == 0) - ||(j == size - 1)) - { - b_diag = false; - } - } - } - } + S32 i, j, count; + bool b_diag = false; + bool b_right = true; + + i = 0; + j = 0; + count = 0; + + while ( (i < size) + &&(j < size)) + { + gDeCopyMatrix[j*size + i] = count; + + count++; + + if (!b_diag) + { + if (b_right) + { + if (i < size - 1) + i++; + else + j++; + b_right = false; + b_diag = true; + } + else + { + if (j < size - 1) + j++; + else + i++; + b_right = true; + b_diag = true; + } + } + else + { + if (b_right) + { + i++; + j--; + if ( (i == size - 1) + ||(j == 0)) + { + b_diag = false; + } + } + else + { + i--; + j++; + if ( (i == 0) + ||(j == size - 1)) + { + b_diag = false; + } + } + } + } } void init_patch_decompressor(S32 size) { - if (size != gCurrentDeSize) - { - gCurrentDeSize = size; - build_patch_dequantize_table(size); - setup_patch_icosines(size); - build_decopy_matrix(size); - } + if (size != gCurrentDeSize) + { + gCurrentDeSize = size; + build_patch_dequantize_table(size); + setup_patch_icosines(size); + build_decopy_matrix(size); + } } inline void idct_line(F32 *linein, F32 *lineout, S32 line) { - S32 n; - F32 total; - F32 *pcp = gPatchICosines; + S32 n; + F32 total; + F32 *pcp = gPatchICosines; #ifdef _PATCH_SIZE_16_AND_32_ONLY - F32 oosob = 2.f/16.f; - S32 line_size = line*NORMAL_PATCH_SIZE; - F32 *tlinein, *tpcp; - - - for (n = 0; n < NORMAL_PATCH_SIZE; n++) - { - tpcp = pcp + n; - tlinein = linein + line_size; - - total = OO_SQRT2*(*(tlinein++)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein)*(*(tpcp += NORMAL_PATCH_SIZE)); - - *(lineout + line_size + n) = total*oosob; - } + F32 oosob = 2.f/16.f; + S32 line_size = line*NORMAL_PATCH_SIZE; + F32 *tlinein, *tpcp; + + + for (n = 0; n < NORMAL_PATCH_SIZE; n++) + { + tpcp = pcp + n; + tlinein = linein + line_size; + + total = OO_SQRT2*(*(tlinein++)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein)*(*(tpcp += NORMAL_PATCH_SIZE)); + + *(lineout + line_size + n) = total*oosob; + } #else - F32 oosob = 2.f/size; - S32 size = gGOPP->patch_size; - S32 line_size = line*size; - S32 u; - for (n = 0; n < size; n++) - { - total = OO_SQRT2*linein[line_size]; - for (u = 1; u < size; u++) - { - total += linein[line_size + u]*pcp[u*size+n]; - } - lineout[line_size + n] = total*oosob; - } + F32 oosob = 2.f/size; + S32 size = gGOPP->patch_size; + S32 line_size = line*size; + S32 u; + for (n = 0; n < size; n++) + { + total = OO_SQRT2*linein[line_size]; + for (u = 1; u < size; u++) + { + total += linein[line_size + u]*pcp[u*size+n]; + } + lineout[line_size + n] = total*oosob; + } #endif } inline void idct_line_large_slow(F32 *linein, F32 *lineout, S32 line) { - S32 n; - F32 total; - F32 *pcp = gPatchICosines; - - F32 oosob = 2.f/32.f; - S32 line_size = line*LARGE_PATCH_SIZE; - F32 *tlinein, *tpcp; - - - for (n = 0; n < LARGE_PATCH_SIZE; n++) - { - tpcp = pcp + n; - tlinein = linein + line_size; - - total = OO_SQRT2*(*(tlinein++)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein)*(*(tpcp += LARGE_PATCH_SIZE)); - - *(lineout + line_size + n) = total*oosob; - } + S32 n; + F32 total; + F32 *pcp = gPatchICosines; + + F32 oosob = 2.f/32.f; + S32 line_size = line*LARGE_PATCH_SIZE; + F32 *tlinein, *tpcp; + + + for (n = 0; n < LARGE_PATCH_SIZE; n++) + { + tpcp = pcp + n; + tlinein = linein + line_size; + + total = OO_SQRT2*(*(tlinein++)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein)*(*(tpcp += LARGE_PATCH_SIZE)); + + *(lineout + line_size + n) = total*oosob; + } } // Nota Bene: assumes that coefficients beyond 128 are 0! void idct_line_large(F32 *linein, F32 *lineout, S32 line) { - S32 n; - F32 total; - F32 *pcp = gPatchICosines; - - F32 oosob = 2.f/32.f; - S32 line_size = line*LARGE_PATCH_SIZE; - F32 *tlinein, *tpcp; - F32 *baselinein = linein + line_size; - F32 *baselineout = lineout + line_size; - - - for (n = 0; n < LARGE_PATCH_SIZE; n++) - { - tpcp = pcp++; - tlinein = baselinein; - - total = OO_SQRT2*(*(tlinein++)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein)*(*(tpcp)); - - *baselineout++ = total*oosob; - } + S32 n; + F32 total; + F32 *pcp = gPatchICosines; + + F32 oosob = 2.f/32.f; + S32 line_size = line*LARGE_PATCH_SIZE; + F32 *tlinein, *tpcp; + F32 *baselinein = linein + line_size; + F32 *baselineout = lineout + line_size; + + + for (n = 0; n < LARGE_PATCH_SIZE; n++) + { + tpcp = pcp++; + tlinein = baselinein; + + total = OO_SQRT2*(*(tlinein++)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein++)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein)*(*(tpcp)); + + *baselineout++ = total*oosob; + } } inline void idct_column(F32 *linein, F32 *lineout, S32 column) { - S32 n; - F32 total; - F32 *pcp = gPatchICosines; + S32 n; + F32 total; + F32 *pcp = gPatchICosines; #ifdef _PATCH_SIZE_16_AND_32_ONLY - F32 *tlinein, *tpcp; + F32 *tlinein, *tpcp; - for (n = 0; n < NORMAL_PATCH_SIZE; n++) - { - tpcp = pcp + n; - tlinein = linein + column; + for (n = 0; n < NORMAL_PATCH_SIZE; n++) + { + tpcp = pcp + n; + tlinein = linein + column; - total = OO_SQRT2*(*tlinein); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total = OO_SQRT2*(*tlinein); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); + total += *(tlinein += NORMAL_PATCH_SIZE)*(*(tpcp += NORMAL_PATCH_SIZE)); - *(lineout + (n<<4) + column) = total; - } + *(lineout + (n<<4) + column) = total; + } #else - S32 size = gGOPP->patch_size; - S32 u; - S32 u_size; - - for (n = 0; n < size; n++) - { - total = OO_SQRT2*linein[column]; - for (u = 1; u < size; u++) - { - u_size = u*size; - total += linein[u_size + column]*pcp[u_size+n]; - } - lineout[size*n + column] = total; - } + S32 size = gGOPP->patch_size; + S32 u; + S32 u_size; + + for (n = 0; n < size; n++) + { + total = OO_SQRT2*linein[column]; + for (u = 1; u < size; u++) + { + u_size = u*size; + total += linein[u_size + column]*pcp[u_size+n]; + } + lineout[size*n + column] = total; + } #endif } inline void idct_column_large_slow(F32 *linein, F32 *lineout, S32 column) { - S32 n; - F32 total; - F32 *pcp = gPatchICosines; - - F32 *tlinein, *tpcp; - - for (n = 0; n < LARGE_PATCH_SIZE; n++) - { - tpcp = pcp + n; - tlinein = linein + column; - - total = OO_SQRT2*(*tlinein); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - - *(lineout + (n<<5) + column) = total; - } + S32 n; + F32 total; + F32 *pcp = gPatchICosines; + + F32 *tlinein, *tpcp; + + for (n = 0; n < LARGE_PATCH_SIZE; n++) + { + tpcp = pcp + n; + tlinein = linein + column; + + total = OO_SQRT2*(*tlinein); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + + *(lineout + (n<<5) + column) = total; + } } // Nota Bene: assumes that coefficients beyond 128 are 0! void idct_column_large(F32 *linein, F32 *lineout, S32 column) { - S32 n, m; - F32 total; - F32 *pcp = gPatchICosines; + S32 n, m; + F32 total; + F32 *pcp = gPatchICosines; - F32 *tlinein, *tpcp; - F32 *baselinein = linein + column; - F32 *baselineout = lineout + column; + F32 *tlinein, *tpcp; + F32 *baselinein = linein + column; + F32 *baselineout = lineout + column; - for (n = 0; n < LARGE_PATCH_SIZE; n++) - { - tpcp = pcp++; - tlinein = baselinein; + for (n = 0; n < LARGE_PATCH_SIZE; n++) + { + tpcp = pcp++; + tlinein = baselinein; - total = OO_SQRT2*(*tlinein); - for (m = 1; m < NORMAL_PATCH_SIZE; m++) - total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); + total = OO_SQRT2*(*tlinein); + for (m = 1; m < NORMAL_PATCH_SIZE; m++) + total += *(tlinein += LARGE_PATCH_SIZE)*(*(tpcp += LARGE_PATCH_SIZE)); - *(baselineout + (n<<5)) = total; - } + *(baselineout + (n<<5)) = total; + } } inline void idct_patch(F32 *block) { - F32 temp[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; + F32 temp[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; #ifdef _PATCH_SIZE_16_AND_32_ONLY - idct_column(block, temp, 0); - idct_column(block, temp, 1); - idct_column(block, temp, 2); - idct_column(block, temp, 3); - - idct_column(block, temp, 4); - idct_column(block, temp, 5); - idct_column(block, temp, 6); - idct_column(block, temp, 7); - - idct_column(block, temp, 8); - idct_column(block, temp, 9); - idct_column(block, temp, 10); - idct_column(block, temp, 11); - - idct_column(block, temp, 12); - idct_column(block, temp, 13); - idct_column(block, temp, 14); - idct_column(block, temp, 15); - - idct_line(temp, block, 0); - idct_line(temp, block, 1); - idct_line(temp, block, 2); - idct_line(temp, block, 3); - - idct_line(temp, block, 4); - idct_line(temp, block, 5); - idct_line(temp, block, 6); - idct_line(temp, block, 7); - - idct_line(temp, block, 8); - idct_line(temp, block, 9); - idct_line(temp, block, 10); - idct_line(temp, block, 11); - - idct_line(temp, block, 12); - idct_line(temp, block, 13); - idct_line(temp, block, 14); - idct_line(temp, block, 15); + idct_column(block, temp, 0); + idct_column(block, temp, 1); + idct_column(block, temp, 2); + idct_column(block, temp, 3); + + idct_column(block, temp, 4); + idct_column(block, temp, 5); + idct_column(block, temp, 6); + idct_column(block, temp, 7); + + idct_column(block, temp, 8); + idct_column(block, temp, 9); + idct_column(block, temp, 10); + idct_column(block, temp, 11); + + idct_column(block, temp, 12); + idct_column(block, temp, 13); + idct_column(block, temp, 14); + idct_column(block, temp, 15); + + idct_line(temp, block, 0); + idct_line(temp, block, 1); + idct_line(temp, block, 2); + idct_line(temp, block, 3); + + idct_line(temp, block, 4); + idct_line(temp, block, 5); + idct_line(temp, block, 6); + idct_line(temp, block, 7); + + idct_line(temp, block, 8); + idct_line(temp, block, 9); + idct_line(temp, block, 10); + idct_line(temp, block, 11); + + idct_line(temp, block, 12); + idct_line(temp, block, 13); + idct_line(temp, block, 14); + idct_line(temp, block, 15); #else - S32 i; - S32 size = gGOPP->patch_size; - for (i = 0; i < size; i++) - { - idct_column(block, temp, i); - } - for (i = 0; i < size; i++) - { - idct_line(temp, block, i); - } + S32 i; + S32 size = gGOPP->patch_size; + for (i = 0; i < size; i++) + { + idct_column(block, temp, i); + } + for (i = 0; i < size; i++) + { + idct_line(temp, block, i); + } #endif } inline void idct_patch_large(F32 *block) { - F32 temp[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; - - idct_column_large_slow(block, temp, 0); - idct_column_large_slow(block, temp, 1); - idct_column_large_slow(block, temp, 2); - idct_column_large_slow(block, temp, 3); - - idct_column_large_slow(block, temp, 4); - idct_column_large_slow(block, temp, 5); - idct_column_large_slow(block, temp, 6); - idct_column_large_slow(block, temp, 7); - - idct_column_large_slow(block, temp, 8); - idct_column_large_slow(block, temp, 9); - idct_column_large_slow(block, temp, 10); - idct_column_large_slow(block, temp, 11); - - idct_column_large_slow(block, temp, 12); - idct_column_large_slow(block, temp, 13); - idct_column_large_slow(block, temp, 14); - idct_column_large_slow(block, temp, 15); - - idct_column_large_slow(block, temp, 16); - idct_column_large_slow(block, temp, 17); - idct_column_large_slow(block, temp, 18); - idct_column_large_slow(block, temp, 19); - - idct_column_large_slow(block, temp, 20); - idct_column_large_slow(block, temp, 21); - idct_column_large_slow(block, temp, 22); - idct_column_large_slow(block, temp, 23); - - idct_column_large_slow(block, temp, 24); - idct_column_large_slow(block, temp, 25); - idct_column_large_slow(block, temp, 26); - idct_column_large_slow(block, temp, 27); - - idct_column_large_slow(block, temp, 28); - idct_column_large_slow(block, temp, 29); - idct_column_large_slow(block, temp, 30); - idct_column_large_slow(block, temp, 31); - - idct_line_large_slow(temp, block, 0); - idct_line_large_slow(temp, block, 1); - idct_line_large_slow(temp, block, 2); - idct_line_large_slow(temp, block, 3); - - idct_line_large_slow(temp, block, 4); - idct_line_large_slow(temp, block, 5); - idct_line_large_slow(temp, block, 6); - idct_line_large_slow(temp, block, 7); - - idct_line_large_slow(temp, block, 8); - idct_line_large_slow(temp, block, 9); - idct_line_large_slow(temp, block, 10); - idct_line_large_slow(temp, block, 11); - - idct_line_large_slow(temp, block, 12); - idct_line_large_slow(temp, block, 13); - idct_line_large_slow(temp, block, 14); - idct_line_large_slow(temp, block, 15); - - idct_line_large_slow(temp, block, 16); - idct_line_large_slow(temp, block, 17); - idct_line_large_slow(temp, block, 18); - idct_line_large_slow(temp, block, 19); - - idct_line_large_slow(temp, block, 20); - idct_line_large_slow(temp, block, 21); - idct_line_large_slow(temp, block, 22); - idct_line_large_slow(temp, block, 23); - - idct_line_large_slow(temp, block, 24); - idct_line_large_slow(temp, block, 25); - idct_line_large_slow(temp, block, 26); - idct_line_large_slow(temp, block, 27); - - idct_line_large_slow(temp, block, 28); - idct_line_large_slow(temp, block, 29); - idct_line_large_slow(temp, block, 30); - idct_line_large_slow(temp, block, 31); + F32 temp[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; + + idct_column_large_slow(block, temp, 0); + idct_column_large_slow(block, temp, 1); + idct_column_large_slow(block, temp, 2); + idct_column_large_slow(block, temp, 3); + + idct_column_large_slow(block, temp, 4); + idct_column_large_slow(block, temp, 5); + idct_column_large_slow(block, temp, 6); + idct_column_large_slow(block, temp, 7); + + idct_column_large_slow(block, temp, 8); + idct_column_large_slow(block, temp, 9); + idct_column_large_slow(block, temp, 10); + idct_column_large_slow(block, temp, 11); + + idct_column_large_slow(block, temp, 12); + idct_column_large_slow(block, temp, 13); + idct_column_large_slow(block, temp, 14); + idct_column_large_slow(block, temp, 15); + + idct_column_large_slow(block, temp, 16); + idct_column_large_slow(block, temp, 17); + idct_column_large_slow(block, temp, 18); + idct_column_large_slow(block, temp, 19); + + idct_column_large_slow(block, temp, 20); + idct_column_large_slow(block, temp, 21); + idct_column_large_slow(block, temp, 22); + idct_column_large_slow(block, temp, 23); + + idct_column_large_slow(block, temp, 24); + idct_column_large_slow(block, temp, 25); + idct_column_large_slow(block, temp, 26); + idct_column_large_slow(block, temp, 27); + + idct_column_large_slow(block, temp, 28); + idct_column_large_slow(block, temp, 29); + idct_column_large_slow(block, temp, 30); + idct_column_large_slow(block, temp, 31); + + idct_line_large_slow(temp, block, 0); + idct_line_large_slow(temp, block, 1); + idct_line_large_slow(temp, block, 2); + idct_line_large_slow(temp, block, 3); + + idct_line_large_slow(temp, block, 4); + idct_line_large_slow(temp, block, 5); + idct_line_large_slow(temp, block, 6); + idct_line_large_slow(temp, block, 7); + + idct_line_large_slow(temp, block, 8); + idct_line_large_slow(temp, block, 9); + idct_line_large_slow(temp, block, 10); + idct_line_large_slow(temp, block, 11); + + idct_line_large_slow(temp, block, 12); + idct_line_large_slow(temp, block, 13); + idct_line_large_slow(temp, block, 14); + idct_line_large_slow(temp, block, 15); + + idct_line_large_slow(temp, block, 16); + idct_line_large_slow(temp, block, 17); + idct_line_large_slow(temp, block, 18); + idct_line_large_slow(temp, block, 19); + + idct_line_large_slow(temp, block, 20); + idct_line_large_slow(temp, block, 21); + idct_line_large_slow(temp, block, 22); + idct_line_large_slow(temp, block, 23); + + idct_line_large_slow(temp, block, 24); + idct_line_large_slow(temp, block, 25); + idct_line_large_slow(temp, block, 26); + idct_line_large_slow(temp, block, 27); + + idct_line_large_slow(temp, block, 28); + idct_line_large_slow(temp, block, 29); + idct_line_large_slow(temp, block, 30); + idct_line_large_slow(temp, block, 31); } -S32 gDitherNoise = 128; +S32 gDitherNoise = 128; void decompress_patch(F32 *patch, S32 *cpatch, LLPatchHeader *ph) { - S32 i, j; - - F32 block[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE], *tblock = block; - F32 *tpatch; - - LLGroupHeader *gopp = gGOPP; - S32 size = gopp->patch_size; - F32 range = ph->range; - S32 prequant = (ph->quant_wbits >> 4) + 2; - S32 quantize = 1<<prequant; - F32 hmin = ph->dc_offset; - S32 stride = gopp->stride; - - F32 ooq = 1.f/(F32)quantize; - F32 *dq = gPatchDequantizeTable; - S32 *decopy_matrix = gDeCopyMatrix; - - F32 mult = ooq*range; - F32 addval = mult*(F32)(1<<(prequant - 1))+hmin; - - for (i = 0; i < size*size; i++) - { - *(tblock++) = *(cpatch + *(decopy_matrix++))*(*dq++); - } - - if (size == 16) - { - idct_patch(block); - } - else - { - idct_patch_large(block); - } - - for (j = 0; j < size; j++) - { - tpatch = patch + j*stride; - tblock = block + j*size; - for (i = 0; i < size; i++) - { - *(tpatch++) = *(tblock++)*mult+addval; - } - } + S32 i, j; + + F32 block[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE], *tblock = block; + F32 *tpatch; + + LLGroupHeader *gopp = gGOPP; + S32 size = gopp->patch_size; + F32 range = ph->range; + S32 prequant = (ph->quant_wbits >> 4) + 2; + S32 quantize = 1<<prequant; + F32 hmin = ph->dc_offset; + S32 stride = gopp->stride; + + F32 ooq = 1.f/(F32)quantize; + F32 *dq = gPatchDequantizeTable; + S32 *decopy_matrix = gDeCopyMatrix; + + F32 mult = ooq*range; + F32 addval = mult*(F32)(1<<(prequant - 1))+hmin; + + for (i = 0; i < size*size; i++) + { + *(tblock++) = *(cpatch + *(decopy_matrix++))*(*dq++); + } + + if (size == 16) + { + idct_patch(block); + } + else + { + idct_patch_large(block); + } + + for (j = 0; j < size; j++) + { + tpatch = patch + j*stride; + tblock = block + j*size; + for (i = 0; i < size; i++) + { + *(tpatch++) = *(tblock++)*mult+addval; + } + } } void decompress_patchv(LLVector3 *v, S32 *cpatch, LLPatchHeader *ph) { - S32 i, j; - - F32 block[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE], *tblock = block; - LLVector3 *tvec; - - LLGroupHeader *gopp = gGOPP; - S32 size = gopp->patch_size; - F32 range = ph->range; - S32 prequant = (ph->quant_wbits >> 4) + 2; - S32 quantize = 1<<prequant; - F32 hmin = ph->dc_offset; - S32 stride = gopp->stride; - - F32 ooq = 1.f/(F32)quantize; - F32 *dq = gPatchDequantizeTable; - S32 *decopy_matrix = gDeCopyMatrix; - - F32 mult = ooq*range; - F32 addval = mult*(F32)(1<<(prequant - 1))+hmin; - -// bool b_diag = false; -// bool b_right = true; - - for (i = 0; i < size*size; i++) - { - *(tblock++) = *(cpatch + *(decopy_matrix++))*(*dq++); - } - - if (size == 16) - idct_patch(block); - else - idct_patch_large(block); - - for (j = 0; j < size; j++) - { - tvec = v + j*stride; - tblock = block + j*size; - for (i = 0; i < size; i++) - { - (*tvec++).mV[VZ] = *(tblock++)*mult+addval; - } - } + S32 i, j; + + F32 block[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE], *tblock = block; + LLVector3 *tvec; + + LLGroupHeader *gopp = gGOPP; + S32 size = gopp->patch_size; + F32 range = ph->range; + S32 prequant = (ph->quant_wbits >> 4) + 2; + S32 quantize = 1<<prequant; + F32 hmin = ph->dc_offset; + S32 stride = gopp->stride; + + F32 ooq = 1.f/(F32)quantize; + F32 *dq = gPatchDequantizeTable; + S32 *decopy_matrix = gDeCopyMatrix; + + F32 mult = ooq*range; + F32 addval = mult*(F32)(1<<(prequant - 1))+hmin; + +// bool b_diag = false; +// bool b_right = true; + + for (i = 0; i < size*size; i++) + { + *(tblock++) = *(cpatch + *(decopy_matrix++))*(*dq++); + } + + if (size == 16) + idct_patch(block); + else + idct_patch_large(block); + + for (j = 0; j < size; j++) + { + tvec = v + j*stride; + tblock = block + j*size; + for (i = 0; i < size; i++) + { + (*tvec++).mV[VZ] = *(tblock++)*mult+addval; + } + } } diff --git a/indra/llmessage/sound_ids.cpp b/indra/llmessage/sound_ids.cpp index 2b8a0807c6..17575dc687 100644 --- a/indra/llmessage/sound_ids.cpp +++ b/indra/llmessage/sound_ids.cpp @@ -1,24 +1,24 @@ -/** +/** * @file sound_ids.cpp * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,48 +29,48 @@ #include "lluuid.h" const LLUUID SND_NULL = LLUUID::null; -const LLUUID SND_RIDE ("00000000-0000-0000-0000-000000000100"); -const LLUUID SND_SHOT ("00000000-0000-0000-0000-000000000101"); -const LLUUID SND_MORTAR ("00000000-0000-0000-0000-000000000102"); -const LLUUID SND_HIT ("00000000-0000-0000-0000-000000000103"); -const LLUUID SND_EXPLOSION ("00000000-0000-0000-0000-000000000104"); -const LLUUID SND_BOING ("00000000-0000-0000-0000-000000000105"); +const LLUUID SND_RIDE ("00000000-0000-0000-0000-000000000100"); +const LLUUID SND_SHOT ("00000000-0000-0000-0000-000000000101"); +const LLUUID SND_MORTAR ("00000000-0000-0000-0000-000000000102"); +const LLUUID SND_HIT ("00000000-0000-0000-0000-000000000103"); +const LLUUID SND_EXPLOSION ("00000000-0000-0000-0000-000000000104"); +const LLUUID SND_BOING ("00000000-0000-0000-0000-000000000105"); const LLUUID SND_OBJECT_CREATE ("9f1bc096-3592-411e-9b0b-c447a9ff054c"); // -// Different bird sounds for different states +// Different bird sounds for different states // -const LLUUID SND_CHIRP ("00000000-0000-0000-0000-000000000106"); // Flying random chirp -const LLUUID SND_CHIRP2 ("828a9526-175b-455d-8af0-0e3c0fb602b2"); // Spooked by user -const LLUUID SND_CHIRP3 ("f99772d6-1ce6-4a39-a28b-06d26c94c9e3"); // Spooked by object -const LLUUID SND_CHIRP4 ("54472ca4-7fc9-42cb-b7d5-99ad5b12bd50"); // Chasing other bird -const LLUUID SND_CHIRP5 ("2929964f-fac5-40d7-9179-2864a8fa9ace"); // Hopping random chirp -const LLUUID SND_CHIRPDEAD ("9abff1d3-863a-4e04-bd83-3834fd7fcff4"); // Hit by grenade - dead! +const LLUUID SND_CHIRP ("00000000-0000-0000-0000-000000000106"); // Flying random chirp +const LLUUID SND_CHIRP2 ("828a9526-175b-455d-8af0-0e3c0fb602b2"); // Spooked by user +const LLUUID SND_CHIRP3 ("f99772d6-1ce6-4a39-a28b-06d26c94c9e3"); // Spooked by object +const LLUUID SND_CHIRP4 ("54472ca4-7fc9-42cb-b7d5-99ad5b12bd50"); // Chasing other bird +const LLUUID SND_CHIRP5 ("2929964f-fac5-40d7-9179-2864a8fa9ace"); // Hopping random chirp +const LLUUID SND_CHIRPDEAD ("9abff1d3-863a-4e04-bd83-3834fd7fcff4"); // Hit by grenade - dead! -const LLUUID SND_MUNCH ("00000000-0000-0000-0000-000000000107"); -const LLUUID SND_PUNCH ("00000000-0000-0000-0000-000000000108"); -const LLUUID SND_SPLASH ("00000000-0000-0000-0000-000000000109"); -const LLUUID SND_CLICK ("00000000-0000-0000-0000-000000000110"); -const LLUUID SND_WHISTLE ("ab858f9a-1f44-4d39-9b33-351543d03ccb"); +const LLUUID SND_MUNCH ("00000000-0000-0000-0000-000000000107"); +const LLUUID SND_PUNCH ("00000000-0000-0000-0000-000000000108"); +const LLUUID SND_SPLASH ("00000000-0000-0000-0000-000000000109"); +const LLUUID SND_CLICK ("00000000-0000-0000-0000-000000000110"); +const LLUUID SND_WHISTLE ("ab858f9a-1f44-4d39-9b33-351543d03ccb"); const LLUUID SND_TYPING ("5e191c7b-8996-9ced-a177-b2ac32bfea06"); -const LLUUID SND_ARROW_SHOT ("00000000-0000-0000-0000-000000000111"); -const LLUUID SND_ARROW_THUD ("00000000-0000-0000-0000-000000000112"); -const LLUUID SND_LASER_SHOT ("00000000-0000-0000-0000-000000000113"); -const LLUUID SND_JET_THRUST ("67f5e4f0-0534-4d97-bc01-f297648d20e0"); +const LLUUID SND_ARROW_SHOT ("00000000-0000-0000-0000-000000000111"); +const LLUUID SND_ARROW_THUD ("00000000-0000-0000-0000-000000000112"); +const LLUUID SND_LASER_SHOT ("00000000-0000-0000-0000-000000000113"); +const LLUUID SND_JET_THRUST ("67f5e4f0-0534-4d97-bc01-f297648d20e0"); -const LLUUID SND_SILENCE ("00000000-0000-0000-0000-000000000114"); -const LLUUID SND_BUBBLES ("00000000-0000-0000-0000-000000000115"); -const LLUUID SND_WELCOME ("00000000-0000-0000-0000-000000000116"); -const LLUUID SND_SQUISH ("00000000-0000-0000-0000-000000000117"); -const LLUUID SND_SUBPOD ("00000000-0000-0000-0000-000000000118"); +const LLUUID SND_SILENCE ("00000000-0000-0000-0000-000000000114"); +const LLUUID SND_BUBBLES ("00000000-0000-0000-0000-000000000115"); +const LLUUID SND_WELCOME ("00000000-0000-0000-0000-000000000116"); +const LLUUID SND_SQUISH ("00000000-0000-0000-0000-000000000117"); +const LLUUID SND_SUBPOD ("00000000-0000-0000-0000-000000000118"); const LLUUID SND_FOOTSTEPS ("00000000-0000-0000-0000-000000000119"); const LLUUID SND_STEP_LEFT ("00000000-0000-0000-0000-000000000124"); const LLUUID SND_STEP_RIGHT ("00000000-0000-0000-0000-000000000125"); -const LLUUID SND_BALL_COLLISION ("00000000-0000-0000-0000-000000000120"); +const LLUUID SND_BALL_COLLISION ("00000000-0000-0000-0000-000000000120"); const LLUUID SND_OOOH_SCARE_ME ("00000000-0000-0000-0000-000000000121"); const LLUUID SND_PAYBACK_TIME ("00000000-0000-0000-0000-000000000122"); @@ -275,15 +275,15 @@ const LLUUID SND_ROLL_WOOD_WOOD_07 ("0c6aa481-b5bc-4573-ae83-8e16ff27e750"); const LLUUID SND_ROLL_WOOD_WOOD_08 ("214ab2c7-871a-451b-b0db-4c5677199011"); const LLUUID SND_ROLL_WOOD_WOOD_09 ("0086e4db-3ac6-4545-b414-6f359bedd9a5"); -const LLUUID SND_SLIDE_STONE_STONE_01 ("2a7dcbd1-d3e6-4767-8432-8322648e7b9d"); +const LLUUID SND_SLIDE_STONE_STONE_01 ("2a7dcbd1-d3e6-4767-8432-8322648e7b9d"); -const LLUUID SND_STONE_DIRT_01 ("97727335-392c-4338-ac4b-23a7883279c2"); -const LLUUID SND_STONE_DIRT_02 ("cbe75eb2-3375-41d8-9e3f-2ae46b4164ed"); -const LLUUID SND_STONE_DIRT_03 ("31e236ee-001b-4c8e-ad6c-c2074cb64357"); -const LLUUID SND_STONE_DIRT_04 ("c8091652-e04b-4a11-84ba-15dba06e7a1b"); +const LLUUID SND_STONE_DIRT_01 ("97727335-392c-4338-ac4b-23a7883279c2"); +const LLUUID SND_STONE_DIRT_02 ("cbe75eb2-3375-41d8-9e3f-2ae46b4164ed"); +const LLUUID SND_STONE_DIRT_03 ("31e236ee-001b-4c8e-ad6c-c2074cb64357"); +const LLUUID SND_STONE_DIRT_04 ("c8091652-e04b-4a11-84ba-15dba06e7a1b"); -const LLUUID SND_STONE_STONE_02 ("ba4ef5ac-7435-4240-b826-c24ba8fa5a78"); -const LLUUID SND_STONE_STONE_04 ("ea296329-0f09-4993-af1b-e6784bab1dc9"); +const LLUUID SND_STONE_STONE_02 ("ba4ef5ac-7435-4240-b826-c24ba8fa5a78"); +const LLUUID SND_STONE_STONE_04 ("ea296329-0f09-4993-af1b-e6784bab1dc9"); diff --git a/indra/llmessage/sound_ids.h b/indra/llmessage/sound_ids.h index 6a2e343ad3..d212ca322f 100644 --- a/indra/llmessage/sound_ids.h +++ b/indra/llmessage/sound_ids.h @@ -1,25 +1,25 @@ -/** +/** * @file sound_ids.h * @brief Temporary holder for sound IDs. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,13 +41,13 @@ extern const LLUUID SND_EXPLOSION; extern const LLUUID SND_BOING; extern const LLUUID SND_OBJECT_CREATE; -// Different bird sounds for different states -extern const LLUUID SND_CHIRP; // Flying random chirp -extern const LLUUID SND_CHIRP2; // Spooked by user -extern const LLUUID SND_CHIRP3; // Spooked by object -extern const LLUUID SND_CHIRP4; // Chasing other bird -extern const LLUUID SND_CHIRP5; // Hopping random chirp -extern const LLUUID SND_CHIRPDEAD; // Hit by grenade - dead! +// Different bird sounds for different states +extern const LLUUID SND_CHIRP; // Flying random chirp +extern const LLUUID SND_CHIRP2; // Spooked by user +extern const LLUUID SND_CHIRP3; // Spooked by object +extern const LLUUID SND_CHIRP4; // Chasing other bird +extern const LLUUID SND_CHIRP5; // Hopping random chirp +extern const LLUUID SND_CHIRPDEAD; // Hit by grenade - dead! extern const LLUUID SND_MUNCH; diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h index 0359eba803..cc72242e66 100644 --- a/indra/llmessage/tests/commtest.h +++ b/indra/llmessage/tests/commtest.h @@ -2,26 +2,26 @@ * @file commtest.h * @author Nat Goodspeed * @date 2009-01-09 - * @brief - * + * @brief + * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/tests/llareslistener_test.cpp b/indra/llmessage/tests/llareslistener_test.cpp index 254185cbd0..f4a9e501ec 100644 --- a/indra/llmessage/tests/llareslistener_test.cpp +++ b/indra/llmessage/tests/llareslistener_test.cpp @@ -3,25 +3,25 @@ * @author Mark Palange * @date 2009-02-26 * @brief Tests of llareslistener.h. - * + * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -57,14 +57,14 @@ LLAres::LLAres(): {} LLAres::~LLAres() {} void LLAres::rewriteURI(const std::string &uri, - LLAres::UriRewriteResponder *resp) + LLAres::UriRewriteResponder *resp) { - // This is the only LLAres method I chose to implement. - // The effect is that LLAres returns immediately with - // a result that is equal to the input uri. - std::vector<std::string> result; - result.push_back(uri); - resp->rewriteResult(result); + // This is the only LLAres method I chose to implement. + // The effect is that LLAres returns immediately with + // a result that is equal to the input uri. + std::vector<std::string> result; + result.push_back(uri); + resp->rewriteResult(result); } LLAres::QueryResponder::~QueryResponder() {} @@ -90,11 +90,11 @@ namespace tut typedef llareslistener_group::object object; llareslistener_group llareslistenergrp("llareslistener"); - struct ResponseCallback - { - std::vector<std::string> mURIs; - bool operator()(const LLSD& response) - { + struct ResponseCallback + { + std::vector<std::string> mURIs; + bool operator()(const LLSD& response) + { mURIs.clear(); for (LLSD::array_const_iterator ri(response.beginArray()), rend(response.endArray()); ri != rend; ++ri) @@ -102,16 +102,16 @@ namespace tut mURIs.push_back(*ri); } return false; - } - }; + } + }; template<> template<> void object::test<1>() { set_test_name("test event"); - // Tests the success and failure cases, since they both use - // the same code paths in the LLAres responder. - ResponseCallback response; + // Tests the success and failure cases, since they both use + // the same code paths in the LLAres responder. + ResponseCallback response; std::string pumpname("trigger"); // Since we're asking LLEventPumps to obtain() the pump by the desired // name, it will persist beyond the current scope, so ensure we @@ -121,15 +121,15 @@ namespace tut boost::bind(&ResponseCallback::operator(), &response, _1))); // Now build an LLSD request that will direct its response events to // that pump. - const std::string testURI("login.bar.com"); + const std::string testURI("login.bar.com"); LLSD request; request["op"] = "rewriteURI"; request["uri"] = testURI; request["reply"] = pumpname; LLEventPumps::instance().obtain("LLAres").post(request); - ensure_equals(response.mURIs.size(), 1); - ensure_equals(response.mURIs.front(), testURI); - } + ensure_equals(response.mURIs.size(), 1); + ensure_equals(response.mURIs.front(), testURI); + } template<> template<> void object::test<2>() diff --git a/indra/llmessage/tests/llavatarnamecache_test.cpp b/indra/llmessage/tests/llavatarnamecache_test.cpp index ec6b65d483..3735f42c47 100644 --- a/indra/llmessage/tests/llavatarnamecache_test.cpp +++ b/indra/llmessage/tests/llavatarnamecache_test.cpp @@ -6,25 +6,25 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + #include "linden_common.h" #include "../llavatarnamecache.h" @@ -33,70 +33,70 @@ namespace tut { - struct avatarnamecache_data - { - }; - typedef test_group<avatarnamecache_data> avatarnamecache_test; - typedef avatarnamecache_test::object avatarnamecache_object; - tut::avatarnamecache_test avatarnamecache_testcase("LLAvatarNameCache"); - - template<> template<> - void avatarnamecache_object::test<1>() - { - bool valid = false; - S32 max_age = 0; - - valid = max_age_from_cache_control("max-age=3600", &max_age); - ensure("typical input valid", valid); - ensure_equals("typical input parsed", max_age, 3600); - - valid = max_age_from_cache_control( - " max-age=600 , no-cache,private=\"stuff\" ", &max_age); - ensure("complex input valid", valid); - ensure_equals("complex input parsed", max_age, 600); - - valid = max_age_from_cache_control( - "no-cache, max-age = 123 ", &max_age); - ensure("complex input 2 valid", valid); - ensure_equals("complex input 2 parsed", max_age, 123); - } - - template<> template<> - void avatarnamecache_object::test<2>() - { - bool valid = false; - S32 max_age = -1; - - valid = max_age_from_cache_control("", &max_age); - ensure("empty input returns invalid", !valid); - ensure_equals("empty input doesn't change val", max_age, -1); - - valid = max_age_from_cache_control("no-cache", &max_age); - ensure("no max-age field returns invalid", !valid); - - valid = max_age_from_cache_control("max", &max_age); - ensure("just 'max' returns invalid", !valid); - - valid = max_age_from_cache_control("max-age", &max_age); - ensure("partial max-age is invalid", !valid); - - valid = max_age_from_cache_control("max-age=", &max_age); - ensure("longer partial max-age is invalid", !valid); - - valid = max_age_from_cache_control("max-age=FOO", &max_age); - ensure("invalid integer max-age is invalid", !valid); - - valid = max_age_from_cache_control("max-age 234", &max_age); - ensure("space separated max-age is invalid", !valid); - - valid = max_age_from_cache_control("max-age=0", &max_age); - ensure("zero max-age is valid", valid); - - // *TODO: Handle "0000" as zero - //valid = max_age_from_cache_control("max-age=0000", &max_age); - //ensure("multi-zero max-age is valid", valid); - - valid = max_age_from_cache_control("max-age=-123", &max_age); - ensure("less than zero max-age is invalid", !valid); - } + struct avatarnamecache_data + { + }; + typedef test_group<avatarnamecache_data> avatarnamecache_test; + typedef avatarnamecache_test::object avatarnamecache_object; + tut::avatarnamecache_test avatarnamecache_testcase("LLAvatarNameCache"); + + template<> template<> + void avatarnamecache_object::test<1>() + { + bool valid = false; + S32 max_age = 0; + + valid = max_age_from_cache_control("max-age=3600", &max_age); + ensure("typical input valid", valid); + ensure_equals("typical input parsed", max_age, 3600); + + valid = max_age_from_cache_control( + " max-age=600 , no-cache,private=\"stuff\" ", &max_age); + ensure("complex input valid", valid); + ensure_equals("complex input parsed", max_age, 600); + + valid = max_age_from_cache_control( + "no-cache, max-age = 123 ", &max_age); + ensure("complex input 2 valid", valid); + ensure_equals("complex input 2 parsed", max_age, 123); + } + + template<> template<> + void avatarnamecache_object::test<2>() + { + bool valid = false; + S32 max_age = -1; + + valid = max_age_from_cache_control("", &max_age); + ensure("empty input returns invalid", !valid); + ensure_equals("empty input doesn't change val", max_age, -1); + + valid = max_age_from_cache_control("no-cache", &max_age); + ensure("no max-age field returns invalid", !valid); + + valid = max_age_from_cache_control("max", &max_age); + ensure("just 'max' returns invalid", !valid); + + valid = max_age_from_cache_control("max-age", &max_age); + ensure("partial max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age=", &max_age); + ensure("longer partial max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age=FOO", &max_age); + ensure("invalid integer max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age 234", &max_age); + ensure("space separated max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age=0", &max_age); + ensure("zero max-age is valid", valid); + + // *TODO: Handle "0000" as zero + //valid = max_age_from_cache_control("max-age=0000", &max_age); + //ensure("multi-zero max-age is valid", valid); + + valid = max_age_from_cache_control("max-age=-123", &max_age); + ensure("less than zero max-age is invalid", !valid); + } } diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index d6481d4eea..4caae5f082 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llcoproceduremanager_test.cpp * @author Brad * @date 2019-02 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2019&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -100,7 +100,7 @@ namespace tut sync.yield(); ensure_equals("coprocedure failed to update foo", foo, 1); - + LLCoprocedureManager::instance().close("PoolName"); } diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp index 1c571a74da..78c195580c 100644 --- a/indra/llmessage/tests/llcurl_stub.cpp +++ b/indra/llmessage/tests/llcurl_stub.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,18 +38,18 @@ LLCurl::Responder::Responder() void LLCurl::Responder::httpCompleted() { - if (isGoodStatus()) - { - httpSuccess(); - } - else - { - httpFailure(); - } + if (isGoodStatus()) + { + httpSuccess(); + } + else + { + httpFailure(); + } } void LLCurl::Responder::completedRaw(LLChannelDescriptors const&, - std::shared_ptr<LLBufferArray> const&) + std::shared_ptr<LLBufferArray> const&) { } @@ -67,33 +67,33 @@ void LLCurl::Responder::httpSuccess() std::string LLCurl::Responder::dumpResponse() const { - return "dumpResponse()"; + return "dumpResponse()"; } void LLCurl::Responder::successResult(const LLSD& content) { - setResult(HTTP_OK, "", content); - httpSuccess(); + setResult(HTTP_OK, "", content); + httpSuccess(); } void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content) { - setResult(status, reason, content); - httpFailure(); + setResult(status, reason, content); + httpFailure(); } void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content) { - setResult(status, reason, content); - httpCompleted(); + setResult(status, reason, content); + httpCompleted(); } void LLCurl::Responder::setResult(S32 status, const std::string& reason, const LLSD& content /* = LLSD() */) { - mStatus = status; - mReason = reason; - mContent = content; + mStatus = status; + mReason = reason; + mContent = content; } #endif diff --git a/indra/llmessage/tests/llhost_test.cpp b/indra/llmessage/tests/llhost_test.cpp index efca1bbfca..a66655ad6c 100644 --- a/indra/llmessage/tests/llhost_test.cpp +++ b/indra/llmessage/tests/llhost_test.cpp @@ -7,25 +7,25 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + #include "linden_common.h" #include "../llhost.h" @@ -34,238 +34,238 @@ namespace tut { - struct host_data - { - }; - typedef test_group<host_data> host_test; - typedef host_test::object host_object; - tut::host_test host_testcase("LLHost"); - - - template<> template<> - void host_object::test<1>() - { - LLHost host; - ensure("IP address is not NULL", (0 == host.getAddress()) && (0 == host.getPort()) && !host.isOk()); - } - template<> template<> - void host_object::test<2>() - { - U32 ip_addr = 0xc098017d; - U32 port = 8080; - LLHost host(ip_addr, port); - ensure("IP address is invalid", ip_addr == host.getAddress()); - ensure("Port Number is invalid", port == host.getPort()); - ensure("IP address and port number both should be ok", host.isOk()); - } - - template<> template<> - void host_object::test<3>() - { - const char* str = "192.168.1.1"; - U32 port = 8080; - LLHost host(str, port); - ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str))); - ensure("Port Number is invalid", (port == host.getPort())); - } - - template<> template<> - void host_object::test<4>() - { - U32 ip = ip_string_to_u32("192.168.1.1"); - U32 port = 22; - U64 ip_port = (((U64) ip) << 32) | port; - LLHost host(ip_port); - ensure("IP address is invalid", ip == host.getAddress()); - ensure("Port Number is invalid", port == host.getPort()); - } - - template<> template<> - void host_object::test<5>() - { - std::string ip_port_string = "192.168.1.1:8080"; - U32 ip = ip_string_to_u32("192.168.1.1"); - U32 port = 8080; - - LLHost host(ip_port_string); - ensure("IP address from IP:port is invalid", ip == host.getAddress()); - ensure("Port Number from from IP:port is invalid", port == host.getPort()); - } - - template<> template<> - void host_object::test<6>() - { - U32 ip = 0xc098017d, port = 8080; - LLHost host; - host.set(ip,port); - ensure("IP address is invalid", (ip == host.getAddress())); - ensure("Port Number is invalid", (port == host.getPort())); - } - - template<> template<> - void host_object::test<7>() - { - const char* str = "192.168.1.1"; - U32 port = 8080, ip; - LLHost host; - host.set(str,port); - ip = ip_string_to_u32(str); - ensure("IP address is invalid", (ip == host.getAddress())); - ensure("Port Number is invalid", (port == host.getPort())); - - str = "64.233.187.99"; - ip = ip_string_to_u32(str); - host.setAddress(str); - ensure("IP address is invalid", (ip == host.getAddress())); - - ip = 0xc098017b; - host.setAddress(ip); - ensure("IP address is invalid", (ip == host.getAddress())); - // should still use the old port - ensure("Port Number is invalid", (port == host.getPort())); - - port = 8084; - host.setPort(port); - ensure("Port Number is invalid", (port == host.getPort())); - // should still use the old address - ensure("IP address is invalid", (ip == host.getAddress())); - } - - template<> template<> - void host_object::test<8>() - { - const std::string str("192.168.1.1"); - U32 port = 8080; - LLHost host; - host.set(str,port); - - std::string ip_string = host.getIPString(); - ensure("Function Failed", (ip_string == str)); - - std::string ip_string_port = host.getIPandPort(); - ensure("Function Failed", (ip_string_port == "192.168.1.1:8080")); - } - - -// getHostName() and setHostByName - template<> template<> - void host_object::test<9>() - { - skip("this test is irreparably flaky"); -// skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\""); - // nat: is it reasonable to expect LLHost::getHostName() to echo - // back something resembling the string passed to setHostByName()? - // - // If that's not even reasonable, would a round trip in the /other/ - // direction make more sense? (Call getHostName() for something with - // known IP address; call setHostByName(); verify IP address) - // - // Failing that... is there a plausible way to test getHostName() and - // setHostByName()? Hopefully without putting up a dummy local DNS - // server? - - // monty: If you don't control the DNS server or the DNS configuration - // for the test point then, no, none of these will necessarily be - // reliable and may start to fail at any time. Forward translation - // is subject to CNAME records and round-robin address assignment. - // Reverse lookup is 1-to-many and is more and more likely to have - // nothing to do with the forward translation. - // - // So the test is increasingly meaningless on a real network. - - std::string hostStr = "lindenlab.com"; - LLHost host; - host.setHostByName(hostStr); - - // reverse DNS will likely result in appending of some - // sub-domain to the main hostname. so look for - // the main domain name and not do the exact compare - - std::string hostname = host.getHostName(); - try - { - ensure("getHostName failed", hostname.find(hostStr) != std::string::npos); - } - catch (const std::exception&) - { - std::cerr << "set '" << hostStr << "'; reported '" << hostname << "'" << std::endl; - throw; - } - } - -// setHostByName for dotted IP - template<> template<> - void host_object::test<10>() - { - std::string hostStr = "64.233.167.99"; - LLHost host; - host.setHostByName(hostStr); - ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str())); - } - - template<> template<> - void host_object::test<11>() - { - LLHost host1(0xc098017d, 8080); - LLHost host2 = host1; - ensure("Both IP addresses are not same", (host1.getAddress() == host2.getAddress())); - ensure("Both port numbers are not same", (host1.getPort() == host2.getPort())); - } - - template<> template<> - void host_object::test<12>() - { - LLHost host1("192.168.1.1", 8080); - std::string str1 = "192.168.1.1:8080"; - std::ostringstream stream; - stream << host1; - ensure("Operator << failed", ( stream.str()== str1)); - - // There is no istream >> llhost operator. - //std::istringstream is(stream.str()); - //LLHost host2; - //is >> host2; - //ensure("Operator >> failed. Not compatible with <<", host1 == host2); - } - - // operators ==, !=, < - template<> template<> - void host_object::test<13>() - { - U32 ip_addr = 0xc098017d; - U32 port = 8080; - LLHost host1(ip_addr, port); - LLHost host2(ip_addr, port); - ensure("operator== failed", host1 == host2); - - // change port - host2.setPort(7070); - ensure("operator!= failed", host1 != host2); - - // set port back to 8080 and change IP address now - host2.setPort(8080); - host2.setAddress(ip_addr+10); - ensure("operator!= failed", host1 != host2); - - ensure("operator< failed", host1 < host2); - - // set IP address back to same value and change port - host2.setAddress(ip_addr); - host2.setPort(host1.getPort() + 10); - ensure("operator< failed", host1 < host2); - } - - // invalid ip address string - template<> template<> - void host_object::test<14>() - { - LLHost host1("10.0.1.2", 6143); - ensure("10.0.1.2 should be a valid address", host1.isOk()); - - LLHost host2("booger-brains", 6143); - ensure("booger-brains should be an invalid ip addess", !host2.isOk()); - - LLHost host3("255.255.255.255", 6143); - ensure("255.255.255.255 should be valid broadcast address", host3.isOk()); - } + struct host_data + { + }; + typedef test_group<host_data> host_test; + typedef host_test::object host_object; + tut::host_test host_testcase("LLHost"); + + + template<> template<> + void host_object::test<1>() + { + LLHost host; + ensure("IP address is not NULL", (0 == host.getAddress()) && (0 == host.getPort()) && !host.isOk()); + } + template<> template<> + void host_object::test<2>() + { + U32 ip_addr = 0xc098017d; + U32 port = 8080; + LLHost host(ip_addr, port); + ensure("IP address is invalid", ip_addr == host.getAddress()); + ensure("Port Number is invalid", port == host.getPort()); + ensure("IP address and port number both should be ok", host.isOk()); + } + + template<> template<> + void host_object::test<3>() + { + const char* str = "192.168.1.1"; + U32 port = 8080; + LLHost host(str, port); + ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str))); + ensure("Port Number is invalid", (port == host.getPort())); + } + + template<> template<> + void host_object::test<4>() + { + U32 ip = ip_string_to_u32("192.168.1.1"); + U32 port = 22; + U64 ip_port = (((U64) ip) << 32) | port; + LLHost host(ip_port); + ensure("IP address is invalid", ip == host.getAddress()); + ensure("Port Number is invalid", port == host.getPort()); + } + + template<> template<> + void host_object::test<5>() + { + std::string ip_port_string = "192.168.1.1:8080"; + U32 ip = ip_string_to_u32("192.168.1.1"); + U32 port = 8080; + + LLHost host(ip_port_string); + ensure("IP address from IP:port is invalid", ip == host.getAddress()); + ensure("Port Number from from IP:port is invalid", port == host.getPort()); + } + + template<> template<> + void host_object::test<6>() + { + U32 ip = 0xc098017d, port = 8080; + LLHost host; + host.set(ip,port); + ensure("IP address is invalid", (ip == host.getAddress())); + ensure("Port Number is invalid", (port == host.getPort())); + } + + template<> template<> + void host_object::test<7>() + { + const char* str = "192.168.1.1"; + U32 port = 8080, ip; + LLHost host; + host.set(str,port); + ip = ip_string_to_u32(str); + ensure("IP address is invalid", (ip == host.getAddress())); + ensure("Port Number is invalid", (port == host.getPort())); + + str = "64.233.187.99"; + ip = ip_string_to_u32(str); + host.setAddress(str); + ensure("IP address is invalid", (ip == host.getAddress())); + + ip = 0xc098017b; + host.setAddress(ip); + ensure("IP address is invalid", (ip == host.getAddress())); + // should still use the old port + ensure("Port Number is invalid", (port == host.getPort())); + + port = 8084; + host.setPort(port); + ensure("Port Number is invalid", (port == host.getPort())); + // should still use the old address + ensure("IP address is invalid", (ip == host.getAddress())); + } + + template<> template<> + void host_object::test<8>() + { + const std::string str("192.168.1.1"); + U32 port = 8080; + LLHost host; + host.set(str,port); + + std::string ip_string = host.getIPString(); + ensure("Function Failed", (ip_string == str)); + + std::string ip_string_port = host.getIPandPort(); + ensure("Function Failed", (ip_string_port == "192.168.1.1:8080")); + } + + +// getHostName() and setHostByName + template<> template<> + void host_object::test<9>() + { + skip("this test is irreparably flaky"); +// skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\""); + // nat: is it reasonable to expect LLHost::getHostName() to echo + // back something resembling the string passed to setHostByName()? + // + // If that's not even reasonable, would a round trip in the /other/ + // direction make more sense? (Call getHostName() for something with + // known IP address; call setHostByName(); verify IP address) + // + // Failing that... is there a plausible way to test getHostName() and + // setHostByName()? Hopefully without putting up a dummy local DNS + // server? + + // monty: If you don't control the DNS server or the DNS configuration + // for the test point then, no, none of these will necessarily be + // reliable and may start to fail at any time. Forward translation + // is subject to CNAME records and round-robin address assignment. + // Reverse lookup is 1-to-many and is more and more likely to have + // nothing to do with the forward translation. + // + // So the test is increasingly meaningless on a real network. + + std::string hostStr = "lindenlab.com"; + LLHost host; + host.setHostByName(hostStr); + + // reverse DNS will likely result in appending of some + // sub-domain to the main hostname. so look for + // the main domain name and not do the exact compare + + std::string hostname = host.getHostName(); + try + { + ensure("getHostName failed", hostname.find(hostStr) != std::string::npos); + } + catch (const std::exception&) + { + std::cerr << "set '" << hostStr << "'; reported '" << hostname << "'" << std::endl; + throw; + } + } + +// setHostByName for dotted IP + template<> template<> + void host_object::test<10>() + { + std::string hostStr = "64.233.167.99"; + LLHost host; + host.setHostByName(hostStr); + ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str())); + } + + template<> template<> + void host_object::test<11>() + { + LLHost host1(0xc098017d, 8080); + LLHost host2 = host1; + ensure("Both IP addresses are not same", (host1.getAddress() == host2.getAddress())); + ensure("Both port numbers are not same", (host1.getPort() == host2.getPort())); + } + + template<> template<> + void host_object::test<12>() + { + LLHost host1("192.168.1.1", 8080); + std::string str1 = "192.168.1.1:8080"; + std::ostringstream stream; + stream << host1; + ensure("Operator << failed", ( stream.str()== str1)); + + // There is no istream >> llhost operator. + //std::istringstream is(stream.str()); + //LLHost host2; + //is >> host2; + //ensure("Operator >> failed. Not compatible with <<", host1 == host2); + } + + // operators ==, !=, < + template<> template<> + void host_object::test<13>() + { + U32 ip_addr = 0xc098017d; + U32 port = 8080; + LLHost host1(ip_addr, port); + LLHost host2(ip_addr, port); + ensure("operator== failed", host1 == host2); + + // change port + host2.setPort(7070); + ensure("operator!= failed", host1 != host2); + + // set port back to 8080 and change IP address now + host2.setPort(8080); + host2.setAddress(ip_addr+10); + ensure("operator!= failed", host1 != host2); + + ensure("operator< failed", host1 < host2); + + // set IP address back to same value and change port + host2.setAddress(ip_addr); + host2.setPort(host1.getPort() + 10); + ensure("operator< failed", host1 < host2); + } + + // invalid ip address string + template<> template<> + void host_object::test<14>() + { + LLHost host1("10.0.1.2", 6143); + ensure("10.0.1.2 should be a valid address", host1.isOk()); + + LLHost host2("booger-brains", 6143); + ensure("booger-brains should be an invalid ip addess", !host2.isOk()); + + LLHost host3("255.255.255.255", 6143); + ensure("255.255.255.255 should be valid broadcast address", host3.isOk()); + } } diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index 78faa66a0d..1881144d3e 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llhttpclient_test.cpp * @brief Testing the HTTP client classes. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,265 +47,265 @@ namespace tut { - struct HTTPClientTestData - { - public: - HTTPClientTestData(): - PORT(LLStringUtil::getenv("PORT")), - // Turning NULL PORT into empty string doesn't make things work; - // that's just to keep this initializer from blowing up. We test - // PORT separately in the constructor body. - local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/")) - { - ensure("Set environment variable PORT to local test server port", !PORT.empty()); - apr_pool_create(&mPool, NULL); - LLCurl::initClass(false); - mClientPump = new LLPumpIO(mPool); - - LLHTTPClient::setPump(*mClientPump); - } - - ~HTTPClientTestData() - { - delete mClientPump; - SUBSYSTEM_CLEANUP(LLProxy); - apr_pool_destroy(mPool); - } - - void runThePump(float timeout = 100.0f) - { - LLTimer timer; - timer.setTimerExpirySec(timeout); - - while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired()) - { - LLFrameTimer::updateFrameTime(); - if (mClientPump) - { - mClientPump->pump(); - mClientPump->callback(); - } - } - } - - const std::string PORT; - const std::string local_server; - - private: - apr_pool_t* mPool; - LLPumpIO* mClientPump; - - protected: - void ensureStatusOK() - { - if (mSawError) - { - std::string msg = - llformat("httpFailure() called when not expected, status %d", - mStatus); - fail(msg); - } - } - - void ensureStatusError() - { - if (!mSawError) - { - fail("httpFailure() wasn't called"); - } - } - - LLSD getResult() - { - return mResult; - } - LLSD getHeader() - { - return mHeader; - } - - protected: - bool mSawError; - U32 mStatus; - std::string mReason; - bool mSawCompleted; - bool mSawCompletedHeader; - LLSD mResult; - LLSD mHeader; - bool mResultDeleted; - - class Result : public LLHTTPClient::Responder - { - protected: - Result(HTTPClientTestData& client) - : mClient(client) - { - } - - public: - static Result* build(HTTPClientTestData& client) - { - return new Result(client); - } - - ~Result() - { - mClient.mResultDeleted = true; - } - - protected: - virtual void httpFailure() - { - mClient.mSawError = true; - mClient.mStatus = getStatus(); - mClient.mReason = getReason(); - } - - virtual void httpSuccess() - { - mClient.mResult = getContent(); - } - - virtual void httpCompleted() - { - LLHTTPClient::Responder::httpCompleted(); - - mClient.mSawCompleted = true; - mClient.mSawCompletedHeader = true; - mClient.mHeader = getResponseHeaders(); - } - - private: - HTTPClientTestData& mClient; - }; - - friend class Result; - - protected: - LLHTTPClient::ResponderPtr newResult() - { - mSawError = false; - mStatus = 0; - mSawCompleted = false; - mSawCompletedHeader = false; - mResult.clear(); - mHeader.clear(); - mResultDeleted = false; - - return Result::build(*this); - } - }; - - - typedef test_group<HTTPClientTestData> HTTPClientTestGroup; - typedef HTTPClientTestGroup::object HTTPClientTestObject; - HTTPClientTestGroup httpClientTestGroup("http_client"); - - template<> template<> - void HTTPClientTestObject::test<1>() - { - LLHTTPClient::get(local_server, newResult()); - runThePump(); - ensureStatusOK(); - ensure("result object wasn't destroyed", mResultDeleted); - } - - template<> template<> - void HTTPClientTestObject::test<2>() - { - // Please nobody listen on this particular port... - LLHTTPClient::get("http://127.0.0.1:7950", newResult()); - runThePump(); - ensureStatusError(); - } - - template<> template<> - void HTTPClientTestObject::test<3>() - { - LLSD sd; - - sd["list"][0]["one"] = 1; - sd["list"][0]["two"] = 2; - sd["list"][1]["three"] = 3; - sd["list"][1]["four"] = 4; - - LLHTTPClient::post(local_server + "web/echo", sd, newResult()); - runThePump(); - ensureStatusOK(); - ensure_equals("echoed result matches", getResult(), sd); - } - - template<> template<> - void HTTPClientTestObject::test<4>() - { - LLSD sd; - - sd["message"] = "This is my test message."; - - LLHTTPClient::put(local_server + "test/storage", sd, newResult()); - runThePump(); - ensureStatusOK(); - - LLHTTPClient::get(local_server + "test/storage", newResult()); - runThePump(); - ensureStatusOK(); - ensure_equals("echoed result matches", getResult(), sd); - - } - - template<> template<> - void HTTPClientTestObject::test<5>() - { - LLSD sd; - sd["status"] = 543; - sd["reason"] = "error for testing"; - - LLHTTPClient::post(local_server + "test/error", sd, newResult()); - runThePump(); - ensureStatusError(); - ensure_contains("reason", mReason, sd["reason"]); - } - - template<> template<> - void HTTPClientTestObject::test<6>() - { - const F32 timeout = 1.0f; - LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout); - runThePump(timeout * 5.0f); - ensureStatusError(); - ensure_equals("reason", mReason, "STATUS_EXPIRED"); - } - - template<> template<> - void HTTPClientTestObject::test<7>() - { - LLHTTPClient::get(local_server, newResult()); - runThePump(); - ensureStatusOK(); - LLSD expected = getResult(); - - LLSD result; - result = LLHTTPClient::blockingGet(local_server); - LLSD body = result["body"]; - ensure_equals("echoed result matches", body.size(), expected.size()); - } - template<> template<> - void HTTPClientTestObject::test<8>() - { - // This is testing for the presence of the Header in the returned results - // from an HTTP::get call. - LLHTTPClient::get(local_server, newResult()); - runThePump(); - ensureStatusOK(); - LLSD header = getHeader(); - ensure("got a header", ! header.emptyMap().asBoolean()); - } - template<> template<> - void HTTPClientTestObject::test<9>() - { - LLHTTPClient::head(local_server, newResult()); - runThePump(); - ensureStatusOK(); - ensure("result object wasn't destroyed", mResultDeleted); - } + struct HTTPClientTestData + { + public: + HTTPClientTestData(): + PORT(LLStringUtil::getenv("PORT")), + // Turning NULL PORT into empty string doesn't make things work; + // that's just to keep this initializer from blowing up. We test + // PORT separately in the constructor body. + local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/")) + { + ensure("Set environment variable PORT to local test server port", !PORT.empty()); + apr_pool_create(&mPool, NULL); + LLCurl::initClass(false); + mClientPump = new LLPumpIO(mPool); + + LLHTTPClient::setPump(*mClientPump); + } + + ~HTTPClientTestData() + { + delete mClientPump; + SUBSYSTEM_CLEANUP(LLProxy); + apr_pool_destroy(mPool); + } + + void runThePump(float timeout = 100.0f) + { + LLTimer timer; + timer.setTimerExpirySec(timeout); + + while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired()) + { + LLFrameTimer::updateFrameTime(); + if (mClientPump) + { + mClientPump->pump(); + mClientPump->callback(); + } + } + } + + const std::string PORT; + const std::string local_server; + + private: + apr_pool_t* mPool; + LLPumpIO* mClientPump; + + protected: + void ensureStatusOK() + { + if (mSawError) + { + std::string msg = + llformat("httpFailure() called when not expected, status %d", + mStatus); + fail(msg); + } + } + + void ensureStatusError() + { + if (!mSawError) + { + fail("httpFailure() wasn't called"); + } + } + + LLSD getResult() + { + return mResult; + } + LLSD getHeader() + { + return mHeader; + } + + protected: + bool mSawError; + U32 mStatus; + std::string mReason; + bool mSawCompleted; + bool mSawCompletedHeader; + LLSD mResult; + LLSD mHeader; + bool mResultDeleted; + + class Result : public LLHTTPClient::Responder + { + protected: + Result(HTTPClientTestData& client) + : mClient(client) + { + } + + public: + static Result* build(HTTPClientTestData& client) + { + return new Result(client); + } + + ~Result() + { + mClient.mResultDeleted = true; + } + + protected: + virtual void httpFailure() + { + mClient.mSawError = true; + mClient.mStatus = getStatus(); + mClient.mReason = getReason(); + } + + virtual void httpSuccess() + { + mClient.mResult = getContent(); + } + + virtual void httpCompleted() + { + LLHTTPClient::Responder::httpCompleted(); + + mClient.mSawCompleted = true; + mClient.mSawCompletedHeader = true; + mClient.mHeader = getResponseHeaders(); + } + + private: + HTTPClientTestData& mClient; + }; + + friend class Result; + + protected: + LLHTTPClient::ResponderPtr newResult() + { + mSawError = false; + mStatus = 0; + mSawCompleted = false; + mSawCompletedHeader = false; + mResult.clear(); + mHeader.clear(); + mResultDeleted = false; + + return Result::build(*this); + } + }; + + + typedef test_group<HTTPClientTestData> HTTPClientTestGroup; + typedef HTTPClientTestGroup::object HTTPClientTestObject; + HTTPClientTestGroup httpClientTestGroup("http_client"); + + template<> template<> + void HTTPClientTestObject::test<1>() + { + LLHTTPClient::get(local_server, newResult()); + runThePump(); + ensureStatusOK(); + ensure("result object wasn't destroyed", mResultDeleted); + } + + template<> template<> + void HTTPClientTestObject::test<2>() + { + // Please nobody listen on this particular port... + LLHTTPClient::get("http://127.0.0.1:7950", newResult()); + runThePump(); + ensureStatusError(); + } + + template<> template<> + void HTTPClientTestObject::test<3>() + { + LLSD sd; + + sd["list"][0]["one"] = 1; + sd["list"][0]["two"] = 2; + sd["list"][1]["three"] = 3; + sd["list"][1]["four"] = 4; + + LLHTTPClient::post(local_server + "web/echo", sd, newResult()); + runThePump(); + ensureStatusOK(); + ensure_equals("echoed result matches", getResult(), sd); + } + + template<> template<> + void HTTPClientTestObject::test<4>() + { + LLSD sd; + + sd["message"] = "This is my test message."; + + LLHTTPClient::put(local_server + "test/storage", sd, newResult()); + runThePump(); + ensureStatusOK(); + + LLHTTPClient::get(local_server + "test/storage", newResult()); + runThePump(); + ensureStatusOK(); + ensure_equals("echoed result matches", getResult(), sd); + + } + + template<> template<> + void HTTPClientTestObject::test<5>() + { + LLSD sd; + sd["status"] = 543; + sd["reason"] = "error for testing"; + + LLHTTPClient::post(local_server + "test/error", sd, newResult()); + runThePump(); + ensureStatusError(); + ensure_contains("reason", mReason, sd["reason"]); + } + + template<> template<> + void HTTPClientTestObject::test<6>() + { + const F32 timeout = 1.0f; + LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout); + runThePump(timeout * 5.0f); + ensureStatusError(); + ensure_equals("reason", mReason, "STATUS_EXPIRED"); + } + + template<> template<> + void HTTPClientTestObject::test<7>() + { + LLHTTPClient::get(local_server, newResult()); + runThePump(); + ensureStatusOK(); + LLSD expected = getResult(); + + LLSD result; + result = LLHTTPClient::blockingGet(local_server); + LLSD body = result["body"]; + ensure_equals("echoed result matches", body.size(), expected.size()); + } + template<> template<> + void HTTPClientTestObject::test<8>() + { + // This is testing for the presence of the Header in the returned results + // from an HTTP::get call. + LLHTTPClient::get(local_server, newResult()); + runThePump(); + ensureStatusOK(); + LLSD header = getHeader(); + ensure("got a header", ! header.emptyMap().asBoolean()); + } + template<> template<> + void HTTPClientTestObject::test<9>() + { + LLHTTPClient::head(local_server, newResult()); + runThePump(); + ensureStatusOK(); + ensure("result object wasn't destroyed", mResultDeleted); + } } diff --git a/indra/llmessage/tests/llhttpnode_stub.cpp b/indra/llmessage/tests/llhttpnode_stub.cpp index 479a256bdd..d896084021 100644 --- a/indra/llmessage/tests/llhttpnode_stub.cpp +++ b/indra/llmessage/tests/llhttpnode_stub.cpp @@ -1,26 +1,26 @@ -/** +/** * @file llhttpnode_stub.cpp * @brief STUB Implementation of classes for generic HTTP/LSL/REST handling. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ - * + * * Second Life Viewer Source Code * Copyright (c) 2006-2009, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -69,28 +69,28 @@ const LLHTTPNode* LLHTTPNode::findNode(const std::string& name) const { return N LLHTTPNode::Response::~Response(){} void LLHTTPNode::Response::notFound(const std::string& message) { - status(404, message); + status(404, message); } void LLHTTPNode::Response::notFound() { - status(404, "Not Found"); + status(404, "Not Found"); } void LLHTTPNode::Response::methodNotAllowed() { - status(405, "Method Not Allowed"); + status(405, "Method Not Allowed"); } void LLHTTPNode::Response::statusUnknownError(S32 code) { - status(code, "Unknown Error"); + status(code, "Unknown Error"); } void LLHTTPNode::Response::status(S32 code, const std::string& message) { } -void LLHTTPNode::Response::addHeader(const std::string& name,const std::string& value) +void LLHTTPNode::Response::addHeader(const std::string& name,const std::string& value) { - mHeaders[name] = value; + mHeaders[name] = value; } void LLHTTPNode::describe(Description& desc) const { } diff --git a/indra/llmessage/tests/llnamevalue_test.cpp b/indra/llmessage/tests/llnamevalue_test.cpp index 8902fdd2e8..f77cd102f4 100644 --- a/indra/llmessage/tests/llnamevalue_test.cpp +++ b/indra/llmessage/tests/llnamevalue_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llnamevalue_test.cpp * @author Adroit * @date 2007-02 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,366 +41,366 @@ namespace tut { - struct namevalue_test - { - namevalue_test() - { - } - }; - typedef test_group<namevalue_test> namevalue_t; - typedef namevalue_t::object namevalue_object_t; - tut::namevalue_t tut_namevalue("LLNameValue"); - - - template<> template<> - void namevalue_object_t::test<1>() - { - // LLNameValue() - LLNameValue nValue; - ensure("mName should have been NULL", nValue.mName == NULL); - ensure("getTypeEnum failed",nValue.getTypeEnum() == NVT_NULL); - ensure("getClassEnum failed",nValue.getClassEnum() == NVC_NULL); - ensure("getSendtoEnum failed",nValue.getSendtoEnum() == NVS_NULL); - - LLNameValue nValue1(" SecondLife ASSET RW SIM 232324343"); - - } - - // LLNameValue(const char* data); - // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, const char* nvsendto, - // TNameValueCallback nvcb = NULL, void** user_data = NULL); - template<> template<> - void namevalue_object_t::test<2>() - { - LLNameValue nValue(" SecondLife ASSET RW S 232324343"); - ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); - ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); - ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); - ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); - ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); - ensure("sendToData or sendToViewer failed", !nValue.sendToData() && !nValue.sendToViewer()); - - LLNameValue nValue1("\n\r SecondLife_1 STRING READ_WRITE SIM 232324343"); - ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife_1"))); - ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); - ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); - ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); - ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); - ensure("1. sendToData or sendToViewer failed", !nValue1.sendToData() && !nValue1.sendToViewer()); - - LLNameValue nValue2("SecondLife", "23.5", "F32", "R", "DS"); - ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); - ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); - ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_DATA_SIM); - ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); - ensure("2. sendToData or sendToViewer failed", nValue2.sendToData() && !nValue2.sendToViewer()); - - LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY", "SIM_SPACE"); - ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); - ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); - ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_DATA_SIM); - ensure("3. getS32 failed", *nValue3.getS32() == -43456787); - ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); - - LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV"); - LLVector3 llvec4(1.0, 2.0, 3.0); - ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); - ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); - ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); - ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); - ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); - - LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER"); - LLVector3 llvec5(-1.0f, 2.4f, 3); - ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); - ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); - ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); - ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); - ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); - - LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV"); - ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); - ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); - ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); - ensure("6. getU32 failed", *nValue6.getU32() == 89764323); - ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); - - LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER"); - U64 u64_7 = U64L(89764323323232); - ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); - ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); - ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); - ensure("7. getU32 failed", *nValue7.getU64() == u64_7); - ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); - } - - // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, - // TNameValueCallback nvcb = NULL, void** user_data = NULL); - template<> template<> - void namevalue_object_t::test<3>() - { - LLNameValue nValue("SecondLife", "232324343", "ASSET", "READ_WRITE"); - ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); - ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); - ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); - ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); - ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); - - LLNameValue nValue1("SecondLife", "232324343", "STRING", "READ_WRITE"); - ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); - ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); - ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); - ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); - ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); - - LLNameValue nValue2("SecondLife", "23.5", "F32", "R"); - ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); - ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); - ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); - ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); - - LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY"); - ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); - ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); - ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); - ensure("3. getS32 failed", *nValue3.getS32() == -43456787); - - LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW"); - LLVector3 llvec4(1.0, 2.0, 3.0); - ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); - ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); - ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); - ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); - - LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW"); - LLVector3 llvec5(-1.0f, 2.4f, 3); - ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); - ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); - ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); - ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); - - LLNameValue nValue6("SecondLife", "89764323", "U32", "RW"); - ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); - ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); - ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); - ensure("6. getU32 failed", *nValue6.getU32() == 89764323); - - LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW"); - U64 u64_7 = U64L(89764323323232); - ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); - ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); - ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); - ensure("7. getU32 failed", *nValue7.getU64() == u64_7); - } - - // LLNameValue(const char* name, const char* type, const char* nvclass, - // TNameValueCallback nvcb = NULL, void** user_data = NULL); - template<> template<> - void namevalue_object_t::test<4>() - { - LLNameValue nValue("SecondLife", "STRING", "READ_WRITE"); - ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); - ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_STRING); - ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); - ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); - - LLNameValue nValue1("SecondLife", "ASSET", "READ_WRITE"); - ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); - ensure("1. getTypeEnum for RW failed", nValue1.getTypeEnum() == NVT_ASSET); - ensure("1. getClassEnum for RW failed", nValue1.getClassEnum() == NVC_READ_WRITE); - ensure("1. getSendtoEnum for RW failed", nValue1.getSendtoEnum() == NVS_SIM); - - LLNameValue nValue2("SecondLife", "F32", "READ_ONLY"); - ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); - ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); - ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); - - LLNameValue nValue3("SecondLife", "S32", "READ_ONLY"); - ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); - ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); - ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); - - LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE"); - ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); - ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); - ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); - - LLNameValue nValue6("SecondLife", "U32", "READ_WRITE"); - ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); - ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); - ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); - - LLNameValue nValue7("SecondLife", "U64", "READ_WRITE"); - ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); - ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); - ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); - } - - template<> template<> - void namevalue_object_t::test<5>() - { - LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM"); - - ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); - } - - template<> template<> - void namevalue_object_t::test<6>() - { - LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S"); - ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); - } - - template<> template<> - void namevalue_object_t::test<7>() - { - LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM"); - - ensure("getF32 failed",*nValue.getF32() == 555555.f); - } - - template<> template<> - void namevalue_object_t::test<8>() - { - LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM"); - - ensure("getS32 failed", *nValue.getS32() == -5555); - - S32 sVal = 0x7FFFFFFF; - nValue.setS32(sVal); - ensure("getS32 failed", *nValue.getS32() == sVal); - - sVal = -0x7FFFFFFF; - nValue.setS32(sVal); - ensure("getS32 failed", *nValue.getS32() == sVal); - - sVal = 0; - nValue.setS32(sVal); - ensure("getS32 failed", *nValue.getS32() == sVal); - } - - template<> template<> - void namevalue_object_t::test<9>() - { - LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM"); - LLVector3 vecExpected(-3, 2, 1); - LLVector3 vec; - nValue.getVec3(vec); - ensure("getVec3 failed", vec == vecExpected); - } - - template<> template<> - void namevalue_object_t::test<10>() - { - LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM"); - - ensure("getU32 failed",*nValue.getU32() == 12345678); - - U32 val = 0xFFFFFFFF; - nValue.setU32(val); - ensure("U32 max", *nValue.getU32() == val); - - val = 0; - nValue.setU32(val); - ensure("U32 min", *nValue.getU32() == val); - } - - template<> template<> - void namevalue_object_t::test<11>() - { - //skip_fail("incomplete support for U64."); - LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM"); - - ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); - - // there is no LLNameValue::setU64() - } - - - template<> template<> - void namevalue_object_t::test<12>() - { - //skip_fail("incomplete support for U64."); - LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); - std::string ret_str = nValue.printNameValue(); - - ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); - - LLNameValue nValue1(ret_str.c_str()); - ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64()); - } - - template<> template<> - void namevalue_object_t::test<13>() - { - LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); - std::string ret_str = nValue.printData(); - ensure_equals("1:printData failed",ret_str,"44444444444"); - - LLNameValue nValue1("SecondLife S32 RW DSV 44444"); - ret_str = nValue1.printData(); - ensure_equals("2:printData failed",ret_str,"44444"); - } - - template<> template<> - void namevalue_object_t::test<14>() - { - LLNameValue nValue("SecodLife STRING RW SIM 22222"); - std::ostringstream stream1,stream2,stream3, stream4, stream5; - stream1 << nValue; - ensure_equals("STRING << failed",stream1.str(),"22222"); - - LLNameValue nValue1("SecodLife F32 RW SIM 22222"); - stream2 << nValue1; - ensure_equals("F32 << failed",stream2.str(),"22222"); - - LLNameValue nValue2("SecodLife S32 RW SIM 22222"); - stream3<< nValue2; - ensure_equals("S32 << failed",stream3.str(),"22222"); - - LLNameValue nValue3("SecodLife U32 RW SIM 122222"); - stream4<< nValue3; - ensure_equals("U32 << failed",stream4.str(),"122222"); - - // I don't think we use U64 name value pairs. JC - //skip_fail("incomplete support for U64."); - //LLNameValue nValue4("SecodLife U64 RW SIM 22222"); - //stream5<< nValue4; - //ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); - } - - template<> template<> - void namevalue_object_t::test<15>() - { - LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S"); - - ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); - // this should not have updated as it is read only. - nValue.setAsset("New Value should not be updated"); - ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); - - LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S"); - // this should not have updated as it is read only. - nValue1.setU32(4567); - ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); - - LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S"); - // this should not have updated as it is read only. - nValue2.setS32(4567); - ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); - - LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S"); - // this should not have updated as it is read only. - nValue3.setF32(4567); - ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); - - LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S"); - // this should not have updated as it is read only. - LLVector3 vec(4,5,6); - nValue3.setVec3(vec); - LLVector3 vec1(1,2,3); - ensure("setVec3 on ReadOnly failed", *nValue4.getVec3() == vec1); - - // cant test for U64 as no set64 exists nor any operators support U64 type - } + struct namevalue_test + { + namevalue_test() + { + } + }; + typedef test_group<namevalue_test> namevalue_t; + typedef namevalue_t::object namevalue_object_t; + tut::namevalue_t tut_namevalue("LLNameValue"); + + + template<> template<> + void namevalue_object_t::test<1>() + { + // LLNameValue() + LLNameValue nValue; + ensure("mName should have been NULL", nValue.mName == NULL); + ensure("getTypeEnum failed",nValue.getTypeEnum() == NVT_NULL); + ensure("getClassEnum failed",nValue.getClassEnum() == NVC_NULL); + ensure("getSendtoEnum failed",nValue.getSendtoEnum() == NVS_NULL); + + LLNameValue nValue1(" SecondLife ASSET RW SIM 232324343"); + + } + + // LLNameValue(const char* data); + // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, const char* nvsendto, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<2>() + { + LLNameValue nValue(" SecondLife ASSET RW S 232324343"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + ensure("sendToData or sendToViewer failed", !nValue.sendToData() && !nValue.sendToViewer()); + + LLNameValue nValue1("\n\r SecondLife_1 STRING READ_WRITE SIM 232324343"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife_1"))); + ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); + ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); + ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + ensure("1. sendToData or sendToViewer failed", !nValue1.sendToData() && !nValue1.sendToViewer()); + + LLNameValue nValue2("SecondLife", "23.5", "F32", "R", "DS"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_DATA_SIM); + ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + ensure("2. sendToData or sendToViewer failed", nValue2.sendToData() && !nValue2.sendToViewer()); + + LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY", "SIM_SPACE"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_DATA_SIM); + ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); + + LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV"); + LLVector3 llvec4(1.0, 2.0, 3.0); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); + ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); + + LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER"); + LLVector3 llvec5(-1.0f, 2.4f, 3); + ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); + ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); + ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); + ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); + + LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); + + LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER"); + U64 u64_7 = U64L(89764323323232); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); + } + + // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<3>() + { + LLNameValue nValue("SecondLife", "232324343", "ASSET", "READ_WRITE"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + + LLNameValue nValue1("SecondLife", "232324343", "STRING", "READ_WRITE"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); + ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); + ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); + ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + + LLNameValue nValue2("SecondLife", "23.5", "F32", "R"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + + LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + + LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW"); + LLVector3 llvec4(1.0, 2.0, 3.0); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + + LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW"); + LLVector3 llvec5(-1.0f, 2.4f, 3); + ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); + ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); + ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); + ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + + LLNameValue nValue6("SecondLife", "89764323", "U32", "RW"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + + LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW"); + U64 u64_7 = U64L(89764323323232); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + } + + // LLNameValue(const char* name, const char* type, const char* nvclass, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<4>() + { + LLNameValue nValue("SecondLife", "STRING", "READ_WRITE"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_STRING); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue1("SecondLife", "ASSET", "READ_WRITE"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); + ensure("1. getTypeEnum for RW failed", nValue1.getTypeEnum() == NVT_ASSET); + ensure("1. getClassEnum for RW failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum for RW failed", nValue1.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue2("SecondLife", "F32", "READ_ONLY"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue3("SecondLife", "S32", "READ_ONLY"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE"); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue6("SecondLife", "U32", "READ_WRITE"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue7("SecondLife", "U64", "READ_WRITE"); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + } + + template<> template<> + void namevalue_object_t::test<5>() + { + LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM"); + + ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); + } + + template<> template<> + void namevalue_object_t::test<6>() + { + LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S"); + ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + } + + template<> template<> + void namevalue_object_t::test<7>() + { + LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM"); + + ensure("getF32 failed",*nValue.getF32() == 555555.f); + } + + template<> template<> + void namevalue_object_t::test<8>() + { + LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM"); + + ensure("getS32 failed", *nValue.getS32() == -5555); + + S32 sVal = 0x7FFFFFFF; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + + sVal = -0x7FFFFFFF; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + + sVal = 0; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + } + + template<> template<> + void namevalue_object_t::test<9>() + { + LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM"); + LLVector3 vecExpected(-3, 2, 1); + LLVector3 vec; + nValue.getVec3(vec); + ensure("getVec3 failed", vec == vecExpected); + } + + template<> template<> + void namevalue_object_t::test<10>() + { + LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM"); + + ensure("getU32 failed",*nValue.getU32() == 12345678); + + U32 val = 0xFFFFFFFF; + nValue.setU32(val); + ensure("U32 max", *nValue.getU32() == val); + + val = 0; + nValue.setU32(val); + ensure("U32 min", *nValue.getU32() == val); + } + + template<> template<> + void namevalue_object_t::test<11>() + { + //skip_fail("incomplete support for U64."); + LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM"); + + ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); + + // there is no LLNameValue::setU64() + } + + + template<> template<> + void namevalue_object_t::test<12>() + { + //skip_fail("incomplete support for U64."); + LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); + std::string ret_str = nValue.printNameValue(); + + ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); + + LLNameValue nValue1(ret_str.c_str()); + ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64()); + } + + template<> template<> + void namevalue_object_t::test<13>() + { + LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); + std::string ret_str = nValue.printData(); + ensure_equals("1:printData failed",ret_str,"44444444444"); + + LLNameValue nValue1("SecondLife S32 RW DSV 44444"); + ret_str = nValue1.printData(); + ensure_equals("2:printData failed",ret_str,"44444"); + } + + template<> template<> + void namevalue_object_t::test<14>() + { + LLNameValue nValue("SecodLife STRING RW SIM 22222"); + std::ostringstream stream1,stream2,stream3, stream4, stream5; + stream1 << nValue; + ensure_equals("STRING << failed",stream1.str(),"22222"); + + LLNameValue nValue1("SecodLife F32 RW SIM 22222"); + stream2 << nValue1; + ensure_equals("F32 << failed",stream2.str(),"22222"); + + LLNameValue nValue2("SecodLife S32 RW SIM 22222"); + stream3<< nValue2; + ensure_equals("S32 << failed",stream3.str(),"22222"); + + LLNameValue nValue3("SecodLife U32 RW SIM 122222"); + stream4<< nValue3; + ensure_equals("U32 << failed",stream4.str(),"122222"); + + // I don't think we use U64 name value pairs. JC + //skip_fail("incomplete support for U64."); + //LLNameValue nValue4("SecodLife U64 RW SIM 22222"); + //stream5<< nValue4; + //ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); + } + + template<> template<> + void namevalue_object_t::test<15>() + { + LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S"); + + ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + // this should not have updated as it is read only. + nValue.setAsset("New Value should not be updated"); + ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + + LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S"); + // this should not have updated as it is read only. + nValue1.setU32(4567); + ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); + + LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S"); + // this should not have updated as it is read only. + nValue2.setS32(4567); + ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); + + LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S"); + // this should not have updated as it is read only. + nValue3.setF32(4567); + ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); + + LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S"); + // this should not have updated as it is read only. + LLVector3 vec(4,5,6); + nValue3.setVec3(vec); + LLVector3 vec1(1,2,3); + ensure("setVec3 on ReadOnly failed", *nValue4.getVec3() == vec1); + + // cant test for U64 as no set64 exists nor any operators support U64 type + } } diff --git a/indra/llmessage/tests/llpartdata_test.cpp b/indra/llmessage/tests/llpartdata_test.cpp index de81e0bbb2..c517232bcc 100644 --- a/indra/llmessage/tests/llpartdata_test.cpp +++ b/indra/llmessage/tests/llpartdata_test.cpp @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,116 +39,116 @@ namespace tut { - //bunch of sniffed data that *should* be a valid particle system - static U8 msg[] = { - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x80, - 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x5e, 0x12, 0x0b, 0xa1, 0x58, 0x05, 0xdc, 0x57, 0x66, - 0xb7, 0xf5, 0xac, 0x4b, 0xd1, 0x8f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x0a, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7e, 0xc6, 0x81, 0xdc, 0x7e, 0xc6, 0x81, 0xdc, 0x77, 0xcf, 0xef, 0xd4, 0xce, 0x64, 0x1a, 0x7e, - 0x26, 0x87, 0x55, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0x77, 0xcf, 0x98, 0xa3, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf2, - 0xf1, 0x65, 0x32, 0x1b, 0xef, 0x18, 0x70, 0x66, 0xba, 0x30, 0xa0, 0x11, 0xaa, 0x2f, 0xb0, 0xab, 0xd0, - 0x30, 0x7d, 0xbd, 0x01, 0x00, 0xf8, 0x0d, 0xb8, 0x30, 0x01, 0x00, 0x00, 0x00, 0xce, 0xc6, 0x81, 0xdc, - 0xce, 0xc6, 0x81, 0xdc, 0xc7, 0xcf, 0xef, 0xd4, 0x75, 0x65, 0x1a, 0x7f, 0x62, 0x6f, 0x55, 0x7f, 0x6d, - 0x65, 0x22, 0x7f, 0x6d, 0x65, 0x22, 0x7f, 0xc7, 0xcf, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf2, 0xf1, 0x62, 0x12, 0x1b, 0xef, - 0x18, 0x7e, 0xbd, 0x01, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0xac, 0x28, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, - 0xe0, 0xb9, 0x30, 0x03, 0xe1, 0xb9, 0x30, 0xbb, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb9, 0x30, 0x36, 0xd9, - 0x81, 0xdc, 0x36, 0xd9, 0x81, 0xdc, 0x3f, 0xd0, 0xef, 0xd4, 0xa5, 0x7a, 0x72, 0x7f, 0x26, 0x30, 0x55, - 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x3f, 0xd0, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - struct partdata_test - { - }; + //bunch of sniffed data that *should* be a valid particle system + static U8 msg[] = { + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x5e, 0x12, 0x0b, 0xa1, 0x58, 0x05, 0xdc, 0x57, 0x66, + 0xb7, 0xf5, 0xac, 0x4b, 0xd1, 0x8f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x0a, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0xc6, 0x81, 0xdc, 0x7e, 0xc6, 0x81, 0xdc, 0x77, 0xcf, 0xef, 0xd4, 0xce, 0x64, 0x1a, 0x7e, + 0x26, 0x87, 0x55, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0x77, 0xcf, 0x98, 0xa3, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf2, + 0xf1, 0x65, 0x32, 0x1b, 0xef, 0x18, 0x70, 0x66, 0xba, 0x30, 0xa0, 0x11, 0xaa, 0x2f, 0xb0, 0xab, 0xd0, + 0x30, 0x7d, 0xbd, 0x01, 0x00, 0xf8, 0x0d, 0xb8, 0x30, 0x01, 0x00, 0x00, 0x00, 0xce, 0xc6, 0x81, 0xdc, + 0xce, 0xc6, 0x81, 0xdc, 0xc7, 0xcf, 0xef, 0xd4, 0x75, 0x65, 0x1a, 0x7f, 0x62, 0x6f, 0x55, 0x7f, 0x6d, + 0x65, 0x22, 0x7f, 0x6d, 0x65, 0x22, 0x7f, 0xc7, 0xcf, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf2, 0xf1, 0x62, 0x12, 0x1b, 0xef, + 0x18, 0x7e, 0xbd, 0x01, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xac, 0x28, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, + 0xe0, 0xb9, 0x30, 0x03, 0xe1, 0xb9, 0x30, 0xbb, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb9, 0x30, 0x36, 0xd9, + 0x81, 0xdc, 0x36, 0xd9, 0x81, 0xdc, 0x3f, 0xd0, 0xef, 0xd4, 0xa5, 0x7a, 0x72, 0x7f, 0x26, 0x30, 0x55, + 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x3f, 0xd0, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + struct partdata_test + { + }; + + typedef test_group<partdata_test> partdata_test_t; + typedef partdata_test_t::object partdata_test_object_t; + tut::partdata_test_t tut_partdata_test("LLPartData"); + + template<> template<> + void partdata_test_object_t::test<1>() + { + LLPartSysData llpsysdata; + LLDataPackerBinaryBuffer dp1(msg, sizeof(msg)); - typedef test_group<partdata_test> partdata_test_t; - typedef partdata_test_t::object partdata_test_object_t; - tut::partdata_test_t tut_partdata_test("LLPartData"); + ensure("LLPartSysData::unpack failed.", llpsysdata.unpack(dp1)); - template<> template<> - void partdata_test_object_t::test<1>() - { - LLPartSysData llpsysdata; - LLDataPackerBinaryBuffer dp1(msg, sizeof(msg)); - ensure("LLPartSysData::unpack failed.", llpsysdata.unpack(dp1)); + //mCRC 1 unsigned int + ensure("mCRC different after unpacking", llpsysdata.mCRC == (U32) 1); + //mFlags 0 unsigned int + ensure ("mFlags different after unpacking", llpsysdata.mFlags == (U32) 0); + //mPattern 1 '' unsigned char + ensure ("mPattern different after unpacking", llpsysdata.mPattern == (U8) 1); + //mInnerAngle 0.00000000 float + ensure_approximately_equals("mInnerAngle different after unpacking", llpsysdata.mInnerAngle, 0.f, 8); + //mOuterAngle 0.00000000 float + ensure_approximately_equals("mOuterAngle different after unpacking", llpsysdata.mOuterAngle, 0.f, 8); + //mAngularVelocity 0,0,0 + ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[0], 0.f, 8); + ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[1], 0.f, 8); + ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[2], 0.f, 8); + //mBurstRate 0.097656250 float + ensure_approximately_equals("mBurstRate different after unpacking", llpsysdata.mBurstRate, 0.097656250f, 8); + //mBurstPartCount 1 '' unsigned char + ensure("mBurstPartCount different after unpacking", llpsysdata.mBurstPartCount == (U8) 1); + //mBurstRadius 0.00000000 float + ensure_approximately_equals("mBurstRadius different after unpacking", llpsysdata.mBurstRadius, 0.f, 8); + //mBurstSpeedMin 1.0000000 float + ensure_approximately_equals("mBurstSpeedMin different after unpacking", llpsysdata.mBurstSpeedMin, 1.f, 8); + //mBurstSpeedMax 1.0000000 float + ensure_approximately_equals("mBurstSpeedMax different after unpacking", llpsysdata.mBurstSpeedMax, 1.f, 8); + //mMaxAge 0.00000000 float + ensure_approximately_equals("mMaxAge different after unpacking", llpsysdata.mMaxAge, 0.f, 8); + //mStartAge 0.00000000 float + ensure_approximately_equals("mStartAge different after unpacking", llpsysdata.mStartAge, 0.f, 8); + //mPartAccel <0,0,0> + ensure_approximately_equals("mPartAccel.mV[0] different after unpacking", llpsysdata.mPartAccel.mV[0], 0.f, 7); + ensure_approximately_equals("mPartAccel.mV[1] different after unpacking", llpsysdata.mPartAccel.mV[1], 0.f, 7); + ensure_approximately_equals("mPartAccel.mV[2] different after unpacking", llpsysdata.mPartAccel.mV[2], 0.f, 7); - - //mCRC 1 unsigned int - ensure("mCRC different after unpacking", llpsysdata.mCRC == (U32) 1); - //mFlags 0 unsigned int - ensure ("mFlags different after unpacking", llpsysdata.mFlags == (U32) 0); - //mPattern 1 '' unsigned char - ensure ("mPattern different after unpacking", llpsysdata.mPattern == (U8) 1); - //mInnerAngle 0.00000000 float - ensure_approximately_equals("mInnerAngle different after unpacking", llpsysdata.mInnerAngle, 0.f, 8); - //mOuterAngle 0.00000000 float - ensure_approximately_equals("mOuterAngle different after unpacking", llpsysdata.mOuterAngle, 0.f, 8); - //mAngularVelocity 0,0,0 - ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[0], 0.f, 8); - ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[1], 0.f, 8); - ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[2], 0.f, 8); - //mBurstRate 0.097656250 float - ensure_approximately_equals("mBurstRate different after unpacking", llpsysdata.mBurstRate, 0.097656250f, 8); - //mBurstPartCount 1 '' unsigned char - ensure("mBurstPartCount different after unpacking", llpsysdata.mBurstPartCount == (U8) 1); - //mBurstRadius 0.00000000 float - ensure_approximately_equals("mBurstRadius different after unpacking", llpsysdata.mBurstRadius, 0.f, 8); - //mBurstSpeedMin 1.0000000 float - ensure_approximately_equals("mBurstSpeedMin different after unpacking", llpsysdata.mBurstSpeedMin, 1.f, 8); - //mBurstSpeedMax 1.0000000 float - ensure_approximately_equals("mBurstSpeedMax different after unpacking", llpsysdata.mBurstSpeedMax, 1.f, 8); - //mMaxAge 0.00000000 float - ensure_approximately_equals("mMaxAge different after unpacking", llpsysdata.mMaxAge, 0.f, 8); - //mStartAge 0.00000000 float - ensure_approximately_equals("mStartAge different after unpacking", llpsysdata.mStartAge, 0.f, 8); - //mPartAccel <0,0,0> - ensure_approximately_equals("mPartAccel.mV[0] different after unpacking", llpsysdata.mPartAccel.mV[0], 0.f, 7); - ensure_approximately_equals("mPartAccel.mV[1] different after unpacking", llpsysdata.mPartAccel.mV[1], 0.f, 7); - ensure_approximately_equals("mPartAccel.mV[2] different after unpacking", llpsysdata.mPartAccel.mV[2], 0.f, 7); + //mPartData + LLPartData& data = llpsysdata.mPartData; - //mPartData - LLPartData& data = llpsysdata.mPartData; + //mFlags 132354 unsigned int + ensure ("mPartData.mFlags different after unpacking", data.mFlags == (U32) 132354); + //mMaxAge 10.000000 float + ensure_approximately_equals("mPartData.mMaxAge different after unpacking", data.mMaxAge, 10.f, 8); + //mStartColor <1,1,1,1> + ensure_approximately_equals("mPartData.mStartColor.mV[0] different after unpacking", data.mStartColor.mV[0], 1.f, 8); + ensure_approximately_equals("mPartData.mStartColor.mV[1] different after unpacking", data.mStartColor.mV[1], 1.f, 8); + ensure_approximately_equals("mPartData.mStartColor.mV[2] different after unpacking", data.mStartColor.mV[2], 1.f, 8); + ensure_approximately_equals("mPartData.mStartColor.mV[3] different after unpacking", data.mStartColor.mV[3], 1.f, 8); + //mEndColor <1,1,0,0> + ensure_approximately_equals("mPartData.mEndColor.mV[0] different after unpacking", data.mEndColor.mV[0], 1.f, 8); + ensure_approximately_equals("mPartData.mEndColor.mV[1] different after unpacking", data.mEndColor.mV[1], 1.f, 8); + ensure_approximately_equals("mPartData.mEndColor.mV[2] different after unpacking", data.mEndColor.mV[2], 0.f, 8); + ensure_approximately_equals("mPartData.mEndColor.mV[3] different after unpacking", data.mEndColor.mV[3], 0.f, 8); + //mStartScale <1,1> + ensure_approximately_equals("mPartData.mStartScale.mV[0] different after unpacking", data.mStartScale.mV[0], 1.f, 8); + ensure_approximately_equals("mPartData.mStartScale.mV[1] different after unpacking", data.mStartScale.mV[1], 1.f, 8); + //mEndScale <0,0> + ensure_approximately_equals("mPartData.mEndScale.mV[0] different after unpacking", data.mEndScale.mV[0], 0.f, 8); + ensure_approximately_equals("mPartData.mEndScale.mV[1] different after unpacking", data.mEndScale.mV[1], 0.f, 8); + //mPosOffset <0,0,0> + ensure_approximately_equals("mPartData.mPosOffset.mV[0] different after unpacking", data.mPosOffset.mV[0], 0.f, 8); + ensure_approximately_equals("mPartData.mPosOffset.mV[1] different after unpacking", data.mPosOffset.mV[1], 0.f, 8); + ensure_approximately_equals("mPartData.mPosOffset.mV[2] different after unpacking", data.mPosOffset.mV[2], 0.f, 8); + //mParameter 0.00000000 float + ensure_approximately_equals("mPartData.mParameter different after unpacking", data.mParameter, 0.f, 8); - //mFlags 132354 unsigned int - ensure ("mPartData.mFlags different after unpacking", data.mFlags == (U32) 132354); - //mMaxAge 10.000000 float - ensure_approximately_equals("mPartData.mMaxAge different after unpacking", data.mMaxAge, 10.f, 8); - //mStartColor <1,1,1,1> - ensure_approximately_equals("mPartData.mStartColor.mV[0] different after unpacking", data.mStartColor.mV[0], 1.f, 8); - ensure_approximately_equals("mPartData.mStartColor.mV[1] different after unpacking", data.mStartColor.mV[1], 1.f, 8); - ensure_approximately_equals("mPartData.mStartColor.mV[2] different after unpacking", data.mStartColor.mV[2], 1.f, 8); - ensure_approximately_equals("mPartData.mStartColor.mV[3] different after unpacking", data.mStartColor.mV[3], 1.f, 8); - //mEndColor <1,1,0,0> - ensure_approximately_equals("mPartData.mEndColor.mV[0] different after unpacking", data.mEndColor.mV[0], 1.f, 8); - ensure_approximately_equals("mPartData.mEndColor.mV[1] different after unpacking", data.mEndColor.mV[1], 1.f, 8); - ensure_approximately_equals("mPartData.mEndColor.mV[2] different after unpacking", data.mEndColor.mV[2], 0.f, 8); - ensure_approximately_equals("mPartData.mEndColor.mV[3] different after unpacking", data.mEndColor.mV[3], 0.f, 8); - //mStartScale <1,1> - ensure_approximately_equals("mPartData.mStartScale.mV[0] different after unpacking", data.mStartScale.mV[0], 1.f, 8); - ensure_approximately_equals("mPartData.mStartScale.mV[1] different after unpacking", data.mStartScale.mV[1], 1.f, 8); - //mEndScale <0,0> - ensure_approximately_equals("mPartData.mEndScale.mV[0] different after unpacking", data.mEndScale.mV[0], 0.f, 8); - ensure_approximately_equals("mPartData.mEndScale.mV[1] different after unpacking", data.mEndScale.mV[1], 0.f, 8); - //mPosOffset <0,0,0> - ensure_approximately_equals("mPartData.mPosOffset.mV[0] different after unpacking", data.mPosOffset.mV[0], 0.f, 8); - ensure_approximately_equals("mPartData.mPosOffset.mV[1] different after unpacking", data.mPosOffset.mV[1], 0.f, 8); - ensure_approximately_equals("mPartData.mPosOffset.mV[2] different after unpacking", data.mPosOffset.mV[2], 0.f, 8); - //mParameter 0.00000000 float - ensure_approximately_equals("mPartData.mParameter different after unpacking", data.mParameter, 0.f, 8); - - //mStartGlow 0.00000000 float - ensure_approximately_equals("mPartData.mStartGlow different after unpacking", data.mStartGlow, 0.f, 8); - //mEndGlow 0.00000000 float - ensure_approximately_equals("mPartData.mEndGlow different after unpacking", data.mEndGlow, 0.f, 8); - //mBlendFuncSource 2 '' unsigned char - ensure("mPartData.mBlendFuncSource different after unpacking", data.mBlendFuncSource == (U8) 2); - //mBlendFuncDest 1 '' unsigned char - ensure("mPartData.mBlendFuncDest different after unpacking", data.mBlendFuncDest == (U8) 1); - } + //mStartGlow 0.00000000 float + ensure_approximately_equals("mPartData.mStartGlow different after unpacking", data.mStartGlow, 0.f, 8); + //mEndGlow 0.00000000 float + ensure_approximately_equals("mPartData.mEndGlow different after unpacking", data.mEndGlow, 0.f, 8); + //mBlendFuncSource 2 '' unsigned char + ensure("mPartData.mBlendFuncSource different after unpacking", data.mBlendFuncSource == (U8) 2); + //mBlendFuncDest 1 '' unsigned char + ensure("mPartData.mBlendFuncDest different after unpacking", data.mBlendFuncDest == (U8) 1); + } } diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp index 3f87a4aff6..c5b852453f 100644 --- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,121 +40,121 @@ LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // sensor test doubles bool gClearRecvWasCalled = false; -void LLMessageSystem::clearReceiveState(void) -{ - gClearRecvWasCalled = true; +void LLMessageSystem::clearReceiveState(void) +{ + gClearRecvWasCalled = true; } char gUdpDispatchedData[MAX_BUFFER_SIZE]; bool gUdpDispatchWasCalled = false; bool LLTemplateMessageReader::readMessage(const U8* data,class LLHost const &) { - gUdpDispatchWasCalled = true; - strcpy(gUdpDispatchedData, reinterpret_cast<const char*>(data)); - return true; + gUdpDispatchWasCalled = true; + strcpy(gUdpDispatchedData, reinterpret_cast<const char*>(data)); + return true; } bool gValidateMessage = false; bool LLTemplateMessageReader::validateMessage(const U8*, S32 buffer_size, LLHost const &sender, bool trusted) { - return gValidateMessage; + return gValidateMessage; } LLHost host; -const LLHost& LLMessageSystem::getSender() const -{ - return host; +const LLHost& LLMessageSystem::getSender() const +{ + return host; } const char* gBinaryTemplateData = "BINARYTEMPLATEDATA"; void fillVector(std::vector<U8>& vector_data, const char* data) { - vector_data.resize(strlen(data) + 1); - strcpy(reinterpret_cast<char*>(&vector_data[0]), data); + vector_data.resize(strlen(data) + 1); + strcpy(reinterpret_cast<char*>(&vector_data[0]), data); } namespace tut { - static LLTemplateMessageReader::message_template_number_map_t numberMap; - - struct LLTemplateMessageDispatcherData - { - LLTemplateMessageDispatcherData() - { - mMessageName = "MessageName"; - gUdpDispatchWasCalled = false; - gClearRecvWasCalled = false; - gValidateMessage = false; - mMessage["body"]["binary-template-data"] = std::vector<U8>(); - } - - LLSD mMessage; - LLHTTPNode::ResponsePtr mResponsePtr; - std::string mMessageName; - }; - - typedef test_group<LLTemplateMessageDispatcherData> factory; - typedef factory::object object; + static LLTemplateMessageReader::message_template_number_map_t numberMap; + + struct LLTemplateMessageDispatcherData + { + LLTemplateMessageDispatcherData() + { + mMessageName = "MessageName"; + gUdpDispatchWasCalled = false; + gClearRecvWasCalled = false; + gValidateMessage = false; + mMessage["body"]["binary-template-data"] = std::vector<U8>(); + } + + LLSD mMessage; + LLHTTPNode::ResponsePtr mResponsePtr; + std::string mMessageName; + }; + + typedef test_group<LLTemplateMessageDispatcherData> factory; + typedef factory::object object; } namespace { - tut::factory tf("LLTemplateMessageDispatcher"); + tut::factory tf("LLTemplateMessageDispatcher"); } namespace tut { - // does an empty message stop processing? - template<> template<> - void object::test<1>() - { - LLTemplateMessageReader* pReader = NULL; - LLTemplateMessageDispatcher t(*pReader); - t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure(! gUdpDispatchWasCalled); - ensure(! gClearRecvWasCalled); - } - - // does the disaptch invoke the udp send method? - template<> template<> - void object::test<2>() - { - LLTemplateMessageReader* pReader = NULL; - LLTemplateMessageDispatcher t(*pReader); - gValidateMessage = true; - std::vector<U8> vector_data; - fillVector(vector_data, gBinaryTemplateData); - mMessage["body"]["binary-template-data"] = vector_data; - t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure("udp dispatch was called", gUdpDispatchWasCalled); - } - - // what if the message wasn't valid? We would hope the message gets cleared! - template<> template<> - void object::test<3>() - { - LLTemplateMessageReader* pReader = NULL; - LLTemplateMessageDispatcher t(*pReader); - std::vector<U8> vector_data; - fillVector(vector_data, gBinaryTemplateData); - mMessage["body"]["binary-template-data"] = vector_data; - gValidateMessage = false; - t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure("clear received message was called", gClearRecvWasCalled); - } - - // is the binary data passed through correctly? - template<> template<> - void object::test<4>() - { - LLTemplateMessageReader* pReader = NULL; - LLTemplateMessageDispatcher t(*pReader); - gValidateMessage = true; - std::vector<U8> vector_data; - fillVector(vector_data, gBinaryTemplateData); - mMessage["body"]["binary-template-data"] = vector_data; - t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure("data couriered correctly", strcmp(gBinaryTemplateData, gUdpDispatchedData) == 0); - } + // does an empty message stop processing? + template<> template<> + void object::test<1>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure(! gUdpDispatchWasCalled); + ensure(! gClearRecvWasCalled); + } + + // does the disaptch invoke the udp send method? + template<> template<> + void object::test<2>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + gValidateMessage = true; + std::vector<U8> vector_data; + fillVector(vector_data, gBinaryTemplateData); + mMessage["body"]["binary-template-data"] = vector_data; + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure("udp dispatch was called", gUdpDispatchWasCalled); + } + + // what if the message wasn't valid? We would hope the message gets cleared! + template<> template<> + void object::test<3>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + std::vector<U8> vector_data; + fillVector(vector_data, gBinaryTemplateData); + mMessage["body"]["binary-template-data"] = vector_data; + gValidateMessage = false; + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure("clear received message was called", gClearRecvWasCalled); + } + + // is the binary data passed through correctly? + template<> template<> + void object::test<4>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + gValidateMessage = true; + std::vector<U8> vector_data; + fillVector(vector_data, gBinaryTemplateData); + mMessage["body"]["binary-template-data"] = vector_data; + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure("data couriered correctly", strcmp(gBinaryTemplateData, gUdpDispatchedData) == 0); + } } diff --git a/indra/llmessage/tests/lltestmessagesender.cpp b/indra/llmessage/tests/lltestmessagesender.cpp index ee40e0249e..1765a9eccd 100644 --- a/indra/llmessage/tests/lltestmessagesender.cpp +++ b/indra/llmessage/tests/lltestmessagesender.cpp @@ -1,25 +1,25 @@ -/** - * @file - * @brief +/** + * @file + * @brief * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,7 +32,7 @@ LLTestMessageSender::~LLTestMessageSender() S32 LLTestMessageSender::sendMessage(const LLHost& host, LLStoredMessagePtr message) { - mSendHosts.push_back(host); - mSendMessages.push_back(message); - return 0; + mSendHosts.push_back(host); + mSendMessages.push_back(message); + return 0; } diff --git a/indra/llmessage/tests/lltestmessagesender.h b/indra/llmessage/tests/lltestmessagesender.h index bb89289585..e78cfad96e 100644 --- a/indra/llmessage/tests/lltestmessagesender.h +++ b/indra/llmessage/tests/lltestmessagesender.h @@ -1,25 +1,25 @@ -/** - * @file - * @brief +/** + * @file + * @brief * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,11 +38,11 @@ class LLTestMessageSender : public LLMessageSenderInterface { public: - virtual ~LLTestMessageSender(); - virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message); + virtual ~LLTestMessageSender(); + virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message); - std::vector<LLHost> mSendHosts; - std::vector<LLStoredMessagePtr> mSendMessages; + std::vector<LLHost> mSendHosts; + std::vector<LLStoredMessagePtr> mSendMessages; }; diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp index 41f982a7e2..cc199141b8 100644 --- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,7 +40,7 @@ LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; LLMessageConfig::SenderTrust LLMessageConfig::getSenderTrustedness(const std::string& msg_name) { - return LLMessageConfig::NOT_SET; + return LLMessageConfig::NOT_SET; } void LLMessageSystem::receivedMessageFromTrustedSender() @@ -49,12 +49,12 @@ void LLMessageSystem::receivedMessageFromTrustedSender() bool LLMessageSystem::isTrustedSender(const LLHost& host) const { - return false; + return false; } bool LLMessageSystem::isTrustedMessage(const std::string& name) const { - return false; + return false; } bool messageDispatched = false; @@ -63,80 +63,80 @@ LLSD lastLLSD; std::string lastMessageName; void LLMessageSystem::dispatch(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep) + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) { - messageDispatched = true; - lastLLSD = message; - lastMessageName = msg_name; + messageDispatched = true; + lastLLSD = message; + lastMessageName = msg_name; } void LLMessageSystem::dispatchTemplate(const std::string& msg_name, - const LLSD& message, - LLHTTPNode::ResponsePtr responsep) + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) { - lastLLSD = message; - lastMessageName = msg_name; - messageDispatchedAsBinary = true; + lastLLSD = message; + lastMessageName = msg_name; + messageDispatchedAsBinary = true; } namespace tut { - struct LLTrustedMessageServiceData - { - LLTrustedMessageServiceData() - { - LLSD emptyLLSD; - lastLLSD = emptyLLSD; - lastMessageName = "uninitialised message name"; - messageDispatched = false; - messageDispatchedAsBinary = false; - } - }; - - typedef test_group<LLTrustedMessageServiceData> factory; - typedef factory::object object; + struct LLTrustedMessageServiceData + { + LLTrustedMessageServiceData() + { + LLSD emptyLLSD; + lastLLSD = emptyLLSD; + lastMessageName = "uninitialised message name"; + messageDispatched = false; + messageDispatchedAsBinary = false; + } + }; + + typedef test_group<LLTrustedMessageServiceData> factory; + typedef factory::object object; } namespace { - tut::factory tf("LLTrustedMessageServiceData"); + tut::factory tf("LLTrustedMessageServiceData"); } namespace tut { - // characterisation tests - - // 1) test that messages get forwarded with names etc. as current behaviour (something like LLMessageSystem::dispatch(name, data...) - - // test llsd messages are sent as normal using LLMessageSystem::dispatch() (eventually) - template<> template<> - void object::test<1>() - { - LLHTTPNode::ResponsePtr response; - LLSD input; - LLSD context; - LLTrustedMessageService adapter; - adapter.post(response, context, input); - // test original ting got called wit nowt, ya get me blood? - ensure_equals(messageDispatched, true); - ensure(lastLLSD.has("body")); - } - - // test that llsd wrapped binary-template-data messages are - // sent via LLMessageSystem::binaryDispatch() or similar - template<> template<> - void object::test<2>() - { - LLHTTPNode::ResponsePtr response; - LLSD input; - input["binary-template-data"] = "10001010110"; //make me a message here. - LLSD context; - LLTrustedMessageService adapter; - - adapter.post(response, context, input); - ensure("check template-binary-data message was dispatched as binary", messageDispatchedAsBinary); - ensure_equals(lastLLSD["body"]["binary-template-data"].asString(), "10001010110"); - // test somit got called with "10001010110" (something like LLMessageSystem::dispatchTemplate(blah)) - } + // characterisation tests + + // 1) test that messages get forwarded with names etc. as current behaviour (something like LLMessageSystem::dispatch(name, data...) + + // test llsd messages are sent as normal using LLMessageSystem::dispatch() (eventually) + template<> template<> + void object::test<1>() + { + LLHTTPNode::ResponsePtr response; + LLSD input; + LLSD context; + LLTrustedMessageService adapter; + adapter.post(response, context, input); + // test original ting got called wit nowt, ya get me blood? + ensure_equals(messageDispatched, true); + ensure(lastLLSD.has("body")); + } + + // test that llsd wrapped binary-template-data messages are + // sent via LLMessageSystem::binaryDispatch() or similar + template<> template<> + void object::test<2>() + { + LLHTTPNode::ResponsePtr response; + LLSD input; + input["binary-template-data"] = "10001010110"; //make me a message here. + LLSD context; + LLTrustedMessageService adapter; + + adapter.post(response, context, input); + ensure("check template-binary-data message was dispatched as binary", messageDispatchedAsBinary); + ensure_equals(lastLLSD["body"]["binary-template-data"].asString(), "10001010110"); + // test somit got called with "10001010110" (something like LLMessageSystem::dispatchTemplate(blah)) + } } diff --git a/indra/llmessage/tests/llxfer_file_test.cpp b/indra/llmessage/tests/llxfer_file_test.cpp index cf95d2627c..358659a5b9 100644 --- a/indra/llmessage/tests/llxfer_file_test.cpp +++ b/indra/llmessage/tests/llxfer_file_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llxfer_test.cpp * @author Moss * @date 2007-04-17 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,26 +33,26 @@ namespace tut { - struct llxfer_data - { - }; - typedef test_group<llxfer_data> llxfer_test; - typedef llxfer_test::object llxfer_object; - tut::llxfer_test llxfer("LLXferFile"); + struct llxfer_data + { + }; + typedef test_group<llxfer_data> llxfer_test; + typedef llxfer_test::object llxfer_object; + tut::llxfer_test llxfer("LLXferFile"); - template<> template<> - void llxfer_object::test<1>() - { - // test that we handle an oversized filename correctly. - std::string oversized_filename; - U32 i; - for (i=0; i<LL_MAX_PATH*2; ++i) // create oversized filename - { - oversized_filename += 'X'; - } + template<> template<> + void llxfer_object::test<1>() + { + // test that we handle an oversized filename correctly. + std::string oversized_filename; + U32 i; + for (i=0; i<LL_MAX_PATH*2; ++i) // create oversized filename + { + oversized_filename += 'X'; + } - LLXfer_File xff(oversized_filename, false, 1); - ensure("oversized local_filename nul-terminated", - xff.getFileName().length() < LL_MAX_PATH); - } + LLXfer_File xff(oversized_filename, false, 1); + ensure("oversized local_filename nul-terminated", + xff.getFileName().length() < LL_MAX_PATH); + } } diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h index 5986524342..a88c4ec596 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -2,26 +2,26 @@ * @file networkio.h * @author Nat Goodspeed * @date 2009-01-09 - * @brief - * + * @brief + * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ |