llcategory.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /**
  2. * @file llcategory.cpp
  3. *
  4. * $LicenseInfo:firstyear=2002&license=viewergpl$
  5. *
  6. * Copyright (c) 2002-2009, Linden Research, Inc.
  7. *
  8. * Second Life Viewer Source Code
  9. * The source code in this file ("Source Code") is provided by Linden Lab
  10. * to you under the terms of the GNU General Public License, version 2.0
  11. * ("GPL"), unless you have obtained a separate licensing agreement
  12. * ("Other License"), formally executed by you and Linden Lab. Terms of
  13. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15. *
  16. * There are special exceptions to the terms and conditions of the GPL as
  17. * it is applied to this Source Code. View the full text of the exception
  18. * in the file doc/FLOSS-exception.txt in this software distribution, or
  19. * online at
  20. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21. *
  22. * By copying, modifying or distributing this software, you acknowledge
  23. * that you have read and understood your obligations described above,
  24. * and agree to abide by those obligations.
  25. *
  26. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28. * COMPLETENESS OR PERFORMANCE.
  29. * $/LicenseInfo$
  30. */
  31. #include "linden_common.h"
  32. #include "llcategory.h"
  33. #include "llmessage.h"
  34. const LLCategory LLCategory::none;
  35. ///----------------------------------------------------------------------------
  36. /// Local function declarations, constants, enums, and typedefs
  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. // CATEGORY_INDEX indexes into CATEGORY_NAME at the first occurance of
  44. // a child. Thus, the first child of root is "Object" which is located
  45. // in CATEGORY_NAME[1].
  46. const S32 CATEGORY_INDEX[] =
  47. {
  48. 1, // ROOT
  49. 6, // object
  50. 7, // clothing
  51. 7, // texture
  52. 7, // sound
  53. 7, // landmark
  54. 7, // object|component
  55. 7, // off the end (required for child count calculations)
  56. };
  57. // The heap of names
  58. const char* CATEGORY_NAME[] =
  59. {
  60. "(none)",
  61. "Object", // (none)
  62. "Clothing",
  63. "Texture",
  64. "Sound",
  65. "Landmark",
  66. "Component", // object
  67. NULL
  68. };
  69. ///----------------------------------------------------------------------------
  70. /// Class llcategory
  71. ///----------------------------------------------------------------------------
  72. LLCategory::LLCategory()
  73. {
  74. // this is used as a simple compile time assertion. If this code
  75. // fails to compile, the depth has been changed, and we need to
  76. // clean up some of the code that relies on the depth, such as the
  77. // default constructor. If CATEGORY_DEPTH != 4, this code will
  78. // attempt to construct a zero length array - which the compiler
  79. // should balk at.
  80. // static const char CATEGORY_DEPTH_CHECK[(CATEGORY_DEPTH == 4)?1:0] = {' '}; // unused
  81. // actually initialize the object.
  82. mData[0] = 0;
  83. mData[1] = 0;
  84. mData[2] = 0;
  85. mData[3] = 0;
  86. }
  87. void LLCategory::init(U32 value)
  88. {
  89. U8 v;
  90. for(S32 i = 0; i < CATEGORY_DEPTH; i++)
  91. {
  92. v = (U8)((0x000000ff) & value);
  93. mData[CATEGORY_DEPTH - 1 - i] = v;
  94. value >>= 8;
  95. }
  96. }
  97. U32 LLCategory::getU32() const
  98. {
  99. U32 rv = 0;
  100. rv |= mData[0];
  101. rv <<= 8;
  102. rv |= mData[1];
  103. rv <<= 8;
  104. rv |= mData[2];
  105. rv <<= 8;
  106. rv |= mData[3];
  107. return rv;
  108. }
  109. S32 LLCategory::getSubCategoryCount() const
  110. {
  111. S32 rv = CATEGORY_INDEX[mData[0] + 1] - CATEGORY_INDEX[mData[0]];
  112. return rv;
  113. }
  114. // This method will return a category that is the nth subcategory. If
  115. // you're already at the bottom of the hierarchy, then the method will
  116. // return a copy of this.
  117. LLCategory LLCategory::getSubCategory(U8 n) const
  118. {
  119. LLCategory rv(*this);
  120. for(S32 i = 0; i < (CATEGORY_DEPTH - 1); i++)
  121. {
  122. if(rv.mData[i] == 0)
  123. {
  124. rv.mData[i] = n + 1;
  125. break;
  126. }
  127. }
  128. return rv;
  129. }
  130. // This method will return the name of the leaf category type
  131. const char* LLCategory::lookupName() const
  132. {
  133. S32 i = 0;
  134. S32 index = mData[i++];
  135. while((i < CATEGORY_DEPTH) && (mData[i] != 0))
  136. {
  137. index = CATEGORY_INDEX[index];
  138. ++i;
  139. }
  140. return CATEGORY_NAME[index];
  141. }
  142. // message serialization
  143. void LLCategory::packMessage(LLMessageSystem* msg) const
  144. {
  145. U32 data = getU32();
  146. msg->addU32Fast(_PREHASH_Category, data);
  147. }
  148. // message serialization
  149. void LLCategory::unpackMessage(LLMessageSystem* msg, const char* block)
  150. {
  151. U32 data;
  152. msg->getU32Fast(block, _PREHASH_Category, data);
  153. init(data);
  154. }
  155. // message serialization
  156. void LLCategory::unpackMultiMessage(LLMessageSystem* msg, const char* block,
  157. S32 block_num)
  158. {
  159. U32 data;
  160. msg->getU32Fast(block, _PREHASH_Category, data, block_num);
  161. init(data);
  162. }
  163. ///----------------------------------------------------------------------------
  164. /// Local function definitions
  165. ///----------------------------------------------------------------------------