/**
* test the stream utility, access require
*/
VOID TEST(KernelStreamTest, StreamRequire)
{
    SrsStream s;
    char data[1024];
    
    EXPECT_FALSE(s.require(1));
    EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024));
    EXPECT_TRUE(s.require(1));
    EXPECT_TRUE(s.require(1024));
    
    s.read_bytes(data, 1000);
    EXPECT_TRUE(s.require(1));
    
    s.read_bytes(data, 24);
    EXPECT_FALSE(s.require(1));
}
/**
* test the stream utility, access empty
*/
VOID TEST(KernelStreamTest, StreamEmpty)
{
    SrsStream s;
    char data[1024];
    
    EXPECT_TRUE(s.empty());
    EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024));
    EXPECT_FALSE(s.empty());
    
    s.read_bytes(data, 1024);
    EXPECT_TRUE(s.empty());
}
/**
* test the stream utility, access pos
*/
VOID TEST(KernelStreamTest, StreamPos)
{
    SrsStream s;
    char data[1024];
    
    EXPECT_TRUE(s.pos() == 0);
    EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024));
    EXPECT_TRUE(s.pos() == 0);
    
    s.read_bytes(data, 1024);
    EXPECT_TRUE(s.pos() == 1024);
}
/**
* test the stream utility, read bytes
*/
VOID TEST(KernelStreamTest, StreamReadBytes)
{
    SrsStream s;
    char data[] = "Hello, world!";
    
    EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, sizeof(data) - 1));
    
    char bytes[64];
    s.read_bytes(bytes, 2);
    bytes[2] = 0;
    EXPECT_STREQ("He", bytes);
    
    s.read_bytes(bytes, 2);
    bytes[2] = 0;
    EXPECT_STREQ("ll", bytes);
    
    s.skip(3);
    s.read_bytes(bytes, 6);
    bytes[6] = 0;
    EXPECT_STREQ("world!", bytes);
    
    EXPECT_TRUE(s.empty());
}
int SrsSource::on_aggregate(SrsMessage* msg)
{
    int ret = ERROR_SUCCESS;
    
    SrsStream* stream = aggregate_stream;
    if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) {
        return ret;
    }
    
    while (!stream->empty()) {
        if (!stream->require(1)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message type. ret=%d", ret);
            return ret;
        }
        int8_t type = stream->read_1bytes();
        
        if (!stream->require(3)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message size. ret=%d", ret);
            return ret;
        }
        int32_t data_size = stream->read_3bytes();
        
        if (data_size < 0) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message size(negative). ret=%d", ret);
            return ret;
        }
        
        if (!stream->require(3)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message time. ret=%d", ret);
            return ret;
        }
        int32_t timestamp = stream->read_3bytes();
        
        if (!stream->require(1)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message time(high). ret=%d", ret);
            return ret;
        }
        int32_t time_h = stream->read_1bytes();
        
        timestamp |= time_h<<24;
        timestamp &= 0x7FFFFFFF;
        
        if (!stream->require(3)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message stream_id. ret=%d", ret);
            return ret;
        }
        int32_t stream_id = stream->read_3bytes();
        
        if (data_size > 0 && !stream->require(data_size)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message data. ret=%d", ret);
            return ret;
        }
        
        // to common message.
        SrsCommonMessage __o;
        SrsMessage& o = __o;
        
        o.header.message_type = type;
        o.header.payload_length = data_size;
        o.header.timestamp_delta = timestamp;
        o.header.timestamp = timestamp;
        o.header.stream_id = stream_id;
        o.header.perfer_cid = msg->header.perfer_cid;

        if (data_size > 0) {
            o.size = data_size;
            o.payload = new char[o.size];
            stream->read_bytes(o.payload, o.size);
        }
        
        if (!stream->require(4)) {
            ret = ERROR_RTMP_AGGREGATE;
            srs_error("invalid aggregate message previous tag size. ret=%d", ret);
            return ret;
        }
        stream->read_4bytes();

        // process parsed message
        if (o.header.is_audio()) {
            if ((ret = on_audio(&o)) != ERROR_SUCCESS) {
                return ret;
            }
        } else if (o.header.is_video()) {
            if ((ret = on_video(&o)) != ERROR_SUCCESS) {
                return ret;
            }
        }
    }
    
    return ret;
}