aboutsummaryrefslogtreecommitdiff
path: root/src/gatsstream.cpp
blob: 3e9b21193295e059280613a89aa784bad284e3d4 (plain)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "gats/gatsstream.h"
#include "gats/object.h"

#ifdef WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

// #include <bu/sio.h>
#include <bu/nullstream.h>
// using namespace Bu;

Gats::GatsStream::GatsStream( Bu::Stream &rStream ) :
	rStream( rStream )
{
}

Gats::GatsStream::~GatsStream()
{
}

Gats::Object *Gats::GatsStream::readObject()
{
	char buf[1500];

	// sio << "Gats::GatsStream::readObject(): Scanning for object header." << sio.nl;
	do
	{
		if( qbRead.getSize() < 5 )
		{
			// sio << "Gats::GatsStream::readObject(): reading header data, need 5b, have " << qbRead.getSize() << "b." << sio.nl;
			int iRead = rStream.read( buf, 5-qbRead.getSize() );
			qbRead.write( buf, iRead );

			if( qbRead.getSize() < 5 )
				return NULL;
		}
	} while( !skipReadNulls() );

	uint8_t uVer;
	qbRead.peek( &uVer, 1 );
	// sio << "Gats::GatsStream::readObject(): Packet version:  " << (int)uVer << sio.nl;
	
	int32_t iSize;
	qbRead.peek( &iSize, 4, 1 );
	iSize = ntohl( iSize );
	// sio << "Gats::GatsStream::readObject(): Header read, looking for " << iSize << "b, we have " << qbRead.getSize() << "b." << sio.nl;
	while( qbRead.getSize() < iSize )
	{
		int32_t iRead = iSize - qbRead.getSize();
		if( iRead > 1500 )
			iRead = 1500;
		// sio << "Gats::GatsStream::readObject(): Attempting to read " << iRead << "b." << sio.nl;
		int32_t iReal = rStream.read( buf, iRead );
		// sio << "Gats::GatsStream::readObject(): Read " << iReal << "b." << sio.nl;
		qbRead.write( buf, iReal );
		if( iReal < iRead )
		{
			// sio << "Gats::GatsStream::readObject(): Insufficient data read in block, bailing on read." << sio.nl;
			return NULL;
		}
	}

	if( qbRead.getSize() < iSize )
	{
		// sio << "Gats::GatsStream::readObject(): Somehow, we still don't have enough data, bailing." << sio.nl;
		return NULL;
	}

	// sio << "Gats::GatsStream::readObject(): We have " << qbRead.getSize() << "b of " << iSize << "b, time to read the object." << sio.nl;

	qbRead.seek( 5 );
	Gats::Object *pObj = Gats::Object::read( qbRead );

	// sio << "Gats::GatsStream::readObject(): Read completed, there are " << qbRead.getSize() << "b left in the buffer." << sio.nl;
	return pObj;
}

void Gats::GatsStream::writeObject( Gats::Object *pObject )
{
	Bu::NullStream ns;
	pObject->write( ns );

	uint8_t uBuf = 1; 
	int32_t iSize = htonl( ns.tell()+5 );
	rStream.write( &uBuf, 1 );
	rStream.write( &iSize, 4 );
	pObject->write( rStream );

	// sio << "Object consumed " << ns.tell() << "b." << sio.nl;
}

bool Gats::GatsStream::skipReadNulls()
{
	char buf;

	// sio << "Gats::GatsStream::skipReadNulls(): Scanning for nulls, " << qbRead.getSize() << "b." << sio.nl;
	bool bHaveSeeked = false;
	for(;;)
	{
		if( qbRead.peek( &buf, 1 ) == 0 )
			return false;
		if( buf != 0 )
			return !bHaveSeeked; //true;
		else
		{
			// sio << "Gats::GatsStream::skipReadNulls(): Null byte read, not header yet..." << sio.nl;
			qbRead.seek( 1 );
			bHaveSeeked = true;
		}
	}
}