VANetMessage.cpp 20.1 KB
Newer Older
Jonas Stienen's avatar
Jonas Stienen committed
1
2
3
4
5
6
7
8
9
10
#include "VANetMessage.h"

#include "VANetNetworkProtocol.h"

#include <VACoreEvent.h>
#include <VAException.h>
#include <VACoreVersion.h>

#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaBase/VistaExceptionBase.h>
11
#include <VistaBase/VistaStreamUtils.h>
Jonas Stienen's avatar
Jonas Stienen committed
12
13
14
15
16
17
18

#include <cassert>
#include <cstring>

static int S_nMessageIds = 0;

CVANetMessage::CVANetMessage( VistaSerializingToolset::ByteOrderSwapBehavior bSwapBuffers )
19
20
21
	: m_vecIncomingBuffer( 2048 )
	, m_oOutgoing( 2048 )
	, m_pConnection( NULL )
Jonas Stienen's avatar
Jonas Stienen committed
22
23
24
25
26
27
28
29
30
{
	m_oOutgoing.SetByteorderSwapFlag( bSwapBuffers );
	m_oIncoming.SetByteorderSwapFlag( bSwapBuffers );
	ResetMessage();
}

void CVANetMessage::ResetMessage()
{
	if( m_oIncoming.GetTailSize() > 0 )
31
		vstr::err() << "CVANetMessage::ResetMessage() called before message was fully processed!" << std::endl;
Jonas Stienen's avatar
Jonas Stienen committed
32
33
34
35

	// wait till sending is complete -> this prevents us
	// from deleting the buffer while it is still being read
	// by the connection
36
	if( m_pConnection )
Jonas Stienen's avatar
Jonas Stienen committed
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
		m_pConnection->WaitForSendFinish();

	m_nMessageId = S_nMessageIds++;

	m_oOutgoing.ClearBuffer();
	m_oOutgoing.WriteInt32( 0 ); // size dummy
	m_oOutgoing.WriteInt32( 0 ); // type dummy
	m_oOutgoing.WriteInt32( 0 ); // exceptmode dummy
	m_oOutgoing.WriteInt32( 0 ); // ID

	m_oIncoming.SetBuffer( NULL, 0 );

	m_nExceptionMode = CVANetNetworkProtocol::VA_NP_INVALID;
	m_nMessageType = CVANetNetworkProtocol::VA_NP_INVALID;
	m_nAnswerType = CVANetNetworkProtocol::VA_NP_INVALID;

	m_pConnection = NULL;
}

void CVANetMessage::SetConnection( VistaConnectionIP* pConn )
{
	m_pConnection = pConn;
}

void CVANetMessage::WriteMessage()
{
63
	VANetCompat::byte* pBuffer = ( VANetCompat::byte* )m_oOutgoing.GetBuffer();
Jonas Stienen's avatar
Jonas Stienen committed
64
65
66
	VANetCompat::sint32 iSwapDummy;

	// rewrite size dummy
67
	iSwapDummy = m_oOutgoing.GetBufferSize() - sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
68
69
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
70
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
71

72
	pBuffer += sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
73
74
75
76
77

	// rewrite type dummy
	iSwapDummy = m_nMessageType;
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
78
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
79

80
	pBuffer += sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
81
82
83
84
85

	// rewrite exceptmode dummy
	iSwapDummy = m_nExceptionMode;
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
86
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
87

88
	pBuffer += sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
89
90
91
92
93

	// rewrite messageid dummy
	iSwapDummy = m_nMessageId;
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
94
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
95
96
97

	try
	{
98
99
		// It appears to be safe to transmit an entire buffer of arbitrary size on sender side
		int nRet = m_pConnection->WriteRawBuffer( m_oOutgoing.GetBuffer(), m_oOutgoing.GetBufferSize() );
Jonas Stienen's avatar
Jonas Stienen committed
100
101
		m_pConnection->WaitForSendFinish();
		if( nRet != m_oOutgoing.GetBufferSize() )
102
			VISTA_THROW( "Could not write the expected number of bytes", 255 );
Jonas Stienen's avatar
Jonas Stienen committed
103
	}
104
	catch( VistaExceptionBase& ex )
Jonas Stienen's avatar
Jonas Stienen committed
105
	{
106
		VA_EXCEPT2( NETWORK_ERROR, ex.GetExceptionText() );
Jonas Stienen's avatar
Jonas Stienen committed
107
108
109
110
111
112
113
114
115
	}
}

