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.

102 lines
3.2 KiB

  1. //========= Copyright � 1996-2006, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose: Low level byte swapping routines.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "byteswap.h"
  8. // NOTE: This has to be the last file included!
  9. #include "tier0/memdbgon.h"
  10. //-----------------------------------------------------------------------------
  11. // Copy a single field from the input buffer to the output buffer, swapping the bytes if necessary
  12. //-----------------------------------------------------------------------------
  13. void CByteswap::SwapFieldToTargetEndian( void* pOutputBuffer, void *pData, typedescription_t *pField )
  14. {
  15. switch ( pField->fieldType )
  16. {
  17. case FIELD_CHARACTER:
  18. SwapBufferToTargetEndian<char>( (char*)pOutputBuffer, (char*)pData, pField->fieldSize );
  19. break;
  20. case FIELD_COLOR32:
  21. SwapBufferToTargetEndian<char>( (char*)pOutputBuffer, (char*)pData, pField->fieldSize * 4 );
  22. break;
  23. case FIELD_BOOLEAN:
  24. SwapBufferToTargetEndian<bool>( (bool*)pOutputBuffer, (bool*)pData, pField->fieldSize );
  25. break;
  26. case FIELD_SHORT:
  27. SwapBufferToTargetEndian<short>( (short*)pOutputBuffer, (short*)pData, pField->fieldSize );
  28. break;
  29. case FIELD_FLOAT:
  30. SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize );
  31. break;
  32. case FIELD_INTEGER:
  33. SwapBufferToTargetEndian<int>( (int*)pOutputBuffer, (int*)pData, pField->fieldSize );
  34. break;
  35. case FIELD_INTEGER64:
  36. SwapBufferToTargetEndian<uint64>( (uint64*)pOutputBuffer, (uint64*)pData, pField->fieldSize );
  37. break;
  38. case FIELD_VECTOR:
  39. SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 3 );
  40. break;
  41. case FIELD_VECTOR2D:
  42. SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 2 );
  43. break;
  44. case FIELD_QUATERNION:
  45. SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 4 );
  46. break;
  47. case FIELD_EMBEDDED:
  48. {
  49. typedescription_t *pEmbed = pField->td->dataDesc;
  50. for ( int i = 0; i < pField->fieldSize; ++i )
  51. {
  52. SwapFieldsToTargetEndian( (byte*)pOutputBuffer + pEmbed->fieldOffset,
  53. (byte*)pData + pEmbed->fieldOffset,
  54. pField->td );
  55. pOutputBuffer = (byte*)pOutputBuffer + pField->fieldSizeInBytes;
  56. pData = (byte*)pData + pField->fieldSizeInBytes;
  57. }
  58. }
  59. break;
  60. default:
  61. Assert(0);
  62. }
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Write a block of fields. Works a bit like the saverestore code.
  66. //-----------------------------------------------------------------------------
  67. void CByteswap::SwapFieldsToTargetEndian( void *pOutputBuffer, void *pBaseData, datamap_t *pDataMap )
  68. {
  69. // deal with base class first
  70. if ( pDataMap->baseMap )
  71. {
  72. SwapFieldsToTargetEndian( pOutputBuffer, pBaseData, pDataMap->baseMap );
  73. }
  74. typedescription_t *pFields = pDataMap->dataDesc;
  75. int fieldCount = pDataMap->dataNumFields;
  76. for ( int i = 0; i < fieldCount; ++i )
  77. {
  78. typedescription_t *pField = &pFields[i];
  79. SwapFieldToTargetEndian( (BYTE*)pOutputBuffer + pField->fieldOffset,
  80. (BYTE*)pBaseData + pField->fieldOffset,
  81. pField );
  82. }
  83. }