tamlBinaryParser.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "persistence/taml/binary/tamlBinaryParser.h"
  2. #include "console/console.h"
  3. #include "core/util/zip/zipSubStream.h"
  4. #include "platform/profiler.h"
  5. #include "persistence/taml/taml.h"
  6. bool TamlBinaryParser::accept(const char* pFilename, TamlVisitor& visitor)
  7. {
  8. PROFILE_SCOPE(TamlBinaryParser_Accept);
  9. AssertFatal(pFilename != NULL, "TamlBinaryParser::accept - NULL filename.");
  10. char filenameBuffer[1024];
  11. Con::expandScriptFilename(filenameBuffer, sizeof(filenameBuffer), pFilename);
  12. FileStream stream;
  13. if (!stream.open(filenameBuffer, Torque::FS::File::Read))
  14. {
  15. Con::warnf("TamlBinaryParser::accept - Could not open file '%s'.", filenameBuffer);
  16. return false;
  17. }
  18. // Read TAML signature.
  19. StringTableEntry signature = stream.readSTString();
  20. if (signature != StringTable->insert(TAML_SIGNATURE))
  21. {
  22. Con::warnf("TamlBinaryParser::accept - Invalid signature in '%s'.", filenameBuffer);
  23. stream.close();
  24. return false;
  25. }
  26. U32 versionId;
  27. stream.read(&versionId);
  28. bool compressed;
  29. stream.read(&compressed);
  30. if (compressed)
  31. {
  32. ZipSubRStream zipStream;
  33. zipStream.attachStream(&stream);
  34. parseElement(zipStream, visitor, versionId);
  35. zipStream.detachStream();
  36. }
  37. else
  38. {
  39. parseElement(stream, visitor, versionId);
  40. }
  41. stream.close();
  42. return true;
  43. }
  44. //-----------------------------------------------------------------------------
  45. bool TamlBinaryParser::parseElement(Stream& stream, TamlVisitor& visitor, const U32 versionId)
  46. {
  47. PROFILE_SCOPE(TamlBinaryParser_ParseElement);
  48. // Read the type and name.
  49. StringTableEntry typeName = stream.readSTString();
  50. StringTableEntry objectName = stream.readSTString();
  51. // Read references.
  52. U32 refId, refToId;
  53. stream.read(&refId);
  54. stream.read(&refToId);
  55. // Create a property visitor state.
  56. TamlVisitor::PropertyState propertyState;
  57. propertyState.setObjectName(typeName, false);
  58. if (objectName != StringTable->EmptyString())
  59. propertyState.setProperty("Name", objectName);
  60. if (!visitor.visit(*this, propertyState))
  61. return false;
  62. // Parse attributes.
  63. U32 attrCount;
  64. stream.read(&attrCount);
  65. char valueBuffer[4096];
  66. for (U32 i = 0; i < attrCount; ++i)
  67. {
  68. StringTableEntry attrName = stream.readSTString();
  69. stream.readLongString(sizeof(valueBuffer), valueBuffer);
  70. propertyState.setProperty(attrName, valueBuffer);
  71. visitor.visit(*this, propertyState);
  72. }
  73. // Parse children.
  74. U32 childCount;
  75. stream.read(&childCount);
  76. for (U32 c = 0; c < childCount; ++c)
  77. {
  78. if (!parseElement(stream, visitor, versionId))
  79. return false;
  80. }
  81. // Parse custom nodes.
  82. U32 customCount;
  83. stream.read(&customCount);
  84. for (U32 cn = 0; cn < customCount; ++cn)
  85. {
  86. StringTableEntry customNodeName = stream.readSTString();
  87. propertyState.setProperty("CustomNode", customNodeName);
  88. visitor.visit(*this, propertyState);
  89. parseCustomNode(stream, visitor, versionId);
  90. }
  91. return true;
  92. }
  93. //-----------------------------------------------------------------------------
  94. bool TamlBinaryParser::parseCustomNode(Stream& stream, TamlVisitor& visitor, const U32 versionId)
  95. {
  96. PROFILE_SCOPE(TamlBinaryParser_ParseCustomNode);
  97. bool isProxyObject;
  98. stream.read(&isProxyObject);
  99. if (isProxyObject)
  100. {
  101. // Parse nested proxy element.
  102. return parseElement(stream, visitor, versionId);
  103. }
  104. // Read custom node name and text.
  105. StringTableEntry nodeName = stream.readSTString();
  106. char textBuffer[1024];
  107. stream.readLongString(sizeof(textBuffer), textBuffer);
  108. // Create visitor state for the node.
  109. TamlVisitor::PropertyState nodeState;
  110. nodeState.setObjectName(nodeName, false);
  111. nodeState.setProperty("Text", textBuffer);
  112. visitor.visit(*this, nodeState);
  113. // Parse child nodes.
  114. U32 childCount;
  115. stream.read(&childCount);
  116. for (U32 i = 0; i < childCount; ++i)
  117. {
  118. if (!parseCustomNode(stream, visitor, versionId))
  119. return false;
  120. }
  121. // Parse fields.
  122. U32 fieldCount;
  123. stream.read(&fieldCount);
  124. char valueBuffer[1024];
  125. for (U32 f = 0; f < fieldCount; ++f)
  126. {
  127. StringTableEntry fieldName = stream.readSTString();
  128. stream.readLongString(sizeof(valueBuffer), valueBuffer);
  129. nodeState.setProperty(fieldName, valueBuffer);
  130. visitor.visit(*this, nodeState);
  131. }
  132. return true;
  133. }