PageRenderTime 32ms CodeModel.GetById 7ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llinventory/llcategory.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 179 lines | 102 code | 20 blank | 57 comment | 6 complexity | 969e92ea692b56bdb62120dd67583599 MD5 | raw file
  1/** 
  2 * @file llcategory.cpp
  3 *
  4 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  5 * Second Life Viewer Source Code
  6 * Copyright (C) 2010, Linden Research, Inc.
  7 * 
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation;
 11 * version 2.1 of the License only.
 12 * 
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * Lesser General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this library; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 21 * 
 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 23 * $/LicenseInfo$
 24 */
 25
 26#include "linden_common.h"
 27
 28#include "llcategory.h"
 29
 30#include "message.h"
 31
 32const LLCategory LLCategory::none;
 33
 34///----------------------------------------------------------------------------
 35/// Local function declarations, constants, enums, and typedefs
 36///----------------------------------------------------------------------------
 37
 38// This is the storage of the category names. It's loosely based on a
 39// heap-like structure with indices into it for faster searching and
 40// so that we don't have to maintain a balanced heap. It's *VITALLY*
 41// important that the CATEGORY_INDEX and CATEGORY_NAME tables are kept
 42// in synch.
 43
 44// CATEGORY_INDEX indexes into CATEGORY_NAME at the first occurance of
 45// a child. Thus, the first child of root is "Object" which is located
 46// in CATEGORY_NAME[1].
 47const S32 CATEGORY_INDEX[] =
 48{
 49	1,	// ROOT
 50	6,	// object
 51	7,	// clothing
 52	7,	// texture
 53	7,  // sound
 54	7,  // landmark
 55	7,  // object|component
 56	7,  // off the end (required for child count calculations)
 57};
 58
 59// The heap of names
 60const char* CATEGORY_NAME[] =
 61{
 62	"(none)",
 63	"Object",		// (none)
 64	"Clothing",
 65	"Texture",
 66	"Sound",
 67	"Landmark",
 68	"Component",	// object
 69	NULL
 70};
 71
 72///----------------------------------------------------------------------------
 73/// Class llcategory
 74///----------------------------------------------------------------------------
 75
 76LLCategory::LLCategory()
 77{
 78	// this is used as a simple compile time assertion. If this code
 79	// fails to compile, the depth has been changed, and we need to
 80	// clean up some of the code that relies on the depth, such as the
 81	// default constructor. If CATEGORY_DEPTH != 4, this code will
 82	// attempt to construct a zero length array - which the compiler
 83	// should balk at.
 84//	static const char CATEGORY_DEPTH_CHECK[(CATEGORY_DEPTH == 4)?1:0] = {' '};	// unused
 85
 86	// actually initialize the object.
 87	mData[0] = 0;
 88	mData[1] = 0;
 89	mData[2] = 0;
 90	mData[3] = 0;
 91}
 92
 93void LLCategory::init(U32 value)
 94{
 95	U8 v;
 96	for(S32 i = 0; i < CATEGORY_DEPTH; i++)
 97	{
 98		v = (U8)((0x000000ff) & value);
 99		mData[CATEGORY_DEPTH - 1 - i] = v;
100		value >>= 8;
101	}
102}
103
104U32 LLCategory::getU32() const
105{
106	U32 rv = 0;
107	rv |= mData[0];
108	rv <<= 8;
109	rv |= mData[1];
110	rv <<= 8;
111	rv |= mData[2];
112	rv <<= 8;
113	rv |= mData[3];
114	return rv;
115}
116
117S32 LLCategory::getSubCategoryCount() const
118{
119	S32 rv = CATEGORY_INDEX[mData[0] + 1] - CATEGORY_INDEX[mData[0]];
120	return rv;
121}
122
123// This method will return a category that is the nth subcategory. If
124// you're already at the bottom of the hierarchy, then the method will
125// return a copy of this.
126LLCategory LLCategory::getSubCategory(U8 n) const
127{
128	LLCategory rv(*this);
129	for(S32 i = 0; i < (CATEGORY_DEPTH - 1); i++)
130	{
131		if(rv.mData[i] == 0)
132		{
133			rv.mData[i] = n + 1;
134			break;
135		}
136	}
137	return rv;
138}
139
140// This method will return the name of the leaf category type
141const char* LLCategory::lookupName() const
142{
143	S32 i = 0;
144	S32 index = mData[i++];
145	while((i < CATEGORY_DEPTH) && (mData[i] != 0))
146	{
147		index = CATEGORY_INDEX[index];
148		++i;
149	}
150	return CATEGORY_NAME[index];
151}
152
153// message serialization
154void LLCategory::packMessage(LLMessageSystem* msg) const
155{
156	U32 data = getU32();
157	msg->addU32Fast(_PREHASH_Category, data);
158}
159
160// message serialization
161void LLCategory::unpackMessage(LLMessageSystem* msg, const char* block)
162{
163	U32 data;
164	msg->getU32Fast(block, _PREHASH_Category, data);
165	init(data);
166}
167
168// message serialization
169void LLCategory::unpackMultiMessage(LLMessageSystem* msg, const char* block,
170									S32 block_num)
171{
172	U32 data;
173	msg->getU32Fast(block, _PREHASH_Category, data, block_num);
174	init(data);
175}
176
177///----------------------------------------------------------------------------
178/// Local function definitions
179///----------------------------------------------------------------------------