aboutsummaryrefslogtreecommitdiff
path: root/sp/src/tier1/byteswap.cpp
blob: 9f66297dc2132cd938306373012b19bda6676d50 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Low level byte swapping routines.
//
// $NoKeywords: $
//=============================================================================

#include "byteswap.h"

//-----------------------------------------------------------------------------
// Copy a single field from the input buffer to the output buffer, swapping the bytes if necessary
//-----------------------------------------------------------------------------
void CByteswap::SwapFieldToTargetEndian( void* pOutputBuffer, void *pData, typedescription_t *pField )
{
	switch ( pField->fieldType )
	{
	case FIELD_CHARACTER:
		SwapBufferToTargetEndian<char>( (char*)pOutputBuffer, (char*)pData, pField->fieldSize );
		break;

	case FIELD_BOOLEAN:
		SwapBufferToTargetEndian<bool>( (bool*)pOutputBuffer, (bool*)pData, pField->fieldSize );
		break;

	case FIELD_SHORT:
		SwapBufferToTargetEndian<short>( (short*)pOutputBuffer, (short*)pData, pField->fieldSize );
		break;

	case FIELD_FLOAT:
		SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize );
		break;

	case FIELD_INTEGER:
		SwapBufferToTargetEndian<int>( (int*)pOutputBuffer, (int*)pData, pField->fieldSize );
		break;

	case FIELD_VECTOR:
		SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 3 );
		break;

	case FIELD_VECTOR2D:
		SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 2 );
		break;

	case FIELD_QUATERNION:
		SwapBufferToTargetEndian<uint>( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 4 );
		break;

	case FIELD_EMBEDDED:
		{
			typedescription_t *pEmbed = pField->td->dataDesc;
			for ( int i = 0; i < pField->fieldSize; ++i )
			{
				SwapFieldsToTargetEndian( (byte*)pOutputBuffer + pEmbed->fieldOffset[ TD_OFFSET_NORMAL ], 
										(byte*)pData + pEmbed->fieldOffset[ TD_OFFSET_NORMAL ],  
										pField->td );

				pOutputBuffer = (byte*)pOutputBuffer + pField->fieldSizeInBytes;
				pData = (byte*)pData + pField->fieldSizeInBytes;
			}
		}
		break;
		
	default:
		assert(0); 
	}
}

//-----------------------------------------------------------------------------
// Write a block of fields. Works a bit like the saverestore code.  
//-----------------------------------------------------------------------------
void CByteswap::SwapFieldsToTargetEndian( void *pOutputBuffer, void *pBaseData, datamap_t *pDataMap )
{	
	// deal with base class first
	if ( pDataMap->baseMap )
	{
		SwapFieldsToTargetEndian( pOutputBuffer, pBaseData, pDataMap->baseMap );
	}

	typedescription_t *pFields = pDataMap->dataDesc;
	int fieldCount = pDataMap->dataNumFields;
	for ( int i = 0; i < fieldCount; ++i )
	{
		typedescription_t *pField = &pFields[i];
		SwapFieldToTargetEndian( (BYTE*)pOutputBuffer + pField->fieldOffset[ TD_OFFSET_NORMAL ],  
								 (BYTE*)pBaseData + pField->fieldOffset[ TD_OFFSET_NORMAL ], 
								  pField );
	}
}