123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /**
- * @file llcategory.cpp
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llcategory.h"
- #include "llmessage.h"
- const LLCategory LLCategory::none;
- ///----------------------------------------------------------------------------
- /// Local function declarations, constants, enums, and typedefs
- ///----------------------------------------------------------------------------
- // This is the storage of the category names. It's loosely based on a
- // heap-like structure with indices into it for faster searching and
- // so that we don't have to maintain a balanced heap. It's *VITALLY*
- // important that the CATEGORY_INDEX and CATEGORY_NAME tables are kept
- // in synch.
- // CATEGORY_INDEX indexes into CATEGORY_NAME at the first occurance of
- // a child. Thus, the first child of root is "Object" which is located
- // in CATEGORY_NAME[1].
- const S32 CATEGORY_INDEX[] =
- {
- 1, // ROOT
- 6, // object
- 7, // clothing
- 7, // texture
- 7, // sound
- 7, // landmark
- 7, // object|component
- 7, // off the end (required for child count calculations)
- };
- // The heap of names
- const char* CATEGORY_NAME[] =
- {
- "(none)",
- "Object", // (none)
- "Clothing",
- "Texture",
- "Sound",
- "Landmark",
- "Component", // object
- NULL
- };
- ///----------------------------------------------------------------------------
- /// Class llcategory
- ///----------------------------------------------------------------------------
- LLCategory::LLCategory()
- {
- // this is used as a simple compile time assertion. If this code
- // fails to compile, the depth has been changed, and we need to
- // clean up some of the code that relies on the depth, such as the
- // default constructor. If CATEGORY_DEPTH != 4, this code will
- // attempt to construct a zero length array - which the compiler
- // should balk at.
- // static const char CATEGORY_DEPTH_CHECK[(CATEGORY_DEPTH == 4)?1:0] = {' '}; // unused
- // actually initialize the object.
- mData[0] = 0;
- mData[1] = 0;
- mData[2] = 0;
- mData[3] = 0;
- }
- void LLCategory::init(U32 value)
- {
- U8 v;
- for(S32 i = 0; i < CATEGORY_DEPTH; i++)
- {
- v = (U8)((0x000000ff) & value);
- mData[CATEGORY_DEPTH - 1 - i] = v;
- value >>= 8;
- }
- }
- U32 LLCategory::getU32() const
- {
- U32 rv = 0;
- rv |= mData[0];
- rv <<= 8;
- rv |= mData[1];
- rv <<= 8;
- rv |= mData[2];
- rv <<= 8;
- rv |= mData[3];
- return rv;
- }
- S32 LLCategory::getSubCategoryCount() const
- {
- S32 rv = CATEGORY_INDEX[mData[0] + 1] - CATEGORY_INDEX[mData[0]];
- return rv;
- }
- // This method will return a category that is the nth subcategory. If
- // you're already at the bottom of the hierarchy, then the method will
- // return a copy of this.
- LLCategory LLCategory::getSubCategory(U8 n) const
- {
- LLCategory rv(*this);
- for(S32 i = 0; i < (CATEGORY_DEPTH - 1); i++)
- {
- if(rv.mData[i] == 0)
- {
- rv.mData[i] = n + 1;
- break;
- }
- }
- return rv;
- }
- // This method will return the name of the leaf category type
- const char* LLCategory::lookupName() const
- {
- S32 i = 0;
- S32 index = mData[i++];
- while((i < CATEGORY_DEPTH) && (mData[i] != 0))
- {
- index = CATEGORY_INDEX[index];
- ++i;
- }
- return CATEGORY_NAME[index];
- }
- // message serialization
- void LLCategory::packMessage(LLMessageSystem* msg) const
- {
- U32 data = getU32();
- msg->addU32Fast(_PREHASH_Category, data);
- }
- // message serialization
- void LLCategory::unpackMessage(LLMessageSystem* msg, const char* block)
- {
- U32 data;
- msg->getU32Fast(block, _PREHASH_Category, data);
- init(data);
- }
- // message serialization
- void LLCategory::unpackMultiMessage(LLMessageSystem* msg, const char* block,
- S32 block_num)
- {
- U32 data;
- msg->getU32Fast(block, _PREHASH_Category, data, block_num);
- init(data);
- }
- ///----------------------------------------------------------------------------
- /// Local function definitions
- ///----------------------------------------------------------------------------
|