Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
8.4 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "importkeyvaluebase.h"
  7. #include "dmserializers.h"
  8. #include "datamodel/idatamodel.h"
  9. #include "datamodel/dmelement.h"
  10. #include "datamodel/dmattributevar.h"
  11. #include "tier1/KeyValues.h"
  12. #include "tier1/utlbuffer.h"
  13. #include <limits.h>
  14. //-----------------------------------------------------------------------------
  15. // Default serialization method
  16. //-----------------------------------------------------------------------------
  17. bool CImportKeyValueBase::Serialize( CUtlBuffer &outBuf, CDmElement *pRoot )
  18. {
  19. Warning( "Serialization not supported for importing from keyvalues files\n");
  20. return false;
  21. }
  22. //-----------------------------------------------------------------------------
  23. // Creates a new element
  24. //-----------------------------------------------------------------------------
  25. CDmElement* CImportKeyValueBase::CreateDmElement( const char *pElementType, const char *pElementName, DmObjectId_t *pId )
  26. {
  27. // See if we can create an element of that type
  28. DmElementHandle_t hElement = g_pDataModel->CreateElement( pElementType, pElementName, DMFILEID_INVALID, pId );
  29. if ( hElement == DMELEMENT_HANDLE_INVALID )
  30. {
  31. Warning("%s: Element uses unknown element type %s\n", m_pFileName, pElementType );
  32. return NULL;
  33. }
  34. return g_pDataModel->GetElement( hElement );
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Used to output typed attributes to keyvalues
  38. //-----------------------------------------------------------------------------
  39. void CImportKeyValueBase::PrintBoolAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName )
  40. {
  41. if ( pElement->HasAttribute( pKeyName ) )
  42. {
  43. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  44. if ( pAttribute->GetType() == AT_BOOL )
  45. {
  46. outBuf.Printf("\"%s\" \"%d\"\n", pKeyName, pAttribute->GetValue<bool>( ) );
  47. }
  48. }
  49. }
  50. void CImportKeyValueBase::PrintIntAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName )
  51. {
  52. if ( pElement->HasAttribute( pKeyName ) )
  53. {
  54. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  55. if ( pAttribute->GetType() == AT_INT )
  56. {
  57. outBuf.Printf("\"%s\" \"%d\"\n", pKeyName, pAttribute->GetValue<int>( ) );
  58. }
  59. }
  60. }
  61. void CImportKeyValueBase::PrintFloatAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName )
  62. {
  63. if ( pElement->HasAttribute( pKeyName ) )
  64. {
  65. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  66. if ( pAttribute->GetType() == AT_FLOAT )
  67. {
  68. outBuf.Printf("\"%s\" \"%.10f\"\n", pKeyName, pAttribute->GetValue<float>( ) );
  69. }
  70. }
  71. }
  72. void CImportKeyValueBase::PrintStringAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName, bool bSkipEmptryStrings, bool bPrintValueOnly )
  73. {
  74. if ( pElement->HasAttribute( pKeyName ) )
  75. {
  76. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  77. if ( pAttribute->GetType() == AT_STRING )
  78. {
  79. const char *pValue = pAttribute->GetValueString();
  80. if ( !bSkipEmptryStrings || pValue[0] )
  81. {
  82. if ( !bPrintValueOnly )
  83. {
  84. outBuf.Printf("\"%s\" \"%s\"\n", pKeyName, pValue );
  85. }
  86. else
  87. {
  88. outBuf.Printf("\"%s\"\n", pValue );
  89. }
  90. }
  91. }
  92. }
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Used to add typed attributes from keyvalues
  96. //-----------------------------------------------------------------------------
  97. bool CImportKeyValueBase::AddBoolAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, bool *pDefault )
  98. {
  99. KeyValues *pKey = pKeyValues->FindKey( pKeyName );
  100. bool bValue;
  101. if ( pKey )
  102. {
  103. bValue = pKey->GetInt() != 0;
  104. }
  105. else
  106. {
  107. if ( !pDefault )
  108. return true;
  109. bValue = *pDefault;
  110. }
  111. return pElement->SetValue( pKeyName, bValue ) != NULL;
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Used to add typed attributes from keyvalues
  115. //-----------------------------------------------------------------------------
  116. bool CImportKeyValueBase::AddIntAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, int *pDefault )
  117. {
  118. KeyValues *pKey = pKeyValues->FindKey( pKeyName );
  119. int nValue;
  120. if ( pKey )
  121. {
  122. nValue = pKey->GetInt();
  123. }
  124. else
  125. {
  126. if ( !pDefault )
  127. return true;
  128. nValue = *pDefault;
  129. }
  130. return pElement->SetValue( pKeyName, nValue ) != NULL;
  131. }
  132. bool CImportKeyValueBase::AddFloatAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, float *pDefault )
  133. {
  134. KeyValues *pKey = pKeyValues->FindKey( pKeyName );
  135. float flValue;
  136. if ( pKey )
  137. {
  138. flValue = pKey->GetFloat();
  139. }
  140. else
  141. {
  142. if ( !pDefault )
  143. return true;
  144. flValue = *pDefault;
  145. }
  146. return pElement->SetValue( pKeyName, flValue ) != NULL;
  147. }
  148. bool CImportKeyValueBase::AddStringAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, const char *pDefault )
  149. {
  150. KeyValues *pKey = pKeyValues->FindKey( pKeyName );
  151. const char *pValue = "";
  152. if ( pKey )
  153. {
  154. pValue = pKey->GetString();
  155. }
  156. else
  157. {
  158. if ( !pDefault )
  159. return true;
  160. pValue = pDefault;
  161. }
  162. return pElement->SetValue( pKeyName, pValue ) != NULL;
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Used to add typed attributes from keyvalues
  166. //-----------------------------------------------------------------------------
  167. bool CImportKeyValueBase::AddBoolAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, bool *pDefault )
  168. {
  169. if ( !AddBoolAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
  170. return false;
  171. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  172. pAttribute->AddFlag( nFlags );
  173. return true;
  174. }
  175. bool CImportKeyValueBase::AddIntAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, int *pDefault )
  176. {
  177. if ( !AddIntAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
  178. return false;
  179. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  180. pAttribute->AddFlag( nFlags );
  181. return true;
  182. }
  183. bool CImportKeyValueBase::AddFloatAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, float *pDefault )
  184. {
  185. if ( !AddFloatAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
  186. return false;
  187. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  188. pAttribute->AddFlag( nFlags );
  189. return true;
  190. }
  191. bool CImportKeyValueBase::AddStringAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, const char *pDefault )
  192. {
  193. if ( !AddStringAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
  194. return false;
  195. CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
  196. pAttribute->AddFlag( nFlags );
  197. return true;
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Recursively resolves all attributes pointing to elements
  201. //-----------------------------------------------------------------------------
  202. void CImportKeyValueBase::RecursivelyResolveElement( CDmElement* pElement )
  203. {
  204. if ( !pElement )
  205. return;
  206. pElement->Resolve();
  207. CDmAttribute *pAttribute = pElement->FirstAttribute();
  208. while ( pAttribute )
  209. {
  210. switch ( pAttribute->GetType() )
  211. {
  212. case AT_ELEMENT:
  213. {
  214. CDmElement *pElement = pAttribute->GetValueElement<CDmElement>();
  215. RecursivelyResolveElement( pElement );
  216. }
  217. break;
  218. case AT_ELEMENT_ARRAY:
  219. {
  220. CDmrElementArray<> array( pAttribute );
  221. int nCount = array.Count();
  222. for ( int i = 0; i < nCount; ++i )
  223. {
  224. CDmElement *pElement = array[ i ];
  225. RecursivelyResolveElement( pElement );
  226. }
  227. }
  228. break;
  229. }
  230. pAttribute = pAttribute->NextAttribute( );
  231. }
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Main entry point for the unserialization
  235. //-----------------------------------------------------------------------------
  236. bool CImportKeyValueBase::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
  237. const char *pSourceFormatName, int nSourceFormatVersion,
  238. DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
  239. {
  240. *ppRoot = NULL;
  241. m_pFileName = g_pDataModel->GetFileName( fileid );
  242. KeyValues *kv = new KeyValues( "dmx file" );
  243. if ( !kv )
  244. return false;
  245. bool bOk = kv->LoadFromBuffer( "dmx file", buf );
  246. if ( bOk )
  247. {
  248. *ppRoot = UnserializeFromKeyValues( kv );
  249. }
  250. kv->deleteThis();
  251. return bOk;
  252. }