diff options
Diffstat (limited to 'indra/llinventory/llcategory.cpp')
-rw-r--r-- | indra/llinventory/llcategory.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/indra/llinventory/llcategory.cpp b/indra/llinventory/llcategory.cpp new file mode 100644 index 0000000000..7a7bbf530a --- /dev/null +++ b/indra/llinventory/llcategory.cpp @@ -0,0 +1,161 @@ +/** + * @file llcategory.cpp + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llcategory.h" + +#include "message.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 +///---------------------------------------------------------------------------- |