void CVANetMessage::ReadMessage()
{
	try
	{
		VANetCompat::sint32 nMessageSize;
		int nReturn = m_pConnection->ReadInt32( nMessageSize );
116
117
118

		if( nReturn != sizeof( VANetCompat::sint32 ) )
			VA_EXCEPT2( NETWORK_ERROR, "Received less bytes than expected" );
Jonas Stienen's avatar
Jonas Stienen committed
119
120

		// we need at least the three protocol ints
121
		assert( nMessageSize >= 3 * sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
122

123
		if( nMessageSize > ( int ) m_vecIncomingBuffer.size() )
Jonas Stienen's avatar
Jonas Stienen committed
124
125
			m_vecIncomingBuffer.resize( nMessageSize );

126
127
		int iBytesReadTotal = 0;
		while( nMessageSize != iBytesReadTotal )
128
129
		{
			int iIncommingBytes = m_pConnection->WaitForIncomingData( 0 );
130
131
132
133
			int iBytesRead = 0;
			if( iBytesReadTotal + iIncommingBytes > nMessageSize )
				iBytesRead = m_pConnection->ReadRawBuffer( &m_vecIncomingBuffer[ iBytesReadTotal ], nMessageSize - iBytesReadTotal ); // read residual bytes
			else
Jonas Stienen's avatar
Jonas Stienen committed
134
				iBytesRead = m_pConnection->ReadRawBuffer( &m_vecIncomingBuffer[ iBytesReadTotal ], iIncommingBytes ); // read all incoming bytes
135
136
				
			iBytesReadTotal += iBytesRead;
137
		}
138
		assert( iBytesReadTotal == nMessageSize );
Jonas Stienen's avatar
Jonas Stienen committed
139

140
		m_oIncoming.SetBuffer( ( VistaType::byte* ) &m_vecIncomingBuffer[ 0 ], nMessageSize, false );
Jonas Stienen's avatar
Jonas Stienen committed
141
	}
142
	catch( VistaExceptionBase& ex )
Jonas Stienen's avatar
Jonas Stienen committed
143
	{
144
145
		VA_EXCEPT2( NETWORK_ERROR, ex.GetExceptionText() );
	}
Jonas Stienen's avatar
Jonas Stienen committed
146
147
148
149
150
151
152
153

	m_nMessageType = ReadInt();
	m_nExceptionMode = ReadInt();
	m_nMessageId = ReadInt();
}

void CVANetMessage::WriteAnswer()
{
154
	VANetCompat::byte* pBuffer = ( VANetCompat::byte* )m_oOutgoing.GetBuffer();
Jonas Stienen's avatar
Jonas Stienen committed
155
156
157
	VANetCompat::sint32 iSwapDummy;

	// rewrite size dummy
158
	iSwapDummy = m_oOutgoing.GetBufferSize() - sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
159
160
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
161
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
162

163
	pBuffer += sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
164
165
166
167
168

	// rewrite type dummy
	iSwapDummy = m_nAnswerType;
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
169
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
170

171
	pBuffer += sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
172
173
174
175
176

	// rewrite exceptmode dummy
	iSwapDummy = m_nExceptionMode;
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
177
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
178

179
	pBuffer += sizeof( VANetCompat::sint32 );
Jonas Stienen's avatar
Jonas Stienen committed
180
181
182
183
184

	// rewrite message dummy
	iSwapDummy = m_nMessageId;
	if( m_oOutgoing.GetByteorderSwapFlag() )
		VistaSerializingToolset::Swap4( &iSwapDummy );
185
	memcpy( pBuffer, &iSwapDummy, sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
186
187
188

	try
	{
189
190
		// It appears to be safe to transmit an entire buffer of arbitrary size on sender side
		int nRet = m_pConnection->WriteRawBuffer( m_oOutgoing.GetBuffer(), m_oOutgoing.GetBufferSize() );
Jonas Stienen's avatar
Jonas Stienen committed
191
192
		m_pConnection->WaitForSendFinish();
		if( nRet != m_oOutgoing.GetBufferSize() )
193
			VISTA_THROW( "Could not write the expected number of bytes", 255 );
Jonas Stienen's avatar
Jonas Stienen committed
194
	}
195
	catch( VistaExceptionBase& ex )
Jonas Stienen's avatar
Jonas Stienen committed
196
	{
197
		VA_EXCEPT2( NETWORK_ERROR, ex.GetExceptionText() );
Jonas Stienen's avatar
Jonas Stienen committed
198
199
200
201
202
203
204
205
	}
}

void CVANetMessage::ReadAnswer()
{
	try
	{
		VANetCompat::sint32 nMessageSize;
206
207
208
209
210
211
212
213
214
		int nReturn;
		try
		{
			nReturn = m_pConnection->ReadInt32( nMessageSize );
		}
		catch( ... )
		{
			nReturn = -1; // Network connection error
		}
Dipl.-Ing. Jonas Stienen's avatar
style    
Dipl.-Ing. Jonas Stienen committed
215
216

		if( nReturn != sizeof( VANetCompat::sint32 ) )
217
218
219
		{
			VA_EXCEPT2( NETWORK_ERROR, "Received less bytes than expected during ReadAnswer of VANetMessage. Payload too long?" );
		}
Jonas Stienen's avatar
Jonas Stienen committed
220

221
222
		// we need at least the three protocol types
		assert( nMessageSize >= 3 * sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
223

224
		if( nMessageSize > ( int ) m_vecIncomingBuffer.size() )
Jonas Stienen's avatar
Jonas Stienen committed
225
226
			m_vecIncomingBuffer.resize( nMessageSize );

227
		int iBytesReceivedTotal = 0;
228
		while( nMessageSize > iBytesReceivedTotal )
229
230
231
232
233
234
235
236
		{
			int iIncommingBytes = m_pConnection->WaitForIncomingData( 0 );
			int iBytesReceived = m_pConnection->ReadRawBuffer( &m_vecIncomingBuffer[ iBytesReceivedTotal ], iIncommingBytes );
			iBytesReceivedTotal += iBytesReceived;
		}

		if( iBytesReceivedTotal != nMessageSize )
			VA_EXCEPT2( NETWORK_ERROR, "Reading message, but received less bytes than expected." );
Jonas Stienen's avatar
Jonas Stienen committed
237

238
		m_oIncoming.SetBuffer( ( VistaType::byte* ) &m_vecIncomingBuffer[ 0 ], nMessageSize, false );
Jonas Stienen's avatar
Jonas Stienen committed
239
	}
240
	catch( VistaExceptionBase& ex )
Jonas Stienen's avatar
Jonas Stienen committed
241
	{
242
		VA_EXCEPT2( NETWORK_ERROR, ex.GetExceptionText() );
Jonas Stienen's avatar
Jonas Stienen committed
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
	}

	m_nAnswerType = ReadInt();
	ReadInt(); // protocol overhead - just read and ignore
	int nMessageID = ReadInt();
	assert( nMessageID == m_nMessageId );
	m_nMessageId = nMessageID;
}

int CVANetMessage::GetExceptionMode() const
{
	return m_nExceptionMode;
}
int CVANetMessage::GetMessageType() const
{
	return m_nMessageType;
}
int CVANetMessage::GetAnswerType() const
{
	return m_nAnswerType;
}

void CVANetMessage::SetExceptionMode( int nMode )
{
	m_nExceptionMode = nMode;
}
void CVANetMessage::SetMessageType( int nType )
{
	m_nMessageType = nType;
}
void CVANetMessage::SetAnswerType( int nType )
{
	m_nAnswerType = nType;
}

int CVANetMessage::GetIncomingMessageSize() const
{
	return m_oIncoming.GetTailSize();
}
int CVANetMessage::GetOutgoingMessageSize() const
{
	return m_oOutgoing.GetBufferSize();
}

bool CVANetMessage::GetOutgoingMessageHasData() const
{
289
	return ( m_oOutgoing.GetBufferSize() > 4 * sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
290
291
292
293
}

void CVANetMessage::WriteString( const std::string& sValue )
{
294
295
	m_oOutgoing.WriteInt32( ( VANetCompat::sint32 )sValue.size() );
	if( !sValue.empty() ) m_oOutgoing.WriteString( sValue );
Jonas Stienen's avatar
Jonas Stienen committed
296
297
298
}
void CVANetMessage::WriteInt( const int iValue )
{
299
	m_oOutgoing.WriteInt32( ( VANetCompat::sint32 )iValue );
Jonas Stienen's avatar
Jonas Stienen committed
300
301
302
}
void CVANetMessage::WriteUInt64( const uint64_t iValue )
{
303
	m_oOutgoing.WriteUInt64( ( VANetCompat::uint64 )iValue );
Jonas Stienen's avatar
Jonas Stienen committed
304
305
306
307
308
309
310
311
312
313
314
315
316
}
void CVANetMessage::WriteBool( const bool bValue )
{
	m_oOutgoing.WriteBool( bValue );
}
void CVANetMessage::WriteFloat( const float fValue )
{
	m_oOutgoing.WriteFloat32( fValue );
}
void CVANetMessage::WriteDouble( const double dValue )
{
	m_oOutgoing.WriteFloat64( dValue );
}
317

Jonas Stienen's avatar
Jonas Stienen committed
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
void CVANetMessage::WriteVec3( const VAVec3& oVec )
{
	WriteDouble( oVec.x );
	WriteDouble( oVec.y );
	WriteDouble( oVec.z );
}

void CVANetMessage::WriteOrient( const VAOrientYPR& oOrient )
{
	WriteDouble( oOrient.yaw );
	WriteDouble( oOrient.pitch );
	WriteDouble( oOrient.roll );
}

std::string CVANetMessage::ReadString()
{
	VANetCompat::sint32 nSize;
	int nReturn = m_oIncoming.ReadInt32( nSize );
336
337
	assert( nReturn == sizeof( VANetCompat::sint32 ) );

Jonas Stienen's avatar
Jonas Stienen committed
338
	// Empty string?
339
340
	if( nSize == 0 )
		return "";
Jonas Stienen's avatar
Jonas Stienen committed
341
342
343
344
345
346

	std::string sValue;
	nReturn = m_oIncoming.ReadString( sValue, nSize );
	assert( nReturn == nSize );
	return sValue;
}
347

Jonas Stienen's avatar
Jonas Stienen committed
348
349
350
351
int CVANetMessage::ReadInt()
{
	VANetCompat::sint32 nValue;
	int nReturn = m_oIncoming.ReadInt32( nValue );
352
	assert( nReturn == sizeof( VANetCompat::sint32 ) );
Jonas Stienen's avatar
Jonas Stienen committed
353
354
	return nValue;
}
355

Jonas Stienen's avatar
Jonas Stienen committed
356
357
358
359
uint64_t CVANetMessage::ReadUInt64()
{
	VANetCompat::uint64 nValue;
	int nReturn = m_oIncoming.ReadUInt64( nValue );
360
	assert( nReturn == sizeof( VANetCompat::uint64 ) );
Jonas Stienen's avatar
Jonas Stienen committed
361
362
	return nValue;
}
363

Jonas Stienen's avatar
Jonas Stienen committed
364
365
366
367
bool CVANetMessage::ReadBool()
{
	bool bValue;
	int nReturn = m_oIncoming.ReadBool( bValue );
368
	assert( nReturn == sizeof( bool ) );
Jonas Stienen's avatar
Jonas Stienen committed
369
370
	return bValue;
}
371

Jonas Stienen's avatar
Jonas Stienen committed
372
373
374
375
float CVANetMessage::ReadFloat()
{
	float fValue;
	int nReturn = m_oIncoming.ReadFloat32( fValue );
376
	assert( nReturn == sizeof( float ) );
Jonas Stienen's avatar
Jonas Stienen committed
377
378
	return fValue;
}
379

Jonas Stienen's avatar
Jonas Stienen committed
380
381
382
383
double CVANetMessage::ReadDouble()
{
	double dValue;
	int nReturn = m_oIncoming.ReadFloat64( dValue );
384
	assert( nReturn == sizeof( double ) );
Jonas Stienen's avatar
Jonas Stienen committed
385
386
387
388
389
390
391
392
	return dValue;
}

VAVec3 CVANetMessage::ReadVec3()
{
	double x = ReadDouble();
	double y = ReadDouble();
	double z = ReadDouble();
393
	return VAVec3( x, y, z );
Jonas Stienen's avatar
Jonas Stienen committed
394
395
396
397
398
399
400
}

VAOrientYPR CVANetMessage::ReadOrient()
{
	double yaw = ReadDouble();
	double pitch = ReadDouble();
	double roll = ReadDouble();
401
	return VAOrientYPR( yaw, pitch, roll );
Jonas Stienen's avatar
Jonas Stienen committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
}

void CVANetMessage::WriteCoreEvent( const CVACoreEvent& oEvent )
{
	WriteInt( oEvent.iEventID );
	WriteUInt64( oEvent.iEventType );
	WriteInt( oEvent.iObjectID );
	WriteString( oEvent.sObjectID );
	WriteInt( oEvent.iParamID );
	WriteString( oEvent.sParam );
	WriteInt( oEvent.iIndex );
	WriteInt( oEvent.iAuralizationMode );
	WriteDouble( oEvent.dVolume );
	WriteDouble( oEvent.dState );
	WriteBool( oEvent.bMuted );
	WriteString( oEvent.sName );
	WriteString( oEvent.sFilename );
	WriteVec3( oEvent.vPos );
	WriteVec3( oEvent.vView );
	WriteVec3( oEvent.vUp );
	WriteOrient( oEvent.oOrientation );
	WriteVec3( oEvent.vVelocity );

425
426
427
428
429
430
	WriteInt( ( int ) oEvent.vfInputPeaks.size() );
	for( size_t i = 0; i < oEvent.vfInputPeaks.size(); i++ )
		WriteFloat( oEvent.vfInputPeaks[ i ] );
	WriteInt( ( int ) oEvent.vfOutputPeaks.size() );
	for( size_t i = 0; i < oEvent.vfOutputPeaks.size(); i++ )
		WriteFloat( oEvent.vfOutputPeaks[ i ] );
Jonas Stienen's avatar
Jonas Stienen committed
431

432
433
434
	WriteFloat( oEvent.fSysLoad );
	WriteFloat( oEvent.fDSPLoad );
	WriteDouble( oEvent.dCoreClock );
Jonas Stienen's avatar
Jonas Stienen committed
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
}

CVACoreEvent CVANetMessage::ReadCoreEvent()
{
	CVACoreEvent oEvent;
	oEvent.iEventID = ReadInt();
	oEvent.iEventType = ReadUInt64();
	oEvent.iObjectID = ReadInt();
	oEvent.sObjectID = ReadString();
	oEvent.iParamID = ReadInt();
	oEvent.sParam = ReadString();
	oEvent.iIndex = ReadInt();
	oEvent.iAuralizationMode = ReadInt();
	oEvent.dVolume = ReadDouble();
	oEvent.dState = ReadDouble();
	oEvent.bMuted = ReadBool();
	oEvent.sName = ReadString();
	oEvent.sFilename = ReadString();
	oEvent.vPos = ReadVec3();
	oEvent.vView = ReadVec3();
	oEvent.vUp = ReadVec3();
	oEvent.oOrientation = ReadOrient();
	oEvent.vVelocity = ReadVec3();

	int n = ReadInt();
460
461
	for( int i = 0; i < n; i++ )
		oEvent.vfInputPeaks.push_back( ReadFloat() );
Jonas Stienen's avatar
Jonas Stienen committed
462
	n = ReadInt();
463
464
	for( int i = 0; i < n; i++ )
		oEvent.vfOutputPeaks.push_back( ReadFloat() );
Jonas Stienen's avatar
Jonas Stienen committed
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

	oEvent.fSysLoad = ReadFloat();
	oEvent.fDSPLoad = ReadFloat();
	oEvent.dCoreClock = ReadDouble();

	return oEvent;
}


void CVANetMessage::WriteException( const CVAException& oException )
{
	WriteInt( oException.GetErrorCode() );
	WriteString( oException.GetErrorMessage() );
}

// Deserialize a VAException instance from a byte buffer (returns number of bytes read)
// (returns number of bytes read if successfull, otherwise -1)
CVAException CVANetMessage::ReadException()
{
	int nType = ReadInt();
	return CVAException( nType, ReadString() );
}

void CVANetMessage::WriteCoreVersionInfo( const CVACoreVersionInfo& oInfo )
{
	WriteString( oInfo.sVersion );
	WriteString( oInfo.sFlags );
	WriteString( oInfo.sDate );
	WriteString( oInfo.sComments );
}
495

Jonas Stienen's avatar
Jonas Stienen committed
496
497
498
499
500
501
502
503
504
CVACoreVersionInfo CVANetMessage::ReadCoreVersionInfo()
{
	CVACoreVersionInfo oInfo;
	oInfo.sVersion = ReadString();
	oInfo.sFlags = ReadString();
	oInfo.sDate = ReadString();
	oInfo.sComments = ReadString();
	return oInfo;
}
505

Jonas Stienen's avatar
Jonas Stienen committed
506
507
508
509
510
511
512
513
void CVANetMessage::WriteDirectivityInfo( const CVADirectivityInfo& oInfo )
{
	WriteString( oInfo.sName );
	WriteString( oInfo.sFilename );
	WriteInt( oInfo.iID );
	WriteInt( oInfo.iReferences );
	WriteString( oInfo.sDesc );
}
514

Jonas Stienen's avatar
Jonas Stienen committed
515
516
517
518
519
520
521
522
523
524
CVADirectivityInfo CVANetMessage::ReadDirectivityInfo()
{
	CVADirectivityInfo oInfo;
	oInfo.sName = ReadString();
	oInfo.sFilename = ReadString();
	oInfo.iID = ReadInt();
	oInfo.iReferences = ReadInt();
	oInfo.sDesc = ReadString();
	return oInfo;
}
525

Jonas Stienen's avatar
Jonas Stienen committed
526
527
528
529
530
531
532
533
void CVANetMessage::WriteHRIRInfo( const CVAHRIRInfo& oInfo )
{
	WriteString( oInfo.sName );
	WriteString( oInfo.sFilename );
	WriteInt( oInfo.iID );
	WriteInt( oInfo.iReferences );
	WriteString( oInfo.sDesc );
}
534

Jonas Stienen's avatar
Jonas Stienen committed
535
536
537
538
539
540
541
542
543
544
CVAHRIRInfo CVANetMessage::ReadHRIRInfo()
{
	CVAHRIRInfo oInfo;
	oInfo.sName = ReadString();
	oInfo.sFilename = ReadString();
	oInfo.iID = ReadInt();
	oInfo.iReferences = ReadInt();
	oInfo.sDesc = ReadString();
	return oInfo;
}
545

Jonas Stienen's avatar
Jonas Stienen committed
546
547
548
549
550
551
552
553
void CVANetMessage::WriteSoundInfo( const CVASoundInfo& oInfo )
{
	WriteString( oInfo.sName );
	WriteString( oInfo.sFilename );
	WriteInt( oInfo.iLength );
	WriteInt( oInfo.iID );
	WriteDouble( oInfo.dDuration );
}
554

Jonas Stienen's avatar
Jonas Stienen committed
555
556
557
558
559
560
561
562
563
564
CVASoundInfo CVANetMessage::ReadSoundInfo()
{
	CVASoundInfo oInfo;
	oInfo.sName = ReadString();
	oInfo.sFilename = ReadString();
	oInfo.iLength = ReadInt();
	oInfo.iID = ReadInt();
	oInfo.dDuration = ReadDouble();
	return oInfo;
}
565

Jonas Stienen's avatar
Jonas Stienen committed
566
567
568
569
570
571
572
573
574
void CVANetMessage::WriteSignalSourceInfo( const CVASignalSourceInfo& oInfo )
{
	WriteString( oInfo.sName );
	WriteString( oInfo.sType );
	WriteString( oInfo.sState );
	WriteString( oInfo.sID );
	WriteString( oInfo.sDesc );
	WriteInt( oInfo.iReferences );
}
575

Jonas Stienen's avatar
Jonas Stienen committed
576
577
578
579
580
581
582
583
584
585
586
CVASignalSourceInfo CVANetMessage::ReadSignalSourceInfo()
{
	CVASignalSourceInfo oInfo;
	oInfo.sName = ReadString();
	oInfo.sType = ReadString();
	oInfo.sState = ReadString();
	oInfo.sID = ReadString();
	oInfo.sDesc = ReadString();
	oInfo.iReferences = ReadInt();
	return oInfo;
}
587
588

void CVANetMessage::WriteSceneInfo( const CVASceneInfo& )
Jonas Stienen's avatar
Jonas Stienen committed
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
{
	// TODO: Add field when CVASceneInfo gets designed
}

CVASceneInfo CVANetMessage::ReadSceneInfo()
{
	CVASceneInfo oInfo;
	// TODO: Add field when CVASceneInfo gets designed
	return oInfo;
}

void CVANetMessage::WriteModuleInfo( const CVAModuleInfo& oInfo )
{
	WriteString( oInfo.sName );
	WriteString( oInfo.sDesc );
}

void CVANetMessage::ReadModuleInfo( CVAModuleInfo& oInfo )
{
	oInfo.sName = ReadString();
	oInfo.sDesc = ReadString();
}

void CVANetMessage::WriteBlob( const void* pBuf, int nBytes )
{
614
	m_oOutgoing.WriteRawBuffer( pBuf, nBytes );
Jonas Stienen's avatar
Jonas Stienen committed
615
616
617
618
619
620
621
622
623
624
625
626
627
628
}

void CVANetMessage::ReadBlob( void* pBuf, int nBytes )
{
	int nReturn = m_oIncoming.ReadRawBuffer( pBuf, nBytes );
	assert( nReturn == nBytes );
}

void CVANetMessage::WriteVAStruct( const CVAStruct& oStruct )
{
	// Anzahl der Keys schreiben
	WriteInt( oStruct.Size() );

	int nBytes;
629
	for( CVAStruct::const_iterator cit = oStruct.Begin(); cit != oStruct.End(); ++cit ) {
Jonas Stienen's avatar
Jonas Stienen committed
630
631
632
633
634
635
636
637
		// Schlsselnamen
		WriteString( cit->first );

		// Wert-Typ
		int iDatatype = cit->second.GetDatatype();
		WriteInt( iDatatype );

		// Wert
638
		switch( iDatatype ) {
Jonas Stienen's avatar
Jonas Stienen committed
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
		case CVAStructValue::UNASSIGNED:
			// Keinen Wert => Nichts schreiben
			break;

		case CVAStructValue::BOOL:
			WriteBool( cit->second );
			break;

		case CVAStructValue::INT:
			WriteInt( cit->second );
			break;

		case CVAStructValue::DOUBLE:
			WriteDouble( cit->second );
			break;

		case CVAStructValue::STRING:
			WriteString( cit->second );
			break;

		case CVAStructValue::STRUCT:
			WriteVAStruct( cit->second.GetStruct() );
			break;

		case CVAStructValue::DATA:
			nBytes = cit->second.GetDataSize();
			WriteInt( nBytes );
			WriteBlob( cit->second.GetData(), nBytes );
			break;

		case CVAStructValue::SAMPLEBUFFER:
670
671
672
673
674
675
		{
			const CVASampleBuffer& oSampleBuffer( cit->second );
			WriteInt( oSampleBuffer.GetNumSamples() );
			for( int i = 0; i < oSampleBuffer.GetNumSamples(); i++ )
				WriteFloat( oSampleBuffer.vfSamples[ i ] );
		}
Jonas Stienen's avatar
Jonas Stienen committed
676
677
678
679
			break;

		default:
			// Implementierung vergessen? Oder neuer Datentyp?
680
			VA_EXCEPT2( PROTOCOL_ERROR, "Unsupported key datatype" );
Jonas Stienen's avatar
Jonas Stienen committed
681
682
683
684
685
686
687
688
689
690
691
		}
	}
}

void CVANetMessage::ReadVAStruct( CVAStruct& oStruct )
{
	oStruct.Clear();

	// Anzahl der Keys lesen
	int nKeys = ReadInt();

692
	for( int i = 0; i < nKeys; i++ ) {
Jonas Stienen's avatar
Jonas Stienen committed
693
694
695
696
697
698
699
		// Schlsselnamen
		std::string sKeyName = ReadString();

		// Wert-Typ
		int iDatatype = ReadInt();

		// Wert
700
		switch( iDatatype ) {
Jonas Stienen's avatar
Jonas Stienen committed
701
702
		case CVAStructValue::UNASSIGNED:
			// Keinen Wert => Leeren Schssel
703
			oStruct[ sKeyName ];
Jonas Stienen's avatar
Jonas Stienen committed
704
705
706
			break;

		case CVAStructValue::BOOL:
707
			oStruct[ sKeyName ] = ReadBool();
Jonas Stienen's avatar
Jonas Stienen committed
708
709
710
			break;

		case CVAStructValue::INT:
711
			oStruct[ sKeyName ] = ReadInt();
Jonas Stienen's avatar
Jonas Stienen committed
712
713
714
			break;

		case CVAStructValue::DOUBLE:
715
			oStruct[ sKeyName ] = ReadDouble();
Jonas Stienen's avatar
Jonas Stienen committed
716
717
718
			break;

		case CVAStructValue::STRING:
719
			oStruct[ sKeyName ] = ReadString();
Jonas Stienen's avatar
Jonas Stienen committed
720
721
722
			break;

		case CVAStructValue::STRUCT:
723
724
725
726
727
		{
			CVAStruct oSubstruct;
			ReadVAStruct( oSubstruct );
			oStruct[ sKeyName ] = oSubstruct;
		}
Jonas Stienen's avatar
Jonas Stienen committed
728
729
730
			break;

		case CVAStructValue::DATA:
731
732
733
734
		{
			int iDataSize = ReadInt();
			void* pData = ( void* ) new char[ iDataSize ];
			try
Jonas Stienen's avatar
Jonas Stienen committed
735
			{
736
				ReadBlob( pData, iDataSize );
Jonas Stienen's avatar
Jonas Stienen committed
737
			}
738
739
740
741
742
743
744
			catch( ... )
			{
				delete[] pData;
				throw;
			}
			oStruct[ sKeyName ] = CVAStructValue( pData, iDataSize );
		}
Jonas Stienen's avatar
Jonas Stienen committed
745
746
747
			break;

		case CVAStructValue::SAMPLEBUFFER:
748
749
750
		{
			int iNumSamples = ReadInt();
			oStruct[ sKeyName ] = CVASampleBuffer( iNumSamples, false );
751
			CVASampleBuffer& oSampleBuffer( oStruct[ sKeyName.c_str() ] );
752
753
754
			for( int i = 0; i < iNumSamples; i++ )
				oSampleBuffer.vfSamples[ i ] = ReadFloat();
		}
Jonas Stienen's avatar
Jonas Stienen committed
755
756
757
758
			break;

		default:
			// Implementierung vergessen? Oder neuer Datentyp?
759
			VA_EXCEPT2( PROTOCOL_ERROR, "Structure contains unknown key datatype" );
Jonas Stienen's avatar
Jonas Stienen committed
760
761
		}
	}
762

Jonas Stienen's avatar
Jonas Stienen committed
763
764
765
766
767
768
769
770
771
772
773
774
}

VistaConnectionIP* CVANetMessage::GetConnection() const
{
	return m_pConnection;
}

void CVANetMessage::ClearConnection()
{
	m_pConnection = NULL;
}

775
void CVANetMessage::WriteAudioRenderingModuleInfo( const CVAAudioRendererInfo& oRenderer )
Jonas Stienen's avatar
Jonas Stienen committed
776
777
778
{
	WriteString( oRenderer.sID );
	WriteString( oRenderer.sClass );
779
780
	WriteBool( oRenderer.bEnabled );
	WriteString( oRenderer.sDescription );
Jonas Stienen's avatar
Jonas Stienen committed
781
782
}

783
void CVANetMessage::WriteAudioReproductionModuleInfo( const CVAAudioReproductionInfo& oRepro )
Jonas Stienen's avatar
Jonas Stienen committed
784
785
786
{
	WriteString( oRepro.sID );
	WriteString( oRepro.sClass );
787
788
	WriteBool( oRepro.bEnabled );
	WriteString( oRepro.sDescription );
Jonas Stienen's avatar
Jonas Stienen committed
789
790
}

791
CVAAudioRendererInfo CVANetMessage::ReadAudioRenderingModuleInfo()
Jonas Stienen's avatar
Jonas Stienen committed
792
{
793
	CVAAudioRendererInfo oRenderer;
Jonas Stienen's avatar
Jonas Stienen committed
794
795
	oRenderer.sID = ReadString();
	oRenderer.sClass = ReadString();
796
797
	oRenderer.bEnabled = ReadBool();
	oRenderer.sDescription = ReadString();
Jonas Stienen's avatar
Jonas Stienen committed
798
799
800
	return oRenderer;
}

801
CVAAudioReproductionInfo CVANetMessage::ReadAudioReproductionModuleInfo()
Jonas Stienen's avatar
Jonas Stienen committed
802
{
803
	CVAAudioReproductionInfo oRepro;
Jonas Stienen's avatar
Jonas Stienen committed
804
805
	oRepro.sID = ReadString();
	oRepro.sClass = ReadString();
806
807
	oRepro.bEnabled = ReadBool();
	oRepro.sDescription = ReadString();
Jonas Stienen's avatar
Jonas Stienen committed
808
809
	return oRepro;
}