SerializedDataIterator.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* Copyright The kNet Project.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. /** @file SerializedDataIterator.cpp
  12. @brief */
  13. #include <cassert>
  14. #include "kNet/DebugMemoryLeakCheck.h"
  15. #include "kNet/SerializedDataIterator.h"
  16. namespace kNet
  17. {
  18. BasicSerializedDataType SerializedDataIterator::NextElementType() const
  19. {
  20. if (currentElementStack.empty())
  21. return SerialInvalid;
  22. assert(currentElementStack.back().elem);
  23. // If we don't know how many instances there are of the next element, it's the next field
  24. // to be filled - our iterator is pointing to the dynamicCount property of that field.
  25. if (currentElementStack.back().elem->varyingCount && currentElementStack.back().dynamicCountSpecified == false)
  26. return SerialDynamicCount;
  27. return currentElementStack.back().elem->type;
  28. }
  29. const SerializedElementDesc *SerializedDataIterator::NextElementDesc() const
  30. {
  31. return currentElementStack.empty() ? 0 : currentElementStack.back().elem;
  32. }
  33. void SerializedDataIterator::ProceedToNextVariable()
  34. {
  35. if (currentElementStack.empty())
  36. return;
  37. ElemInfo &nextVar = currentElementStack.back();
  38. if (nextVar.elem->type == SerialStruct)
  39. {
  40. ++nextVar.nextElem;
  41. if (nextVar.nextElem >= (int)nextVar.elem->elements.size())
  42. {
  43. nextVar.nextElem = 0;
  44. ++nextVar.nextIndex;
  45. if (nextVar.nextIndex >= nextVar.count)
  46. {
  47. currentElementStack.pop_back();
  48. ProceedToNextVariable();
  49. return;
  50. }
  51. }
  52. DescendIntoStructure();
  53. }
  54. else
  55. {
  56. ++nextVar.nextIndex;
  57. if (nextVar.nextIndex >= nextVar.count)
  58. {
  59. currentElementStack.pop_back();
  60. ProceedToNextVariable();
  61. }
  62. }
  63. }
  64. void SerializedDataIterator::ProceedNVariables(int count)
  65. {
  66. ///\todo Can optimize a great deal here.
  67. for(int i = 0; i < count; ++i)
  68. ProceedToNextVariable();
  69. }
  70. void SerializedDataIterator::ProceedToNextElement()
  71. {
  72. ElemInfo &nextVar = currentElementStack.back();
  73. ++nextVar.nextElem;
  74. if (nextVar.nextElem >= (int)nextVar.elem->elements.size())
  75. {
  76. nextVar.nextElem = 0;
  77. ++nextVar.nextIndex;
  78. if (nextVar.nextIndex >= nextVar.count)
  79. {
  80. currentElementStack.pop_back();
  81. ProceedToNextElement();
  82. }
  83. }
  84. else
  85. {
  86. /* currentElementStack.push_back(ElemInfo());
  87. ElemInfo &newVar = currentElementStack.back();
  88. newVar.elem = nextVar.elem->elements[nextVar.nextElem];
  89. newVar.nextIndex = 0;
  90. newVar.nextElem = 0;
  91. newVar.count = (newVar.elem->multiplicity == ElemVarying) ? 0 : newVar.elem->count;
  92. */
  93. DescendIntoStructure();
  94. }
  95. }
  96. void SerializedDataIterator::SetVaryingElemSize(u32 count)
  97. {
  98. ElemInfo &nextVar = currentElementStack.back();
  99. assert(nextVar.dynamicCountSpecified == false);
  100. assert(nextVar.elem->varyingCount == true);
  101. assert(nextVar.nextIndex == 0);
  102. nextVar.count = count;
  103. nextVar.dynamicCountSpecified = true;
  104. // If this was a varying-arity structure node, descend down into filling the struct.
  105. DescendIntoStructure();
  106. }
  107. void SerializedDataIterator::DescendIntoStructure()
  108. {
  109. ElemInfo &nextVar = currentElementStack.back();
  110. if (nextVar.dynamicCountSpecified == false && nextVar.elem->varyingCount == true)
  111. return;
  112. if (nextVar.nextElem >= (int)nextVar.elem->elements.size())
  113. return;
  114. ElemInfo newVar;
  115. newVar.elem = nextVar.elem->elements[nextVar.nextElem];
  116. newVar.nextIndex = 0;
  117. newVar.nextElem = 0;
  118. newVar.count = (newVar.elem->varyingCount ? 0 : newVar.elem->count); // A varying block? Then the user has to supply multiplicity.
  119. newVar.dynamicCountSpecified = false;
  120. currentElementStack.push_back(newVar);
  121. // Descend again in case we have a struct-in-struct-in-struct...
  122. DescendIntoStructure();
  123. }
  124. void SerializedDataIterator::ResetTraversal()
  125. {
  126. currentElementStack.clear();
  127. ElemInfo newVar;
  128. newVar.elem = desc.data;
  129. newVar.nextIndex = 0;
  130. newVar.nextElem = 0;
  131. newVar.count = (newVar.elem->varyingCount ? 0 : newVar.elem->count); // A varying block? Then the user has to supply multiplicity.
  132. newVar.dynamicCountSpecified = false;
  133. currentElementStack.push_back(newVar);
  134. // Descend again in case we have a struct-in-struct-in-struct...
  135. DescendIntoStructure();
  136. }
  137. } // ~kNet