| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #include "persistence/taml/binary/tamlBinaryParser.h"
- #include "console/console.h"
- #include "core/util/zip/zipSubStream.h"
- #include "platform/profiler.h"
- #include "persistence/taml/taml.h"
- bool TamlBinaryParser::accept(const char* pFilename, TamlVisitor& visitor)
- {
- isRoot = true;
- PROFILE_SCOPE(TamlBinaryParser_Accept);
- AssertFatal(pFilename != NULL, "TamlBinaryParser::accept - NULL filename.");
- char filenameBuffer[1024];
- Con::expandScriptFilename(filenameBuffer, sizeof(filenameBuffer), pFilename);
- FileStream stream;
- if (!stream.open(filenameBuffer, Torque::FS::File::Read))
- {
- Con::warnf("TamlBinaryParser::accept - Could not open file '%s'.", filenameBuffer);
- return false;
- }
- // Read TAML signature.
- StringTableEntry signature = stream.readSTString();
- if (signature != StringTable->insert(TAML_SIGNATURE))
- {
- Con::warnf("TamlBinaryParser::accept - Invalid signature in '%s'.", filenameBuffer);
- stream.close();
- return false;
- }
- setParsingFilename(pFilename);
- U32 versionId;
- stream.read(&versionId);
- bool compressed;
- stream.read(&compressed);
- if (compressed)
- {
- ZipSubRStream zipStream;
- zipStream.attachStream(&stream);
- parseElement(zipStream, visitor, versionId);
- zipStream.detachStream();
- }
- else
- {
- parseElement(stream, visitor, versionId);
- }
- stream.close();
- setParsingFilename(StringTable->EmptyString());
- return true;
- }
- //-----------------------------------------------------------------------------
- bool TamlBinaryParser::parseElement(Stream& stream, TamlVisitor& visitor, const U32 versionId)
- {
- PROFILE_SCOPE(TamlBinaryParser_ParseElement);
- // --- Read element header ---
- StringTableEntry pElementName = stream.readSTString();
- StringTableEntry pObjectName = stream.readSTString();
- // Read references.
- U32 refId, refToId;
- stream.read(&refId);
- stream.read(&refToId);
- // If this is a reference to another object, skip it.
- if (refToId != 0)
- return true;
- // Create a property visitor state.
- TamlVisitor::PropertyState propertyState;
- propertyState.setObjectName(pElementName, isRoot);
- if (pObjectName != StringTable->EmptyString())
- propertyState.setProperty("Name", pObjectName);
- if(isRoot)
- isRoot = false;
- // --- Attributes ---
- parseAttributes(stream, visitor, versionId, propertyState);
- // --- Children ---
- parseChildren(stream, visitor, versionId);
- // --- Custom elements ---
- parseCustomElements(stream, visitor, versionId);
- return true;
- }
- void TamlBinaryParser::parseAttributes(Stream& stream, TamlVisitor& visitor, const U32 versionId, TamlVisitor::PropertyState& state)
- {
- PROFILE_SCOPE(TamlBinaryParser_ParseAttributes);
- U32 attributeCount;
- stream.read(&attributeCount);
- if (attributeCount == 0)
- return;
- char valueBuffer[4096];
- for (U32 i = 0; i < attributeCount; ++i)
- {
- StringTableEntry attrName = stream.readSTString();
- stream.readLongString(4096, valueBuffer);
- state.setProperty(attrName, valueBuffer);
- const bool visitStatus = visitor.visit(*this, state);
- if (!visitStatus)
- return;
- }
- }
- //-----------------------------------------------------------------------------
- void TamlBinaryParser::parseChildren(Stream& stream, TamlVisitor& visitor, const U32 versionId)
- {
- PROFILE_SCOPE(TamlBinaryParser_ParseChildren);
- U32 childCount = 0;
- stream.read(&childCount);
- if (childCount == 0)
- return;
- for (U32 i = 0; i < childCount; ++i)
- {
- parseElement(stream, visitor, versionId);
- }
- }
- //-----------------------------------------------------------------------------
- void TamlBinaryParser::parseCustomElements(Stream& stream, TamlVisitor& visitor, const U32 versionId)
- {
- PROFILE_SCOPE(TamlBinaryParser_ParseCustomElements);
- U32 customNodeCount = 0;
- stream.read(&customNodeCount);
- if (customNodeCount == 0)
- return;
- TamlVisitor::PropertyState state;
- for (U32 nodeIndex = 0; nodeIndex < customNodeCount; ++nodeIndex)
- {
- StringTableEntry nodeName = stream.readSTString();
- state.setObjectName(nodeName, false);
- U32 nodeChildrenCount = 0;
- stream.read(&nodeChildrenCount);
- if (nodeChildrenCount == 0)
- return;
- for(U32 nodeChild = 0; nodeChild < nodeChildrenCount; ++nodeChild)
- parseCustomNode(stream, visitor, versionId, state);
- }
- }
- //-----------------------------------------------------------------------------
- bool TamlBinaryParser::parseCustomNode(Stream& stream, TamlVisitor& visitor, const U32 versionId, TamlVisitor::PropertyState& state)
- {
- PROFILE_SCOPE(TamlBinaryParser_ParseCustomNode);
- bool isProxyObject;
- stream.read(&isProxyObject);
- if (isProxyObject)
- {
- // Parse nested proxy element.
- return parseElement(stream, visitor, versionId);
- }
- StringTableEntry nodeName = stream.readSTString();
- char nodeValue[MAX_TAML_NODE_FIELDVALUE_LENGTH];
- stream.readLongString(MAX_TAML_NODE_FIELDVALUE_LENGTH, nodeValue);
- U32 childCount;
- stream.read(&childCount);
- for (U32 i = 0; i < childCount; ++i)
- {
- if (!parseCustomNode(stream, visitor, versionId, state))
- return false;
- }
- U32 fieldCount;
- stream.read(&fieldCount);
- if (fieldCount > 0)
- {
- char valueBuffer[MAX_TAML_NODE_FIELDVALUE_LENGTH];
- for (U32 f = 0; f < fieldCount; ++f)
- {
- StringTableEntry fieldName = stream.readSTString();
- stream.readLongString(MAX_TAML_NODE_FIELDVALUE_LENGTH, valueBuffer);
- state.setProperty(fieldName, valueBuffer);
- const bool visitStatus = visitor.visit(*this, state);
- if (!visitStatus)
- return false;
- }
- }
- return true;
- }
|