aboutsummaryrefslogtreecommitdiff
path: root/c++-libbu++/src/gatsstream.cpp
blob: 05fbd84a59e376d22f85635c36f8581d08d639a3 (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
115
/*
 * Copyright (C) 2007-2012 Xagasoft, All rights reserved.
 *
 * This file is part of the libgats library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#include "gats/gatsstream.h"
#include "gats/object.h"

// #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 = be32toh( 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 = htobe32( 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;
        }
    }
}