PageRenderTime 28ms CodeModel.GetById 9ms RepoModel.GetById 0ms 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
Possible License(s): LGPL-2.1
  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. #include "linden_common.h"
  26. #include "llcategory.h"
  27. #include "message.h"
  28. const LLCategory LLCategory::none;
  29. ///----------------------------------------------------------------------------
  30. /// Local function declarations, constants, enums, and typedefs
  31. ///----------------------------------------------------------------------------
  32. // This is the storage of the category names. It's loosely based on a
  33. // heap-like structure with indices into it for faster searching and
  34. // so that we don't have to maintain a balanced heap. It's *VITALLY*
  35. // important that the CATEGORY_INDEX and CATEGORY_NAME tables are kept
  36. // in synch.
  37. // CATEGORY_INDEX indexes into CATEGORY_NAME at the first occurance of
  38. // a child. Thus, the first child of root is "Object" which is located
  39. // in CATEGORY_NAME[1].
  40. const S32 CATEGORY_INDEX[] =
  41. {
  42. 1, // ROOT
  43. 6, // object
  44. 7, // clothing
  45. 7, // texture
  46. 7, // sound
  47. 7, // landmark
  48. 7, // object|component
  49. 7, // off the end (required for child count calculations)
  50. };
  51. // The heap of names
  52. const char* CATEGORY_NAME[] =
  53. {
  54. "(none)",
  55. "Object", // (none)
  56. "Clothing",
  57. "Texture",
  58. "Sound",
  59. "Landmark",
  60. "Component", // object
  61. NULL
  62. };
  63. ///----------------------------------------------------------------------------
  64. /// Class llcategory
  65. ///----------------------------------------------------------------------------
  66. LLCategory::LLCategory()
  67. {
  68. // this is used as a simple compile time assertion. If this code
  69. // fails to compile, the depth has been changed, and we need to
  70. // clean up some of the code that relies on the depth, such as the
  71. // default constructor. If CATEGORY_DEPTH != 4, this code will
  72. // attempt to construct a zero length array - which the compiler
  73. // should balk at.
  74. // static const char CATEGORY_DEPTH_CHECK[(CATEGORY_DEPTH == 4)?1:0] = {' '}; // unused
  75. // actually initialize the object.
  76. mData[0] = 0;
  77. mData[1] = 0;
  78. mData[2] = 0;
  79. mData[3] = 0;
  80. }
  81. void LLCategory::init(U32 value)
  82. {
  83. U8 v;
  84. for(S32 i = 0; i < CATEGORY_DEPTH; i++)
  85. {
  86. v = (U8)((0x000000ff) & value);
  87. mData[CATEGORY_DEPTH - 1 - i] = v;
  88. value >>= 8;
  89. }
  90. }
  91. U32 LLCategory::getU32() const
  92. {
  93. U32 rv = 0;
  94. rv |= mData[0];
  95. rv <<= 8;
  96. rv |= mData[1];
  97. rv <<= 8;
  98. rv |= mData[2];
  99. rv <<= 8;
  100. rv |= mData[3];
  101. return rv;
  102. }
  103. S32 LLCategory::getSubCategoryCount() const
  104. {
  105. S32 rv = CATEGORY_INDEX[mData[0] + 1] - CATEGORY_INDEX[mData[0]];
  106. return rv;
  107. }
  108. // This method will return a category that is the nth subcategory. If
  109. // you're already at the bottom of the hierarchy, then the method will
  110. // return a copy of this.
  111. LLCategory LLCategory::getSubCategory(U8 n) const
  112. {
  113. LLCategory rv(*this);
  114. for(S32 i = 0; i < (CATEGORY_DEPTH - 1); i++)
  115. {
  116. if(rv.mData[i] == 0)
  117. {
  118. rv.mData[i] = n + 1;
  119. break;
  120. }
  121. }
  122. return rv;
  123. }
  124. // This method will return the name of the leaf category type
  125. const char* LLCategory::lookupName() const
  126. {
  127. S32 i = 0;
  128. S32 index = mData[i++];
  129. while((i < CATEGORY_DEPTH) && (mData[i] != 0))
  130. {
  131. index = CATEGORY_INDEX[index];
  132. ++i;
  133. }
  134. return CATEGORY_NAME[index];
  135. }
  136. // message serialization
  137. void LLCategory::packMessage(LLMessageSystem* msg) const
  138. {
  139. U32 data = getU32();
  140. msg->addU32Fast(_PREHASH_Category, data);
  141. }
  142. // message serialization
  143. void LLCategory::unpackMessage(LLMessageSystem* msg, const char* block)
  144. {
  145. U32 data;
  146. msg->getU32Fast(block, _PREHASH_Category, data);
  147. init(data);
  148. }
  149. // message serialization
  150. void LLCategory::unpackMultiMessage(LLMessageSystem* msg, const char* block,
  151. S32 block_num)
  152. {
  153. U32 data;
  154. msg->getU32Fast(block, _PREHASH_Category, data, block_num);
  155. init(data);
  156. }
  157. ///----------------------------------------------------------------------------
  158. /// Local function definitions
  159. ///----------------------------------------------------------------------------