123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2013 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "persistence/taml/binary/tamlBinaryWriter.h"
- #ifndef _ZIPSUBSTREAM_H_
- #include "core/util/zip/zipSubStream.h"
- #endif
- // Debug Profiling.
- #include "platform/profiler.h"
- //-----------------------------------------------------------------------------
- bool TamlBinaryWriter::write( FileStream& stream, const TamlWriteNode* pTamlWriteNode, const bool compressed )
- {
- // Debug Profiling.
- PROFILE_SCOPE(TamlBinaryWriter_Write);
-
- // Write Taml signature.
- stream.writeString( StringTable->insert( TAML_SIGNATURE ) );
- // Write version Id.
- stream.write( mVersionId );
- // Write compressed flag.
- stream.write( compressed );
- // Are we compressed?
- if ( compressed )
- {
- // yes, so attach zip stream.
- ZipSubWStream zipStream;
- zipStream.attachStream( &stream );
- // Write element.
- writeElement( zipStream, pTamlWriteNode );
- // Detach zip stream.
- zipStream.detachStream();
- }
- else
- {
- // No, so write element.
- writeElement( stream, pTamlWriteNode );
- }
- return true;
- }
- //-----------------------------------------------------------------------------
- void TamlBinaryWriter::writeElement( Stream& stream, const TamlWriteNode* pTamlWriteNode )
- {
- // Debug Profiling.
- PROFILE_SCOPE(TamlBinaryWriter_WriteElement);
- // Fetch object.
- SimObject* pSimObject = pTamlWriteNode->mpSimObject;
- // Fetch element name.
- const char* pElementName = pSimObject->getClassName();
- // Write element name.
- stream.writeString( pElementName );
- // Fetch object name.
- const char* pObjectName = pTamlWriteNode->mpObjectName;
- // Write object name.
- stream.writeString( pObjectName != NULL ? pObjectName : StringTable->EmptyString() );
- // Fetch reference Id.
- const U32 tamlRefId = pTamlWriteNode->mRefId;
- // Write reference Id.
- stream.write( tamlRefId );
- // Do we have a reference to node?
- if ( pTamlWriteNode->mRefToNode != NULL )
- {
- // Yes, so fetch reference to Id.
- const U32 tamlRefToId = pTamlWriteNode->mRefToNode->mRefId;
- // Sanity!
- AssertFatal( tamlRefToId != 0, "Taml: Invalid reference to Id." );
- // Write reference to Id.
- stream.write( tamlRefToId );
- // Finished.
- return;
- }
- // No, so write no reference to Id.
- stream.write( 0 );
- // Write attributes.
- writeAttributes( stream, pTamlWriteNode );
- // Write children.
- writeChildren( stream, pTamlWriteNode );
- // Write custom elements.
- writeCustomElements( stream, pTamlWriteNode );
- }
- //-----------------------------------------------------------------------------
- void TamlBinaryWriter::writeAttributes( Stream& stream, const TamlWriteNode* pTamlWriteNode )
- {
- // Debug Profiling.
- PROFILE_SCOPE(TamlBinaryWriter_WriteAttributes);
- // Fetch fields.
- const Vector<TamlWriteNode::FieldValuePair*>& fields = pTamlWriteNode->mFields;
- // Write placeholder attribute count.
- stream.write( (U32)fields.size() );
- // Finish if no fields.
- if ( fields.size() == 0 )
- return;
- // Iterate fields.
- for( Vector<TamlWriteNode::FieldValuePair*>::const_iterator itr = fields.begin(); itr != fields.end(); ++itr )
- {
- // Fetch field/value pair.
- TamlWriteNode::FieldValuePair* pFieldValue = (*itr);
- // Write attribute.
- stream.writeString( pFieldValue->mName );
- stream.writeLongString( 4096, pFieldValue->mpValue );
- }
- }
- void TamlBinaryWriter::writeChildren( Stream& stream, const TamlWriteNode* pTamlWriteNode )
- {
- // Debug Profiling.
- PROFILE_SCOPE(TamlBinaryWriter_WriteChildren);
- // Fetch children.
- Vector<TamlWriteNode*>* pChildren = pTamlWriteNode->mChildren;
- // Do we have any children?
- if ( pChildren == NULL )
- {
- // No, so write no children.
- stream.write( (U32)0 );
- return;
- }
- // Write children count.
- stream.write( (U32)pChildren->size() );
- // Iterate children.
- for( Vector<TamlWriteNode*>::iterator itr = pChildren->begin(); itr != pChildren->end(); ++itr )
- {
- // Write child.
- writeElement( stream, (*itr) );
- }
- }
- //-----------------------------------------------------------------------------
- void TamlBinaryWriter::writeCustomElements( Stream& stream, const TamlWriteNode* pTamlWriteNode )
- {
- // Debug Profiling.
- PROFILE_SCOPE(TamlBinaryWriter_WriteCustomElements);
- // Fetch custom nodes.
- const TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes;
- // Fetch custom nodes.
- const TamlCustomNodeVector& nodes = customNodes.getNodes();
- // Write custom node count.
- stream.write( (U32)nodes.size() );
- // Finish if there are no nodes.
- if ( nodes.size() == 0 )
- return;
- // Iterate custom nodes.
- for( TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr )
- {
- // Fetch the custom node.
- TamlCustomNode* pCustomNode = *customNodesItr;
- // Write custom node name.
- stream.writeString( pCustomNode->getNodeName() );
- // Fetch node children.
- const TamlCustomNodeVector& nodeChildren = pCustomNode->getChildren();
- // Iterate children nodes.
- for( TamlCustomNodeVector::const_iterator childNodeItr = nodeChildren.begin(); childNodeItr != nodeChildren.end(); ++childNodeItr )
- {
- // Fetch child node.
- const TamlCustomNode* pChildNode = *childNodeItr;
- // Write the custom node.
- writeCustomNode( stream, pChildNode );
- }
- }
- }
- //-----------------------------------------------------------------------------
- void TamlBinaryWriter::writeCustomNode( Stream& stream, const TamlCustomNode* pCustomNode )
- {
- // Is the node a proxy object?
- if ( pCustomNode->isProxyObject() )
- {
- // Yes, so flag as proxy object.
- stream.write( true );
- // Write the element.
- writeElement( stream, pCustomNode->getProxyWriteNode() );
- return;
- }
- // No, so flag as custom node.
- stream.write( false );
- // Write custom node name.
- stream.writeString( pCustomNode->getNodeName() );
- // Write custom node text.
- stream.writeLongString(MAX_TAML_NODE_FIELDVALUE_LENGTH, pCustomNode->getNodeTextField().getFieldValue());
- // Fetch node children.
- const TamlCustomNodeVector& nodeChildren = pCustomNode->getChildren();
- // Fetch child node count.
- const U32 childNodeCount = (U32)nodeChildren.size();
- // Write custom node count.
- stream.write( childNodeCount );
- // Do we have any children nodes.
- if ( childNodeCount > 0 )
- {
- // Yes, so iterate children nodes.
- for( TamlCustomNodeVector::const_iterator childNodeItr = nodeChildren.begin(); childNodeItr != nodeChildren.end(); ++childNodeItr )
- {
- // Fetch child node.
- const TamlCustomNode* pChildNode = *childNodeItr;
- // Write the custom node.
- writeCustomNode( stream, pChildNode );
- }
- }
- // Fetch fields.
- const TamlCustomFieldVector& fields = pCustomNode->getFields();
- // Fetch child field count.
- const U32 childFieldCount = (U32)fields.size();
- // Write custom field count.
- stream.write( childFieldCount );
- // Do we have any child fields?
- if ( childFieldCount > 0 )
- {
- // Yes, so iterate fields.
- for ( TamlCustomFieldVector::const_iterator fieldItr = fields.begin(); fieldItr != fields.end(); ++fieldItr )
- {
- // Fetch node field.
- const TamlCustomField* pField = *fieldItr;
- // Write the node field.
- stream.writeString( pField->getFieldName() );
- stream.writeLongString( MAX_TAML_NODE_FIELDVALUE_LENGTH, pField->getFieldValue() );
- }
- }
- }
|