/*
The MIT License (MIT)

Copyright (c) 2013-2014 winlin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_utest_protocol.hpp>

using namespace std;

#include <srs_kernel_error.hpp>
#include <srs_core_autofree.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_protocol_msg_array.hpp>
#include <srs_protocol_stack.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_app_st.hpp>
#include <srs_protocol_amf0.hpp>
#include <srs_protocol_rtmp.hpp>

MockEmptyIO::MockEmptyIO()
{
}

MockEmptyIO::~MockEmptyIO()
{
}

bool MockEmptyIO::is_never_timeout(int64_t /*timeout_us*/)
{
    return true;
}

int MockEmptyIO::read_fully(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
{
    return ERROR_SUCCESS;
}

int MockEmptyIO::write(void* /*buf*/, size_t /*size*/, ssize_t* /*nwrite*/)
{
    return ERROR_SUCCESS;
}

void MockEmptyIO::set_recv_timeout(int64_t /*timeout_us*/)
{
}

int64_t MockEmptyIO::get_recv_timeout()
{
    return -1;
}

int64_t MockEmptyIO::get_recv_bytes()
{
    return -1;
}

void MockEmptyIO::set_send_timeout(int64_t /*timeout_us*/)
{
}

int64_t MockEmptyIO::get_send_timeout()
{
    return 0;
}

int64_t MockEmptyIO::get_send_bytes()
{
    return 0;
}

int MockEmptyIO::writev(const iovec */*iov*/, int /*iov_size*/, ssize_t* /*nwrite*/)
{
    return ERROR_SUCCESS;
}

int MockEmptyIO::read(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
{
    return ERROR_SUCCESS;
}

MockBufferIO::MockBufferIO()
{
    recv_timeout = send_timeout = ST_UTIME_NO_TIMEOUT;
    recv_bytes = send_bytes = 0;
}

MockBufferIO::~MockBufferIO()
{
}

bool MockBufferIO::is_never_timeout(int64_t timeout_us)
{
    return (int64_t)ST_UTIME_NO_TIMEOUT == timeout_us;
}

int MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
{
    if (in_buffer.length() < (int)size) {
        return ERROR_SOCKET_READ;
    }
    memcpy(buf, in_buffer.bytes(), size);
    
    recv_bytes += size;
    if (nread) {
        *nread = size;
    }
    in_buffer.erase(size);
    return ERROR_SUCCESS;
}

int MockBufferIO::write(void* buf, size_t size, ssize_t* nwrite)
{
    send_bytes += size;
    if (nwrite) {
        *nwrite = size;
    }
    out_buffer.append((char*)buf, size);
    return ERROR_SUCCESS;
}

void MockBufferIO::set_recv_timeout(int64_t timeout_us)
{
    recv_timeout = timeout_us;
}

int64_t MockBufferIO::get_recv_timeout()
{
    return recv_timeout;
}

int64_t MockBufferIO::get_recv_bytes()
{
    return recv_bytes;
}

void MockBufferIO::set_send_timeout(int64_t timeout_us)
{
    send_timeout = timeout_us;
}

int64_t MockBufferIO::get_send_timeout()
{
    return send_timeout;
}

int64_t MockBufferIO::get_send_bytes()
{
    return send_bytes;
}

int MockBufferIO::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
{
    int ret = ERROR_SUCCESS;
    
    ssize_t total = 0;
    for (int i = 0; i <iov_size; i++) {
        const iovec& pi = iov[i];
        
        ssize_t writen = 0;
        if ((ret = write(pi.iov_base, pi.iov_len, &writen)) != ERROR_SUCCESS) {
            return ret;
        }
        total += writen;
    }
    
    if (nwrite) {
        *nwrite = total;
    }
    return ret;
}

int MockBufferIO::read(void* buf, size_t size, ssize_t* nread)
{
    if (in_buffer.length() <= 0) {
        return ERROR_SOCKET_READ;
    }
    
    size_t available = srs_min(in_buffer.length(), (int)size);
    memcpy(buf, in_buffer.bytes(), available);
    
    recv_bytes += available;
    if (nread) {
        *nread = available;
    }
    in_buffer.erase(available);
    return ERROR_SUCCESS;
}

#ifdef ENABLE_UTEST_PROTOCOL

#ifdef SRS_AUTO_SSL

// verify the sha256
VOID TEST(ProtocolHandshakeTest, OpensslSha256)
{
    // randome bytes to ensure the openssl sha256 is ok.
    char random_bytes[] = {
        (char)0x8b, (char)0x1c, (char)0x5c, (char)0x5c, (char)0x3b, (char)0x98, (char)0x60, (char)0x80, (char)0x3c, (char)0x97, (char)0x43, (char)0x79, (char)0x9c, (char)0x94, (char)0xec, (char)0x63, (char)0xaa, (char)0xd9, (char)0x10, (char)0xd7, (char)0x0d, (char)0x91, (char)0xfb, (char)0x1f, (char)0xbf, (char)0xe0, (char)0x29, (char)0xde, (char)0x77, (char)0x09, (char)0x21, (char)0x34, (char)0xa5, (char)0x7d, (char)0xdf, (char)0xe3, (char)0xdf, (char)0x11, (char)0xdf, (char)0xd4, (char)0x00, (char)0x57, (char)0x38, (char)0x5b, (char)0xae, (char)0x9e, (char)0x89, (char)0x35, (char)0xcf, (char)0x07, (char)0x48, (char)0xca, (char)0xc8, (char)0x25, (char)0x46, (char)0x3c,
        (char)0xb6, (char)0xdb, (char)0x9b, (char)0x39, (char)0xa6, (char)0x07, (char)0x3d, (char)0xaf, (char)0x8b, (char)0x85, (char)0xa2, (char)0x2f, (char)0x03, (char)0x64, (char)0x5e, (char)0xbd, (char)0xb4, (char)0x20, (char)0x01, (char)0x48, (char)0x2e, (char)0xc2, (char)0xe6, (char)0xcc, (char)0xce, (char)0x61, (char)0x59, (char)0x47, (char)0xf9, (char)0xdd, (char)0xc2, (char)0xa2, (char)0xfe, (char)0x64, (char)0xe6, (char)0x0b, (char)0x41, (char)0x4f, (char)0xe4, (char)0x8a, (char)0xca, (char)0xbe, (char)0x4d, (char)0x0e, (char)0x73, (char)0xba, (char)0x82, (char)0x30, (char)0x3c, (char)0x53, (char)0x36, (char)0x2e, (char)0xd3, (char)0x04, (char)0xae, (char)0x49,
        (char)0x44, (char)0x71, (char)0x6d, (char)0x4d, (char)0x5a, (char)0x14, (char)0x94, (char)0x94, (char)0x57, (char)0x78, (char)0xb9, (char)0x2a, (char)0x34, (char)0x49, (char)0xf8, (char)0xc2, (char)0xec, (char)0x4e, (char)0x29, (char)0xb6, (char)0x28, (char)0x54, (char)0x4a, (char)0x5e, (char)0x68, (char)0x06, (char)0xfe, (char)0xfc, (char)0xd5, (char)0x01, (char)0x35, (char)0x0c, (char)0x95, (char)0x6f, (char)0xe9, (char)0x77, (char)0x8a, (char)0xfc, (char)0x11, (char)0x15, (char)0x1a, (char)0xda, (char)0x6c, (char)0xf5, (char)0xba, (char)0x9e, (char)0x41, (char)0xd9, (char)0x7e, (char)0x0f, (char)0xdb, (char)0x33, (char)0xda, (char)0x35, (char)0x9d, (char)0x34,
        (char)0x67, (char)0x8f, (char)0xdf, (char)0x71, (char)0x63, (char)0x04, (char)0x9c, (char)0x54, (char)0xb6, (char)0x18, (char)0x10, (char)0x2d, (char)0x42, (char)0xd2, (char)0xf3, (char)0x14, (char)0x34, (char)0xa1, (char)0x31, (char)0x90, (char)0x48, (char)0xc9, (char)0x4b, (char)0x87, (char)0xb5, (char)0xcd, (char)0x62, (char)0x6b, (char)0x77, (char)0x18, (char)0x36, (char)0xd9, (char)0xc9, (char)0xc9, (char)0xae, (char)0x89, (char)0xfb, (char)0xed, (char)0xcd, (char)0xcb, (char)0xdb, (char)0x6e, (char)0xe3, (char)0x22, (char)0xbf, (char)0x7b, (char)0x72, (char)0x8a, (char)0xc3, (char)0x79, (char)0xd6, (char)0x1b, (char)0x6c, (char)0xe7, (char)0x9c, (char)0xc9,
        (char)0xfd, (char)0x48, (char)0xaa, (char)0xc1, (char)0xfa, (char)0xbf, (char)0x33, (char)0x87, (char)0x5c, (char)0x0d, (char)0xe5, (char)0x34, (char)0x24, (char)0x70, (char)0x14, (char)0x1e, (char)0x4a, (char)0x48, (char)0x07, (char)0x6e, (char)0xaf, (char)0xbf, (char)0xfe, (char)0x34, (char)0x1e, (char)0x1e, (char)0x19, (char)0xfc, (char)0xb5, (char)0x8a, (char)0x4f, (char)0x3c, (char)0xb4, (char)0xcf, (char)0xde, (char)0x24, (char)0x79, (char)0x65, (char)0x17, (char)0x22, (char)0x3f, (char)0xc0, (char)0x06, (char)0x76, (char)0x4e, (char)0x3c, (char)0xfb, (char)0xc3, (char)0xd0, (char)0x7f, (char)0x7b, (char)0x87, (char)0x5c, (char)0xeb, (char)0x97, (char)0x87,
    };
    
    char digest[__SRS_OpensslHashSize];
    ASSERT_EQ(ERROR_SUCCESS, 
        openssl_HMACsha256(
            SrsGenuineFPKey, 30, 
            random_bytes, sizeof(random_bytes), 
            digest
        )
    );
    
    char expect_digest[] = {
        (char)0x1b, (char)0xc7, (char)0xe6, (char)0x14, (char)0xd5, (char)0x19, (char)0x8d, (char)0x99, (char)0x42, (char)0x0a, (char)0x21, (char)0x95, (char)0x26, (char)0x9a, (char)0x8a, (char)0x56,
        (char)0xb4, (char)0x82, (char)0x2a, (char)0x7f, (char)0xd3, (char)0x1d, (char)0xc3, (char)0xd8, (char)0x92, (char)0x97, (char)0xc4, (char)0x61, (char)0xb7, (char)0x4d, (char)0x5d, (char)0xd2
    };
    EXPECT_TRUE(srs_bytes_equals(digest, expect_digest, 32));
}

// verify the dh key
VOID TEST(ProtocolHandshakeTest, DHKey)
{
    _srs_internal::SrsDH dh;
    
    ASSERT_TRUE(ERROR_SUCCESS == dh.initialize(true));
    
    char pub_key1[128];
    int pkey_size = 128;
    EXPECT_TRUE(ERROR_SUCCESS == dh.copy_public_key(pub_key1, pkey_size));
    ASSERT_EQ(128, pkey_size);
    
    char pub_key2[128];
    EXPECT_TRUE(ERROR_SUCCESS == dh.copy_public_key(pub_key2, pkey_size));
    ASSERT_EQ(128, pkey_size);
    
    EXPECT_TRUE(srs_bytes_equals(pub_key1, pub_key2, 128));
    
    // another dh
    _srs_internal::SrsDH dh0;
    
    ASSERT_TRUE(ERROR_SUCCESS == dh0.initialize(true));
    
    EXPECT_TRUE(ERROR_SUCCESS == dh0.copy_public_key(pub_key2, pkey_size));
    ASSERT_EQ(128, pkey_size);
    
    EXPECT_FALSE(srs_bytes_equals(pub_key1, pub_key2, 128));
}

// flash will sendout a c0c1 encrypt by ssl.
VOID TEST(ProtocolHandshakeTest, VerifyFPC0C1)
{
    char c0c1[] = {
        (char)0x03, (char)0x00, (char)0x0f, (char)0x64, (char)0xd0, (char)0x80, (char)0x00, (char)0x07, (char)0x02, (char)0xe6, (char)0x42, (char)0xe5, (char)0x2b, (char)0xf1, (char)0x1d, (char)0x0f, (char)0x6c, (char)0xc8, (char)0x50, (char)0xf2, (char)0x06, (char)0xae, (char)0xd5, (char)0x4f, (char)0xdb, (char)0xfe, (char)0x79, (char)0xc2, (char)0xef, (char)0xf5, (char)0x01, (char)0x74, (char)0x4b, (char)0x5b, (char)0xe7, (char)0x37, (char)0xa3, (char)0xe0, (char)0xca, (char)0xe1, (char)0x97, (char)0x07, (char)0xdb, (char)0x54, (char)0x1d, (char)0x4c, (char)0x4b, (char)0xa3, (char)0xc3, (char)0x3e, (char)0xa9, (char)0xeb, (char)0xa9, (char)0x5b, (char)0x2f, (char)0x38, (char)0xa0, (char)0xa9, (char)0x98, (char)0x38, (char)0x80, (char)0x1b, (char)0xfb, (char)0xa7, (char)0x04, (char)0xff, (char)0xfd, (char)0x45, (char)0xfe, (char)0xfa, (char)0xc1, (char)0xe4, (char)0x1c, (char)0x77, (char)0x9a, (char)0x19, (char)0x39, (char)0x34, (char)0x10, (char)0x79, (char)0x12, (char)0xcf, (char)0x4e, (char)0xea, (char)0x34, (char)0x7d, (char)0x88, (char)0x47, (char)0xca, (char)0xf2, (char)0xb3, (char)0x09, (char)0x50, (char)0xbb, (char)0xe1, (char)0x20, (char)0x9b, (char)0x25, (char)0xb0, (char)0x3c, (char)0xbc, (char)0x46, (char)0x7a, (char)0x36, (char)0xb8, (char)0xc2, (char)0x4d, (char)0xd0, (char)0xf1, (char)0x20, (char)0x2a, (char)0xcc, (char)0x7a, (char)0x91, (char)0xab, (char)0x0b, (char)0xb6, (char)0xc7, (char)0x09, (char)0x0d, (char)0xf1, (char)0x34, (char)0x0c, (char)0x37, (char)0xbe, (char)0xad, (char)0x0e, (char)0xe3, (char)0x6b, (char)0x68, (char)0x0a, (char)0x7e, (char)0xd2, (char)0xd4, (char)0xc5, (char)0x3d, (char)0xdc, (char)0xac, (char)0x28, (char)0x8b, (char)0x88, (char)0xb5, (char)0x1e, (char)0xd8, (char)0x2b, (char)0x68, (char)0x72, (char)0x55, (char)0x64, (char)0xa2, (char)0xa5, (char)0x69, (char)0x0a, (char)0xdb, (char)0x26, (char)0xff, (char)0x63, (char)0x2d, (char)0xb8, (char)0xff, (char)0xb6, (char)0x33, (char)0xd3, (char)0x9d, (char)0x5c, (char)0x46, (char)0xd6, (char)0xbf, (char)0x8b, (char)0x1c, (char)0x5c, (char)0x5c, (char)0x3b, (char)0x98, (char)0x60, (char)0x80, (char)0x3c, (char)0x97, (char)0x43, (char)0x79, (char)0x9c, (char)0x94, (char)0xec, (char)0x63, (char)0xaa, (char)0xd9, (char)0x10, (char)0xd7, (char)0x0d, (char)0x91, (char)0xfb, (char)0x1f, (char)0xbf, (char)0xe0, (char)0x29, (char)0xde, (char)0x77, (char)0x09, (char)0x21, (char)0x34, (char)0xa5, (char)0x7d, (char)0xdf, (char)0xe3, (char)0xdf, (char)0x11, (char)0xdf, (char)0xd4, (char)0x00, (char)0x57, (char)0x38, (char)0x5b, (char)0xae, (char)0x9e, (char)0x89, (char)0x35, (char)0xcf, (char)0x07, (char)0x48, (char)0xca, (char)0xc8, (char)0x25, (char)0x46, (char)0x3c,
        (char)0xb6, (char)0xdb, (char)0x9b, (char)0x39, (char)0xa6, (char)0x07, (char)0x3d, (char)0xaf, (char)0x8b, (char)0x85, (char)0xa2, (char)0x2f, (char)0x03, (char)0x64, (char)0x5e, (char)0xbd, (char)0xb4, (char)0x20, (char)0x01, (char)0x48, (char)0x2e, (char)0xc2, (char)0xe6, (char)0xcc, (char)0xce, (char)0x61, (char)0x59, (char)0x47, (char)0xf9, (char)0xdd, (char)0xc2, (char)0xa2, (char)0xfe, (char)0x64, (char)0xe6, (char)0x0b, (char)0x41, (char)0x4f, (char)0xe4, (char)0x8a, (char)0xca, (char)0xbe, (char)0x4d, (char)0x0e, (char)0x73, (char)0xba, (char)0x82, (char)0x30, (char)0x3c, (char)0x53, (char)0x36, (char)0x2e, (char)0xd3, (char)0x04, (char)0xae, (char)0x49, (char)0x44, (char)0x71, (char)0x6d, (char)0x4d, (char)0x5a, (char)0x14, (char)0x94, (char)0x94, (char)0x57, (char)0x78, (char)0xb9, (char)0x2a, (char)0x34, (char)0x49, (char)0xf8, (char)0xc2, (char)0xec, (char)0x4e, (char)0x29, (char)0xb6, (char)0x28, (char)0x54, (char)0x4a, (char)0x5e, (char)0x68, (char)0x06, (char)0xfe, (char)0xfc, (char)0xd5, (char)0x01, (char)0x35, (char)0x0c, (char)0x95, (char)0x6f, (char)0xe9, (char)0x77, (char)0x8a, (char)0xfc, (char)0x11, (char)0x15, (char)0x1a, (char)0xda, (char)0x6c, (char)0xf5, (char)0xba, (char)0x9e, (char)0x41, (char)0xd9, (char)0x7e, (char)0x0f, (char)0xdb, (char)0x33, (char)0xda, (char)0x35, (char)0x9d, (char)0x34, (char)0x67, (char)0x8f, (char)0xdf, (char)0x71, (char)0x63, (char)0x04, (char)0x9c, (char)0x54, (char)0xb6, (char)0x18, (char)0x10, (char)0x2d, (char)0x42, (char)0xd2, (char)0xf3, (char)0x14, (char)0x34, (char)0xa1, (char)0x31, (char)0x90, (char)0x48, (char)0xc9, (char)0x4b, (char)0x87, (char)0xb5, (char)0xcd, (char)0x62, (char)0x6b, (char)0x77, (char)0x18, (char)0x36, (char)0xd9, (char)0xc9, (char)0xc9, (char)0xae, (char)0x89, (char)0xfb, (char)0xed, (char)0xcd, (char)0xcb, (char)0xdb, (char)0x6e, (char)0xe3, (char)0x22, (char)0xbf, (char)0x7b, (char)0x72, (char)0x8a, (char)0xc3, (char)0x79, (char)0xd6, (char)0x1b, (char)0x6c, (char)0xe7, (char)0x9c, (char)0xc9, (char)0xfd, (char)0x48, (char)0xaa, (char)0xc1, (char)0xfa, (char)0xbf, (char)0x33, (char)0x87, (char)0x5c, (char)0x0d, (char)0xe5, (char)0x34, (char)0x24, (char)0x70, (char)0x14, (char)0x1e, (char)0x4a, (char)0x48, (char)0x07, (char)0x6e, (char)0xaf, (char)0xbf, (char)0xfe, (char)0x34, (char)0x1e, (char)0x1e, (char)0x19, (char)0xfc, (char)0xb5, (char)0x8a, (char)0x4f, (char)0x3c, (char)0xb4, (char)0xcf, (char)0xde, (char)0x24, (char)0x79, (char)0x65, (char)0x17, (char)0x22, (char)0x3f, (char)0xc0, (char)0x06, (char)0x76, (char)0x4e, (char)0x3c, (char)0xfb, (char)0xc3, (char)0xd0, (char)0x7f, (char)0x7b, (char)0x87, (char)0x5c, (char)0xeb, (char)0x97, (char)0x87,
        (char)0x99, (char)0x20, (char)0x70, (char)0x7b, (char)0xf8, (char)0x97, (char)0x73, (char)0xdc, (char)0xb4, (char)0x94, (char)0x43, (char)0x27, (char)0x03, (char)0xbd, (char)0xb5, (char)0x91, (char)0xd9, (char)0x3e, (char)0x51, (char)0x1a, (char)0xd5, (char)0x60, (char)0x9c, (char)0x71, (char)0xd3, (char)0xc7, (char)0x1f, (char)0xd7, (char)0xef, (char)0x2f, (char)0xa1, (char)0xf7, (char)0xe6, (char)0xb1, (char)0x31, (char)0x9d, (char)0xec, (char)0xa3, (char)0xe1, (char)0x01, (char)0x57, (char)0xa8, (char)0x1c, (char)0x34, (char)0xf8, (char)0x82, (char)0xf5, (char)0x4d, (char)0xb8, (char)0x32, (char)0xe4, (char)0x4b, (char)0x90, (char)0x97, (char)0xcf, (char)0x8c, (char)0x2e, (char)0x89, (char)0xd0, (char)0xbc, (char)0xc0, (char)0xca, (char)0x45, (char)0x5e, (char)0x5c, (char)0x36, (char)0x47, (char)0x98, (char)0xa8, (char)0x57, (char)0xb5, (char)0x56, (char)0xc9, (char)0x11, (char)0xe4, (char)0x2f, (char)0xf0, (char)0x2b, (char)0x2c, (char)0xc1, (char)0x49, (char)0x1a, (char)0xfb, (char)0xdd, (char)0x89, (char)0x3f, (char)0x18, (char)0x98, (char)0x78, (char)0x13, (char)0x83, (char)0xf4, (char)0x30, (char)0xe2, (char)0x4e, (char)0x0e, (char)0xf4, (char)0x6c, (char)0xcb, (char)0xc6, (char)0xc7, (char)0x31, (char)0xe9, (char)0x78, (char)0x74, (char)0xfd, (char)0x53, (char)0x05, (char)0x4e, (char)0x7b, (char)0xd3, (char)0x9b, (char)0xeb, (char)0x15, (char)0xc0, (char)0x6f, (char)0xbf, (char)0xa4, (char)0x69, (char)0x7d, (char)0xd1, (char)0x53, (char)0x0f, (char)0x0b, (char)0xc1, (char)0x2b, (char)0xad, (char)0x00, (char)0x44, (char)0x10, (char)0xe2, (char)0x9f, (char)0xb9, (char)0xf3, (char)0x0c, (char)0x98, (char)0x53, (char)0xf0, (char)0x60, (char)0xcb, (char)0xee, (char)0x7e, (char)0x5c, (char)0x83, (char)0x4a, (char)0xde, (char)0xa0, (char)0x7a, (char)0xcf, (char)0x50, (char)0x2b, (char)0x84, (char)0x09, (char)0xff, (char)0x42, (char)0xe4, (char)0x80, (char)0x2a, (char)0x64, (char)0x20, (char)0x9b, (char)0xb9, (char)0xba, (char)0xd4, (char)0x54, (char)0xca, (char)0xd8, (char)0xdc, (char)0x0a, (char)0x4d, (char)0xdd, (char)0x84, (char)0x91, (char)0x5e, (char)0x16, (char)0x90, (char)0x1d, (char)0xdc, (char)0xe3, (char)0x95, (char)0x55, (char)0xac, (char)0xf2, (char)0x8c, (char)0x9a, (char)0xcc, (char)0xb2, (char)0x6d, (char)0x17, (char)0x01, (char)0xe4, (char)0x01, (char)0xc6, (char)0xba, (char)0xe4, (char)0xb8, (char)0xd5, (char)0xbd, (char)0x7b, (char)0x43, (char)0xc9, (char)0x69, (char)0x6b, (char)0x40, (char)0xf7, (char)0xdc, (char)0x65, (char)0xa4, (char)0xf7, (char)0xca, (char)0x1f, (char)0xd8, (char)0xe5, (char)0xba, (char)0x4c, (char)0xdf, (char)0xe4, (char)0x64, (char)0x9e, (char)0x7d, (char)0xbd, (char)0x54, (char)0x13, (char)0x13,
        (char)0xc6, (char)0x0c, (char)0xb8, (char)0x1d, (char)0x31, (char)0x0a, (char)0x49, (char)0xe2, (char)0x43, (char)0xb6, (char)0x95, (char)0x5f, (char)0x05, (char)0x6e, (char)0x66, (char)0xf4, (char)0x21, (char)0xa8, (char)0x65, (char)0xce, (char)0xf8, (char)0x8e, (char)0xcc, (char)0x16, (char)0x1e, (char)0xbb, (char)0xd8, (char)0x0e, (char)0xcb, (char)0xd2, (char)0x48, (char)0x37, (char)0xaf, (char)0x4e, (char)0x67, (char)0x45, (char)0xf1, (char)0x79, (char)0x69, (char)0xd2, (char)0xee, (char)0xa4, (char)0xb5, (char)0x01, (char)0xbf, (char)0x57, (char)0x0f, (char)0x68, (char)0x37, (char)0xbe, (char)0x4e, (char)0xff, (char)0xc9, (char)0xb9, (char)0x92, (char)0x23, (char)0x06, (char)0x75, (char)0xa0, (char)0x42, (char)0xe4, (char)0x0a, (char)0x30, (char)0xf0, (char)0xaf, (char)0xb0, (char)0x54, (char)0x88, (char)0x7c, (char)0xc0, (char)0xc1, (char)0x0c, (char)0x6d, (char)0x01, (char)0x36, (char)0x63, (char)0xf3, (char)0x3d, (char)0xbc, (char)0x72, (char)0xf6, (char)0x96, (char)0xc8, (char)0x87, (char)0xab, (char)0x8b, (char)0x0c, (char)0x91, (char)0x2f, (char)0x42, (char)0x2a, (char)0x11, (char)0xf6, (char)0x2d, (char)0x5e, (char)0x77, (char)0xce, (char)0x9c, (char)0xc1, (char)0x34, (char)0xe5, (char)0x2d, (char)0x9b, (char)0xd0, (char)0x37, (char)0x97, (char)0x0e, (char)0x39, (char)0xe5, (char)0xaa, (char)0xbe, (char)0x15, (char)0x3e, (char)0x6b, (char)0x1e, (char)0x73, (char)0xf6, (char)0xd7, (char)0xf4, (char)0xd6, (char)0x71, (char)0x70, (char)0xc6, (char)0xa1, (char)0xe6, (char)0x04, (char)0xd3, (char)0x7c, (char)0x2d, (char)0x1c, (char)0x98, (char)0x47, (char)0xdb, (char)0x8f, (char)0x59, (char)0x99, (char)0x2a, (char)0x57, (char)0x63, (char)0x14, (char)0xc7, (char)0x02, (char)0x42, (char)0x74, (char)0x57, (char)0x02, (char)0x22, (char)0xb2, (char)0x55, (char)0xe9, (char)0xf3, (char)0xe0, (char)0x76, (char)0x1c, (char)0x50, (char)0xbf, (char)0x43, (char)0x65, (char)0xbe, (char)0x52, (char)0xbd, (char)0x46, (char)0xf0, (char)0xfd, (char)0x5e, (char)0x25, (char)0xfe, (char)0x34, (char)0x50, (char)0x0d, (char)0x24, (char)0x7c, (char)0xfc, (char)0xfa, (char)0x82, (char)0x2f, (char)0x8c, (char)0x7d, (char)0x97, (char)0x1b, (char)0x07, (char)0x6b, (char)0x20, (char)0x6c, (char)0x9b, (char)0x7b, (char)0xae, (char)0xbf, (char)0xb3, (char)0x4f, (char)0x6e, (char)0xbb, (char)0xb6, (char)0xc4, (char)0xe9, (char)0xa5, (char)0x07, (char)0xa7, (char)0x74, (char)0x45, (char)0x16, (char)0x8a, (char)0x12, (char)0xee, (char)0x42, (char)0xc8, (char)0xea, (char)0xb5, (char)0x33, (char)0x69, (char)0xef, (char)0xff, (char)0x60, (char)0x6d, (char)0x99, (char)0xa3, (char)0x92, (char)0x5d, (char)0x0f, (char)0xbe, (char)0xb7, (char)0x4e, (char)0x1c, (char)0x85,
        (char)0xef, (char)0x9e, (char)0x1d, (char)0x38, (char)0x72, (char)0x1f, (char)0xe0, (char)0xca, (char)0xc9, (char)0x90, (char)0x85, (char)0x3f, (char)0xa6, (char)0x5d, (char)0x60, (char)0x3f, (char)0xe6, (char)0x92, (char)0x08, (char)0x3b, (char)0xd4, (char)0xc3, (char)0xa2, (char)0x7e, (char)0x7c, (char)0x35, (char)0x49, (char)0xd4, (char)0x21, (char)0x38, (char)0x8c, (char)0x2c, (char)0x49, (char)0xb3, (char)0xcb, (char)0x33, (char)0xd4, (char)0xc2, (char)0x88, (char)0xdc, (char)0x09, (char)0xb3, (char)0x8a, (char)0x13, (char)0x95, (char)0x0f, (char)0xb4, (char)0x0a, (char)0xd1, (char)0x1d, (char)0xc8, (char)0xe4, (char)0x64, (char)0xb4, (char)0x24, (char)0x51, (char)0xe1, (char)0x0a, (char)0x22, (char)0xd4, (char)0x45, (char)0x77, (char)0x91, (char)0x0a, (char)0xc6, (char)0x61, (char)0xa1, (char)0x2c, (char)0x50, (char)0x84, (char)0x1c, (char)0x0c, (char)0xbe, (char)0x05, (char)0x1c, (char)0x3b, (char)0x4f, (char)0x27, (char)0x83, (char)0x33, (char)0xba, (char)0xfb, (char)0x7f, (char)0xa0, (char)0xc6, (char)0x38, (char)0xb4, (char)0x0c, (char)0x15, (char)0x49, (char)0x8f, (char)0xfa, (char)0x17, (char)0x76, (char)0xa9, (char)0x54, (char)0xf4, (char)0x6c, (char)0x7e, (char)0x5e, (char)0x39, (char)0xb8, (char)0xa8, (char)0x78, (char)0x86, (char)0x48, (char)0xb2, (char)0x18, (char)0xf1, (char)0xde, (char)0x0d, (char)0x24, (char)0xee, (char)0x6b, (char)0x01, (char)0x7d, (char)0x60, (char)0xfa, (char)0x35, (char)0xfe, (char)0x71, (char)0x0b, (char)0xfa, (char)0x8c, (char)0x79, (char)0x6c, (char)0x0b, (char)0x25, (char)0x84, (char)0x6d, (char)0x1a, (char)0x1d, (char)0xe0, (char)0x33, (char)0xa1, (char)0xa0, (char)0x8f, (char)0x47, (char)0x08, (char)0x4b, (char)0x5c, (char)0x8c, (char)0xc6, (char)0x1e, (char)0x2a, (char)0x6d, (char)0xd8, (char)0x3e, (char)0x09, (char)0x83, (char)0x96, (char)0xe6, (char)0xbc, (char)0x14, (char)0x55, (char)0x17, (char)0xcb, (char)0x50, (char)0x44, (char)0xdb, (char)0x80, (char)0xab, (char)0xb9, (char)0xf0, (char)0x1a, (char)0x3a, (char)0x9e, (char)0x23, (char)0xd5, (char)0x46, (char)0x73, (char)0x4b, (char)0xd0, (char)0x41, (char)0x9d, (char)0x29, (char)0x03, (char)0x59, (char)0x29, (char)0xeb, (char)0x82, (char)0x71, (char)0x09, (char)0x0c, (char)0x26, (char)0x10, (char)0x0f, (char)0x59, (char)0xd4, (char)0xd7, (char)0xb4, (char)0x4d, (char)0xe5, (char)0x35, (char)0xf5, (char)0x19, (char)0xef, (char)0xc7, (char)0xe7, (char)0x43, (char)0x0a, (char)0x3e, (char)0xeb, (char)0x3d, (char)0xc5, (char)0x55, (char)0xde, (char)0x04, (char)0xe7, (char)0x88, (char)0x72, (char)0x6c, (char)0xf7, (char)0x9d, (char)0x86, (char)0xb2, (char)0x0c, (char)0x83, (char)0x55, (char)0x20, (char)0x67, (char)0xc0, (char)0xc9, (char)0x15,
        (char)0x3c, (char)0x76, (char)0x69, (char)0x80, (char)0x79, (char)0x68, (char)0x89, (char)0x16, (char)0x0a, (char)0xaf, (char)0xe4, (char)0x2c, (char)0xf0, (char)0x0e, (char)0x26, (char)0x74, (char)0x84, (char)0xfb, (char)0x27, (char)0xd4, (char)0x1c, (char)0x61, (char)0xbe, (char)0xe8, (char)0xc3, (char)0xce, (char)0x74, (char)0xd9, (char)0xf8, (char)0x5a, (char)0xa8, (char)0x63, (char)0x13, (char)0x27, (char)0xfa, (char)0xab, (char)0x93, (char)0x32, (char)0x25, (char)0x18, (char)0xb1, (char)0x78, (char)0x2f, (char)0xd3, (char)0x93, (char)0x0b, (char)0xc6, (char)0x5a, (char)0xda, (char)0xfe, (char)0xff, (char)0x7e, (char)0x38, (char)0x0c, (char)0x26, (char)0x44, (char)0x4c, (char)0x23, (char)0xe0, (char)0x8e, (char)0x64, (char)0xff, (char)0x07, (char)0xbc, (char)0x5b, (char)0x87, (char)0xd6, (char)0x3c, (char)0x8e, (char)0xe7, (char)0xd1, (char)0x78, (char)0x55, (char)0x00, (char)0x19, (char)0xbe, (char)0x98, (char)0x55, (char)0x1e, (char)0x16, (char)0xea, (char)0x63, (char)0x79, (char)0xb5, (char)0xaf, (char)0x9a, (char)0x20, (char)0x04, (char)0x8d, (char)0x3f, (char)0xdc, (char)0x15, (char)0x29, (char)0xc4, (char)0xe3, (char)0x9a, (char)0x82, (char)0x92, (char)0x85, (char)0xee, (char)0x1c, (char)0x37, (char)0xb3, (char)0xd7, (char)0xd2, (char)0x2e, (char)0x1e, (char)0xdb, (char)0x59, (char)0x87, (char)0xef, (char)0xa8, (char)0x9a, (char)0xaa, (char)0xa4, (char)0xed, (char)0x89, (char)0x33, (char)0xa8, (char)0xa7, (char)0x6c, (char)0x96, (char)0x9f, (char)0x26, (char)0xeb, (char)0xdc, (char)0x61, (char)0xc4, (char)0x8f, (char)0xd3, (char)0x2b, (char)0x81, (char)0x86, (char)0x6c, (char)0x9c, (char)0xc2, (char)0xb1, (char)0xb5, (char)0xbc, (char)0xa6, (char)0xd6, (char)0xd6, (char)0x1d, (char)0xce, (char)0x93, (char)0x78, (char)0xb3, (char)0xec, (char)0xa8, (char)0x64, (char)0x19, (char)0x13, (char)0x59, (char)0x1c, (char)0xb9, (char)0xbf, (char)0xd8, (char)0x7f, (char)0x27, (char)0x8e, (char)0x6f, (char)0x05, (char)0xd9, (char)0x1a, (char)0xa4, (char)0x1a, (char)0xc2, (char)0x46, (char)0x81, (char)0x52, (char)0xa5, (char)0xaf, (char)0x73, (char)0x35, (char)0x34, (char)0x88, (char)0x60, (char)0x46, (char)0x4d, (char)0x09, (char)0x87, (char)0xf1, (char)0x7e, (char)0x5e, (char)0xea, (char)0x32, (char)0x98, (char)0xb4, (char)0x68, (char)0x28, (char)0xff, (char)0x47, (char)0xde, (char)0x72, (char)0x9b, (char)0xc5, (char)0xfe, (char)0xb8, (char)0x93, (char)0xe8, (char)0x79, (char)0xe4, (char)0xa6, (char)0xd7, (char)0x63, (char)0x94, (char)0x29, (char)0x94, (char)0x33, (char)0x30, (char)0x61, (char)0xd4, (char)0x19, (char)0x36, (char)0x99, (char)0x94, (char)0x31, (char)0xbf, (char)0x93, (char)0x46, (char)0x04, (char)0xc0, (char)0xfe, (char)0x4d,
        (char)0x92, (char)0xb4, (char)0xbc, (char)0xb2, (char)0x14, (char)0x3f, (char)0xf7, (char)0xce, (char)0x05, (char)0xcf, (char)0xf2, (char)0x5b, (char)0x66, (char)0xcb, (char)0x67, (char)0xa9, (char)0x8f, (char)0x63, (char)0xd4, (char)0x7c, (char)0x1d, (char)0x33, (char)0x6a, (char)0x05, (char)0xfb, (char)0xf7, (char)0x11, (char)0x03, (char)0x97, (char)0xff, (char)0x02, (char)0x1b, (char)0x6f, (char)0x15, (char)0x8b, (char)0x33, (char)0xe6, (char)0xf7, (char)0x5d, (char)0x93, (char)0x21, (char)0x9d, (char)0x17, (char)0xde, (char)0x9e, (char)0x87, (char)0xdc, (char)0xcd, (char)0x9a, (char)0x6a, (char)0x30, (char)0x3e, (char)0xa9, (char)0x70, (char)0xed, (char)0x93, (char)0x1d, (char)0x43, (char)0xb5, (char)0x5d, (char)0xb0, (char)0x46, (char)0x74, (char)0x73, (char)0x3b, (char)0x25, (char)0xfa, (char)0x0e, (char)0xe3, (char)0x70, (char)0x74, (char)0x2d, (char)0x75, (char)0xd6, (char)0x14, (char)0x67, (char)0x40, (char)0x31, (char)0xf9, (char)0x2c, (char)0xf6, (char)0x38, (char)0xea, (char)0x45, (char)0x33, (char)0xc1, (char)0xb6, (char)0xd5, (char)0x93, (char)0x0f, (char)0x5c, (char)0xaf, (char)0x3a, (char)0x53, (char)0x75, (char)0xd6, (char)0xe8, (char)0x97, (char)0xa0, (char)0x51, (char)0x3f, (char)0x96, (char)0x41, (char)0x32, (char)0x0b, (char)0x59, (char)0x48, (char)0xbf, (char)0x2b, (char)0x19, (char)0x67, (char)0x98, (char)0x42, (char)0xfe, (char)0x44, (char)0x23, (char)0x84, (char)0xa9, (char)0x09, (char)0x40, (char)0x4e, (char)0x10, (char)0x25, (char)0xdf, (char)0x68, (char)0x93, (char)0x6b, (char)0x0d, (char)0xa8, (char)0x51, (char)0x47, (char)0x55, (char)0xb7, (char)0xb8, (char)0x22, (char)0xab, (char)0xa3, (char)0x3c, (char)0x78, (char)0xd6, (char)0x8b, (char)0x4f, (char)0x2a, (char)0x73, (char)0xc1, (char)0x4a, (char)0x4a, (char)0xdd, (char)0x73, (char)0xb1, (char)0xc0, (char)0x8c, (char)0x5f, (char)0xf6, (char)0xe7, (char)0xbe, (char)0x9c, (char)0x96, (char)0xd6, (char)0x37, (char)0x91, (char)0x05, (char)0x52, (char)0xd1, (char)0x2f, (char)0xa9, (char)0xdc, (char)0xca, (char)0x11, (char)0x30, (char)0x6d, (char)0x4f, (char)0xb5, (char)0x6e, (char)0x39, (char)0x24, (char)0x28, (char)0x80, (char)0x54, (char)0x28, (char)0x87, (char)0xe6, (char)0x40, (char)0xeb, (char)0xd8, (char)0x7a, (char)0x1f, (char)0x63, (char)0x56, (char)0xc1, (char)0x4d, (char)0xa0, (char)0xf8    
    };
    ASSERT_EQ(1537, (int)sizeof(c0c1));
    
    // c0
    EXPECT_EQ(0x03, c0c1[0]);
    
    // c1
    c1s1 c1;
    
    // the schema of data must be schema0: key-digest.
    ASSERT_EQ(ERROR_SUCCESS, c1.parse(c0c1 + 1, srs_schema0));
    EXPECT_EQ((int32_t)0x000f64d0, c1.time);
    EXPECT_EQ((int32_t)0x80000702, c1.version);
    
    // manually validate the c1
    // @see: calc_c1_digest
    char* c1s1_joined_bytes = srs_bytes_join_schema0(c1.time, c1.version, &c1.block0.key, &c1.block1.digest);
    SrsAutoFree(char, c1s1_joined_bytes);
    
    bool is_valid;
    ASSERT_EQ(ERROR_SUCCESS, c1.c1_validate_digest(is_valid));
    ASSERT_TRUE(is_valid);
    
    // 128bytes key
    char key[] = {
        (char)0x01, (char)0xc6, (char)0xba, (char)0xe4, (char)0xb8, (char)0xd5, (char)0xbd, (char)0x7b, (char)0x43, (char)0xc9, (char)0x69, (char)0x6b, (char)0x40, (char)0xf7, (char)0xdc, (char)0x65, (char)0xa4, (char)0xf7, (char)0xca, (char)0x1f, (char)0xd8, (char)0xe5, (char)0xba, (char)0x4c, (char)0xdf, (char)0xe4, (char)0x64, (char)0x9e, (char)0x7d, (char)0xbd, (char)0x54, (char)0x13, (char)0x13, (char)0xc6, (char)0x0c, (char)0xb8, (char)0x1d, (char)0x31, (char)0x0a, (char)0x49, (char)0xe2, (char)0x43, (char)0xb6, (char)0x95, (char)0x5f, (char)0x05, (char)0x6e, (char)0x66,
        (char)0xf4, (char)0x21, (char)0xa8, (char)0x65, (char)0xce, (char)0xf8, (char)0x8e, (char)0xcc, (char)0x16, (char)0x1e, (char)0xbb, (char)0xd8, (char)0x0e, (char)0xcb, (char)0xd2, (char)0x48, (char)0x37, (char)0xaf, (char)0x4e, (char)0x67, (char)0x45, (char)0xf1, (char)0x79, (char)0x69, (char)0xd2, (char)0xee, (char)0xa4, (char)0xb5, (char)0x01, (char)0xbf, (char)0x57, (char)0x0f, (char)0x68, (char)0x37, (char)0xbe, (char)0x4e, (char)0xff, (char)0xc9, (char)0xb9, (char)0x92, (char)0x23, (char)0x06, (char)0x75, (char)0xa0, (char)0x42, (char)0xe4, (char)0x0a, (char)0x30,
        (char)0xf0, (char)0xaf, (char)0xb0, (char)0x54, (char)0x88, (char)0x7c, (char)0xc0, (char)0xc1, (char)0x0c, (char)0x6d, (char)0x01, (char)0x36, (char)0x63, (char)0xf3, (char)0x3d, (char)0xbc, (char)0x72, (char)0xf6, (char)0x96, (char)0xc8, (char)0x87, (char)0xab, (char)0x8b, (char)0x0c, (char)0x91, (char)0x2f, (char)0x42, (char)0x2a, (char)0x11, (char)0xf6, (char)0x2d, (char)0x5e
    };
    EXPECT_TRUE(srs_bytes_equals(c1.block0.key.key, key, 128));
    
    // 32bytes digest
    char digest[] = {
        (char)0x6c, (char)0x96, (char)0x9f, (char)0x26, (char)0xeb, (char)0xdc, (char)0x61, (char)0xc4, (char)0x8f, (char)0xd3, (char)0x2b, (char)0x81, (char)0x86, (char)0x6c, (char)0x9c, (char)0xc2,
        (char)0xb1, (char)0xb5, (char)0xbc, (char)0xa6, (char)0xd6, (char)0xd6, (char)0x1d, (char)0xce, (char)0x93, (char)0x78, (char)0xb3, (char)0xec, (char)0xa8, (char)0x64, (char)0x19, (char)0x13
    };
    EXPECT_TRUE(srs_bytes_equals(c1.block1.digest.digest, digest, 32));
}

VOID TEST(ProtocolHandshakeTest, ComplexHandshake)
{
    SrsHandshakeBytes bytes;
    
    if (true) {
        char c0c1[] = {
            (char)0x03, (char)0x01, (char)0x14, (char)0xf7, (char)0x4e, (char)0x80, (char)0x00, (char)0x07, (char)0x02, (char)0xac, (char)0x14, (char)0x98, (char)0x57, (char)0x0a, (char)0x07, (char)0x58, (char)0x44, (char)0x96, (char)0x47, (char)0xb5, (char)0x9a, (char)0x73, (char)0xf6, (char)0x07, (char)0x0f, (char)0x49, (char)0x0d, (char)0x72, (char)0xb8, (char)0x16, (char)0xbb, (char)0xb2, (char)0xb7, (char)0x61, (char)0x17, (char)0x79, (char)0xa0, (char)0xe9, (char)0x98, (char)0xca, (char)0xb2, (char)0x86, (char)0x64, (char)0x5f, (char)0x65, (char)0x3e, (char)0xfc, (char)0x4d, (char)0xc0, (char)0x0e, (char)0x4c, (char)0xfa, (char)0x91, (char)0xc7, (char)0x0f, (char)0x2e, (char)0x57, (char)0x31, (char)0x4b, (char)0x96, (char)0xef, (char)0xc9, (char)0x81, (char)0x02, (char)0x00, (char)0x54, (char)0x25, (char)0x2b, (char)0xb2, (char)0x0d, (char)0x7c, (char)0xee, (char)0xba, (char)0xdb, (char)0xe4, (char)0x06, (char)0x78, (char)0xcd, (char)0x70, (char)0x2c, (char)0x54, (char)0x5a, (char)0x3a, (char)0x03, (char)0x13, (char)0x2e, (char)0xe7, (char)0x4b, (char)0x87, (char)0x40, (char)0x77, (char)0x0b, (char)0x9f, (char)0xd2, (char)0xab, (char)0x32, (char)0x07, (char)0x6f, (char)0x1e, (char)0x75, (char)0x74, (char)0xe9, (char)0xc7, (char)0x44, (char)0xd9, (char)0x76, (char)0x53, (char)0xba, (char)0xe2, (char)0x52, (char)0xfa, (char)0xcc, (char)0xef, (char)0x34, (char)0xd5, (char)0x14, (char)0x61, (char)0xac, (char)0xcc, (char)0x63, (char)0xfd, (char)0x2b, (char)0x2d, (char)0xb3, (char)0xb8, (char)0xdd, (char)0x8a, (char)0x51, (char)0x9a, (char)0x2d, (char)0x0e, (char)0xfa, (char)0x84, (char)0x25, (char)0x55, (char)0xb2, (char)0xb7, (char)0x94, (char)0x54, (char)0x68, (char)0xfb, (char)0x94, (char)0xdf, (char)0xd8, (char)0xeb, (char)0x43, (char)0xd0, (char)0x11, (char)0x70, (char)0x8f, (char)0xf5, (char)0x48, (char)0xfc, (char)0x69, (char)0x4d, (char)0x5b, (char)0xc6, (char)0x53, (char)0x8a, (char)0x22, (char)0xea, (char)0x62, (char)0x84, (char)0x89, (char)0x6b, (char)0xfe, (char)0x4e, (char)0xab, (char)0x51, (char)0x98, (char)0xf4, (char)0x4f, (char)0xae, (char)0xf8, (char)0xdf, (char)0xac, (char)0x43, (char)0xed, (char)0x5a, (char)0x04, (char)0x97, (char)0xc4, (char)0xbe, (char)0x44, (char)0x5b, (char)0x99, (char)0x20, (char)0x68, (char)0x67, (char)0x0f, (char)0xe3, (char)0xfa, (char)0x4c, (char)0x9d, (char)0xe7, (char)0x0b, (char)0x3f, (char)0x80, (char)0x7c, (char)0x4c, (char)0x35, (char)0xf6, (char)0xdd, (char)0x20, (char)0x05, (char)0xfd, (char)0x0f, (char)0x39, (char)0xb7, (char)0x36, (char)0x45, (char)0x4c, (char)0xb7, (char)0x62, (char)0x92, (char)0x35, (char)0x2a, (char)0xcd, (char)0xb9, (char)0x49, (char)0xea, (char)0x12, (char)0x0b, (char)0x5f, (char)0x39, (char)0xae, (char)0x3b, (char)0x49, (char)0x29, (char)0xe6, (char)0x30, (char)0xc7, (char)0x7c, (char)0x77, (char)0xaf, (char)0x00, (char)0x43, (char)0x4d, (char)0x06, (char)0x45, (char)0x72, (char)0x73, (char)0x25, (char)0x71, (char)0x5e, (char)0x35, (char)0x04, (char)0xbd, (char)0xe9, (char)0x48, (char)0x23, (char)0x64, (char)0x4d, (char)0x15, (char)0x0b, (char)0xc5, (char)0x3f, (char)0x6e, (char)0x3a, (char)0xd5, (char)0xd5, (char)0xa6, (char)0xae, (char)0x3b, (char)0x4c, (char)0x66, (char)0x6a, (char)0x70, (char)0x8b, (char)0xf3, (char)0x6a, (char)0x43, (char)0xc4, (char)0xb9, (char)0xbd, (char)0xa0, (char)0x09, (char)0x72, (char)0xbc, (char)0xce, (char)0x7a, (char)0xea, (char)0x49, (char)0xf2, (char)0x86, (char)0xa7, (char)0xd8, (char)0x4a, (char)0x87, (char)0x28, (char)0xca, (char)0x2c, (char)0x53, (char)0xee, (char)0x96, (char)0x0b, (char)0xbe, (char)0x15, (char)0x14, (char)0xa8, (char)0x00, (char)0xca, (char)0x76, (char)0x08, (char)0x4d, (char)0x0f, (char)0xef, (char)0x78, (char)0x4b, (char)0xf6, (char)0x47, (char)0x60, (char)0xfc, (char)0x16, (char)0x00, (char)0x7c, (char)0x6b, (char)0x49, (char)0x39, (char)0x64, (char)0x36, (char)0xee, (char)0x45, (char)0x3a, (char)0x9a, (char)0xa5, (char)0xbf, (char)0xfb, (char)0x7b, (char)0xe7, (char)0xcf, (char)0x42, (char)0x82, (char)0x48, (char)0x1b, (char)0x30, (char)0xfe, (char)0x0d, (char)0xba, (char)0x10, (char)0xb8, (char)0xe1, (char)0x40, (char)0xcc, (char)0x6f, (char)0x36, (char)0x1c, (char)0x94, (char)0x5d, (char)0x50, (char)0x9e, (char)0x21, (char)0x08, (char)0xc9, (char)0xd5, (char)0xb0, (char)0x32, (char)0x51, (char)0x6a, (char)0x8f, (char)0xfa, (char)0x57, (char)0x8d, (char)0x45, (char)0xd7, (char)0xd2, (char)0xd0, (char)0xd6, (char)0x6c, (char)0x78, (char)0x95, (char)0xe9, (char)0xe1, (char)0x20, (char)0x97, (char)0x1a, (char)0x43, (char)0x40, (char)0xa3, (char)0xb5, (char)0xcc, (char)0x4b, (char)0x12, (char)0x84, (char)0x1e, (char)0x0e, (char)0xd3, (char)0x32, (char)0xca, (char)0x99, (char)0xc3, (char)0x2b, (char)0x78, (char)0x17, (char)0x24, (char)0x6b, (char)0xc7, (char)0xbc, (char)0x9d, (char)0x05, (char)0xc6, (char)0xaf, (char)0x8f, (char)0x19, (char)0x75, (char)0x3c, (char)0x08, (char)0xa6, (char)0x08, (char)0x26, (char)0x5b, (char)0xf4, (char)0x10, (char)0x40, (char)0xaa, (char)0x6a, (char)0x7e, (char)0xb9, (char)0xde, (char)0x0b, (char)0x23, (char)0x3f, (char)0x53, (char)0x5a, (char)0x20, (char)0x13, (char)0x62, (char)0xec, (char)0x53, (char)0x86, (char)0x81, (char)0x1f, (char)0xf6, (char)0x8e, (char)0xe3, (char)0xd1, (char)0xaa, (char)0xb5, (char)0x41, (char)0x87, (char)0x62, (char)0xd2, (char)0xb7, (char)0x09, (char)0x12, (char)0x71, (char)0x01, (char)0x2c, (char)0xac, (char)0x6d, (char)0x9d, (char)0x37, (char)0x46, (char)0x5b, (char)0xdc, (char)0x76, (char)0x2c, (char)0x96, (char)0x61, (char)0x88, (char)0x55, (char)0x5a, (char)0x20, (char)0xc2, (char)0x84, (char)0x95, (char)0xbd, (char)0x72, (char)0xc4, (char)0xb7, (char)0x22, (char)0xae, (char)0xeb, (char)0x49, (char)0x0e, (char)0x16, (char)0xf1, (char)0xf1, (char)0xbf, (char)0xc5, (char)0xc7, (char)0xa8, (char)0x8d, (char)0xfb, (char)0xe1, (char)0x08, (char)0x6c, (char)0xc4, (char)0x79, (char)0x81, (char)0x13, (char)0xe8, (char)0x39, (char)0xbf, (char)0x6e, (char)0x5c, (char)0xa1, (char)0x62, (char)0xfb, (char)0x32, (char)0x2a, (char)0x62, (char)0xf0, (char)0x12, (char)0x07, (char)0x31, (char)0x93, (char)0x40, (char)0xf3, (char)0xc0, (char)0xea, (char)0x1d, (char)0xd8, (char)0x65, (char)0xba, (char)0x12, (char)0xb3, (char)0x9b, (char)0xf5, (char)0x59, (char)0x9c, (char)0x4e, (char)0xf6, (char)0xb9, (char)0xf7, (char)0x85, (char)0xa1, (char)0xd9, (char)0x2f, (char)0x7c, (char)0x8b, (char)0xd0, (char)0xfc, (char)0x53, (char)0x3b, (char)0xed, (char)0x85, (char)0xa4, (char)0xd2, (char)0x5e, (char)0x69, (char)0x61, (char)0x02, (char)0x53, (char)0xb6, (char)0x19, (char)0xc7, (char)0x82, (char)0xea, (char)0x8a, (char)0x45, (char)0x01, (char)0x5d, (char)0x4b, (char)0xb3, (char)0x06, (char)0x86, (char)0x7f, (char)0x4b, (char)0x2f, (char)0xe7, (char)0xa8, (char)0xd0, (char)0x28, (char)0x62, (char)0x02, (char)0xe8, (char)0xf3, (char)0x9e, (char)0x1e, (char)0x72, (char)0x82, (char)0x07, (char)0x9f, (char)0xdd, (char)0xd2, (char)0x83, (char)0x7d, (char)0x89, (char)0x73, (char)0x1b, (char)0x6f, (char)0x35, (char)0x20, (char)0xb7, (char)0x88, (char)0x15, (char)0x92, (char)0xa7, (char)0x11, (char)0xfe, (char)0x81, (char)0x68, (char)0xed, (char)0x14, (char)0x07, (char)0xdf, (char)0x4a, (char)0x06, (char)0x9c, (char)0x5e, (char)0x7e, (char)0x34, (char)0x3a, (char)0x2a, (char)0x8a, (char)0xd3, (char)0xe8, (char)0xf8, (char)0xd4, (char)0xdb, (char)0xe3, (char)0xe9, (char)0x73, (char)0xbf, (char)0xa7, (char)0xe9, (char)0x73, (char)0x62, (char)0xf2, (char)0x9d, (char)0xc1, (char)0xf7, (char)0x51, (char)0xeb, (char)0xff, (char)0xb7, (char)0xe6, (char)0xd9, (char)0xac, (char)0x46, (char)0x06, (char)0x74, (char)0xe2, (char)0x25, (char)0x3f, (char)0x46, (char)0x43, (char)0xce, (char)0x49, (char)0x52, (char)0x25, (char)0x1b, (char)0xf9, (char)0x24, (char)0x5c, (char)0xda, (char)0xfd, (char)0x7f, (char)0xf6, (char)0xef, (char)0xb3, (char)0xd5, (char)0xe9, (char)0x6e, (char)0x35, (char)0xb8, (char)0xd1, (char)0x0e, (char)0x2c, (char)0xc1, (char)0x48, (char)0x5a, (char)0x27, (char)0x0a, (char)0x81, (char)0x01, (char)0x0f, (char)0xe4, (char)0x51, (char)0xcf, (char)0x89, (char)0x36, (char)0xd3, (char)0xe8, (char)0x5e, (char)0x05, (char)0xb9, (char)0x83, (char)0x42, (char)0xf3, (char)0xa5, (char)0x94, (char)0x67, (char)0x6d, (char)0x6a, (char)0x6e, (char)0xad, (char)0xf8, (char)0x90, (char)0xb1, (char)0x1d, (char)0x63, (char)0x18, (char)0x52, (char)0xc1, (char)0xbf, (char)0xbc, (char)0xad, (char)0xf4, (char)0xd2, (char)0xc5, (char)0xef, (char)0xca, (char)0x4c, (char)0xfe, (char)0xa1, (char)0xda, (char)0x15, (char)0x92, (char)0x4c, (char)0x42, (char)0x3d, (char)0xfc, (char)0x80, (char)0x7e, (char)0x49, (char)0x13, (char)0x4e, (char)0xf6, (char)0xe1, (char)0xee, (char)0x70, (char)0xca, (char)0xd9, (char)0x0a, (char)0xde, (char)0x9b, (char)0xea, (char)0xcd, (char)0xf9, (char)0x90, (char)0xfd, (char)0xae, (char)0x09, (char)0xce, (char)0xb6, (char)0xa0, (char)0xf7, (char)0xd1, (char)0xe6, (char)0x0c, (char)0x55, (char)0x1e, (char)0x3f, (char)0xbb, (char)0x1e, (char)0xff, (char)0x3d, (char)0xdb, (char)0xdd, (char)0x27, (char)0x80, (char)0x06, (char)0x53, (char)0x7e, (char)0x0b, (char)0x2a, (char)0x80, (char)0x24, (char)0x51, (char)0x5c, (char)0x6a, (char)0xab, (char)0x32, (char)0x5d, (char)0x37, (char)0x8a, (char)0xf4, (char)0xb7, (char)0x11, (char)0xa7, (char)0xc1, (char)0x9e, (char)0x05, (char)0x2c, (char)0x16, (char)0xc2, (char)0x08, (char)0xe2, (char)0xac, (char)0x1a, (char)0xeb, (char)0x60, (char)0xf8, (char)0xd2, (char)0xea, (char)0x39, (char)0x01, (char)0x1c, (char)0x64, (char)0xbd, (char)0x22, (char)0x80, (char)0x19, (char)0x20, (char)0xc9, (char)0x6f, (char)0xdd, (char)0x5c, (char)0x73, (char)0x8c, (char)0xa1, (char)0x53, (char)0x48, (char)0x2e, (char)0x99, (char)0x1d, (char)0xc0, (char)0x8f, (char)0x28, (char)0xf1, (char)0xe3, (char)0xc5, (char)0xc5, (char)0x65, (char)0x53, (char)0xf2, (char)0x44, (char)0x44, (char)0x24, (char)0xb9, (char)0xe2, (char)0x73, (char)0xe4, (char)0x76, (char)0x14, (char)0x56, (char)0xb8, (char)0x82, (char)0xe3, (char)0xb4, (char)0xfd, (char)0x68, (char)0x31, (char)0xed, (char)0x40, (char)0x10, (char)0x99, (char)0xd3, (char)0x3d, (char)0xe5, (char)0x6b, (char)0x14, (char)0x61, (char)0x66, (char)0x9a, (char)0xf6, (char)0x33, (char)0x98, (char)0xc5, (char)0x4d, (char)0x11, (char)0xbb, (char)0xf8, (char)0x56, (char)0xf8, (char)0x8f, (char)0xd7, (char)0xb9, (char)0xda, (char)0xa3, (char)0x56, (char)0x1a, (char)0xe0, (char)0x9e, (char)0xbe, (char)0x5f, (char)0x56, (char)0xe5, (char)0xb9, (char)0xd8, (char)0xf3, (char)0xbc, (char)0x19, (char)0xf5, (char)0xe9, (char)0x1f, (char)0xd2, (char)0xea, (char)0xf4, (char)0x5a, (char)0xde, (char)0xed, (char)0xd4, (char)0x9e, (char)0xc8, (char)0xf5, (char)0x54, 
            (char)0x83, (char)0x8b, (char)0x8c, (char)0x2d, (char)0x24, (char)0x0e, (char)0x30, (char)0xb1, (char)0x84, (char)0xa2, (char)0xbe, (char)0x2c, (char)0x86, (char)0xe6, (char)0x42, (char)0x82, (char)0xaa, (char)0x37, (char)0x64, (char)0x55, (char)0x51, (char)0xbc, (char)0xde, (char)0xc0, (char)0x63, (char)0x88, (char)0xf6, (char)0x31, (char)0x71, (char)0x52, (char)0xd5, (char)0x34, (char)0x0f, (char)0x8e, (char)0xcb, (char)0x28, (char)0x65, (char)0x93, (char)0x1a, (char)0x66, (char)0x3b, (char)0x21, (char)0x00, (char)0xaa, (char)0x7a, (char)0xda, (char)0x2d, (char)0xf6, (char)0x7e, (char)0xb5, (char)0x27, (char)0x79, (char)0xf4, (char)0x50, (char)0x3b, (char)0x10, (char)0x6b, (char)0x3c, (char)0xd7, (char)0x99, (char)0x9d, (char)0xf6, (char)0xc5, (char)0x01, (char)0x91, (char)0xa0, (char)0xd5, (char)0x4f, (char)0xd3, (char)0x76, (char)0x54, (char)0xa8, (char)0x5c, (char)0x35, (char)0x1d, (char)0xe2, (char)0x35, (char)0x6a, (char)0x68, (char)0x67, (char)0x03, (char)0xc4, (char)0x1f, (char)0xe9, (char)0x60, (char)0xb8, (char)0x49, (char)0xb1, (char)0x9a, (char)0x40, (char)0xd9, (char)0x3c, (char)0x4c, (char)0x73, (char)0xaa, (char)0x88, (char)0x63, (char)0xaf, (char)0xfe, (char)0xe8, (char)0xa8, (char)0x0c, (char)0x96, (char)0xbe, (char)0xb4, (char)0x65, (char)0x7c, (char)0x27, (char)0xfb, (char)0xc1, (char)0x27, (char)0x24, (char)0x58, (char)0xab, (char)0x4b, (char)0xa0, (char)0x5a, (char)0x7d, (char)0xc7, (char)0xca, (char)0x2d, (char)0xa5, (char)0x22, (char)0xa7, (char)0xed, (char)0x26, (char)0x87, (char)0xd5, (char)0x44, (char)0x1a, (char)0xc7, (char)0xdd, (char)0xfb, (char)0x60, (char)0xfc, (char)0xe5, (char)0x50, (char)0xd9, (char)0x8d, (char)0xa7, (char)0xdb, (char)0x78, (char)0xb6, (char)0x9d, (char)0x80, (char)0x0f, (char)0xb9, (char)0x5f, (char)0xa7, (char)0x53, (char)0x92, (char)0x5d, (char)0x18, (char)0xce, (char)0x89, (char)0xc2, (char)0x69, (char)0xee, (char)0xcf, (char)0xb6, (char)0x66, (char)0xe5, (char)0x66, (char)0xd2, (char)0xe3, (char)0x35, (char)0x74, (char)0x0b, (char)0x83, (char)0xb6, (char)0xde, (char)0xf1, (char)0xfb, (char)0xb4, (char)0x1d, (char)0x4b, (char)0x94, (char)0x95, (char)0x06, (char)0x82, (char)0xe7, (char)0x1c, (char)0xf8, (char)0xc5, (char)0xe6, (char)0xd0, (char)0xf2, (char)0x17, (char)0x37, (char)0x44, (char)0xfe, (char)0x99, (char)0x43, (char)0x82, (char)0xbb, (char)0x88, (char)0xe4, (char)0x43, (char)0x67, (char)0xcc, (char)0x4d, (char)0x5f, (char)0xa6, (char)0x26, (char)0xd7, (char)0x53, (char)0xd6, (char)0x45, (char)0x96, (char)0x2b, (char)0x63, (char)0xd1, (char)0x2a, (char)0xa1, (char)0x2c, (char)0x41, (char)0x59, (char)0x8b, (char)0xb8, (char)0xc1, (char)0x89, (char)0x03, (char)0x3a, (char)0x61, (char)0x13, (char)0xc4, (char)0x2c, (char)0x37, (char)0xa5, (char)0xbf, (char)0xd7, (char)0xdb, (char)0xd8, (char)0x53, (char)0x5f, (char)0xa1, (char)0xdb, (char)0xdb, (char)0xa5, (char)0x73, (char)0xb6, (char)0xf7, (char)0x74, (char)0xa0, (char)0xf8, (char)0x93, (char)0xf5, (char)0x61, (char)0xee, (char)0x3c, (char)0xe7, (char)0x00, (char)0x01, (char)0x98, (char)0xe0, (char)0xa1, (char)0x22, (char)0xb6, (char)0x9a, (char)0x83, (char)0x44, (char)0xa1, (char)0xe6, (char)0x70, (char)0x56, (char)0x65, (char)0x92, (char)0x1e, (char)0xf0, (char)0xbc, (char)0x73, (char)0xa5, (char)0x7a, (char)0xc1, (char)0x1a, (char)0x02, (char)0xf9, (char)0xd4, (char)0xc4, (char)0x7c, (char)0x81, (char)0xda, (char)0x15, (char)0xc0, (char)0xd4, (char)0x25, (char)0xdc, (char)0x17, (char)0xa6, (char)0x0d, (char)0x90, (char)0x55, (char)0xf2, (char)0x10, (char)0xf8, (char)0xa7, (char)0x71, (char)0x9b, (char)0xed, (char)0xdf, (char)0xdf, (char)0xa1, (char)0xe4, (char)0xb9, (char)0x12, (char)0x6b, (char)0x05, (char)0x3e, (char)0x83, (char)0x99, (char)0x49, (char)0xbf, (char)0x66, (char)0xbb, (char)0xf6, (char)0x76, (char)0xd3, (char)0xa9, (char)0x24, (char)0x61, (char)0x8c, (char)0x25, (char)0x49, (char)0xd0, (char)0xf7, (char)0x83, (char)0x44, (char)0xfb, (char)0x27, (char)0xe2, (char)0x7d, (char)0x69, (char)0x6d, (char)0x34, (char)0x67, (char)0xed, (char)0x39, (char)0x89, (char)0x02, (char)0xcb, (char)0x2f, (char)0x33, (char)0x3c, (char)0xcd, (char)0x12, (char)0x42, (char)0x8f, (char)0x86, (char)0x7d, (char)0xda, (char)0x3f, (char)0xd7, (char)0x26, (char)0x62, (char)0x9c, (char)0x1f, (char)0x2e, (char)0xa8, (char)0xc3, (char)0x85, (char)0xf1, (char)0x73, (char)0xe5, (char)0x2c, (char)0x11, (char)0xde, (char)0x98, (char)0xc8, (char)0xb0, (char)0x10, (char)0x17, (char)0x55, (char)0xf5, (char)0x32, (char)0x52, (char)0x67, (char)0xca, (char)0x64, (char)0x50, (char)0x28, (char)0x9a, (char)0x24, (char)0x92, (char)0xa1, (char)0x97, (char)0x57, (char)0x81, (char)0xaf, (char)0xca, (char)0x1e, (char)0xc0, (char)0xa4, (char)0x71, (char)0x2d, (char)0x2a, (char)0xec, (char)0xc9, (char)0x23, (char)0x6a, (char)0x0c, (char)0x1d, (char)0x54, (char)0x15, (char)0x2a, (char)0x56, (char)0x42, (char)0x0a, (char)0x83, (char)0xff, (char)0x28, (char)0xba, (char)0xe7, (char)0x68, (char)0x38, (char)0xf5, (char)0x32, (char)0xa9, (char)0xb7, (char)0xe7, (char)0x70, (char)0x32, (char)0xa8, (char)0x79, (char)0x5e, (char)0x46, (char)0x1d, (char)0xec, (char)0x29, (char)0x8a, (char)0xde, (char)0x41, (char)0x94, (char)0x94, (char)0x26, (char)0x79, (char)0xc2, (char)0x52, (char)0x23, (char)0xe0, (char)0xa1, (char)0x1d, (char)0x65, (char)0x0c, (char)0xbe, (char)0x1b, (char)0x87, (char)0x2a, (char)0x21, (char)0x53, (char)0x2f, (char)0x35, (char)0x56, (char)0xe8, (char)0xd1, (char)0x7b, (char)0xb8, (char)0x23, (char)0x75, (char)0x56, (char)0xc7, (char)0x08, (char)0x9d, (char)0x13, (char)0xf0, (char)0x8f, (char)0x80, (char)0x38, (char)0xe9, (char)0x92, (char)0xf7, (char)0x16, (char)0xc2, (char)0xf3, (char)0x74, (char)0xa7, (char)0x92, (char)0xf5, (char)0x49, (char)0x7d, (char)0x09, (char)0x41, (char)0xbc, (char)0x07, (char)0x61, (char)0x1f, (char)0xe6, (char)0xa0, (char)0xd8, (char)0xa6, (char)0xe3, (char)0x72, (char)0xa4, (char)0x59, (char)0x4a, (char)0xd9, (char)0x33, (char)0x40, (char)0x80, (char)0x3a, (char)0x3a, (char)0xb3, (char)0xa0, (char)0x96, (char)0xca, (char)0x56, (char)0x98, (char)0xbd, (char)0x1f, (char)0x80, (char)0x86, (char)0x6c, (char)0xe1, (char)0x09, (char)0x64, (char)0x1b, (char)0x1a, (char)0xc9, (char)0x52, (char)0xaa, (char)0xd1, (char)0x39, (char)0xea, (char)0x4b, (char)0x6a, (char)0x3e, (char)0x4e, (char)0xa4, (char)0xea, (char)0x00, (char)0xde, (char)0x07, (char)0x0b, (char)0x23, (char)0xbc, (char)0x40, (char)0xc4, (char)0xd2, (char)0xd9, (char)0xf6, (char)0xda, (char)0x8e, (char)0x22, (char)0x36, (char)0xbe, (char)0x5e, (char)0x65, (char)0x6e, (char)0xbe, (char)0xc8, (char)0xb0, (char)0x07, (char)0xa2, (char)0x2d, (char)0xe9, (char)0x4b, (char)0x73, (char)0x54, (char)0xe6, (char)0x0a, (char)0xf2, (char)0xd3, (char)0x83, (char)0x8b, (char)0x27, (char)0x4c, (char)0xcc, (char)0x0c, (char)0x8a, (char)0xd4, (char)0x2b, (char)0xb8, (char)0x95, (char)0x2e, (char)0x42, (char)0x64, (char)0x29, (char)0xc1, (char)0xe0, (char)0x6b, (char)0x92, (char)0xab, (char)0xfe, (char)0x53, (char)0x06, (char)0x96, (char)0x4a, (char)0x8c, (char)0x5d, (char)0x7c, (char)0x51, (char)0x74, (char)0xd0, (char)0x1e, (char)0x37, (char)0x35, (char)0x9c, (char)0x1e, (char)0x69, (char)0x8f, (char)0x68, (char)0x18, (char)0xd9, (char)0xbe, (char)0xaf, (char)0x81, (char)0x9b, (char)0x7e, (char)0xd8, (char)0x71, (char)0x9d, (char)0xb6, (char)0x50, (char)0x43, (char)0x78, (char)0x85, (char)0x7d, (char)0x65, (char)0x93, (char)0x45, (char)0xb4, (char)0x02, (char)0xd0, (char)0x5c, (char)0x36, (char)0xe2, (char)0x62, (char)0x3f, (char)0x40, (char)0x33, (char)0xee, (char)0x91, (char)0xe5, (char)0x3f, (char)0x67, (char)0x39, (char)0x2f, (char)0x1b, (char)0x89, (char)0x9f, (char)0x04, (char)0x9d, (char)0x46, (char)0x3e, (char)0x70, (char)0x92, (char)0x9e, (char)0x8c, (char)0xf5 
        };
        char s0s1s2[] = {
            (char)0x03, (char)0xac, (char)0x44, (char)0x29, (char)0x53, (char)0x04, (char)0x05, (char)0x00, (char)0x01, (char)0x6e, (char)0x65, (char)0x69, (char)0x2d, (char)0x69, (char)0x2d, (char)0x69, (char)0x73, (char)0x6e, (char)0x69, (char)0x73, (char)0x6c, (char)0x65, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x69, (char)0x77, (char)0x74, (char)0x2e, (char)0x6e, (char)0x72, (char)0x76, (char)0x72, (char)0x65, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x69, (char)0x70, (char)0x72, (char)0x73, (char)0x6e, (char)0x65, (char)0x72, (char)0x72, (char)0x6e, (char)0x2d, (char)0x65, (char)0x74, (char)0x72, (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x69, (char)0x76, (char)0x77, (char)0x2d, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x76, (char)0x73, (char)0x72, (char)0x2e, (char)0x2d, (char)0x76, (char)0x65, (char)0x31, (char)0x65, (char)0x6d, (char)0x6d, (char)0x73, (char)0x69, (char)0x73, (char)0x74, (char)0x2e, (char)0x74, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x65, (char)0x2d, (char)0x74, (char)0x69, (char)0x31, (char)0x65, (char)0x2d, (char)0x6f, (char)0x77, (char)0x2e, (char)0x76, (char)0x77, (char)0x2d, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x31, (char)0x74, (char)0x73, (char)0x70, (char)0x74, (char)0x6e, (char)0x72, (char)0x6e, (char)0x73, (char)0x6d, (char)0x2e, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x69, (char)0x77, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x6c, (char)0x2e, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6c, (char)0x73, (char)0x65, (char)0x73, (char)0x70, (char)0x2d, (char)0x65, (char)0x72, (char)0x40, (char)0x72, (char)0x74, (char)0x6e, (char)0x6e, (char)0x6d, (char)0x6f, (char)0x70, (char)0x74, (char)0x73, (char)0x2d, (char)0x63, (char)0x69, (char)0x32, (char)0x31, (char)0x2d, (char)0x40, (char)0x69, (char)0x70, (char)0x2d, (char)0x2d, (char)0x72, (char)0x69, (char)0x74, (char)0x63, (char)0x6f, (char)0x69, (char)0x69, (char)0x65, (char)0x6e, (char)0x32, (char)0x6f, (char)0x6c, (char)0x6e, (char)0x72, (char)0x73, (char)0x77, (char)0x65, (char)0x65, (char)0x72, (char)0x32, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x72, (char)0x6e, (char)0x65, (char)0x6d, (char)0x31, (char)0x65, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x40, (char)0x70, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2d, (char)0x77, (char)0x63, (char)0x63, (char)0x74, (char)0x40, (char)0x36, (char)0x2d, (char)0x72, (char)0x65, (char)0x70, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x65, (char)0x74, (char)0x70, (char)0x76, (char)0x40, (char)0x76, (char)0x72, (char)0x72, (char)0x69, (char)0x77, (char)0x76, (char)0x69, (char)0x74, (char)0x74, (char)0x65, (char)0x31, (char)0x6d, (char)0x2e, (char)0x6f, (char)0x72, (char)0x73, (char)0x73, (char)0x6c, (char)0x40, (char)0x36, (char)0x72, (char)0x70, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x32, (char)0x6c, (char)0x77, (char)0x70, (char)0x76, (char)0x65, (char)0x72, (char)0x76, (char)0x63, (char)0x65, (char)0x65, (char)0x77, (char)0x72, (char)0x6e, (char)0x2e, (char)0x76, (char)0x69, (char)0x69, (char)0x2e, (char)0x40, (char)0x72, (char)0x2e, (char)0x2e, (char)0x72, (char)0x73, (char)0x6e, (char)0x72, (char)0x72, (char)0x6e, (char)0x70, (char)0x40, (char)0x77, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x63, (char)0x74, (char)0x2d, (char)0x70, (char)0x72, (char)0x2d, (char)0x74, (char)0x72, (char)0x31, (char)0x65, (char)0x6e, (char)0x2d, (char)0x76, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x74, (char)0x76, (char)0x2d, (char)0x74, (char)0x65, (char)0x2e, (char)0x2d, (char)0x6c, (char)0x76, (char)0x2d, (char)0x6c, (char)0x70, (char)0x73, (char)0x6d, (char)0x65, (char)0x72, (char)0x31, (char)0x31, (char)0x36, (char)0x76, (char)0x73, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6e, (char)0x73, (char)0x72, (char)0x2d, (char)0x6f, (char)0x6c, (char)0x65, (char)0x74, (char)0x77, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x65, (char)0x6d, (char)0x76, (char)0x31, (char)0x65, (char)0x73, (char)0x72, (char)0x6c, (char)0x72, (char)0x77, (char)0x65, (char)0x76, (char)0x74, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x32, (char)0x73, (char)0x6d, (char)0x72, (char)0x2d, (char)0x6d, (char)0x40, (char)0x69, (char)0x40, (char)0x69, (char)0x31, (char)0x69, (char)0x6f, (char)0x6e, (char)0x6d, (char)0x69, (char)0x73, (char)0x70, (char)0x72, (char)0x77, (char)0x6f, (char)0x6f, (char)0x65, (char)0x77, (char)0x76, (char)0x70, (char)0x70, (char)0x6c, (char)0x6f, (char)0x72, (char)0x65, (char)0x32, (char)0x36, (char)0x6c, (char)0x74, (char)0x6e, (char)0x72, (char)0x74, (char)0x2d, (char)0x6e, (char)0x6c, (char)0x72, (char)0x72, (char)0x2d, (char)0x74, (char)0x65, (char)0x73, (char)0x70, (char)0x65, (char)0x72, (char)0x6c, (char)0x65, (char)0x65, (char)0x2d, (char)0x6e, (char)0x70, (char)0x6e, (char)0x40, (char)0x65, (char)0x6e, (char)0x6e, (char)0x74, (char)0x65, (char)0x6e, (char)0x72, (char)0x6e, (char)0xfe, (char)0x5a, (char)0x38, (char)0x79, (char)0x81, (char)0xe8, (char)0x49, (char)0xee, (char)0x93, (char)0xbb, (char)0xa0, (char)0x59, (char)0x4a, (char)0xa0, (char)0xcc, (char)0x31, (char)0xbf, (char)0x0d, (char)0x86, (char)0xc0, (char)0x3f, (char)0xae, (char)0x2a, (char)0x16, (char)0xfa, (char)0xf0, (char)0x4e, (char)0x0f, (char)0xa3, (char)0x01, (char)0x06, (char)0xa0, (char)0x0e, (char)0xa5, (char)0x8c, (char)0xa4, (char)0xca, (char)0xd2, (char)0x01, (char)0xa5, (char)0x90, (char)0xbd, (char)0x55, (char)0xd1, (char)0x42, (char)0x2b, (char)0xd4, (char)0xb3, (char)0xbb, (char)0x06, (char)0xb1, (char)0x3a, (char)0x94, (char)0x41, (char)0x76, (char)0x1d, (char)0xa5, (char)0x23, (char)0x6e, (char)0x1e, (char)0x59, (char)0x73, (char)0x63, (char)0x34, (char)0x60, (char)0xd3, (char)0x48, (char)0xc0, (char)0x3b, (char)0xcf, (char)0xf1, (char)0xa8, (char)0x38, (char)0xd6, (char)0xf3, (char)0x5e, (char)0x6d, (char)0xcb, (char)0xea, (char)0xfc, (char)0x9c, (char)0x52, (char)0xae, (char)0x9a, (char)0x89, (char)0xdb, (char)0x24, (char)0x1b, (char)0x92, (char)0x4a, (char)0x85, (char)0x97, (char)0x3c, (char)0xd8, (char)0x4c, (char)0x31, (char)0xad, (char)0xfd, (char)0x00, (char)0xef, (char)0xc5, (char)0x17, (char)0xa5, (char)0x22, (char)0xc0, (char)0xf1, (char)0x94, (char)0x18, (char)0xec, (char)0xf6, (char)0x49, (char)0xe5, (char)0x05, (char)0x11, (char)0x12, (char)0x67, (char)0x6c, (char)0x71, (char)0xc0, (char)0x84, (char)0x6d, (char)0x50, (char)0xf8, (char)0x23, (char)0x01, (char)0x57, (char)0xc4, (char)0xfc, (char)0x73, (char)0x65, (char)0x69, (char)0x6e, (char)0x65, (char)0x72, (char)0x6d, (char)0x6f, (char)0x69, (char)0x2d, (char)0x65, (char)0x65, (char)0x69, (char)0x63, (char)0x63, (char)0x69, (char)0x2d, (char)0x72, (char)0x2d, (char)0x69, (char)0x2d, (char)0x2d, (char)0x77, (char)0x72, (char)0x76, (char)0x72, (char)0x72, (char)0x2d, (char)0x76, (char)0x70, (char)0x63, (char)0x69, (char)0x74, (char)0x73, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x73, (char)0x6c, (char)0x65, (char)0x6e, (char)0x73, (char)0x77, (char)0x69, (char)0x63, (char)0x69, (char)0x70, (char)0x31, (char)0x40, (char)0x72, (char)0x69, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x72, (char)0x63, (char)0x72, (char)0x77, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x72, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x6d, (char)0x76, (char)0x36, (char)0x6d, (char)0x72, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x76, (char)0x6d, (char)0x76, (char)0x74, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x72, (char)0x6e, (char)0x6d, (char)0x77, (char)0x6c, (char)0x40, (char)0x32, (char)0x70, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x31, (char)0x2e, (char)0x70, (char)0x36, (char)0x31, (char)0x65, (char)0x70, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x6e, (char)0x6e, (char)0x73, (char)0x32, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x69, (char)0x65, (char)0x31, (char)0x74, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x76, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6e, (char)0x70, (char)0x74, (char)0x73, (char)0x72, (char)0x6d, (char)0x72, (char)0x72, (char)0x69, (char)0x65, (char)0x74, (char)0x65, (char)0x65, (char)0x2d, (char)0x70, (char)0x74, (char)0x6e, (char)0x74, (char)0x65, (char)0x6f, (char)0x72, (char)0x69, (char)0x76, (char)0x40, (char)0x31, (char)0x69, (char)0x72, (char)0x6d, (char)0x6d, (char)0x77, (char)0x69, (char)0x72, (char)0x65, (char)0x6e, (char)0x40, (char)0x63, (char)0x40, (char)0x65, (char)0x65, (char)0x69, (char)0x2d, (char)0x72, (char)0x65, (char)0x40, (char)0x69, (char)0x32, (char)0x74, (char)0x73, (char)0x6e, (char)0x36, (char)0x2d, (char)0x70, (char)0x65, (char)0x6c, (char)0x70, (char)0x6e, (char)0x72, (char)0x69, (char)0x32, (char)0x65, (char)0x74, (char)0x76, (char)0x77, (char)0x73, (char)0x6f, (char)0x77, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x73, (char)0x65, (char)0x65, (char)0x70, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x2d, (char)0x65, (char)0x2e, (char)0x73, (char)0x69, (char)0x67, (char)0x45, (char)0x8b, (char)0x6b, (char)0x3b, (char)0xc9, (char)0x5f, (char)0x09, (char)0x65, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6d, (char)0x70, (char)0x70, (char)0x73, (char)0x63, (char)0x70, (char)0x40, (char)0x72, (char)0x76, (char)0x65, (char)0x6e, (char)0x6f, (char)0x6c, (char)0x69, (char)0x2e, (char)0x72, (char)0x73, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x65, (char)0x77, (char)0x73, (char)0x69, (char)0x70, (char)0x77, (char)0x63, (char)0x65, (char)0x74, (char)0x72, (char)0x73, (char)0x31, (char)0x65, (char)0x65, (char)0x72, (char)0x76, (char)0x69, (char)0x65, (char)0x77, (char)0x6d, (char)0x65, (char)0x36, (char)0x6e, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6e, (char)0x70, (char)0x77, (char)0x72, (char)0x65, (char)0x31, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x65, (char)0x2e, (char)0x77, (char)0x6e, (char)0x6f, (char)0x2d, (char)0x76, (char)0x65, (char)0x72, (char)0x6c, (char)0x31, (char)0x76, (char)0x65, (char)0x72, (char)0x2d, (char)0x36, (char)0x6c, (char)0x70, (char)0x6f, (char)0x65, (char)0x72, (char)0x73, (char)0x63, (char)0x72, (char)0x77, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x65, (char)0x6c, (char)0x76, (char)0x72, (char)0x65, (char)0x6e, (char)0x65, (char)0x2e, (char)0x6f, (char)0x2d, (char)0x72, (char)0x70, (char)0x65, (char)0x74, (char)0x72, 
            (char)0x77, (char)0x69, (char)0x69, (char)0x72, (char)0x65, (char)0x77, (char)0x6c, (char)0x72, (char)0x2d, (char)0x69, (char)0x72, (char)0x31, (char)0x6e, (char)0x65, (char)0x70, (char)0x72, (char)0x74, (char)0x76, (char)0x6c, (char)0x2e, (char)0x72, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6c, (char)0x2e, (char)0x2e, (char)0x72, (char)0x2d, (char)0x6e, (char)0x63, (char)0x32, (char)0x2e, (char)0x65, (char)0x2d, (char)0x65, (char)0x69, (char)0x2d, (char)0x65, (char)0x70, (char)0x6e, (char)0x72, (char)0x72, (char)0x32, (char)0x2e, (char)0x73, (char)0x70, (char)0x77, (char)0x65, (char)0x73, (char)0x77, (char)0x73, (char)0x40, (char)0x40, (char)0x73, (char)0x63, (char)0x2e, (char)0x65, (char)0x76, (char)0x70, (char)0x65, (char)0x69, (char)0x65, (char)0x70, (char)0x73, (char)0x40, (char)0x65, (char)0x73, (char)0x2d, (char)0x2d, (char)0x2e, (char)0x2e, (char)0x73, (char)0x65, (char)0x6f, (char)0x65, (char)0x65, (char)0x6d, (char)0x76, (char)0x70, (char)0x6d, (char)0x69, (char)0x70, (char)0x70, (char)0x69, (char)0x2e, (char)0x76, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x6d, (char)0x73, (char)0x6f, (char)0x73, (char)0x72, (char)0x72, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x72, (char)0x73, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x74, (char)0x65, (char)0x69, (char)0x40, (char)0x63, (char)0x69, (char)0x70, (char)0x6c, (char)0x6e, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x63, (char)0x6c, (char)0x72, (char)0x2e, (char)0x36, (char)0x69, (char)0x72, (char)0x6c, (char)0x6c, (char)0x2d, (char)0x6f, (char)0x76, (char)0x69, (char)0x6f, (char)0x2d, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x2e, (char)0x70, (char)0x73, (char)0x6d, (char)0x6f, (char)0x2e, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x2d, (char)0x6d, (char)0x76, (char)0x6e, (char)0x69, (char)0x73, (char)0x73, (char)0x73, (char)0x74, (char)0x63, (char)0x65, (char)0x76, (char)0x2e, (char)0x77, (char)0x2d, (char)0x36, (char)0x73, (char)0x69, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x36, (char)0x74, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x6d, (char)0x31, (char)0x72, (char)0x6f, (char)0x74, (char)0x76, (char)0x31, (char)0x65, (char)0x6d, (char)0x69, (char)0x72, (char)0x69, (char)0x69, (char)0x2d, (char)0x72, (char)0x73, (char)0x72, (char)0x72, (char)0x76, (char)0x31, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x77, (char)0x70, (char)0x69, (char)0x72, (char)0x6e, (char)0x76, (char)0x74, (char)0x6f, (char)0x65, (char)0x63, (char)0x6f, (char)0x73, (char)0x65, (char)0x73, (char)0x72, (char)0x69, (char)0x69, (char)0x40, (char)0x6e, (char)0x65, (char)0x65, (char)0x65, (char)0x65, (char)0x77, (char)0x70, (char)0x70, (char)0x6e, (char)0x72, (char)0x6e, (char)0x65, (char)0x72, (char)0x32, (char)0x65, (char)0x2d, (char)0x77, (char)0x69, (char)0x6e, (char)0x70, (char)0x69, (char)0x6f, (char)0x76, (char)0x77, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x72, (char)0xfe, (char)0x98, (char)0xf3, (char)0xb4, (char)0xff, (char)0x3f, (char)0x2e, (char)0xdb, (char)0x59, (char)0xbd, (char)0x32, (char)0x02, (char)0x6a, (char)0x44, (char)0x03, (char)0x67, (char)0x9e, (char)0xe1, (char)0x98, (char)0x97, (char)0xed, (char)0x67, (char)0x6d, (char)0xb0, (char)0x8f, (char)0xa9, (char)0xb6, (char)0xf8, (char)0x4d, (char)0x92, (char)0x35, (char)0x19, (char)0x72, (char)0x72, (char)0x65, (char)0x74, (char)0x73, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6e, (char)0x72, (char)0x65, (char)0x32, (char)0x72, (char)0x77, (char)0x72, (char)0x73, (char)0x77, (char)0x73, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6c, (char)0x70, (char)0x74, (char)0x65, (char)0x69, (char)0x72, (char)0x74, (char)0x6e, (char)0x76, (char)0x65, (char)0x76, (char)0x76, (char)0x69, (char)0x69, (char)0x65, (char)0x70, (char)0x6e, (char)0x73, (char)0x6e, (char)0x36, (char)0x76, (char)0x70, (char)0x76, (char)0x6c, (char)0x6c, (char)0x70, (char)0x6e, (char)0x6e, (char)0x74, (char)0x2e, (char)0x6f, (char)0x32, (char)0x74, (char)0x76, (char)0x74, (char)0x40, (char)0x72, (char)0x6e, (char)0x72, (char)0x74, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x73, (char)0x32, (char)0x72, (char)0x32, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x6e, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x69, (char)0x74, (char)0x74, (char)0x6e, (char)0x72, (char)0x6c, (char)0x31, (char)0x74, (char)0x77, (char)0x31, (char)0x63, (char)0x63, (char)0x74, (char)0x69, (char)0x72, (char)0x69, (char)0x72, (char)0x70, (char)0x31, (char)0x74, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x65, (char)0x6c, (char)0x76, (char)0x6d, (char)0x72, (char)0x6c, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x6f, (char)0x69, (char)0x6c, (char)0x74, (char)0x6e, (char)0x65, (char)0x69, (char)0x77, (char)0x73, (char)0x70, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x74, (char)0x2e, (char)0x65, (char)0x65, (char)0x6d, (char)0x72, (char)0x31, (char)0x2d, (char)0x72, (char)0x36, (char)0x65, (char)0x2d, (char)0x69, (char)0x6d, (char)0x36, (char)0x6e, (char)0x72, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x31, (char)0x6e, (char)0x40, (char)0x72, (char)0x40, (char)0x6f, (char)0x73, (char)0x6d, (char)0x36, (char)0x2e, (char)0x72, (char)0x65, (char)0x36, (char)0x74, (char)0x77, (char)0x65, (char)0x65, (char)0x73, (char)0x36, (char)0x76, (char)0x6c, (char)0x6f, (char)0x2d, (char)0x36, (char)0x6d, (char)0x36, (char)0x70, (char)0x32, (char)0x74, (char)0x6d, (char)0x65, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x74, (char)0x2d, (char)0x63, (char)0x2d, (char)0x6e, (char)0x32, (char)0x72, (char)0x63, (char)0x2d, (char)0x77, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x6e, (char)0x76, (char)0x6f, (char)0x72, (char)0x40, (char)0x65, (char)0x65, (char)0x6d, (char)0x77, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6e, (char)0x73, (char)0x76, (char)0x65, (char)0x69, (char)0x69, (char)0x72, (char)0x6f, (char)0x65, (char)0x70, (char)0x69, (char)0x6d, (char)0x76, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x74, (char)0x2d, (char)0x69, (char)0x65, (char)0x72, (char)0x69, (char)0x6f, (char)0x72, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x69, (char)0x2e, (char)0x77, (char)0x69, (char)0x70, (char)0x69, (char)0x6d, (char)0x36, (char)0x72, (char)0x76, (char)0x65, (char)0x76, (char)0x73, (char)0x6e, (char)0x72, (char)0x65, (char)0x2e, (char)0x76, (char)0x2d, (char)0x76, (char)0x6f, (char)0x2d, (char)0x65, (char)0x73, (char)0x72, (char)0x74, (char)0x36, (char)0x2d, (char)0x6f, (char)0x70, (char)0x73, (char)0x74, (char)0x74, (char)0x77, (char)0x6c, (char)0x2d, (char)0x65, (char)0x72, (char)0x6e, (char)0x65, (char)0x6c, (char)0x72, (char)0x32, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6f, (char)0x65, (char)0x36, (char)0x31, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x31, (char)0x74, (char)0x69, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x6e, (char)0x2d, (char)0x63, (char)0x40, (char)0x31, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x65, (char)0x70, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x73, (char)0x69, (char)0x65, (char)0x65, (char)0x6e, (char)0x2e, (char)0x63, (char)0x6c, (char)0x72, (char)0x65, (char)0x2d, (char)0x2e, (char)0x6d, (char)0x72, (char)0x76, (char)0x70, (char)0x69, (char)0x6d, (char)0x40, (char)0x32, (char)0x77, (char)0x72, (char)0x6e, (char)0x72, (char)0x6c, (char)0x36, (char)0x72, (char)0x31, (char)0x2d, (char)0x73, (char)0x74, (char)0x2d, (char)0x69, (char)0x63, (char)0x40, (char)0x70, (char)0x32, (char)0x65, (char)0x31, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x63, (char)0x74, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x65, (char)0x77, (char)0x69, (char)0x69, (char)0x73, (char)0x6e, (char)0x77, (char)0x77, (char)0x73, (char)0x6f, (char)0x69, (char)0x70, (char)0x73, (char)0x2d, (char)0x65, (char)0x65, (char)0x73, (char)0x65, (char)0x77, (char)0x2d, (char)0x73, (char)0x72, (char)0x6d, (char)0x65, (char)0x32, (char)0x6e, (char)0x73, (char)0x36, (char)0x65, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6f, (char)0x6f, (char)0x36, (char)0x63, (char)0x74, (char)0x72, (char)0x63, (char)0x77, (char)0x69, (char)0x2e, (char)0x31, (char)0x6c, (char)0x65, (char)0x77, (char)0x72, (char)0x65, (char)0x76, (char)0x74, (char)0x2d, (char)0x77, (char)0x2e, (char)0x76, (char)0x72, (char)0x6e, (char)0x36, (char)0x70, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x77, (char)0x69, (char)0x65, (char)0x74, (char)0x2d, (char)0x6e, (char)0x63, (char)0x6e, (char)0x70, (char)0x2d, (char)0x6e, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x63, (char)0x65, (char)0x2d, (char)0x76, (char)0x70, (char)0x73, (char)0x31, (char)0x73, (char)0x2d, (char)0x76, (char)0x6e, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x6c, (char)0x2d, (char)0x65, (char)0x6e, (char)0x73, (char)0x6c, (char)0x65, (char)0x74, (char)0x70, (char)0x65, (char)0x2d, (char)0x6e, (char)0x77, (char)0x76, (char)0x40, (char)0x69, (char)0x40, (char)0x63, (char)0x6f, (char)0x72, (char)0x32, (char)0x6d, (char)0x31, (char)0x72, (char)0x36, (char)0x69, (char)0x73, (char)0x72, (char)0x70, (char)0x65, (char)0x2d, (char)0x6c, (char)0x2e, (char)0x72, (char)0x74, (char)0x74, (char)0x65, (char)0x69, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x65, (char)0x6f, (char)0x65, (char)0x74, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6e, (char)0x31, (char)0x65, (char)0x76, (char)0x72, (char)0x73, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x65, (char)0x69, (char)0x70, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x72, (char)0x76, (char)0x72, (char)0x6c, (char)0x2e, (char)0x70, (char)0x76, (char)0x6e, (char)0x69, (char)0x72, (char)0x70, (char)0x73, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x72, (char)0x70, (char)0x65, (char)0x63, (char)0x72, (char)0x70, (char)0x6e, (char)0x36, (char)0x6c, (char)0x74, (char)0x72, (char)0x72, (char)0x72, (char)0x73, (char)0x65, (char)0x40, (char)0x63, (char)0x6d, (char)0x63, (char)0x32, (char)0x65, (char)0x32, (char)0x69, (char)0x6e, 
            (char)0x77, (char)0x65, (char)0x74, (char)0x72, (char)0x77, (char)0x40, (char)0x69, (char)0x65, (char)0x70, (char)0x31, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x72, (char)0x72, (char)0x32, (char)0x72, (char)0x6c, (char)0x77, (char)0x6e, (char)0x6f, (char)0x77, (char)0x6c, (char)0x74, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x70, (char)0x6c, (char)0x72, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x69, (char)0x36, (char)0x69, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6d, (char)0x72, (char)0x73, (char)0x6f, (char)0x6d, (char)0x74, (char)0x70, (char)0x76, (char)0x6d, (char)0x6d, (char)0x69, (char)0x72, (char)0x70, (char)0x70, (char)0x2d, (char)0x31, (char)0x63, (char)0x6c, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x77, (char)0x74, (char)0x73, (char)0x6c, (char)0x72, (char)0x6e, (char)0x65, (char)0x65, (char)0x2d, (char)0x6c, (char)0x69, (char)0x2d, (char)0x6e, (char)0x74, (char)0x70, (char)0x72, (char)0x77, (char)0x77, (char)0x65, (char)0x65, (char)0x65, (char)0x2d, (char)0x76, (char)0x6e, (char)0x72, (char)0x69, (char)0x69, (char)0x73, (char)0x65, (char)0x74, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x72, (char)0x69, (char)0x72, (char)0x73, (char)0x72, (char)0x6f, (char)0x2e, (char)0x77, (char)0x2d, (char)0x2d, (char)0x6c, (char)0x6e, (char)0x65, (char)0x65, (char)0x6d, (char)0x73, (char)0x2e, (char)0x72, (char)0x65, (char)0x73, (char)0x40, (char)0x69, (char)0x32, (char)0x69, (char)0x32, (char)0x6e, (char)0x65, (char)0x32, (char)0x65, (char)0x74, (char)0x6d, (char)0x65, (char)0x74, (char)0x36, (char)0x6e, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x69, (char)0x32, (char)0x6f, (char)0x70, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x72, (char)0x69, (char)0x6e, (char)0x6d, (char)0x69, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x31, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x76, (char)0x69, (char)0x6d, (char)0x65, (char)0x6c, (char)0x65, (char)0x31, (char)0x74, (char)0x74, (char)0x72, (char)0x63, (char)0x2e, (char)0x69, (char)0x65, (char)0x2d, (char)0x6d, (char)0x72, (char)0x70, (char)0x6e, (char)0x6c, (char)0x65, (char)0x31, (char)0x73, (char)0x73, (char)0x40, (char)0x74, (char)0x72, (char)0x73, (char)0x2e, (char)0x74, (char)0x6e, (char)0x77, (char)0x6c, (char)0x6f, (char)0x70, (char)0x77, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x77, (char)0x69, (char)0x6e, (char)0x69, (char)0x2d, (char)0x72, (char)0x70, (char)0x70, (char)0x73, (char)0x2e, (char)0x76, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x2d, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x36, (char)0x77, (char)0x77, (char)0x77, (char)0x40, (char)0x2d, (char)0x6d, (char)0x69, (char)0x74, (char)0x72, (char)0x2d, (char)0x32, (char)0x6f, (char)0x76, (char)0x72, (char)0x2d, (char)0x2d, (char)0x65, (char)0x2e, (char)0x2e, (char)0x72, (char)0x6e, (char)0x32, (char)0x74, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x2e, (char)0x6d, (char)0x2d, (char)0x6f, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x40, (char)0x69, (char)0x77, (char)0x65, (char)0x6c, (char)0x2d, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x72, (char)0x32, (char)0x40, (char)0x73, (char)0x65, (char)0x36, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x63, (char)0x77, (char)0x72, (char)0x6c, (char)0x72, (char)0x6e, (char)0x74, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x70, (char)0x6d, (char)0x65, (char)0x6c, (char)0x73, (char)0x65, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x70, (char)0x2d, (char)0x31, (char)0x72, (char)0x74, (char)0x2e, (char)0x65, (char)0x74, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x69, (char)0x40, (char)0x36, (char)0x2d, (char)0x74, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x6e, (char)0x6d, (char)0x63, (char)0x76, (char)0x74, (char)0x6d, (char)0x70, (char)0x32, (char)0x70, (char)0x69, (char)0x69, (char)0x2d, (char)0x73, (char)0x72, (char)0x74, (char)0x65, (char)0x74, (char)0x74, (char)0x70, (char)0x2d, (char)0x31, (char)0x6c, (char)0x77, (char)0x65, (char)0x72, (char)0x70, (char)0x73, (char)0x36, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x72, (char)0x36, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x40, (char)0x6c, (char)0x74, (char)0x6c, (char)0x72, (char)0x2d, (char)0x70, (char)0x74, (char)0x76, (char)0x74, (char)0x6f, (char)0x72, (char)0x31, (char)0x73, (char)0x70, (char)0x65, (char)0x74, (char)0x69, (char)0x6e, (char)0x69, (char)0x6c, (char)0x70, (char)0x72, (char)0x65, (char)0x70, (char)0x72, (char)0x73, (char)0x69, (char)0x2d, (char)0x6d, (char)0x63, (char)0x2d, (char)0x72, (char)0x2d, (char)0x36, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6d, (char)0x69, (char)0x76, (char)0x76, (char)0x6d, (char)0x74, (char)0x72, (char)0x77, (char)0x74, (char)0x2e, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2e, (char)0x6c, (char)0x73, (char)0x6e, (char)0x6f, (char)0x76, (char)0x31, (char)0x74, (char)0x65, (char)0x65, (char)0x31, (char)0x69, (char)0x65, (char)0x32, (char)0x2d, (char)0x74, (char)0x2d, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x32, (char)0x72, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x77, (char)0x77, (char)0x2e, (char)0x6e, (char)0x72, (char)0x65, (char)0x70, (char)0x76, (char)0x40, (char)0x77, (char)0x65, (char)0x2d, (char)0x70, (char)0x36, (char)0x2d, (char)0x74, (char)0x65, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x31, (char)0x36, (char)0x69, (char)0x31, (char)0x74, (char)0x76, (char)0x65, (char)0x77, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x32, (char)0x6e, (char)0x70, (char)0x73, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x6c, (char)0x32, (char)0x77, (char)0x72, (char)0x69, (char)0x70, (char)0x76, (char)0x32, (char)0x65, (char)0x6c, (char)0x36, (char)0x65, (char)0x69, (char)0x31, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6d, (char)0x65, (char)0x65, (char)0x77, (char)0x6e, (char)0x2d, (char)0x32, (char)0x77, (char)0x69, (char)0x65, (char)0x6d, (char)0x74, (char)0x77, (char)0x40, (char)0x65, (char)0x6e, (char)0x77, (char)0x73, (char)0x65, (char)0x72, (char)0x6c, (char)0x40, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x76, (char)0x72, (char)0x31, (char)0x2d, (char)0x65, (char)0x36, (char)0x72, (char)0x2d, (char)0x70, (char)0x69, (char)0x6e, (char)0x63, (char)0x31, (char)0x2d, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x77, (char)0x2d, (char)0x72, (char)0x76, (char)0x63, (char)0x69, (char)0x2d, (char)0x6d, (char)0x70, (char)0x2d, (char)0x6c, (char)0x69, (char)0x63, (char)0x69, (char)0x77, (char)0x6e, (char)0x69, (char)0x77, (char)0x36, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x74, (char)0x72, (char)0x6e, (char)0x65, (char)0x6f, (char)0x73, (char)0x2d, (char)0x2e, (char)0x72, (char)0x63, (char)0x76, (char)0x74, (char)0x36, (char)0x65, (char)0x72, (char)0x65, (char)0x6d, (char)0x32, (char)0x72, (char)0x70, (char)0x40, (char)0x65, (char)0x74, (char)0x6e, (char)0x32, (char)0x70, (char)0x2d, (char)0x31, (char)0x40, (char)0x6c, (char)0x65, (char)0x6c, (char)0x76, (char)0x69, (char)0x69, (char)0x76, (char)0x76, (char)0x73, (char)0x31, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x6d, (char)0x69, (char)0x2d, (char)0x72, (char)0x74, (char)0x74, (char)0x6c, (char)0x31, (char)0x74, (char)0x6e, (char)0x6e, (char)0x65, (char)0x77, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x6e, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x65, (char)0x72, (char)0x2d, (char)0x6c, (char)0x76, (char)0x77, (char)0x63, (char)0x77, (char)0x72, (char)0x6d, (char)0x72, (char)0x2e, (char)0x65, (char)0x73, (char)0x32, (char)0x72, (char)0x36, (char)0x77, (char)0x72, (char)0x72, (char)0x6d, (char)0x74, (char)0x2d, (char)0x72, (char)0x2e, (char)0x73, (char)0x73, (char)0x65, (char)0x77, (char)0x6e, (char)0x65, (char)0x69, (char)0x65, (char)0x2d, (char)0x65, (char)0x77, (char)0x6f, (char)0x74, (char)0x72, (char)0x32, (char)0x40, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x32, (char)0x70, (char)0x73, (char)0x72, (char)0x40, (char)0x2d, (char)0x65, (char)0x69, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x40, (char)0x36, (char)0x72, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x72, (char)0x72, (char)0x74, (char)0x36, (char)0x6c, (char)0x76, (char)0x65, (char)0x76, (char)0x2d, (char)0x74, (char)0x6c, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x69, (char)0x72, (char)0x6d, (char)0x40, (char)0x2d, (char)0x6e, (char)0x70, (char)0x73, (char)0x2d, (char)0x6d, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x36, (char)0x6e, (char)0x77, (char)0x2d, (char)0x69, (char)0x2d, (char)0x32, (char)0x72, (char)0x6d, (char)0x72, (char)0x6c, (char)0x32, (char)0x6c, (char)0x73, (char)0x6d, (char)0x65, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x77, (char)0x74, (char)0x6f, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x65, (char)0x73, (char)0x63, (char)0x65, (char)0x74, (char)0x74, (char)0x72, (char)0x65, (char)0x72, (char)0x2e, (char)0x6e, (char)0x73, (char)0x65, (char)0x76, (char)0x6c, (char)0x76, (char)0x77, (char)0x72, (char)0x6e, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x65, (char)0x73, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x77, (char)0x2d, (char)0x77, (char)0x70, (char)0x65, (char)0x6c, (char)0x72, (char)0x6e, (char)0x2e, (char)0x31, (char)0x73, (char)0x2e, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x6d, (char)0x32, (char)0x70, (char)0x76, (char)0x76, (char)0x31, (char)0x76, (char)0x77, (char)0x65, (char)0x6e, (char)0x73, (char)0x63, (char)0x2e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x77, (char)0x6e, (char)0x65, (char)0x6d, (char)0x2d, (char)0x72, (char)0x6e, (char)0x74, (char)0x6e, (char)0x40, (char)0x73, (char)0x2d, (char)0x74, (char)0x74, (char)0x65, (char)0x72, (char)0x2d, (char)0x2d, (char)0x69, (char)0x73, (char)0x70, 
            (char)0x69, (char)0x6c, (char)0x72, (char)0x76, (char)0x6d, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x65, (char)0x65, (char)0x72, (char)0x6f, (char)0x6e, (char)0x72, (char)0x72, (char)0x6c, (char)0x6e, (char)0x6e, (char)0x65, (char)0x6d, (char)0x74, (char)0x6c, (char)0x74, (char)0x65, (char)0x69, (char)0x2d, (char)0x6f, (char)0x69, (char)0x2e, (char)0x6e, (char)0x63, (char)0x65, (char)0x6c, (char)0x40, (char)0x70, (char)0x2d, (char)0x2d, (char)0x74, (char)0x73, (char)0x74, (char)0x40, (char)0x72, (char)0x74, (char)0x6c, (char)0x72, (char)0x6e, (char)0x6f, (char)0x73, (char)0x65, (char)0x74, (char)0x6d, (char)0x69, (char)0x32, (char)0x72, (char)0x65, (char)0x77, (char)0x6e, (char)0x76, (char)0x74, (char)0x73, (char)0x2d, (char)0x72, (char)0x6e, (char)0x69, (char)0x73, (char)0x40, (char)0x36, (char)0x2d, (char)0x6d, (char)0x2e, (char)0x65, (char)0x6d, (char)0x40, (char)0x69, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x72, (char)0x76, (char)0x6c, (char)0x65, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x65, (char)0x69, (char)0x6e, (char)0x72, (char)0x2d, (char)0x63, (char)0x72, (char)0x69, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x69, (char)0x70, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6c, (char)0x72, (char)0x2d, (char)0x65, (char)0x2d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6e, (char)0x76, (char)0x6e, (char)0x40, (char)0x2d, (char)0x65, (char)0x72, (char)0x72, (char)0x6f, (char)0x6f, (char)0x72, (char)0x6c, (char)0x65, (char)0x74, (char)0x73, (char)0x72, (char)0x70, (char)0x77, (char)0x69, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x65, (char)0x74, (char)0x6c, (char)0x2d, (char)0x74, (char)0x6f, (char)0x2d, (char)0x74, (char)0x70, (char)0x72, (char)0x6e, (char)0x73, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x32, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x77, (char)0x2d, (char)0x72, (char)0x6f, (char)0x70, (char)0x76, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x72, (char)0x36, (char)0x40, (char)0x6d, (char)0x72, (char)0x6c, (char)0x6d, (char)0x77, (char)0x6c, (char)0x6e, (char)0x69, (char)0x72, (char)0x6d, (char)0x76, (char)0x73, (char)0x2e, (char)0x73, (char)0x72, (char)0x77, (char)0x73, (char)0x76, (char)0x2d, (char)0x73, (char)0x76, (char)0x6d, (char)0x76, (char)0x65, (char)0x69, (char)0x76, (char)0x63, (char)0x65, (char)0x72, (char)0x31, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x73, (char)0x6d, (char)0x31, (char)0x72, (char)0x6e, (char)0x72, (char)0x2d, (char)0x2d, (char)0x36, (char)0x72, (char)0x73, (char)0x77, (char)0x2d, (char)0x77, (char)0x36, (char)0x76, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x72, (char)0x70, (char)0x2d, (char)0x74, (char)0x32, (char)0x6c, (char)0x63, (char)0x6d, (char)0x6f, (char)0x6e, (char)0x2e, (char)0x2d, (char)0x69, (char)0x65, (char)0x73, (char)0x6d, (char)0x65, (char)0x73, (char)0x6e, (char)0x6d, (char)0x6c, (char)0x65, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x32, (char)0x70, (char)0x65, (char)0x73, (char)0x6c, (char)0x6d, (char)0x70, (char)0x6d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6c, (char)0x76, (char)0x73, (char)0x63, (char)0x73, (char)0x65, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x2d, (char)0x70, (char)0x6d, (char)0x69, (char)0x69, (char)0x65, (char)0x2d, (char)0x6c, (char)0x72, (char)0x69, (char)0x6c, (char)0x2d, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x31, (char)0x72, (char)0x69, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x73, (char)0x65, (char)0x32, (char)0x2d, (char)0x6f, (char)0x2d, (char)0x70, (char)0x72, (char)0x6f, (char)0x65, (char)0x69, (char)0x73, (char)0x32, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x74, (char)0x6d, (char)0x6d, (char)0x73, (char)0x76, (char)0x6c, (char)0x69, (char)0x65, (char)0x2d, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x31, (char)0x2d, (char)0x76, (char)0x73, (char)0x2e, (char)0x2d, (char)0x2d, (char)0x72, (char)0x76, (char)0x77, (char)0x65, (char)0x72, (char)0x72, (char)0x40, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x72, (char)0x74, (char)0x73, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x6f, (char)0x74, (char)0x70, (char)0x63, (char)0xb8, (char)0xa1, (char)0x11, (char)0x6e, (char)0xd7, (char)0x74, (char)0x16, (char)0x7f, (char)0xb4, (char)0xba, (char)0x40, (char)0x93, (char)0x98, (char)0x00, (char)0x71, (char)0xcc, (char)0x42, (char)0xa7, (char)0x2f, (char)0x28, (char)0x69, (char)0xe7, (char)0x31, (char)0x48, (char)0x22, (char)0xa0, (char)0xe1, (char)0x45, (char)0xe3, (char)0xf7, (char)0x7f, (char)0x3a
        };
        char c2[] = {
            (char)0x5b, (char)0x52, (char)0xf1, (char)0x2d, (char)0x94, (char)0xcb, (char)0xb0, (char)0x86, (char)0xd8, (char)0xd3, (char)0xe3, (char)0x20, (char)0x88, (char)0x47, (char)0xcf, (char)0x5a, (char)0x49, (char)0xd2, (char)0x11, (char)0x30, (char)0x92, (char)0x17, (char)0x8d, (char)0xf4, (char)0x99, (char)0xf7, (char)0x6c, (char)0x8a, (char)0xbc, (char)0xe7, (char)0x5c, (char)0x58, (char)0x6a, (char)0x65, (char)0xed, (char)0x81, (char)0xdc, (char)0xdd, (char)0xcf, (char)0x83, (char)0xcd, (char)0xa4, (char)0xed, (char)0xa2, (char)0x5e, (char)0x63, (char)0xd9, (char)0x98, (char)0xf6, (char)0x2e, (char)0x15, (char)0x76, (char)0x9a, (char)0xc8, (char)0x8c, (char)0x42, (char)0x54, (char)0x44, (char)0xf4, (char)0x47, (char)0xf5, (char)0x96, (char)0xc9, (char)0x6e, (char)0x23, (char)0x09, (char)0x1a, (char)0x0d, (char)0xe3, (char)0x04, (char)0xe6, (char)0xed, (char)0x48, (char)0x49, (char)0x62, (char)0x31, (char)0xe8, (char)0x36, (char)0x04, (char)0xed, (char)0xb9, (char)0xe7, (char)0xa6, (char)0x35, (char)0x4d, (char)0xcd, (char)0xe3, (char)0xfa, (char)0xa0, (char)0xc8, (char)0x34, (char)0xbd, (char)0x62, (char)0x7b, (char)0xbc, (char)0xbe, (char)0x1c, (char)0x5b, (char)0x69, (char)0x1f, (char)0x9c, (char)0x30, (char)0x20, (char)0x48, (char)0x52, (char)0xd1, (char)0xb6, (char)0x5e, (char)0xa2, (char)0x6e, (char)0x06, (char)0x94, (char)0x72, (char)0x10, (char)0x56, (char)0x7c, (char)0x94, (char)0xa5, (char)0xc0, (char)0xaa, (char)0xea, (char)0x48, (char)0x61, (char)0x03, (char)0x14, (char)0x94, (char)0x09, (char)0x77, (char)0xd9, (char)0xa7, (char)0xfe, (char)0x78, (char)0x17, (char)0x95, (char)0x4f, (char)0x7e, (char)0xb0, (char)0x32, (char)0x63, (char)0x02, (char)0x17, (char)0x47, (char)0x1e, (char)0x7d, (char)0xb2, (char)0x7d, (char)0xb5, (char)0xcb, (char)0x9f, (char)0x61, (char)0x65, (char)0xed, (char)0x03, (char)0xd2, (char)0xdb, (char)0xd1, (char)0xb3, (char)0xd6, (char)0x1a, (char)0xf5, (char)0x67, (char)0x0b, (char)0x8b, (char)0x6b, (char)0x44, (char)0xf2, (char)0x62, (char)0x42, (char)0xc2, (char)0x4d, (char)0xe1, (char)0x5c, (char)0xfe, (char)0xc6, (char)0x19, (char)0x2b, (char)0xfb, (char)0x03, (char)0x0f, (char)0x1b, (char)0x89, (char)0x08, (char)0x86, (char)0x40, (char)0xca, (char)0x45, (char)0x15, (char)0xda, (char)0x65, (char)0xcc, (char)0x73, (char)0x00, (char)0x49, (char)0x4e, (char)0x48, (char)0x21, (char)0x25, (char)0xc6, (char)0xde, (char)0x26, (char)0x21, (char)0x1d, (char)0xea, (char)0x3c, (char)0x11, (char)0xac, (char)0xef, (char)0x34, (char)0x4c, (char)0x96, (char)0xcc, (char)0x5e, (char)0x26, (char)0xf3, (char)0xcd, (char)0x70, (char)0x0d, (char)0x62, (char)0xea, (char)0x09, (char)0x35, (char)0x2b, (char)0x1e, (char)0x60, (char)0xe4, (char)0x76, (char)0xd3, (char)0x65, (char)0x01, (char)0x8c, (char)0xab, (char)0xd4, (char)0x89, (char)0xad, (char)0x81, (char)0x9d, (char)0x04, (char)0x01, (char)0xd5, (char)0x55, (char)0x3c, (char)0xcb, (char)0x32, (char)0xe1, (char)0xb5, (char)0xd4, (char)0xda, (char)0xb4, (char)0xa9, (char)0x01, (char)0xb2, (char)0x10, (char)0xc7, (char)0xb1, (char)0xa9, (char)0x54, (char)0x66, (char)0x1d, (char)0xcc, (char)0xff, (char)0x54, (char)0x0b, (char)0x84, (char)0x37, (char)0xe0, (char)0x3a, (char)0xa5, (char)0x68, (char)0x80, (char)0x87, (char)0xbc, (char)0x3c, (char)0x0f, (char)0xda, (char)0x7e, (char)0x3c, (char)0x23, (char)0xfc, (char)0xd8, (char)0xc5, (char)0x52, (char)0xf7, (char)0x22, (char)0x12, (char)0x05, (char)0x9c, (char)0x68, (char)0x39, (char)0xb1, (char)0xed, (char)0x26, (char)0x24, (char)0x2b, (char)0x7e, (char)0x0b, (char)0xaf, (char)0x9e, (char)0x97, (char)0x45, (char)0x7b, (char)0xa9, (char)0xbc, (char)0x48, (char)0x0e, (char)0x66, (char)0x93, (char)0x32, (char)0x0d, (char)0x6b, (char)0xd6, (char)0xf0, (char)0x4f, (char)0x54, (char)0x18, (char)0xcd, (char)0xc9, (char)0x8c, (char)0xce, (char)0xc4, (char)0xa2, (char)0xff, (char)0x1e, (char)0x69, (char)0x17, (char)0x7e, (char)0xf4, (char)0x99, (char)0x09, (char)0x68, (char)0xa1, (char)0x9e, (char)0x1f, (char)0xbf, (char)0x90, (char)0xdc, (char)0x77, (char)0x5d, (char)0x50, (char)0x2b, (char)0x0e, (char)0xff, (char)0x96, (char)0xdc, (char)0x21, (char)0x2e, (char)0x74, (char)0x22, (char)0x28, (char)0x88, (char)0xa0, (char)0x00, (char)0x32, (char)0x15, (char)0xb0, (char)0xfd, (char)0xb1, (char)0xc9, (char)0x75, (char)0xb3, (char)0x3c, (char)0xbd, (char)0x89, (char)0xc5, (char)0xa4, (char)0x48, (char)0x17, (char)0xa9, (char)0xc9, (char)0x50, (char)0x61, (char)0x0c, (char)0x35, (char)0x31, (char)0x55, (char)0x11, (char)0xe3, (char)0x23, (char)0xe9, (char)0x3e, (char)0x78, (char)0x25, (char)0xdc, (char)0x50, (char)0xe8, (char)0x23, (char)0x5f, (char)0xb7, (char)0x3f, (char)0xc7, (char)0xae, (char)0xf0, (char)0x82, (char)0x35, (char)0x46, (char)0x34, (char)0x63, (char)0xcc, (char)0x5d, (char)0x96, (char)0xb8, (char)0x6a, (char)0x7a, (char)0x7f, (char)0x54, (char)0x27, (char)0x1a, (char)0xa4, (char)0x63, (char)0xdd, (char)0xb0, (char)0xb6, (char)0x17, (char)0x08, (char)0xa1, (char)0x2e, (char)0x95, (char)0x9e, (char)0xd4, (char)0x9b, (char)0x71, (char)0x83, (char)0x81, (char)0x6c, (char)0xea, (char)0xab, (char)0x00, (char)0x2e, (char)0xca, (char)0x60, (char)0xc1, (char)0x4b, (char)0x83, (char)0xa7, (char)0xab, (char)0x47, (char)0xe8, (char)0x1b, (char)0x5a, (char)0x78, (char)0x4f, (char)0xec, (char)0xbd, (char)0x62, (char)0x94, (char)0x25, (char)0x75, (char)0x2e, (char)0x64, (char)0xe7, (char)0x70, (char)0x13, (char)0xac, (char)0xe9, (char)0x89, (char)0x4f, (char)0x1e, (char)0x79, (char)0xbc, (char)0x15, (char)0x0c, (char)0x8d, (char)0x40, (char)0xe8, (char)0x16, (char)0x31, (char)0x7c, (char)0xb8, (char)0xa5, (char)0xd7, (char)0x21, (char)0x39, (char)0x93, (char)0x9b, (char)0xe6, (char)0x05, (char)0x81, (char)0xb6, (char)0x20, (char)0xa8, (char)0x5d, (char)0x73, (char)0x58, (char)0x8b, (char)0x66, (char)0x92, (char)0xac, (char)0x23, (char)0xa0, (char)0xf4, (char)0x8c, (char)0xab, (char)0x58, (char)0xae, (char)0xb6, (char)0x9c, (char)0x3c, (char)0x4d, (char)0x77, (char)0x5f, (char)0xae, (char)0xe2, (char)0x57, (char)0x89, (char)0x8f, (char)0xe4, (char)0x68, (char)0x81, (char)0x24, (char)0x7d, (char)0x3b, (char)0x99, (char)0x46, (char)0x9f, (char)0x7b, (char)0x9d, (char)0xa6, (char)0xdd, (char)0x99, (char)0xcf, (char)0xc1, (char)0x79, (char)0x04, (char)0x95, (char)0xce, (char)0x96, (char)0x7a, (char)0xd9, (char)0xb5, (char)0x6e, (char)0xcf, (char)0xd1, (char)0x72, (char)0x18, (char)0x97, (char)0x76, (char)0xe2, (char)0xb7, (char)0x38, (char)0x1e, (char)0x24, (char)0x0b, (char)0x09, (char)0x00, (char)0x8b, (char)0x28, (char)0x5d, (char)0xf8, (char)0xd0, (char)0x50, (char)0x7f, (char)0xeb, (char)0x3b, (char)0x37, (char)0x61, (char)0x0b, (char)0xd3, (char)0xff, (char)0x65, (char)0x7d, (char)0x88, (char)0x1e, (char)0x1d, (char)0xbb, (char)0x6c, (char)0xf5, (char)0xf8, (char)0xf3, (char)0x2b, (char)0x51, (char)0xd9, (char)0x6d, (char)0xc9, (char)0xbe, (char)0xbe, (char)0xd1, (char)0x94, (char)0x0e, (char)0x58, (char)0x2a, (char)0x0a, (char)0xe4, (char)0xf8, (char)0x28, (char)0x26, (char)0xc3, (char)0x74, (char)0x87, (char)0xd3, (char)0x81, (char)0x48, (char)0x6e, (char)0x9b, (char)0xd5, (char)0xa1, (char)0x60, (char)0x87, (char)0xfc, (char)0x1b, (char)0x06, (char)0x33, (char)0x0d, (char)0x87, (char)0xfa, (char)0x9b, (char)0xf9, (char)0x73, (char)0x6b, (char)0x0c, (char)0xdf, (char)0xea, (char)0xee, (char)0x32, (char)0x78, (char)0xe0, (char)0xf8, (char)0x18, (char)0x3f, (char)0xc3, (char)0x3b, (char)0x12, (char)0x88, (char)0x0b, (char)0xb2, (char)0x4a, (char)0x52, (char)0x64, (char)0x4e, (char)0x58, (char)0x54, (char)0x82, (char)0x52, (char)0x61, (char)0x54, (char)0x28, (char)0x1b, (char)0xf7, (char)0x99, (char)0x06, (char)0xa2, (char)0xad, (char)0x04, (char)0x19, (char)0x9f, (char)0x2e, (char)0x34, (char)0xe6, (char)0xf0, (char)0xee, (char)0xeb, (char)0x93, (char)0x9a, (char)0x9c, (char)0x73, (char)0x86, (char)0x23, (char)0x6d, (char)0x5d, (char)0xae, (char)0x64, (char)0xec, (char)0x6f, (char)0xf9, (char)0x7c, (char)0xc7, (char)0x46, (char)0x96, (char)0xdb, (char)0x44, (char)0xf4, (char)0xab, (char)0xc9, (char)0x67, (char)0x61, (char)0xb8, (char)0xec, (char)0xf0, (char)0x99, (char)0xe0, (char)0x4d, (char)0x45, (char)0xed, (char)0xa3, (char)0x1c, (char)0xe9, (char)0x68, (char)0x31, (char)0x85, (char)0xa5, (char)0xa1, (char)0xba, (char)0x08, (char)0xdb, (char)0x3f, (char)0x84, (char)0x75, (char)0x70, (char)0x24, (char)0xcd, (char)0x49, (char)0xd4, (char)0x07, (char)0xa8, (char)0xaa, (char)0x52, (char)0xd9, (char)0x55, (char)0x68, (char)0x8f, (char)0x78, (char)0xd2, (char)0x5d, (char)0x46, (char)0x23, (char)0x60, (char)0x76, (char)0xe1, (char)0x22, (char)0xdc, (char)0x2a, (char)0xeb, (char)0xac, (char)0xbc, (char)0xeb, (char)0xd6, (char)0x4c, (char)0x0f, (char)0xb5, (char)0xcb, (char)0x47, (char)0xce, (char)0x43, (char)0x59, (char)0x1d, (char)0x3e, (char)0xfc, (char)0x7f, (char)0x7c, (char)0x93, (char)0x9e, (char)0xef, (char)0xcd, (char)0x79, (char)0x5c, (char)0x08, (char)0x8e, (char)0xeb, (char)0xa8, (char)0x98, (char)0x3e, (char)0x95, (char)0xd1, (char)0x36, (char)0x42, (char)0x57, (char)0xfd, (char)0x6d, (char)0xdc, (char)0xe0, (char)0xa3, (char)0x3f, (char)0x46, (char)0x32, (char)0xb7, (char)0xff, (char)0x00, (char)0x4f, (char)0x7b, (char)0x23, (char)0x4d, (char)0xd0, (char)0xe5, (char)0xdd, (char)0x40, (char)0xab, (char)0xb2, (char)0xcb, (char)0x45, (char)0x92, (char)0x76, (char)0x7c, (char)0x5b, (char)0x98, (char)0xc7, (char)0xc0, (char)0x54, (char)0x34, (char)0x94, (char)0x8e, (char)0xbb, (char)0x28, (char)0xcf, (char)0xba, (char)0xd9, (char)0xa0, (char)0xe6, (char)0xf3, (char)0x65, (char)0x61, (char)0xd7, (char)0x10, (char)0xd3, (char)0xeb, (char)0xce, (char)0x21, (char)0x6a, (char)0xca, (char)0x61, (char)0xe7, (char)0x81, (char)0x15, (char)0x18, (char)0x4e, (char)0x71, (char)0xb0, (char)0x99, (char)0x62, (char)0xd9, (char)0xeb, (char)0xd0, (char)0x8b, (char)0xe9, (char)0xdf, (char)0x6a, (char)0x6d, (char)0x59, (char)0x0b, (char)0x45, (char)0x93, (char)0x38, (char)0xfe, (char)0xe6, (char)0x6a, (char)0xd1, (char)0x5f, (char)0xb6, (char)0xe9, (char)0x86, (char)0x01, (char)0x38, (char)0xab, (char)0x59, (char)0x5c, (char)0xd7, (char)0xb7, (char)0xfa, (char)0x81, (char)0x8a, (char)0xbe, (char)0xdc, (char)0xeb, (char)0x50, (char)0x7d, (char)0x81, (char)0xfa, (char)0x1b, (char)0x8f, (char)0xce, (char)0x53, (char)0x38, (char)0xe4, (char)0x8a, (char)0x82, (char)0xbe, (char)0x7d, (char)0xdc, (char)0xd8, (char)0x57, (char)0x5a, (char)0x48, (char)0xa3, (char)0x38, (char)0x74, (char)0x8a, (char)0xac, (char)0xf2, (char)0xfd, (char)0xbf, (char)0xcc, (char)0xd8, (char)0x08, (char)0x4d, (char)0x3e, (char)0xae, (char)0xa9, (char)0x00, (char)0x66, (char)0x06, (char)0xcb, (char)0xf3, 
            (char)0x50, (char)0xcc, (char)0x52, (char)0xc7, (char)0x4b, (char)0x16, (char)0x33, (char)0xa5, (char)0xde, (char)0x20, (char)0xed, (char)0x6a, (char)0xa7, (char)0x58, (char)0x5e, (char)0x4e, (char)0x7e, (char)0x29, (char)0xab, (char)0xb9, (char)0x65, (char)0x9d, (char)0x17, (char)0xe0, (char)0x1e, (char)0x79, (char)0x77, (char)0xf6, (char)0x1e, (char)0xa0, (char)0xcb, (char)0x0c, (char)0xf7, (char)0xc0, (char)0xe4, (char)0xf6, (char)0x3b, (char)0x60, (char)0x81, (char)0xfe, (char)0xed, (char)0xd9, (char)0x42, (char)0xa9, (char)0x61, (char)0x9d, (char)0xa8, (char)0xd7, (char)0xe8, (char)0xaa, (char)0x97, (char)0xad, (char)0xbb, (char)0xba, (char)0x13, (char)0x6e, (char)0x05, (char)0xa5, (char)0xce, (char)0x7a, (char)0x65, (char)0x6f, (char)0x55, (char)0xe3, (char)0xcf, (char)0xbc, (char)0x67, (char)0x14, (char)0x64, (char)0x57, (char)0x9c, (char)0x46, (char)0x14, (char)0xd6, (char)0x1d, (char)0x39, (char)0x1c, (char)0xd3, (char)0xe8, (char)0x98, (char)0x20, (char)0x5a, (char)0x1a, (char)0x05, (char)0x3b, (char)0x27, (char)0xd5, (char)0x84, (char)0xca, (char)0xd4, (char)0x0b, (char)0xc4, (char)0x1e, (char)0xd8, (char)0x46, (char)0x29, (char)0x48, (char)0x95, (char)0xdb, (char)0xe5, (char)0x58, (char)0x8a, (char)0x51, (char)0xc7, (char)0x74, (char)0x7f, (char)0x53, (char)0xa8, (char)0xbb, (char)0x58, (char)0xc0, (char)0x5b, (char)0xe1, (char)0xa7, (char)0x27, (char)0x36, (char)0x6c, (char)0xa6, (char)0x70, (char)0xec, (char)0x88, (char)0xcd, (char)0x9a, (char)0x70, (char)0xe1, (char)0xa0, (char)0xc7, (char)0xdd, (char)0x60, (char)0x71, (char)0xf4, (char)0x2a, (char)0x51, (char)0x98, (char)0x8e, (char)0xab, (char)0xb8, (char)0x13, (char)0x03, (char)0x48, (char)0x5f, (char)0x44, (char)0xf8, (char)0x88, (char)0xd9, (char)0x7d, (char)0xd3, (char)0xf1, (char)0x5f, (char)0xc4, (char)0x2b, (char)0x44, (char)0x15, (char)0x57, (char)0x31, (char)0xa4, (char)0xa1, (char)0xdb, (char)0x6d, (char)0x2a, (char)0x5a, (char)0x5a, (char)0xf7, (char)0xde, (char)0xd5, (char)0x23, (char)0x38, (char)0x00, (char)0xe5, (char)0x5c, (char)0x55, (char)0xe7, (char)0x37, (char)0x9c, (char)0xcb, (char)0x8b, (char)0xc0, (char)0x33, (char)0x42, (char)0x68, (char)0x23, (char)0x84, (char)0x7d, (char)0x89, (char)0x9d, (char)0xae, (char)0x59, (char)0x18, (char)0xae, (char)0xea, (char)0x46, (char)0x3f, (char)0xac, (char)0x57, (char)0x0d, (char)0x5d, (char)0x49, (char)0x14, (char)0x50, (char)0xe5, (char)0x70, (char)0x17, (char)0x73, (char)0x09, (char)0x11, (char)0x93, (char)0x6b, (char)0x02, (char)0x22, (char)0xb7, (char)0x63, (char)0xc9, (char)0xe6, (char)0xa4, (char)0xe3, (char)0xb1, (char)0xf7, (char)0xa6, (char)0x58, (char)0x8d, (char)0x14, (char)0xa1, (char)0xda, (char)0x6a, (char)0xb9, (char)0x38, (char)0xf9, (char)0x20, (char)0x45, (char)0x8c, (char)0xe6, (char)0x32, (char)0x23, (char)0x9d, (char)0x5f, (char)0xba, (char)0xcb, (char)0xb4, (char)0x95, (char)0xf9, (char)0xa9, (char)0x5c, (char)0x60, (char)0x03, (char)0x5a, (char)0x8c, (char)0xa7, (char)0xb9, (char)0x65, (char)0xa8, (char)0x84, (char)0x38, (char)0xc0, (char)0x25, (char)0xe6, (char)0xa7, (char)0xc0, (char)0x3b, (char)0xbc, (char)0x11, (char)0xed, (char)0x0e, (char)0x9a, (char)0x6f, (char)0xfe, (char)0x61, (char)0x79, (char)0x86, (char)0x92, (char)0x3a, (char)0xce, (char)0xe0, (char)0xb7, (char)0x70, (char)0xad, (char)0xe0, (char)0xcc, (char)0x88, (char)0x47, (char)0xd9, (char)0x2a, (char)0x3d, (char)0x41, (char)0x06, (char)0x77, (char)0x41, (char)0xbe, (char)0x3f, (char)0x55, (char)0x31, (char)0x54, (char)0x10, (char)0x14, (char)0x5b, (char)0xdf, (char)0x88, (char)0xb2, (char)0x9f, (char)0xff, (char)0x11, (char)0xb8, (char)0x11, (char)0xdc, (char)0x5e, (char)0x64, (char)0xf9, (char)0x97, (char)0x8a, (char)0x26, (char)0x6a, (char)0x44, (char)0xb4, (char)0x83, (char)0x83, (char)0x9b, (char)0x81, (char)0xaa, (char)0xfd, (char)0xb5, (char)0x8b, (char)0x16, (char)0x18, (char)0x2e, (char)0x5c, (char)0xe4, (char)0x5b, (char)0x8f, (char)0xdd, (char)0x7c, (char)0x1f, (char)0x33, (char)0x2f, (char)0xef, (char)0x57, (char)0x8c, (char)0x6a, (char)0x3f, (char)0x3c, (char)0x19, (char)0x5e, (char)0x73, (char)0x64, (char)0xc5, (char)0xaf, (char)0x1d, (char)0xa1, (char)0xb4, (char)0x11, (char)0xee, (char)0x6b, (char)0x7e, (char)0x66, (char)0xfb, (char)0xaa, (char)0x03, (char)0x17, (char)0xe4, (char)0xc9, (char)0x90, (char)0x4b, (char)0xf2, (char)0x50, (char)0x55, (char)0x71, (char)0xad, (char)0x31, (char)0x71, (char)0x49, (char)0xd7, (char)0x80, (char)0xd1, (char)0xa5, (char)0x9f, (char)0x6d, (char)0x71, (char)0x28, (char)0x2b, (char)0x65, (char)0xcf, (char)0x8d, (char)0xb1, (char)0x2a, (char)0x33, (char)0xdc, (char)0x93, (char)0xff, (char)0x86, (char)0xd7, (char)0xa6, (char)0xd0, (char)0x46, (char)0x66, (char)0x32, (char)0x3d, (char)0x18, (char)0x8c, (char)0xd3, (char)0xda, (char)0xf6, (char)0x1b, (char)0xa0, (char)0x2d, (char)0x29, (char)0xfd, (char)0x8d, (char)0x57, (char)0x2c, (char)0x82, (char)0xed, (char)0x38, (char)0x4a, (char)0x6f, (char)0xc4, (char)0x3c, (char)0x9a, (char)0x61, (char)0xcb, (char)0xe5, (char)0xcf, (char)0xd3, (char)0x83, (char)0xa1, (char)0x91, (char)0x93, (char)0x0d, (char)0x75, (char)0xfd, (char)0x4e, (char)0x2c, (char)0x83, (char)0xa0, (char)0x85, (char)0x27, (char)0x13, (char)0x5a, (char)0x24, (char)0xbd, (char)0x08, (char)0x1e, (char)0xe9, (char)0xab, (char)0x92, (char)0x41, (char)0xc2, (char)0x3a, (char)0xa0, (char)0xe1, (char)0xfd, (char)0x00, (char)0xb9, (char)0xf8, (char)0xca, (char)0x0b, (char)0x1a, (char)0x8e, (char)0xf6, (char)0x27, (char)0x9f, (char)0x5a, (char)0xf0, (char)0x23, (char)0x07, (char)0xc8, (char)0xbf, (char)0xf6, (char)0x74, (char)0xe7, (char)0xf8, (char)0x67, (char)0xfc, (char)0x28, (char)0x4e, (char)0x6a, (char)0x6c, (char)0xc6, (char)0x83, (char)0xe3, (char)0xf0, (char)0x01, (char)0xe0, (char)0x0f, (char)0x2d, (char)0xdf, (char)0x9e, (char)0x4b, (char)0x8b, (char)0x06, (char)0x15, (char)0x4c, (char)0x9f, (char)0xdf, (char)0x55, (char)0x14, (char)0x44, (char)0xde, (char)0x34, (char)0x35, (char)0x5a, (char)0xcb, (char)0xe5, (char)0xa7, (char)0xb5, (char)0x7e, (char)0x00, (char)0x31, (char)0x98, (char)0x5f, (char)0x51, (char)0x11, (char)0x37, (char)0xe1, (char)0xd2, (char)0x99, (char)0x8f, (char)0x70, (char)0x13, (char)0x40, (char)0xa0, (char)0xbe, (char)0xf8, (char)0xde, (char)0xac, (char)0x37, (char)0x06, (char)0xb6, (char)0x26, (char)0xf3, (char)0xb1, (char)0x97, (char)0x0b, (char)0x85, (char)0x68, (char)0x09, (char)0xa4, (char)0xc8, (char)0x34, (char)0x0a, (char)0x41, (char)0x6e, (char)0xac, (char)0x1a, (char)0x5b, (char)0xe0, (char)0x91, (char)0x6f, (char)0xa3, (char)0x0a, (char)0xf6, (char)0x05, (char)0x37, (char)0x32, (char)0xe1, (char)0x8e, (char)0xd8, (char)0xed, (char)0x55, (char)0xa3, (char)0x54, (char)0x3f, (char)0x62, (char)0x95, (char)0x82, (char)0xcf, (char)0x0a, (char)0x19, (char)0xb4, (char)0x9f, (char)0x04, (char)0xcc, (char)0x86, (char)0x7e, (char)0xf1, (char)0xe5, (char)0x8b, (char)0x67, (char)0x73, (char)0xa2, (char)0x46, (char)0x4e, (char)0xf2, (char)0x98, (char)0x94, (char)0xb5, (char)0xeb, (char)0xa5, (char)0xbd, (char)0xcb, (char)0x66, (char)0x82, (char)0xe9, (char)0x87, (char)0xe9, (char)0xe3, (char)0x50, (char)0x55, (char)0x4b, (char)0xd6, (char)0x67, (char)0x30, (char)0xe1, (char)0x7c, (char)0x15, (char)0x77, (char)0x29, (char)0xfd, (char)0x85, (char)0x67, (char)0x5a, (char)0xc4, (char)0xd5, (char)0x69, (char)0xfa, (char)0xc7, (char)0x66, (char)0x66, (char)0x49, (char)0xf7, (char)0x5a, (char)0xcd, (char)0xd1, (char)0x81, (char)0x5c, (char)0x74, (char)0x8d, (char)0xbf, (char)0xc5, (char)0xc2, (char)0xff, (char)0x4d, (char)0x90, (char)0xe8, (char)0x8e, (char)0x05, (char)0x00, (char)0xff, (char)0x7a, (char)0xd7, (char)0xb2, (char)0x7a, (char)0xad, (char)0x8b, (char)0xd6, (char)0x4b, (char)0x52, (char)0x09, (char)0x50, (char)0x4b
        };
        
        ASSERT_EQ(ERROR_SUCCESS, bytes.create_c0c1());
        memcpy(bytes.c0c1, c0c1, 1537);
        ASSERT_EQ(ERROR_SUCCESS, bytes.create_s0s1s2());
        memcpy(bytes.s0s1s2, s0s1s2, 3073);
        ASSERT_EQ(ERROR_SUCCESS, bytes.create_c2());
        memcpy(bytes.c2, c2, 1536);
    }
    
    SrsHandshakeBytes* hs_bytes = &bytes;
    
    if (true) {
        bool is_valid;
        
        c1s1 c1;
        ASSERT_EQ(ERROR_SUCCESS, c1.parse(hs_bytes->c0c1 + 1, srs_schema0));
        ASSERT_EQ(ERROR_SUCCESS, c1.c1_validate_digest(is_valid));
        ASSERT_TRUE(is_valid);
        
        c1s1 s1;
        ASSERT_EQ(ERROR_SUCCESS, s1.parse(hs_bytes->s0s1s2 + 1, c1.schema));
        ASSERT_EQ(ERROR_SUCCESS, s1.s1_validate_digest(is_valid));
        ASSERT_TRUE(is_valid);
        
        c2s2 c2;
        c2.parse(hs_bytes->c2);
        ASSERT_EQ(ERROR_SUCCESS, c2.c2_validate(&s1, is_valid));
        ASSERT_TRUE(is_valid);
        
        c2s2 s2;
        s2.parse(hs_bytes->s0s1s2 + 1 + 1536);
        ASSERT_EQ(ERROR_SUCCESS, s2.s2_validate(&c1, is_valid));
        ASSERT_TRUE(is_valid);
    }
}

#endif

VOID TEST(ProtocolHandshakeTest, SimpleHandshake)
{
    char c0c1[] = {
        (char)0x03, (char)0x01, (char)0x14, (char)0xf7, (char)0x4e, (char)0x80, (char)0x00, (char)0x07, (char)0x02, (char)0xac, (char)0x14, (char)0x98, (char)0x57, (char)0x0a, (char)0x07, (char)0x58, (char)0x44, (char)0x96, (char)0x47, (char)0xb5, (char)0x9a, (char)0x73, (char)0xf6, (char)0x07, (char)0x0f, (char)0x49, (char)0x0d, (char)0x72, (char)0xb8, (char)0x16, (char)0xbb, (char)0xb2, (char)0xb7, (char)0x61, (char)0x17, (char)0x79, (char)0xa0, (char)0xe9, (char)0x98, (char)0xca, (char)0xb2, (char)0x86, (char)0x64, (char)0x5f, (char)0x65, (char)0x3e, (char)0xfc, (char)0x4d, (char)0xc0, (char)0x0e, (char)0x4c, (char)0xfa, (char)0x91, (char)0xc7, (char)0x0f, (char)0x2e, (char)0x57, (char)0x31, (char)0x4b, (char)0x96, (char)0xef, (char)0xc9, (char)0x81, (char)0x02, (char)0x00, (char)0x54, (char)0x25, (char)0x2b, (char)0xb2, (char)0x0d, (char)0x7c, (char)0xee, (char)0xba, (char)0xdb, (char)0xe4, (char)0x06, (char)0x78, (char)0xcd, (char)0x70, (char)0x2c, (char)0x54, (char)0x5a, (char)0x3a, (char)0x03, (char)0x13, (char)0x2e, (char)0xe7, (char)0x4b, (char)0x87, (char)0x40, (char)0x77, (char)0x0b, (char)0x9f, (char)0xd2, (char)0xab, (char)0x32, (char)0x07, (char)0x6f, (char)0x1e, (char)0x75, (char)0x74, (char)0xe9, (char)0xc7, (char)0x44, (char)0xd9, (char)0x76, (char)0x53, (char)0xba, (char)0xe2, (char)0x52, (char)0xfa, (char)0xcc, (char)0xef, (char)0x34, (char)0xd5, (char)0x14, (char)0x61, (char)0xac, (char)0xcc, (char)0x63, (char)0xfd, (char)0x2b, (char)0x2d, (char)0xb3, (char)0xb8, (char)0xdd, (char)0x8a, (char)0x51, (char)0x9a, (char)0x2d, (char)0x0e, (char)0xfa, (char)0x84, (char)0x25, (char)0x55, (char)0xb2, (char)0xb7, (char)0x94, (char)0x54, (char)0x68, (char)0xfb, (char)0x94, (char)0xdf, (char)0xd8, (char)0xeb, (char)0x43, (char)0xd0, (char)0x11, (char)0x70, (char)0x8f, (char)0xf5, (char)0x48, (char)0xfc, (char)0x69, (char)0x4d, (char)0x5b, (char)0xc6, (char)0x53, (char)0x8a, (char)0x22, (char)0xea, (char)0x62, (char)0x84, (char)0x89, (char)0x6b, (char)0xfe, (char)0x4e, (char)0xab, (char)0x51, (char)0x98, (char)0xf4, (char)0x4f, (char)0xae, (char)0xf8, (char)0xdf, (char)0xac, (char)0x43, (char)0xed, (char)0x5a, (char)0x04, (char)0x97, (char)0xc4, (char)0xbe, (char)0x44, (char)0x5b, (char)0x99, (char)0x20, (char)0x68, (char)0x67, (char)0x0f, (char)0xe3, (char)0xfa, (char)0x4c, (char)0x9d, (char)0xe7, (char)0x0b, (char)0x3f, (char)0x80, (char)0x7c, (char)0x4c, (char)0x35, (char)0xf6, (char)0xdd, (char)0x20, (char)0x05, (char)0xfd, (char)0x0f, (char)0x39, (char)0xb7, (char)0x36, (char)0x45, (char)0x4c, (char)0xb7, (char)0x62, (char)0x92, (char)0x35, (char)0x2a, (char)0xcd, (char)0xb9, (char)0x49, (char)0xea, (char)0x12, (char)0x0b, (char)0x5f, (char)0x39, (char)0xae, (char)0x3b, (char)0x49, (char)0x29, (char)0xe6, (char)0x30, (char)0xc7, (char)0x7c, (char)0x77, (char)0xaf, (char)0x00, (char)0x43, (char)0x4d, (char)0x06, (char)0x45, (char)0x72, (char)0x73, (char)0x25, (char)0x71, (char)0x5e, (char)0x35, (char)0x04, (char)0xbd, (char)0xe9, (char)0x48, (char)0x23, (char)0x64, (char)0x4d, (char)0x15, (char)0x0b, (char)0xc5, (char)0x3f, (char)0x6e, (char)0x3a, (char)0xd5, (char)0xd5, (char)0xa6, (char)0xae, (char)0x3b, (char)0x4c, (char)0x66, (char)0x6a, (char)0x70, (char)0x8b, (char)0xf3, (char)0x6a, (char)0x43, (char)0xc4, (char)0xb9, (char)0xbd, (char)0xa0, (char)0x09, (char)0x72, (char)0xbc, (char)0xce, (char)0x7a, (char)0xea, (char)0x49, (char)0xf2, (char)0x86, (char)0xa7, (char)0xd8, (char)0x4a, (char)0x87, (char)0x28, (char)0xca, (char)0x2c, (char)0x53, (char)0xee, (char)0x96, (char)0x0b, (char)0xbe, (char)0x15, (char)0x14, (char)0xa8, (char)0x00, (char)0xca, (char)0x76, (char)0x08, (char)0x4d, (char)0x0f, (char)0xef, (char)0x78, (char)0x4b, (char)0xf6, (char)0x47, (char)0x60, (char)0xfc, (char)0x16, (char)0x00, (char)0x7c, (char)0x6b, (char)0x49, (char)0x39, (char)0x64, (char)0x36, (char)0xee, (char)0x45, (char)0x3a, (char)0x9a, (char)0xa5, (char)0xbf, (char)0xfb, (char)0x7b, (char)0xe7, (char)0xcf, (char)0x42, (char)0x82, (char)0x48, (char)0x1b, (char)0x30, (char)0xfe, (char)0x0d, (char)0xba, (char)0x10, (char)0xb8, (char)0xe1, (char)0x40, (char)0xcc, (char)0x6f, (char)0x36, (char)0x1c, (char)0x94, (char)0x5d, (char)0x50, (char)0x9e, (char)0x21, (char)0x08, (char)0xc9, (char)0xd5, (char)0xb0, (char)0x32, (char)0x51, (char)0x6a, (char)0x8f, (char)0xfa, (char)0x57, (char)0x8d, (char)0x45, (char)0xd7, (char)0xd2, (char)0xd0, (char)0xd6, (char)0x6c, (char)0x78, (char)0x95, (char)0xe9, (char)0xe1, (char)0x20, (char)0x97, (char)0x1a, (char)0x43, (char)0x40, (char)0xa3, (char)0xb5, (char)0xcc, (char)0x4b, (char)0x12, (char)0x84, (char)0x1e, (char)0x0e, (char)0xd3, (char)0x32, (char)0xca, (char)0x99, (char)0xc3, (char)0x2b, (char)0x78, (char)0x17, (char)0x24, (char)0x6b, (char)0xc7, (char)0xbc, (char)0x9d, (char)0x05, (char)0xc6, (char)0xaf, (char)0x8f, (char)0x19, (char)0x75, (char)0x3c, (char)0x08, (char)0xa6, (char)0x08, (char)0x26, (char)0x5b, (char)0xf4, (char)0x10, (char)0x40, (char)0xaa, (char)0x6a, (char)0x7e, (char)0xb9, (char)0xde, (char)0x0b, (char)0x23, (char)0x3f, (char)0x53, (char)0x5a, (char)0x20, (char)0x13, (char)0x62, (char)0xec, (char)0x53, (char)0x86, (char)0x81, (char)0x1f, (char)0xf6, (char)0x8e, (char)0xe3, (char)0xd1, (char)0xaa, (char)0xb5, (char)0x41, (char)0x87, (char)0x62, (char)0xd2, (char)0xb7, (char)0x09, (char)0x12, (char)0x71, (char)0x01, (char)0x2c, (char)0xac, (char)0x6d, (char)0x9d, (char)0x37, (char)0x46, (char)0x5b, (char)0xdc, (char)0x76, (char)0x2c, (char)0x96, (char)0x61, (char)0x88, (char)0x55, (char)0x5a, (char)0x20, (char)0xc2, (char)0x84, (char)0x95, (char)0xbd, (char)0x72, (char)0xc4, (char)0xb7, (char)0x22, (char)0xae, (char)0xeb, (char)0x49, (char)0x0e, (char)0x16, (char)0xf1, (char)0xf1, (char)0xbf, (char)0xc5, (char)0xc7, (char)0xa8, (char)0x8d, (char)0xfb, (char)0xe1, (char)0x08, (char)0x6c, (char)0xc4, (char)0x79, (char)0x81, (char)0x13, (char)0xe8, (char)0x39, (char)0xbf, (char)0x6e, (char)0x5c, (char)0xa1, (char)0x62, (char)0xfb, (char)0x32, (char)0x2a, (char)0x62, (char)0xf0, (char)0x12, (char)0x07, (char)0x31, (char)0x93, (char)0x40, (char)0xf3, (char)0xc0, (char)0xea, (char)0x1d, (char)0xd8, (char)0x65, (char)0xba, (char)0x12, (char)0xb3, (char)0x9b, (char)0xf5, (char)0x59, (char)0x9c, (char)0x4e, (char)0xf6, (char)0xb9, (char)0xf7, (char)0x85, (char)0xa1, (char)0xd9, (char)0x2f, (char)0x7c, (char)0x8b, (char)0xd0, (char)0xfc, (char)0x53, (char)0x3b, (char)0xed, (char)0x85, (char)0xa4, (char)0xd2, (char)0x5e, (char)0x69, (char)0x61, (char)0x02, (char)0x53, (char)0xb6, (char)0x19, (char)0xc7, (char)0x82, (char)0xea, (char)0x8a, (char)0x45, (char)0x01, (char)0x5d, (char)0x4b, (char)0xb3, (char)0x06, (char)0x86, (char)0x7f, (char)0x4b, (char)0x2f, (char)0xe7, (char)0xa8, (char)0xd0, (char)0x28, (char)0x62, (char)0x02, (char)0xe8, (char)0xf3, (char)0x9e, (char)0x1e, (char)0x72, (char)0x82, (char)0x07, (char)0x9f, (char)0xdd, (char)0xd2, (char)0x83, (char)0x7d, (char)0x89, (char)0x73, (char)0x1b, (char)0x6f, (char)0x35, (char)0x20, (char)0xb7, (char)0x88, (char)0x15, (char)0x92, (char)0xa7, (char)0x11, (char)0xfe, (char)0x81, (char)0x68, (char)0xed, (char)0x14, (char)0x07, (char)0xdf, (char)0x4a, (char)0x06, (char)0x9c, (char)0x5e, (char)0x7e, (char)0x34, (char)0x3a, (char)0x2a, (char)0x8a, (char)0xd3, (char)0xe8, (char)0xf8, (char)0xd4, (char)0xdb, (char)0xe3, (char)0xe9, (char)0x73, (char)0xbf, (char)0xa7, (char)0xe9, (char)0x73, (char)0x62, (char)0xf2, (char)0x9d, (char)0xc1, (char)0xf7, (char)0x51, (char)0xeb, (char)0xff, (char)0xb7, (char)0xe6, (char)0xd9, (char)0xac, (char)0x46, (char)0x06, (char)0x74, (char)0xe2, (char)0x25, (char)0x3f, (char)0x46, (char)0x43, (char)0xce, (char)0x49, (char)0x52, (char)0x25, (char)0x1b, (char)0xf9, (char)0x24, (char)0x5c, (char)0xda, (char)0xfd, (char)0x7f, (char)0xf6, (char)0xef, (char)0xb3, (char)0xd5, (char)0xe9, (char)0x6e, (char)0x35, (char)0xb8, (char)0xd1, (char)0x0e, (char)0x2c, (char)0xc1, (char)0x48, (char)0x5a, (char)0x27, (char)0x0a, (char)0x81, (char)0x01, (char)0x0f, (char)0xe4, (char)0x51, (char)0xcf, (char)0x89, (char)0x36, (char)0xd3, (char)0xe8, (char)0x5e, (char)0x05, (char)0xb9, (char)0x83, (char)0x42, (char)0xf3, (char)0xa5, (char)0x94, (char)0x67, (char)0x6d, (char)0x6a, (char)0x6e, (char)0xad, (char)0xf8, (char)0x90, (char)0xb1, (char)0x1d, (char)0x63, (char)0x18, (char)0x52, (char)0xc1, (char)0xbf, (char)0xbc, (char)0xad, (char)0xf4, (char)0xd2, (char)0xc5, (char)0xef, (char)0xca, (char)0x4c, (char)0xfe, (char)0xa1, (char)0xda, (char)0x15, (char)0x92, (char)0x4c, (char)0x42, (char)0x3d, (char)0xfc, (char)0x80, (char)0x7e, (char)0x49, (char)0x13, (char)0x4e, (char)0xf6, (char)0xe1, (char)0xee, (char)0x70, (char)0xca, (char)0xd9, (char)0x0a, (char)0xde, (char)0x9b, (char)0xea, (char)0xcd, (char)0xf9, (char)0x90, (char)0xfd, (char)0xae, (char)0x09, (char)0xce, (char)0xb6, (char)0xa0, (char)0xf7, (char)0xd1, (char)0xe6, (char)0x0c, (char)0x55, (char)0x1e, (char)0x3f, (char)0xbb, (char)0x1e, (char)0xff, (char)0x3d, (char)0xdb, (char)0xdd, (char)0x27, (char)0x80, (char)0x06, (char)0x53, (char)0x7e, (char)0x0b, (char)0x2a, (char)0x80, (char)0x24, (char)0x51, (char)0x5c, (char)0x6a, (char)0xab, (char)0x32, (char)0x5d, (char)0x37, (char)0x8a, (char)0xf4, (char)0xb7, (char)0x11, (char)0xa7, (char)0xc1, (char)0x9e, (char)0x05, (char)0x2c, (char)0x16, (char)0xc2, (char)0x08, (char)0xe2, (char)0xac, (char)0x1a, (char)0xeb, (char)0x60, (char)0xf8, (char)0xd2, (char)0xea, (char)0x39, (char)0x01, (char)0x1c, (char)0x64, (char)0xbd, (char)0x22, (char)0x80, (char)0x19, (char)0x20, (char)0xc9, (char)0x6f, (char)0xdd, (char)0x5c, (char)0x73, (char)0x8c, (char)0xa1, (char)0x53, (char)0x48, (char)0x2e, (char)0x99, (char)0x1d, (char)0xc0, (char)0x8f, (char)0x28, (char)0xf1, (char)0xe3, (char)0xc5, (char)0xc5, (char)0x65, (char)0x53, (char)0xf2, (char)0x44, (char)0x44, (char)0x24, (char)0xb9, (char)0xe2, (char)0x73, (char)0xe4, (char)0x76, (char)0x14, (char)0x56, (char)0xb8, (char)0x82, (char)0xe3, (char)0xb4, (char)0xfd, (char)0x68, (char)0x31, (char)0xed, (char)0x40, (char)0x10, (char)0x99, (char)0xd3, (char)0x3d, (char)0xe5, (char)0x6b, (char)0x14, (char)0x61, (char)0x66, (char)0x9a, (char)0xf6, (char)0x33, (char)0x98, (char)0xc5, (char)0x4d, (char)0x11, (char)0xbb, (char)0xf8, (char)0x56, (char)0xf8, (char)0x8f, (char)0xd7, (char)0xb9, (char)0xda, (char)0xa3, (char)0x56, (char)0x1a, (char)0xe0, (char)0x9e, (char)0xbe, (char)0x5f, (char)0x56, (char)0xe5, (char)0xb9, (char)0xd8, (char)0xf3, (char)0xbc, (char)0x19, (char)0xf5, (char)0xe9, (char)0x1f, (char)0xd2, (char)0xea, (char)0xf4, (char)0x5a, (char)0xde, (char)0xed, (char)0xd4, (char)0x9e, (char)0xc8, (char)0xf5, (char)0x54, 
        (char)0x83, (char)0x8b, (char)0x8c, (char)0x2d, (char)0x24, (char)0x0e, (char)0x30, (char)0xb1, (char)0x84, (char)0xa2, (char)0xbe, (char)0x2c, (char)0x86, (char)0xe6, (char)0x42, (char)0x82, (char)0xaa, (char)0x37, (char)0x64, (char)0x55, (char)0x51, (char)0xbc, (char)0xde, (char)0xc0, (char)0x63, (char)0x88, (char)0xf6, (char)0x31, (char)0x71, (char)0x52, (char)0xd5, (char)0x34, (char)0x0f, (char)0x8e, (char)0xcb, (char)0x28, (char)0x65, (char)0x93, (char)0x1a, (char)0x66, (char)0x3b, (char)0x21, (char)0x00, (char)0xaa, (char)0x7a, (char)0xda, (char)0x2d, (char)0xf6, (char)0x7e, (char)0xb5, (char)0x27, (char)0x79, (char)0xf4, (char)0x50, (char)0x3b, (char)0x10, (char)0x6b, (char)0x3c, (char)0xd7, (char)0x99, (char)0x9d, (char)0xf6, (char)0xc5, (char)0x01, (char)0x91, (char)0xa0, (char)0xd5, (char)0x4f, (char)0xd3, (char)0x76, (char)0x54, (char)0xa8, (char)0x5c, (char)0x35, (char)0x1d, (char)0xe2, (char)0x35, (char)0x6a, (char)0x68, (char)0x67, (char)0x03, (char)0xc4, (char)0x1f, (char)0xe9, (char)0x60, (char)0xb8, (char)0x49, (char)0xb1, (char)0x9a, (char)0x40, (char)0xd9, (char)0x3c, (char)0x4c, (char)0x73, (char)0xaa, (char)0x88, (char)0x63, (char)0xaf, (char)0xfe, (char)0xe8, (char)0xa8, (char)0x0c, (char)0x96, (char)0xbe, (char)0xb4, (char)0x65, (char)0x7c, (char)0x27, (char)0xfb, (char)0xc1, (char)0x27, (char)0x24, (char)0x58, (char)0xab, (char)0x4b, (char)0xa0, (char)0x5a, (char)0x7d, (char)0xc7, (char)0xca, (char)0x2d, (char)0xa5, (char)0x22, (char)0xa7, (char)0xed, (char)0x26, (char)0x87, (char)0xd5, (char)0x44, (char)0x1a, (char)0xc7, (char)0xdd, (char)0xfb, (char)0x60, (char)0xfc, (char)0xe5, (char)0x50, (char)0xd9, (char)0x8d, (char)0xa7, (char)0xdb, (char)0x78, (char)0xb6, (char)0x9d, (char)0x80, (char)0x0f, (char)0xb9, (char)0x5f, (char)0xa7, (char)0x53, (char)0x92, (char)0x5d, (char)0x18, (char)0xce, (char)0x89, (char)0xc2, (char)0x69, (char)0xee, (char)0xcf, (char)0xb6, (char)0x66, (char)0xe5, (char)0x66, (char)0xd2, (char)0xe3, (char)0x35, (char)0x74, (char)0x0b, (char)0x83, (char)0xb6, (char)0xde, (char)0xf1, (char)0xfb, (char)0xb4, (char)0x1d, (char)0x4b, (char)0x94, (char)0x95, (char)0x06, (char)0x82, (char)0xe7, (char)0x1c, (char)0xf8, (char)0xc5, (char)0xe6, (char)0xd0, (char)0xf2, (char)0x17, (char)0x37, (char)0x44, (char)0xfe, (char)0x99, (char)0x43, (char)0x82, (char)0xbb, (char)0x88, (char)0xe4, (char)0x43, (char)0x67, (char)0xcc, (char)0x4d, (char)0x5f, (char)0xa6, (char)0x26, (char)0xd7, (char)0x53, (char)0xd6, (char)0x45, (char)0x96, (char)0x2b, (char)0x63, (char)0xd1, (char)0x2a, (char)0xa1, (char)0x2c, (char)0x41, (char)0x59, (char)0x8b, (char)0xb8, (char)0xc1, (char)0x89, (char)0x03, (char)0x3a, (char)0x61, (char)0x13, (char)0xc4, (char)0x2c, (char)0x37, (char)0xa5, (char)0xbf, (char)0xd7, (char)0xdb, (char)0xd8, (char)0x53, (char)0x5f, (char)0xa1, (char)0xdb, (char)0xdb, (char)0xa5, (char)0x73, (char)0xb6, (char)0xf7, (char)0x74, (char)0xa0, (char)0xf8, (char)0x93, (char)0xf5, (char)0x61, (char)0xee, (char)0x3c, (char)0xe7, (char)0x00, (char)0x01, (char)0x98, (char)0xe0, (char)0xa1, (char)0x22, (char)0xb6, (char)0x9a, (char)0x83, (char)0x44, (char)0xa1, (char)0xe6, (char)0x70, (char)0x56, (char)0x65, (char)0x92, (char)0x1e, (char)0xf0, (char)0xbc, (char)0x73, (char)0xa5, (char)0x7a, (char)0xc1, (char)0x1a, (char)0x02, (char)0xf9, (char)0xd4, (char)0xc4, (char)0x7c, (char)0x81, (char)0xda, (char)0x15, (char)0xc0, (char)0xd4, (char)0x25, (char)0xdc, (char)0x17, (char)0xa6, (char)0x0d, (char)0x90, (char)0x55, (char)0xf2, (char)0x10, (char)0xf8, (char)0xa7, (char)0x71, (char)0x9b, (char)0xed, (char)0xdf, (char)0xdf, (char)0xa1, (char)0xe4, (char)0xb9, (char)0x12, (char)0x6b, (char)0x05, (char)0x3e, (char)0x83, (char)0x99, (char)0x49, (char)0xbf, (char)0x66, (char)0xbb, (char)0xf6, (char)0x76, (char)0xd3, (char)0xa9, (char)0x24, (char)0x61, (char)0x8c, (char)0x25, (char)0x49, (char)0xd0, (char)0xf7, (char)0x83, (char)0x44, (char)0xfb, (char)0x27, (char)0xe2, (char)0x7d, (char)0x69, (char)0x6d, (char)0x34, (char)0x67, (char)0xed, (char)0x39, (char)0x89, (char)0x02, (char)0xcb, (char)0x2f, (char)0x33, (char)0x3c, (char)0xcd, (char)0x12, (char)0x42, (char)0x8f, (char)0x86, (char)0x7d, (char)0xda, (char)0x3f, (char)0xd7, (char)0x26, (char)0x62, (char)0x9c, (char)0x1f, (char)0x2e, (char)0xa8, (char)0xc3, (char)0x85, (char)0xf1, (char)0x73, (char)0xe5, (char)0x2c, (char)0x11, (char)0xde, (char)0x98, (char)0xc8, (char)0xb0, (char)0x10, (char)0x17, (char)0x55, (char)0xf5, (char)0x32, (char)0x52, (char)0x67, (char)0xca, (char)0x64, (char)0x50, (char)0x28, (char)0x9a, (char)0x24, (char)0x92, (char)0xa1, (char)0x97, (char)0x57, (char)0x81, (char)0xaf, (char)0xca, (char)0x1e, (char)0xc0, (char)0xa4, (char)0x71, (char)0x2d, (char)0x2a, (char)0xec, (char)0xc9, (char)0x23, (char)0x6a, (char)0x0c, (char)0x1d, (char)0x54, (char)0x15, (char)0x2a, (char)0x56, (char)0x42, (char)0x0a, (char)0x83, (char)0xff, (char)0x28, (char)0xba, (char)0xe7, (char)0x68, (char)0x38, (char)0xf5, (char)0x32, (char)0xa9, (char)0xb7, (char)0xe7, (char)0x70, (char)0x32, (char)0xa8, (char)0x79, (char)0x5e, (char)0x46, (char)0x1d, (char)0xec, (char)0x29, (char)0x8a, (char)0xde, (char)0x41, (char)0x94, (char)0x94, (char)0x26, (char)0x79, (char)0xc2, (char)0x52, (char)0x23, (char)0xe0, (char)0xa1, (char)0x1d, (char)0x65, (char)0x0c, (char)0xbe, (char)0x1b, (char)0x87, (char)0x2a, (char)0x21, (char)0x53, (char)0x2f, (char)0x35, (char)0x56, (char)0xe8, (char)0xd1, (char)0x7b, (char)0xb8, (char)0x23, (char)0x75, (char)0x56, (char)0xc7, (char)0x08, (char)0x9d, (char)0x13, (char)0xf0, (char)0x8f, (char)0x80, (char)0x38, (char)0xe9, (char)0x92, (char)0xf7, (char)0x16, (char)0xc2, (char)0xf3, (char)0x74, (char)0xa7, (char)0x92, (char)0xf5, (char)0x49, (char)0x7d, (char)0x09, (char)0x41, (char)0xbc, (char)0x07, (char)0x61, (char)0x1f, (char)0xe6, (char)0xa0, (char)0xd8, (char)0xa6, (char)0xe3, (char)0x72, (char)0xa4, (char)0x59, (char)0x4a, (char)0xd9, (char)0x33, (char)0x40, (char)0x80, (char)0x3a, (char)0x3a, (char)0xb3, (char)0xa0, (char)0x96, (char)0xca, (char)0x56, (char)0x98, (char)0xbd, (char)0x1f, (char)0x80, (char)0x86, (char)0x6c, (char)0xe1, (char)0x09, (char)0x64, (char)0x1b, (char)0x1a, (char)0xc9, (char)0x52, (char)0xaa, (char)0xd1, (char)0x39, (char)0xea, (char)0x4b, (char)0x6a, (char)0x3e, (char)0x4e, (char)0xa4, (char)0xea, (char)0x00, (char)0xde, (char)0x07, (char)0x0b, (char)0x23, (char)0xbc, (char)0x40, (char)0xc4, (char)0xd2, (char)0xd9, (char)0xf6, (char)0xda, (char)0x8e, (char)0x22, (char)0x36, (char)0xbe, (char)0x5e, (char)0x65, (char)0x6e, (char)0xbe, (char)0xc8, (char)0xb0, (char)0x07, (char)0xa2, (char)0x2d, (char)0xe9, (char)0x4b, (char)0x73, (char)0x54, (char)0xe6, (char)0x0a, (char)0xf2, (char)0xd3, (char)0x83, (char)0x8b, (char)0x27, (char)0x4c, (char)0xcc, (char)0x0c, (char)0x8a, (char)0xd4, (char)0x2b, (char)0xb8, (char)0x95, (char)0x2e, (char)0x42, (char)0x64, (char)0x29, (char)0xc1, (char)0xe0, (char)0x6b, (char)0x92, (char)0xab, (char)0xfe, (char)0x53, (char)0x06, (char)0x96, (char)0x4a, (char)0x8c, (char)0x5d, (char)0x7c, (char)0x51, (char)0x74, (char)0xd0, (char)0x1e, (char)0x37, (char)0x35, (char)0x9c, (char)0x1e, (char)0x69, (char)0x8f, (char)0x68, (char)0x18, (char)0xd9, (char)0xbe, (char)0xaf, (char)0x81, (char)0x9b, (char)0x7e, (char)0xd8, (char)0x71, (char)0x9d, (char)0xb6, (char)0x50, (char)0x43, (char)0x78, (char)0x85, (char)0x7d, (char)0x65, (char)0x93, (char)0x45, (char)0xb4, (char)0x02, (char)0xd0, (char)0x5c, (char)0x36, (char)0xe2, (char)0x62, (char)0x3f, (char)0x40, (char)0x33, (char)0xee, (char)0x91, (char)0xe5, (char)0x3f, (char)0x67, (char)0x39, (char)0x2f, (char)0x1b, (char)0x89, (char)0x9f, (char)0x04, (char)0x9d, (char)0x46, (char)0x3e, (char)0x70, (char)0x92, (char)0x9e, (char)0x8c, (char)0xf5 
    };
    char s0s1s2[] = {
        (char)0x03, (char)0xac, (char)0x44, (char)0x29, (char)0x53, (char)0x04, (char)0x05, (char)0x00, (char)0x01, (char)0x6e, (char)0x65, (char)0x69, (char)0x2d, (char)0x69, (char)0x2d, (char)0x69, (char)0x73, (char)0x6e, (char)0x69, (char)0x73, (char)0x6c, (char)0x65, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x69, (char)0x77, (char)0x74, (char)0x2e, (char)0x6e, (char)0x72, (char)0x76, (char)0x72, (char)0x65, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x69, (char)0x70, (char)0x72, (char)0x73, (char)0x6e, (char)0x65, (char)0x72, (char)0x72, (char)0x6e, (char)0x2d, (char)0x65, (char)0x74, (char)0x72, (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x69, (char)0x76, (char)0x77, (char)0x2d, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x76, (char)0x73, (char)0x72, (char)0x2e, (char)0x2d, (char)0x76, (char)0x65, (char)0x31, (char)0x65, (char)0x6d, (char)0x6d, (char)0x73, (char)0x69, (char)0x73, (char)0x74, (char)0x2e, (char)0x74, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x65, (char)0x2d, (char)0x74, (char)0x69, (char)0x31, (char)0x65, (char)0x2d, (char)0x6f, (char)0x77, (char)0x2e, (char)0x76, (char)0x77, (char)0x2d, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x31, (char)0x74, (char)0x73, (char)0x70, (char)0x74, (char)0x6e, (char)0x72, (char)0x6e, (char)0x73, (char)0x6d, (char)0x2e, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x69, (char)0x77, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x6c, (char)0x2e, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6c, (char)0x73, (char)0x65, (char)0x73, (char)0x70, (char)0x2d, (char)0x65, (char)0x72, (char)0x40, (char)0x72, (char)0x74, (char)0x6e, (char)0x6e, (char)0x6d, (char)0x6f, (char)0x70, (char)0x74, (char)0x73, (char)0x2d, (char)0x63, (char)0x69, (char)0x32, (char)0x31, (char)0x2d, (char)0x40, (char)0x69, (char)0x70, (char)0x2d, (char)0x2d, (char)0x72, (char)0x69, (char)0x74, (char)0x63, (char)0x6f, (char)0x69, (char)0x69, (char)0x65, (char)0x6e, (char)0x32, (char)0x6f, (char)0x6c, (char)0x6e, (char)0x72, (char)0x73, (char)0x77, (char)0x65, (char)0x65, (char)0x72, (char)0x32, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x72, (char)0x6e, (char)0x65, (char)0x6d, (char)0x31, (char)0x65, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x40, (char)0x70, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2d, (char)0x77, (char)0x63, (char)0x63, (char)0x74, (char)0x40, (char)0x36, (char)0x2d, (char)0x72, (char)0x65, (char)0x70, (char)0x2d, (char)0x6e, (char)0x69, (char)0x6d, (char)0x65, (char)0x74, (char)0x70, (char)0x76, (char)0x40, (char)0x76, (char)0x72, (char)0x72, (char)0x69, (char)0x77, (char)0x76, (char)0x69, (char)0x74, (char)0x74, (char)0x65, (char)0x31, (char)0x6d, (char)0x2e, (char)0x6f, (char)0x72, (char)0x73, (char)0x73, (char)0x6c, (char)0x40, (char)0x36, (char)0x72, (char)0x70, (char)0x72, (char)0x70, (char)0x72, (char)0x69, (char)0x32, (char)0x6c, (char)0x77, (char)0x70, (char)0x76, (char)0x65, (char)0x72, (char)0x76, (char)0x63, (char)0x65, (char)0x65, (char)0x77, (char)0x72, (char)0x6e, (char)0x2e, (char)0x76, (char)0x69, (char)0x69, (char)0x2e, (char)0x40, (char)0x72, (char)0x2e, (char)0x2e, (char)0x72, (char)0x73, (char)0x6e, (char)0x72, (char)0x72, (char)0x6e, (char)0x70, (char)0x40, (char)0x77, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x63, (char)0x74, (char)0x2d, (char)0x70, (char)0x72, (char)0x2d, (char)0x74, (char)0x72, (char)0x31, (char)0x65, (char)0x6e, (char)0x2d, (char)0x76, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x74, (char)0x76, (char)0x2d, (char)0x74, (char)0x65, (char)0x2e, (char)0x2d, (char)0x6c, (char)0x76, (char)0x2d, (char)0x6c, (char)0x70, (char)0x73, (char)0x6d, (char)0x65, (char)0x72, (char)0x31, (char)0x31, (char)0x36, (char)0x76, (char)0x73, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6e, (char)0x73, (char)0x72, (char)0x2d, (char)0x6f, (char)0x6c, (char)0x65, (char)0x74, (char)0x77, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x65, (char)0x6d, (char)0x76, (char)0x31, (char)0x65, (char)0x73, (char)0x72, (char)0x6c, (char)0x72, (char)0x77, (char)0x65, (char)0x76, (char)0x74, (char)0x72, (char)0x69, (char)0x72, (char)0x76, (char)0x32, (char)0x73, (char)0x6d, (char)0x72, (char)0x2d, (char)0x6d, (char)0x40, (char)0x69, (char)0x40, (char)0x69, (char)0x31, (char)0x69, (char)0x6f, (char)0x6e, (char)0x6d, (char)0x69, (char)0x73, (char)0x70, (char)0x72, (char)0x77, (char)0x6f, (char)0x6f, (char)0x65, (char)0x77, (char)0x76, (char)0x70, (char)0x70, (char)0x6c, (char)0x6f, (char)0x72, (char)0x65, (char)0x32, (char)0x36, (char)0x6c, (char)0x74, (char)0x6e, (char)0x72, (char)0x74, (char)0x2d, (char)0x6e, (char)0x6c, (char)0x72, (char)0x72, (char)0x2d, (char)0x74, (char)0x65, (char)0x73, (char)0x70, (char)0x65, (char)0x72, (char)0x6c, (char)0x65, (char)0x65, (char)0x2d, (char)0x6e, (char)0x70, (char)0x6e, (char)0x40, (char)0x65, (char)0x6e, (char)0x6e, (char)0x74, (char)0x65, (char)0x6e, (char)0x72, (char)0x6e, (char)0xfe, (char)0x5a, (char)0x38, (char)0x79, (char)0x81, (char)0xe8, (char)0x49, (char)0xee, (char)0x93, (char)0xbb, (char)0xa0, (char)0x59, (char)0x4a, (char)0xa0, (char)0xcc, (char)0x31, (char)0xbf, (char)0x0d, (char)0x86, (char)0xc0, (char)0x3f, (char)0xae, (char)0x2a, (char)0x16, (char)0xfa, (char)0xf0, (char)0x4e, (char)0x0f, (char)0xa3, (char)0x01, (char)0x06, (char)0xa0, (char)0x0e, (char)0xa5, (char)0x8c, (char)0xa4, (char)0xca, (char)0xd2, (char)0x01, (char)0xa5, (char)0x90, (char)0xbd, (char)0x55, (char)0xd1, (char)0x42, (char)0x2b, (char)0xd4, (char)0xb3, (char)0xbb, (char)0x06, (char)0xb1, (char)0x3a, (char)0x94, (char)0x41, (char)0x76, (char)0x1d, (char)0xa5, (char)0x23, (char)0x6e, (char)0x1e, (char)0x59, (char)0x73, (char)0x63, (char)0x34, (char)0x60, (char)0xd3, (char)0x48, (char)0xc0, (char)0x3b, (char)0xcf, (char)0xf1, (char)0xa8, (char)0x38, (char)0xd6, (char)0xf3, (char)0x5e, (char)0x6d, (char)0xcb, (char)0xea, (char)0xfc, (char)0x9c, (char)0x52, (char)0xae, (char)0x9a, (char)0x89, (char)0xdb, (char)0x24, (char)0x1b, (char)0x92, (char)0x4a, (char)0x85, (char)0x97, (char)0x3c, (char)0xd8, (char)0x4c, (char)0x31, (char)0xad, (char)0xfd, (char)0x00, (char)0xef, (char)0xc5, (char)0x17, (char)0xa5, (char)0x22, (char)0xc0, (char)0xf1, (char)0x94, (char)0x18, (char)0xec, (char)0xf6, (char)0x49, (char)0xe5, (char)0x05, (char)0x11, (char)0x12, (char)0x67, (char)0x6c, (char)0x71, (char)0xc0, (char)0x84, (char)0x6d, (char)0x50, (char)0xf8, (char)0x23, (char)0x01, (char)0x57, (char)0xc4, (char)0xfc, (char)0x73, (char)0x65, (char)0x69, (char)0x6e, (char)0x65, (char)0x72, (char)0x6d, (char)0x6f, (char)0x69, (char)0x2d, (char)0x65, (char)0x65, (char)0x69, (char)0x63, (char)0x63, (char)0x69, (char)0x2d, (char)0x72, (char)0x2d, (char)0x69, (char)0x2d, (char)0x2d, (char)0x77, (char)0x72, (char)0x76, (char)0x72, (char)0x72, (char)0x2d, (char)0x76, (char)0x70, (char)0x63, (char)0x69, (char)0x74, (char)0x73, (char)0x6d, (char)0x65, (char)0x6c, (char)0x2d, (char)0x73, (char)0x6c, (char)0x65, (char)0x6e, (char)0x73, (char)0x77, (char)0x69, (char)0x63, (char)0x69, (char)0x70, (char)0x31, (char)0x40, (char)0x72, (char)0x69, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x72, (char)0x63, (char)0x72, (char)0x77, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x72, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x6d, (char)0x76, (char)0x36, (char)0x6d, (char)0x72, (char)0x77, (char)0x72, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x76, (char)0x6d, (char)0x76, (char)0x74, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x72, (char)0x6e, (char)0x6d, (char)0x77, (char)0x6c, (char)0x40, (char)0x32, (char)0x70, (char)0x65, (char)0x65, (char)0x69, (char)0x72, (char)0x31, (char)0x2e, (char)0x70, (char)0x36, (char)0x31, (char)0x65, (char)0x70, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x6e, (char)0x6e, (char)0x73, (char)0x32, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x69, (char)0x65, (char)0x31, (char)0x74, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x76, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6e, (char)0x70, (char)0x74, (char)0x73, (char)0x72, (char)0x6d, (char)0x72, (char)0x72, (char)0x69, (char)0x65, (char)0x74, (char)0x65, (char)0x65, (char)0x2d, (char)0x70, (char)0x74, (char)0x6e, (char)0x74, (char)0x65, (char)0x6f, (char)0x72, (char)0x69, (char)0x76, (char)0x40, (char)0x31, (char)0x69, (char)0x72, (char)0x6d, (char)0x6d, (char)0x77, (char)0x69, (char)0x72, (char)0x65, (char)0x6e, (char)0x40, (char)0x63, (char)0x40, (char)0x65, (char)0x65, (char)0x69, (char)0x2d, (char)0x72, (char)0x65, (char)0x40, (char)0x69, (char)0x32, (char)0x74, (char)0x73, (char)0x6e, (char)0x36, (char)0x2d, (char)0x70, (char)0x65, (char)0x6c, (char)0x70, (char)0x6e, (char)0x72, (char)0x69, (char)0x32, (char)0x65, (char)0x74, (char)0x76, (char)0x77, (char)0x73, (char)0x6f, (char)0x77, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x73, (char)0x65, (char)0x65, (char)0x70, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x2d, (char)0x65, (char)0x2e, (char)0x73, (char)0x69, (char)0x67, (char)0x45, (char)0x8b, (char)0x6b, (char)0x3b, (char)0xc9, (char)0x5f, (char)0x09, (char)0x65, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6d, (char)0x70, (char)0x70, (char)0x73, (char)0x63, (char)0x70, (char)0x40, (char)0x72, (char)0x76, (char)0x65, (char)0x6e, (char)0x6f, (char)0x6c, (char)0x69, (char)0x2e, (char)0x72, (char)0x73, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x65, (char)0x77, (char)0x73, (char)0x69, (char)0x70, (char)0x77, (char)0x63, (char)0x65, (char)0x74, (char)0x72, (char)0x73, (char)0x31, (char)0x65, (char)0x65, (char)0x72, (char)0x76, (char)0x69, (char)0x65, (char)0x77, (char)0x6d, (char)0x65, (char)0x36, (char)0x6e, (char)0x6e, (char)0x69, (char)0x6d, (char)0x6e, (char)0x70, (char)0x77, (char)0x72, (char)0x65, (char)0x31, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x65, (char)0x2e, (char)0x77, (char)0x6e, (char)0x6f, (char)0x2d, (char)0x76, (char)0x65, (char)0x72, (char)0x6c, (char)0x31, (char)0x76, (char)0x65, (char)0x72, (char)0x2d, (char)0x36, (char)0x6c, (char)0x70, (char)0x6f, (char)0x65, (char)0x72, (char)0x73, (char)0x63, (char)0x72, (char)0x77, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x65, (char)0x6c, (char)0x76, (char)0x72, (char)0x65, (char)0x6e, (char)0x65, (char)0x2e, (char)0x6f, (char)0x2d, (char)0x72, (char)0x70, (char)0x65, (char)0x74, (char)0x72, 
        (char)0x77, (char)0x69, (char)0x69, (char)0x72, (char)0x65, (char)0x77, (char)0x6c, (char)0x72, (char)0x2d, (char)0x69, (char)0x72, (char)0x31, (char)0x6e, (char)0x65, (char)0x70, (char)0x72, (char)0x74, (char)0x76, (char)0x6c, (char)0x2e, (char)0x72, (char)0x65, (char)0x72, (char)0x6c, (char)0x73, (char)0x6c, (char)0x2e, (char)0x2e, (char)0x72, (char)0x2d, (char)0x6e, (char)0x63, (char)0x32, (char)0x2e, (char)0x65, (char)0x2d, (char)0x65, (char)0x69, (char)0x2d, (char)0x65, (char)0x70, (char)0x6e, (char)0x72, (char)0x72, (char)0x32, (char)0x2e, (char)0x73, (char)0x70, (char)0x77, (char)0x65, (char)0x73, (char)0x77, (char)0x73, (char)0x40, (char)0x40, (char)0x73, (char)0x63, (char)0x2e, (char)0x65, (char)0x76, (char)0x70, (char)0x65, (char)0x69, (char)0x65, (char)0x70, (char)0x73, (char)0x40, (char)0x65, (char)0x73, (char)0x2d, (char)0x2d, (char)0x2e, (char)0x2e, (char)0x73, (char)0x65, (char)0x6f, (char)0x65, (char)0x65, (char)0x6d, (char)0x76, (char)0x70, (char)0x6d, (char)0x69, (char)0x70, (char)0x70, (char)0x69, (char)0x2e, (char)0x76, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x6d, (char)0x73, (char)0x6f, (char)0x73, (char)0x72, (char)0x72, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x72, (char)0x73, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x74, (char)0x65, (char)0x69, (char)0x40, (char)0x63, (char)0x69, (char)0x70, (char)0x6c, (char)0x6e, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x63, (char)0x6c, (char)0x72, (char)0x2e, (char)0x36, (char)0x69, (char)0x72, (char)0x6c, (char)0x6c, (char)0x2d, (char)0x6f, (char)0x76, (char)0x69, (char)0x6f, (char)0x2d, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x2e, (char)0x70, (char)0x73, (char)0x6d, (char)0x6f, (char)0x2e, (char)0x6e, (char)0x69, (char)0x65, (char)0x65, (char)0x2d, (char)0x6d, (char)0x76, (char)0x6e, (char)0x69, (char)0x73, (char)0x73, (char)0x73, (char)0x74, (char)0x63, (char)0x65, (char)0x76, (char)0x2e, (char)0x77, (char)0x2d, (char)0x36, (char)0x73, (char)0x69, (char)0x2d, (char)0x72, (char)0x72, (char)0x6c, (char)0x36, (char)0x74, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x6d, (char)0x31, (char)0x72, (char)0x6f, (char)0x74, (char)0x76, (char)0x31, (char)0x65, (char)0x6d, (char)0x69, (char)0x72, (char)0x69, (char)0x69, (char)0x2d, (char)0x72, (char)0x73, (char)0x72, (char)0x72, (char)0x76, (char)0x31, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x77, (char)0x70, (char)0x69, (char)0x72, (char)0x6e, (char)0x76, (char)0x74, (char)0x6f, (char)0x65, (char)0x63, (char)0x6f, (char)0x73, (char)0x65, (char)0x73, (char)0x72, (char)0x69, (char)0x69, (char)0x40, (char)0x6e, (char)0x65, (char)0x65, (char)0x65, (char)0x65, (char)0x77, (char)0x70, (char)0x70, (char)0x6e, (char)0x72, (char)0x6e, (char)0x65, (char)0x72, (char)0x32, (char)0x65, (char)0x2d, (char)0x77, (char)0x69, (char)0x6e, (char)0x70, (char)0x69, (char)0x6f, (char)0x76, (char)0x77, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x72, (char)0xfe, (char)0x98, (char)0xf3, (char)0xb4, (char)0xff, (char)0x3f, (char)0x2e, (char)0xdb, (char)0x59, (char)0xbd, (char)0x32, (char)0x02, (char)0x6a, (char)0x44, (char)0x03, (char)0x67, (char)0x9e, (char)0xe1, (char)0x98, (char)0x97, (char)0xed, (char)0x67, (char)0x6d, (char)0xb0, (char)0x8f, (char)0xa9, (char)0xb6, (char)0xf8, (char)0x4d, (char)0x92, (char)0x35, (char)0x19, (char)0x72, (char)0x72, (char)0x65, (char)0x74, (char)0x73, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6e, (char)0x72, (char)0x65, (char)0x32, (char)0x72, (char)0x77, (char)0x72, (char)0x73, (char)0x77, (char)0x73, (char)0x70, (char)0x2d, (char)0x2d, (char)0x69, (char)0x6c, (char)0x70, (char)0x74, (char)0x65, (char)0x69, (char)0x72, (char)0x74, (char)0x6e, (char)0x76, (char)0x65, (char)0x76, (char)0x76, (char)0x69, (char)0x69, (char)0x65, (char)0x70, (char)0x6e, (char)0x73, (char)0x6e, (char)0x36, (char)0x76, (char)0x70, (char)0x76, (char)0x6c, (char)0x6c, (char)0x70, (char)0x6e, (char)0x6e, (char)0x74, (char)0x2e, (char)0x6f, (char)0x32, (char)0x74, (char)0x76, (char)0x74, (char)0x40, (char)0x72, (char)0x6e, (char)0x72, (char)0x74, (char)0x74, (char)0x2d, (char)0x6f, (char)0x72, (char)0x73, (char)0x32, (char)0x72, (char)0x32, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x6e, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x69, (char)0x74, (char)0x74, (char)0x6e, (char)0x72, (char)0x6c, (char)0x31, (char)0x74, (char)0x77, (char)0x31, (char)0x63, (char)0x63, (char)0x74, (char)0x69, (char)0x72, (char)0x69, (char)0x72, (char)0x70, (char)0x31, (char)0x74, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x65, (char)0x6c, (char)0x76, (char)0x6d, (char)0x72, (char)0x6c, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x6f, (char)0x69, (char)0x6c, (char)0x74, (char)0x6e, (char)0x65, (char)0x69, (char)0x77, (char)0x73, (char)0x70, (char)0x69, (char)0x72, (char)0x2d, (char)0x65, (char)0x74, (char)0x2e, (char)0x65, (char)0x65, (char)0x6d, (char)0x72, (char)0x31, (char)0x2d, (char)0x72, (char)0x36, (char)0x65, (char)0x2d, (char)0x69, (char)0x6d, (char)0x36, (char)0x6e, (char)0x72, (char)0x6d, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x31, (char)0x6e, (char)0x40, (char)0x72, (char)0x40, (char)0x6f, (char)0x73, (char)0x6d, (char)0x36, (char)0x2e, (char)0x72, (char)0x65, (char)0x36, (char)0x74, (char)0x77, (char)0x65, (char)0x65, (char)0x73, (char)0x36, (char)0x76, (char)0x6c, (char)0x6f, (char)0x2d, (char)0x36, (char)0x6d, (char)0x36, (char)0x70, (char)0x32, (char)0x74, (char)0x6d, (char)0x65, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x74, (char)0x2d, (char)0x63, (char)0x2d, (char)0x6e, (char)0x32, (char)0x72, (char)0x63, (char)0x2d, (char)0x77, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x6e, (char)0x76, (char)0x6f, (char)0x72, (char)0x40, (char)0x65, (char)0x65, (char)0x6d, (char)0x77, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6e, (char)0x73, (char)0x76, (char)0x65, (char)0x69, (char)0x69, (char)0x72, (char)0x6f, (char)0x65, (char)0x70, (char)0x69, (char)0x6d, (char)0x76, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x74, (char)0x2d, (char)0x69, (char)0x65, (char)0x72, (char)0x69, (char)0x6f, (char)0x72, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x77, (char)0x69, (char)0x2e, (char)0x77, (char)0x69, (char)0x70, (char)0x69, (char)0x6d, (char)0x36, (char)0x72, (char)0x76, (char)0x65, (char)0x76, (char)0x73, (char)0x6e, (char)0x72, (char)0x65, (char)0x2e, (char)0x76, (char)0x2d, (char)0x76, (char)0x6f, (char)0x2d, (char)0x65, (char)0x73, (char)0x72, (char)0x74, (char)0x36, (char)0x2d, (char)0x6f, (char)0x70, (char)0x73, (char)0x74, (char)0x74, (char)0x77, (char)0x6c, (char)0x2d, (char)0x65, (char)0x72, (char)0x6e, (char)0x65, (char)0x6c, (char)0x72, (char)0x32, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6f, (char)0x65, (char)0x36, (char)0x31, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x31, (char)0x74, (char)0x69, (char)0x69, (char)0x65, (char)0x40, (char)0x69, (char)0x6e, (char)0x2d, (char)0x63, (char)0x40, (char)0x31, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x65, (char)0x70, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x73, (char)0x69, (char)0x65, (char)0x65, (char)0x6e, (char)0x2e, (char)0x63, (char)0x6c, (char)0x72, (char)0x65, (char)0x2d, (char)0x2e, (char)0x6d, (char)0x72, (char)0x76, (char)0x70, (char)0x69, (char)0x6d, (char)0x40, (char)0x32, (char)0x77, (char)0x72, (char)0x6e, (char)0x72, (char)0x6c, (char)0x36, (char)0x72, (char)0x31, (char)0x2d, (char)0x73, (char)0x74, (char)0x2d, (char)0x69, (char)0x63, (char)0x40, (char)0x70, (char)0x32, (char)0x65, (char)0x31, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x63, (char)0x74, (char)0x72, (char)0x74, (char)0x77, (char)0x6e, (char)0x69, (char)0x72, (char)0x65, (char)0x76, (char)0x65, (char)0x77, (char)0x69, (char)0x69, (char)0x73, (char)0x6e, (char)0x77, (char)0x77, (char)0x73, (char)0x6f, (char)0x69, (char)0x70, (char)0x73, (char)0x2d, (char)0x65, (char)0x65, (char)0x73, (char)0x65, (char)0x77, (char)0x2d, (char)0x73, (char)0x72, (char)0x6d, (char)0x65, (char)0x32, (char)0x6e, (char)0x73, (char)0x36, (char)0x65, (char)0x72, (char)0x77, (char)0x70, (char)0x65, (char)0x69, (char)0x2d, (char)0x2d, (char)0x74, (char)0x6f, (char)0x6f, (char)0x36, (char)0x63, (char)0x74, (char)0x72, (char)0x63, (char)0x77, (char)0x69, (char)0x2e, (char)0x31, (char)0x6c, (char)0x65, (char)0x77, (char)0x72, (char)0x65, (char)0x76, (char)0x74, (char)0x2d, (char)0x77, (char)0x2e, (char)0x76, (char)0x72, (char)0x6e, (char)0x36, (char)0x70, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x77, (char)0x69, (char)0x65, (char)0x74, (char)0x2d, (char)0x6e, (char)0x63, (char)0x6e, (char)0x70, (char)0x2d, (char)0x6e, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x63, (char)0x65, (char)0x2d, (char)0x76, (char)0x70, (char)0x73, (char)0x31, (char)0x73, (char)0x2d, (char)0x76, (char)0x6e, (char)0x6e, (char)0x6c, (char)0x2d, (char)0x6c, (char)0x2d, (char)0x65, (char)0x6e, (char)0x73, (char)0x6c, (char)0x65, (char)0x74, (char)0x70, (char)0x65, (char)0x2d, (char)0x6e, (char)0x77, (char)0x76, (char)0x40, (char)0x69, (char)0x40, (char)0x63, (char)0x6f, (char)0x72, (char)0x32, (char)0x6d, (char)0x31, (char)0x72, (char)0x36, (char)0x69, (char)0x73, (char)0x72, (char)0x70, (char)0x65, (char)0x2d, (char)0x6c, (char)0x2e, (char)0x72, (char)0x74, (char)0x74, (char)0x65, (char)0x69, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x65, (char)0x6f, (char)0x65, (char)0x74, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6e, (char)0x31, (char)0x65, (char)0x76, (char)0x72, (char)0x73, (char)0x77, (char)0x72, (char)0x2d, (char)0x69, (char)0x65, (char)0x69, (char)0x70, (char)0x65, (char)0x6e, (char)0x6e, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x72, (char)0x76, (char)0x72, (char)0x6c, (char)0x2e, (char)0x70, (char)0x76, (char)0x6e, (char)0x69, (char)0x72, (char)0x70, (char)0x73, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x72, (char)0x70, (char)0x65, (char)0x63, (char)0x72, (char)0x70, (char)0x6e, (char)0x36, (char)0x6c, (char)0x74, (char)0x72, (char)0x72, (char)0x72, (char)0x73, (char)0x65, (char)0x40, (char)0x63, (char)0x6d, (char)0x63, (char)0x32, (char)0x65, (char)0x32, (char)0x69, (char)0x6e, 
        (char)0x77, (char)0x65, (char)0x74, (char)0x72, (char)0x77, (char)0x40, (char)0x69, (char)0x65, (char)0x70, (char)0x31, (char)0x36, (char)0x72, (char)0x73, (char)0x2d, (char)0x72, (char)0x72, (char)0x32, (char)0x72, (char)0x6c, (char)0x77, (char)0x6e, (char)0x6f, (char)0x77, (char)0x6c, (char)0x74, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x70, (char)0x6c, (char)0x72, (char)0x6f, (char)0x69, (char)0x2d, (char)0x2d, (char)0x69, (char)0x36, (char)0x69, (char)0x69, (char)0x76, (char)0x69, (char)0x69, (char)0x6d, (char)0x72, (char)0x73, (char)0x6f, (char)0x6d, (char)0x74, (char)0x70, (char)0x76, (char)0x6d, (char)0x6d, (char)0x69, (char)0x72, (char)0x70, (char)0x70, (char)0x2d, (char)0x31, (char)0x63, (char)0x6c, (char)0x65, (char)0x65, (char)0x6e, (char)0x2d, (char)0x77, (char)0x74, (char)0x73, (char)0x6c, (char)0x72, (char)0x6e, (char)0x65, (char)0x65, (char)0x2d, (char)0x6c, (char)0x69, (char)0x2d, (char)0x6e, (char)0x74, (char)0x70, (char)0x72, (char)0x77, (char)0x77, (char)0x65, (char)0x65, (char)0x65, (char)0x2d, (char)0x76, (char)0x6e, (char)0x72, (char)0x69, (char)0x69, (char)0x73, (char)0x65, (char)0x74, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x72, (char)0x69, (char)0x72, (char)0x73, (char)0x72, (char)0x6f, (char)0x2e, (char)0x77, (char)0x2d, (char)0x2d, (char)0x6c, (char)0x6e, (char)0x65, (char)0x65, (char)0x6d, (char)0x73, (char)0x2e, (char)0x72, (char)0x65, (char)0x73, (char)0x40, (char)0x69, (char)0x32, (char)0x69, (char)0x32, (char)0x6e, (char)0x65, (char)0x32, (char)0x65, (char)0x74, (char)0x6d, (char)0x65, (char)0x74, (char)0x36, (char)0x6e, (char)0x72, (char)0x32, (char)0x6e, (char)0x65, (char)0x69, (char)0x32, (char)0x6f, (char)0x70, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x72, (char)0x69, (char)0x6e, (char)0x6d, (char)0x69, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x31, (char)0x72, (char)0x72, (char)0x73, (char)0x72, (char)0x70, (char)0x73, (char)0x72, (char)0x65, (char)0x65, (char)0x6e, (char)0x76, (char)0x69, (char)0x6d, (char)0x65, (char)0x6c, (char)0x65, (char)0x31, (char)0x74, (char)0x74, (char)0x72, (char)0x63, (char)0x2e, (char)0x69, (char)0x65, (char)0x2d, (char)0x6d, (char)0x72, (char)0x70, (char)0x6e, (char)0x6c, (char)0x65, (char)0x31, (char)0x73, (char)0x73, (char)0x40, (char)0x74, (char)0x72, (char)0x73, (char)0x2e, (char)0x74, (char)0x6e, (char)0x77, (char)0x6c, (char)0x6f, (char)0x70, (char)0x77, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x77, (char)0x69, (char)0x6e, (char)0x69, (char)0x2d, (char)0x72, (char)0x70, (char)0x70, (char)0x73, (char)0x2e, (char)0x76, (char)0x73, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x2d, (char)0x72, (char)0x65, (char)0x76, (char)0x69, (char)0x77, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x36, (char)0x77, (char)0x77, (char)0x77, (char)0x40, (char)0x2d, (char)0x6d, (char)0x69, (char)0x74, (char)0x72, (char)0x2d, (char)0x32, (char)0x6f, (char)0x76, (char)0x72, (char)0x2d, (char)0x2d, (char)0x65, (char)0x2e, (char)0x2e, (char)0x72, (char)0x6e, (char)0x32, (char)0x74, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x2e, (char)0x6d, (char)0x2d, (char)0x6f, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x65, (char)0x65, (char)0x69, (char)0x40, (char)0x69, (char)0x77, (char)0x65, (char)0x6c, (char)0x2d, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x72, (char)0x32, (char)0x40, (char)0x73, (char)0x65, (char)0x36, (char)0x76, (char)0x73, (char)0x72, (char)0x69, (char)0x63, (char)0x77, (char)0x72, (char)0x6c, (char)0x72, (char)0x6e, (char)0x74, (char)0x2d, (char)0x65, (char)0x69, (char)0x72, (char)0x70, (char)0x6d, (char)0x65, (char)0x6c, (char)0x73, (char)0x65, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x70, (char)0x2d, (char)0x31, (char)0x72, (char)0x74, (char)0x2e, (char)0x65, (char)0x74, (char)0x72, (char)0x74, (char)0x72, (char)0x70, (char)0x69, (char)0x40, (char)0x36, (char)0x2d, (char)0x74, (char)0x72, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x6e, (char)0x6d, (char)0x63, (char)0x76, (char)0x74, (char)0x6d, (char)0x70, (char)0x32, (char)0x70, (char)0x69, (char)0x69, (char)0x2d, (char)0x73, (char)0x72, (char)0x74, (char)0x65, (char)0x74, (char)0x74, (char)0x70, (char)0x2d, (char)0x31, (char)0x6c, (char)0x77, (char)0x65, (char)0x72, (char)0x70, (char)0x73, (char)0x36, (char)0x6c, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x76, (char)0x69, (char)0x2e, (char)0x6e, (char)0x72, (char)0x72, (char)0x36, (char)0x65, (char)0x69, (char)0x72, (char)0x69, (char)0x40, (char)0x6c, (char)0x74, (char)0x6c, (char)0x72, (char)0x2d, (char)0x70, (char)0x74, (char)0x76, (char)0x74, (char)0x6f, (char)0x72, (char)0x31, (char)0x73, (char)0x70, (char)0x65, (char)0x74, (char)0x69, (char)0x6e, (char)0x69, (char)0x6c, (char)0x70, (char)0x72, (char)0x65, (char)0x70, (char)0x72, (char)0x73, (char)0x69, (char)0x2d, (char)0x6d, (char)0x63, (char)0x2d, (char)0x72, (char)0x2d, (char)0x36, (char)0x73, (char)0x6e, (char)0x2d, (char)0x6d, (char)0x69, (char)0x76, (char)0x76, (char)0x6d, (char)0x74, (char)0x72, (char)0x77, (char)0x74, (char)0x2e, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x6d, (char)0x2e, (char)0x6c, (char)0x73, (char)0x6e, (char)0x6f, (char)0x76, (char)0x31, (char)0x74, (char)0x65, (char)0x65, (char)0x31, (char)0x69, (char)0x65, (char)0x32, (char)0x2d, (char)0x74, (char)0x2d, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x70, (char)0x65, (char)0x6e, (char)0x2d, (char)0x69, (char)0x32, (char)0x72, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x73, (char)0x77, (char)0x77, (char)0x2e, (char)0x6e, (char)0x72, (char)0x65, (char)0x70, (char)0x76, (char)0x40, (char)0x77, (char)0x65, (char)0x2d, (char)0x70, (char)0x36, (char)0x2d, (char)0x74, (char)0x65, (char)0x2d, (char)0x69, (char)0x74, (char)0x76, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x73, (char)0x31, (char)0x36, (char)0x69, (char)0x31, (char)0x74, (char)0x76, (char)0x65, (char)0x77, (char)0x6c, (char)0x6e, (char)0x6c, (char)0x32, (char)0x6e, (char)0x70, (char)0x73, (char)0x69, (char)0x69, (char)0x65, (char)0x72, (char)0x2d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x6c, (char)0x32, (char)0x77, (char)0x72, (char)0x69, (char)0x70, (char)0x76, (char)0x32, (char)0x65, (char)0x6c, (char)0x36, (char)0x65, (char)0x69, (char)0x31, (char)0x6e, (char)0x72, (char)0x6c, (char)0x6d, (char)0x65, (char)0x65, (char)0x77, (char)0x6e, (char)0x2d, (char)0x32, (char)0x77, (char)0x69, (char)0x65, (char)0x6d, (char)0x74, (char)0x77, (char)0x40, (char)0x65, (char)0x6e, (char)0x77, (char)0x73, (char)0x65, (char)0x72, (char)0x6c, (char)0x40, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x76, (char)0x72, (char)0x31, (char)0x2d, (char)0x65, (char)0x36, (char)0x72, (char)0x2d, (char)0x70, (char)0x69, (char)0x6e, (char)0x63, (char)0x31, (char)0x2d, (char)0x69, (char)0x6e, (char)0x65, (char)0x2d, (char)0x65, (char)0x2e, (char)0x77, (char)0x2d, (char)0x72, (char)0x76, (char)0x63, (char)0x69, (char)0x2d, (char)0x6d, (char)0x70, (char)0x2d, (char)0x6c, (char)0x69, (char)0x63, (char)0x69, (char)0x77, (char)0x6e, (char)0x69, (char)0x77, (char)0x36, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x74, (char)0x72, (char)0x6e, (char)0x65, (char)0x6f, (char)0x73, (char)0x2d, (char)0x2e, (char)0x72, (char)0x63, (char)0x76, (char)0x74, (char)0x36, (char)0x65, (char)0x72, (char)0x65, (char)0x6d, (char)0x32, (char)0x72, (char)0x70, (char)0x40, (char)0x65, (char)0x74, (char)0x6e, (char)0x32, (char)0x70, (char)0x2d, (char)0x31, (char)0x40, (char)0x6c, (char)0x65, (char)0x6c, (char)0x76, (char)0x69, (char)0x69, (char)0x76, (char)0x76, (char)0x73, (char)0x31, (char)0x6e, (char)0x65, (char)0x74, (char)0x65, (char)0x6d, (char)0x69, (char)0x2d, (char)0x72, (char)0x74, (char)0x74, (char)0x6c, (char)0x31, (char)0x74, (char)0x6e, (char)0x6e, (char)0x65, (char)0x77, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x6e, (char)0x2d, (char)0x2d, (char)0x2d, (char)0x72, (char)0x73, (char)0x76, (char)0x72, (char)0x72, (char)0x65, (char)0x72, (char)0x65, (char)0x72, (char)0x2d, (char)0x6c, (char)0x76, (char)0x77, (char)0x63, (char)0x77, (char)0x72, (char)0x6d, (char)0x72, (char)0x2e, (char)0x65, (char)0x73, (char)0x32, (char)0x72, (char)0x36, (char)0x77, (char)0x72, (char)0x72, (char)0x6d, (char)0x74, (char)0x2d, (char)0x72, (char)0x2e, (char)0x73, (char)0x73, (char)0x65, (char)0x77, (char)0x6e, (char)0x65, (char)0x69, (char)0x65, (char)0x2d, (char)0x65, (char)0x77, (char)0x6f, (char)0x74, (char)0x72, (char)0x32, (char)0x40, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x32, (char)0x70, (char)0x73, (char)0x72, (char)0x40, (char)0x2d, (char)0x65, (char)0x69, (char)0x65, (char)0x77, (char)0x65, (char)0x70, (char)0x40, (char)0x36, (char)0x72, (char)0x6c, (char)0x6d, (char)0x73, (char)0x69, (char)0x72, (char)0x72, (char)0x74, (char)0x36, (char)0x6c, (char)0x76, (char)0x65, (char)0x76, (char)0x2d, (char)0x74, (char)0x6c, (char)0x72, (char)0x72, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x69, (char)0x72, (char)0x6d, (char)0x40, (char)0x2d, (char)0x6e, (char)0x70, (char)0x73, (char)0x2d, (char)0x6d, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x65, (char)0x36, (char)0x6e, (char)0x77, (char)0x2d, (char)0x69, (char)0x2d, (char)0x32, (char)0x72, (char)0x6d, (char)0x72, (char)0x6c, (char)0x32, (char)0x6c, (char)0x73, (char)0x6d, (char)0x65, (char)0x36, (char)0x69, (char)0x69, (char)0x72, (char)0x77, (char)0x74, (char)0x6f, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x65, (char)0x73, (char)0x63, (char)0x65, (char)0x74, (char)0x74, (char)0x72, (char)0x65, (char)0x72, (char)0x2e, (char)0x6e, (char)0x73, (char)0x65, (char)0x76, (char)0x6c, (char)0x76, (char)0x77, (char)0x72, (char)0x6e, (char)0x6c, (char)0x32, (char)0x2d, (char)0x73, (char)0x65, (char)0x73, (char)0x2e, (char)0x76, (char)0x72, (char)0x65, (char)0x2d, (char)0x72, (char)0x77, (char)0x2d, (char)0x77, (char)0x70, (char)0x65, (char)0x6c, (char)0x72, (char)0x6e, (char)0x2e, (char)0x31, (char)0x73, (char)0x2e, (char)0x72, (char)0x6d, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x6d, (char)0x32, (char)0x70, (char)0x76, (char)0x76, (char)0x31, (char)0x76, (char)0x77, (char)0x65, (char)0x6e, (char)0x73, (char)0x63, (char)0x2e, (char)0x2d, (char)0x69, (char)0x6e, (char)0x69, (char)0x77, (char)0x6e, (char)0x65, (char)0x6d, (char)0x2d, (char)0x72, (char)0x6e, (char)0x74, (char)0x6e, (char)0x40, (char)0x73, (char)0x2d, (char)0x74, (char)0x74, (char)0x65, (char)0x72, (char)0x2d, (char)0x2d, (char)0x69, (char)0x73, (char)0x70, 
        (char)0x69, (char)0x6c, (char)0x72, (char)0x76, (char)0x6d, (char)0x74, (char)0x6e, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x63, (char)0x69, (char)0x65, (char)0x65, (char)0x72, (char)0x6f, (char)0x6e, (char)0x72, (char)0x72, (char)0x6c, (char)0x6e, (char)0x6e, (char)0x65, (char)0x6d, (char)0x74, (char)0x6c, (char)0x74, (char)0x65, (char)0x69, (char)0x2d, (char)0x6f, (char)0x69, (char)0x2e, (char)0x6e, (char)0x63, (char)0x65, (char)0x6c, (char)0x40, (char)0x70, (char)0x2d, (char)0x2d, (char)0x74, (char)0x73, (char)0x74, (char)0x40, (char)0x72, (char)0x74, (char)0x6c, (char)0x72, (char)0x6e, (char)0x6f, (char)0x73, (char)0x65, (char)0x74, (char)0x6d, (char)0x69, (char)0x32, (char)0x72, (char)0x65, (char)0x77, (char)0x6e, (char)0x76, (char)0x74, (char)0x73, (char)0x2d, (char)0x72, (char)0x6e, (char)0x69, (char)0x73, (char)0x40, (char)0x36, (char)0x2d, (char)0x6d, (char)0x2e, (char)0x65, (char)0x6d, (char)0x40, (char)0x69, (char)0x72, (char)0x72, (char)0x70, (char)0x65, (char)0x72, (char)0x76, (char)0x6c, (char)0x65, (char)0x76, (char)0x72, (char)0x65, (char)0x69, (char)0x65, (char)0x69, (char)0x6e, (char)0x72, (char)0x2d, (char)0x63, (char)0x72, (char)0x69, (char)0x6e, (char)0x72, (char)0x69, (char)0x6e, (char)0x69, (char)0x70, (char)0x6e, (char)0x2d, (char)0x69, (char)0x6c, (char)0x72, (char)0x2d, (char)0x65, (char)0x2d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6e, (char)0x76, (char)0x6e, (char)0x40, (char)0x2d, (char)0x65, (char)0x72, (char)0x72, (char)0x6f, (char)0x6f, (char)0x72, (char)0x6c, (char)0x65, (char)0x74, (char)0x73, (char)0x72, (char)0x70, (char)0x77, (char)0x69, (char)0x69, (char)0x6d, (char)0x6c, (char)0x6d, (char)0x6e, (char)0x2d, (char)0x65, (char)0x65, (char)0x65, (char)0x74, (char)0x6c, (char)0x2d, (char)0x74, (char)0x6f, (char)0x2d, (char)0x74, (char)0x70, (char)0x72, (char)0x6e, (char)0x73, (char)0x72, (char)0x69, (char)0x72, (char)0x2e, (char)0x6d, (char)0x69, (char)0x65, (char)0x65, (char)0x32, (char)0x70, (char)0x6c, (char)0x6c, (char)0x65, (char)0x77, (char)0x2d, (char)0x72, (char)0x6f, (char)0x70, (char)0x76, (char)0x65, (char)0x2d, (char)0x72, (char)0x69, (char)0x6d, (char)0x72, (char)0x36, (char)0x40, (char)0x6d, (char)0x72, (char)0x6c, (char)0x6d, (char)0x77, (char)0x6c, (char)0x6e, (char)0x69, (char)0x72, (char)0x6d, (char)0x76, (char)0x73, (char)0x2e, (char)0x73, (char)0x72, (char)0x77, (char)0x73, (char)0x76, (char)0x2d, (char)0x73, (char)0x76, (char)0x6d, (char)0x76, (char)0x65, (char)0x69, (char)0x76, (char)0x63, (char)0x65, (char)0x72, (char)0x31, (char)0x72, (char)0x69, (char)0x76, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x73, (char)0x6d, (char)0x31, (char)0x72, (char)0x6e, (char)0x72, (char)0x2d, (char)0x2d, (char)0x36, (char)0x72, (char)0x73, (char)0x77, (char)0x2d, (char)0x77, (char)0x36, (char)0x76, (char)0x72, (char)0x6d, (char)0x65, (char)0x2d, (char)0x72, (char)0x70, (char)0x2d, (char)0x74, (char)0x32, (char)0x6c, (char)0x63, (char)0x6d, (char)0x6f, (char)0x6e, (char)0x2e, (char)0x2d, (char)0x69, (char)0x65, (char)0x73, (char)0x6d, (char)0x65, (char)0x73, (char)0x6e, (char)0x6d, (char)0x6c, (char)0x65, (char)0x6e, (char)0x72, (char)0x72, (char)0x72, (char)0x32, (char)0x70, (char)0x65, (char)0x73, (char)0x6c, (char)0x6d, (char)0x70, (char)0x6d, (char)0x72, (char)0x6f, (char)0x65, (char)0x6c, (char)0x76, (char)0x73, (char)0x63, (char)0x73, (char)0x65, (char)0x6c, (char)0x2d, (char)0x6e, (char)0x72, (char)0x65, (char)0x65, (char)0x72, (char)0x2d, (char)0x70, (char)0x6d, (char)0x69, (char)0x69, (char)0x65, (char)0x2d, (char)0x6c, (char)0x72, (char)0x69, (char)0x6c, (char)0x2d, (char)0x74, (char)0x65, (char)0x65, (char)0x69, (char)0x31, (char)0x72, (char)0x69, (char)0x6d, (char)0x69, (char)0x74, (char)0x74, (char)0x73, (char)0x65, (char)0x32, (char)0x2d, (char)0x6f, (char)0x2d, (char)0x70, (char)0x72, (char)0x6f, (char)0x65, (char)0x69, (char)0x73, (char)0x32, (char)0x6d, (char)0x65, (char)0x2d, (char)0x65, (char)0x74, (char)0x6d, (char)0x6d, (char)0x73, (char)0x76, (char)0x6c, (char)0x69, (char)0x65, (char)0x2d, (char)0x73, (char)0x74, (char)0x65, (char)0x65, (char)0x72, (char)0x72, (char)0x74, (char)0x31, (char)0x2d, (char)0x76, (char)0x73, (char)0x2e, (char)0x2d, (char)0x2d, (char)0x72, (char)0x76, (char)0x77, (char)0x65, (char)0x72, (char)0x72, (char)0x40, (char)0x6e, (char)0x6c, (char)0x6d, (char)0x72, (char)0x74, (char)0x73, (char)0x72, (char)0x72, (char)0x65, (char)0x65, (char)0x2d, (char)0x6f, (char)0x74, (char)0x70, (char)0x63, (char)0xb8, (char)0xa1, (char)0x11, (char)0x6e, (char)0xd7, (char)0x74, (char)0x16, (char)0x7f, (char)0xb4, (char)0xba, (char)0x40, (char)0x93, (char)0x98, (char)0x00, (char)0x71, (char)0xcc, (char)0x42, (char)0xa7, (char)0x2f, (char)0x28, (char)0x69, (char)0xe7, (char)0x31, (char)0x48, (char)0x22, (char)0xa0, (char)0xe1, (char)0x45, (char)0xe3, (char)0xf7, (char)0x7f, (char)0x3a
    };
    char c2[] = {
        (char)0x5b, (char)0x52, (char)0xf1, (char)0x2d, (char)0x94, (char)0xcb, (char)0xb0, (char)0x86, (char)0xd8, (char)0xd3, (char)0xe3, (char)0x20, (char)0x88, (char)0x47, (char)0xcf, (char)0x5a, (char)0x49, (char)0xd2, (char)0x11, (char)0x30, (char)0x92, (char)0x17, (char)0x8d, (char)0xf4, (char)0x99, (char)0xf7, (char)0x6c, (char)0x8a, (char)0xbc, (char)0xe7, (char)0x5c, (char)0x58, (char)0x6a, (char)0x65, (char)0xed, (char)0x81, (char)0xdc, (char)0xdd, (char)0xcf, (char)0x83, (char)0xcd, (char)0xa4, (char)0xed, (char)0xa2, (char)0x5e, (char)0x63, (char)0xd9, (char)0x98, (char)0xf6, (char)0x2e, (char)0x15, (char)0x76, (char)0x9a, (char)0xc8, (char)0x8c, (char)0x42, (char)0x54, (char)0x44, (char)0xf4, (char)0x47, (char)0xf5, (char)0x96, (char)0xc9, (char)0x6e, (char)0x23, (char)0x09, (char)0x1a, (char)0x0d, (char)0xe3, (char)0x04, (char)0xe6, (char)0xed, (char)0x48, (char)0x49, (char)0x62, (char)0x31, (char)0xe8, (char)0x36, (char)0x04, (char)0xed, (char)0xb9, (char)0xe7, (char)0xa6, (char)0x35, (char)0x4d, (char)0xcd, (char)0xe3, (char)0xfa, (char)0xa0, (char)0xc8, (char)0x34, (char)0xbd, (char)0x62, (char)0x7b, (char)0xbc, (char)0xbe, (char)0x1c, (char)0x5b, (char)0x69, (char)0x1f, (char)0x9c, (char)0x30, (char)0x20, (char)0x48, (char)0x52, (char)0xd1, (char)0xb6, (char)0x5e, (char)0xa2, (char)0x6e, (char)0x06, (char)0x94, (char)0x72, (char)0x10, (char)0x56, (char)0x7c, (char)0x94, (char)0xa5, (char)0xc0, (char)0xaa, (char)0xea, (char)0x48, (char)0x61, (char)0x03, (char)0x14, (char)0x94, (char)0x09, (char)0x77, (char)0xd9, (char)0xa7, (char)0xfe, (char)0x78, (char)0x17, (char)0x95, (char)0x4f, (char)0x7e, (char)0xb0, (char)0x32, (char)0x63, (char)0x02, (char)0x17, (char)0x47, (char)0x1e, (char)0x7d, (char)0xb2, (char)0x7d, (char)0xb5, (char)0xcb, (char)0x9f, (char)0x61, (char)0x65, (char)0xed, (char)0x03, (char)0xd2, (char)0xdb, (char)0xd1, (char)0xb3, (char)0xd6, (char)0x1a, (char)0xf5, (char)0x67, (char)0x0b, (char)0x8b, (char)0x6b, (char)0x44, (char)0xf2, (char)0x62, (char)0x42, (char)0xc2, (char)0x4d, (char)0xe1, (char)0x5c, (char)0xfe, (char)0xc6, (char)0x19, (char)0x2b, (char)0xfb, (char)0x03, (char)0x0f, (char)0x1b, (char)0x89, (char)0x08, (char)0x86, (char)0x40, (char)0xca, (char)0x45, (char)0x15, (char)0xda, (char)0x65, (char)0xcc, (char)0x73, (char)0x00, (char)0x49, (char)0x4e, (char)0x48, (char)0x21, (char)0x25, (char)0xc6, (char)0xde, (char)0x26, (char)0x21, (char)0x1d, (char)0xea, (char)0x3c, (char)0x11, (char)0xac, (char)0xef, (char)0x34, (char)0x4c, (char)0x96, (char)0xcc, (char)0x5e, (char)0x26, (char)0xf3, (char)0xcd, (char)0x70, (char)0x0d, (char)0x62, (char)0xea, (char)0x09, (char)0x35, (char)0x2b, (char)0x1e, (char)0x60, (char)0xe4, (char)0x76, (char)0xd3, (char)0x65, (char)0x01, (char)0x8c, (char)0xab, (char)0xd4, (char)0x89, (char)0xad, (char)0x81, (char)0x9d, (char)0x04, (char)0x01, (char)0xd5, (char)0x55, (char)0x3c, (char)0xcb, (char)0x32, (char)0xe1, (char)0xb5, (char)0xd4, (char)0xda, (char)0xb4, (char)0xa9, (char)0x01, (char)0xb2, (char)0x10, (char)0xc7, (char)0xb1, (char)0xa9, (char)0x54, (char)0x66, (char)0x1d, (char)0xcc, (char)0xff, (char)0x54, (char)0x0b, (char)0x84, (char)0x37, (char)0xe0, (char)0x3a, (char)0xa5, (char)0x68, (char)0x80, (char)0x87, (char)0xbc, (char)0x3c, (char)0x0f, (char)0xda, (char)0x7e, (char)0x3c, (char)0x23, (char)0xfc, (char)0xd8, (char)0xc5, (char)0x52, (char)0xf7, (char)0x22, (char)0x12, (char)0x05, (char)0x9c, (char)0x68, (char)0x39, (char)0xb1, (char)0xed, (char)0x26, (char)0x24, (char)0x2b, (char)0x7e, (char)0x0b, (char)0xaf, (char)0x9e, (char)0x97, (char)0x45, (char)0x7b, (char)0xa9, (char)0xbc, (char)0x48, (char)0x0e, (char)0x66, (char)0x93, (char)0x32, (char)0x0d, (char)0x6b, (char)0xd6, (char)0xf0, (char)0x4f, (char)0x54, (char)0x18, (char)0xcd, (char)0xc9, (char)0x8c, (char)0xce, (char)0xc4, (char)0xa2, (char)0xff, (char)0x1e, (char)0x69, (char)0x17, (char)0x7e, (char)0xf4, (char)0x99, (char)0x09, (char)0x68, (char)0xa1, (char)0x9e, (char)0x1f, (char)0xbf, (char)0x90, (char)0xdc, (char)0x77, (char)0x5d, (char)0x50, (char)0x2b, (char)0x0e, (char)0xff, (char)0x96, (char)0xdc, (char)0x21, (char)0x2e, (char)0x74, (char)0x22, (char)0x28, (char)0x88, (char)0xa0, (char)0x00, (char)0x32, (char)0x15, (char)0xb0, (char)0xfd, (char)0xb1, (char)0xc9, (char)0x75, (char)0xb3, (char)0x3c, (char)0xbd, (char)0x89, (char)0xc5, (char)0xa4, (char)0x48, (char)0x17, (char)0xa9, (char)0xc9, (char)0x50, (char)0x61, (char)0x0c, (char)0x35, (char)0x31, (char)0x55, (char)0x11, (char)0xe3, (char)0x23, (char)0xe9, (char)0x3e, (char)0x78, (char)0x25, (char)0xdc, (char)0x50, (char)0xe8, (char)0x23, (char)0x5f, (char)0xb7, (char)0x3f, (char)0xc7, (char)0xae, (char)0xf0, (char)0x82, (char)0x35, (char)0x46, (char)0x34, (char)0x63, (char)0xcc, (char)0x5d, (char)0x96, (char)0xb8, (char)0x6a, (char)0x7a, (char)0x7f, (char)0x54, (char)0x27, (char)0x1a, (char)0xa4, (char)0x63, (char)0xdd, (char)0xb0, (char)0xb6, (char)0x17, (char)0x08, (char)0xa1, (char)0x2e, (char)0x95, (char)0x9e, (char)0xd4, (char)0x9b, (char)0x71, (char)0x83, (char)0x81, (char)0x6c, (char)0xea, (char)0xab, (char)0x00, (char)0x2e, (char)0xca, (char)0x60, (char)0xc1, (char)0x4b, (char)0x83, (char)0xa7, (char)0xab, (char)0x47, (char)0xe8, (char)0x1b, (char)0x5a, (char)0x78, (char)0x4f, (char)0xec, (char)0xbd, (char)0x62, (char)0x94, (char)0x25, (char)0x75, (char)0x2e, (char)0x64, (char)0xe7, (char)0x70, (char)0x13, (char)0xac, (char)0xe9, (char)0x89, (char)0x4f, (char)0x1e, (char)0x79, (char)0xbc, (char)0x15, (char)0x0c, (char)0x8d, (char)0x40, (char)0xe8, (char)0x16, (char)0x31, (char)0x7c, (char)0xb8, (char)0xa5, (char)0xd7, (char)0x21, (char)0x39, (char)0x93, (char)0x9b, (char)0xe6, (char)0x05, (char)0x81, (char)0xb6, (char)0x20, (char)0xa8, (char)0x5d, (char)0x73, (char)0x58, (char)0x8b, (char)0x66, (char)0x92, (char)0xac, (char)0x23, (char)0xa0, (char)0xf4, (char)0x8c, (char)0xab, (char)0x58, (char)0xae, (char)0xb6, (char)0x9c, (char)0x3c, (char)0x4d, (char)0x77, (char)0x5f, (char)0xae, (char)0xe2, (char)0x57, (char)0x89, (char)0x8f, (char)0xe4, (char)0x68, (char)0x81, (char)0x24, (char)0x7d, (char)0x3b, (char)0x99, (char)0x46, (char)0x9f, (char)0x7b, (char)0x9d, (char)0xa6, (char)0xdd, (char)0x99, (char)0xcf, (char)0xc1, (char)0x79, (char)0x04, (char)0x95, (char)0xce, (char)0x96, (char)0x7a, (char)0xd9, (char)0xb5, (char)0x6e, (char)0xcf, (char)0xd1, (char)0x72, (char)0x18, (char)0x97, (char)0x76, (char)0xe2, (char)0xb7, (char)0x38, (char)0x1e, (char)0x24, (char)0x0b, (char)0x09, (char)0x00, (char)0x8b, (char)0x28, (char)0x5d, (char)0xf8, (char)0xd0, (char)0x50, (char)0x7f, (char)0xeb, (char)0x3b, (char)0x37, (char)0x61, (char)0x0b, (char)0xd3, (char)0xff, (char)0x65, (char)0x7d, (char)0x88, (char)0x1e, (char)0x1d, (char)0xbb, (char)0x6c, (char)0xf5, (char)0xf8, (char)0xf3, (char)0x2b, (char)0x51, (char)0xd9, (char)0x6d, (char)0xc9, (char)0xbe, (char)0xbe, (char)0xd1, (char)0x94, (char)0x0e, (char)0x58, (char)0x2a, (char)0x0a, (char)0xe4, (char)0xf8, (char)0x28, (char)0x26, (char)0xc3, (char)0x74, (char)0x87, (char)0xd3, (char)0x81, (char)0x48, (char)0x6e, (char)0x9b, (char)0xd5, (char)0xa1, (char)0x60, (char)0x87, (char)0xfc, (char)0x1b, (char)0x06, (char)0x33, (char)0x0d, (char)0x87, (char)0xfa, (char)0x9b, (char)0xf9, (char)0x73, (char)0x6b, (char)0x0c, (char)0xdf, (char)0xea, (char)0xee, (char)0x32, (char)0x78, (char)0xe0, (char)0xf8, (char)0x18, (char)0x3f, (char)0xc3, (char)0x3b, (char)0x12, (char)0x88, (char)0x0b, (char)0xb2, (char)0x4a, (char)0x52, (char)0x64, (char)0x4e, (char)0x58, (char)0x54, (char)0x82, (char)0x52, (char)0x61, (char)0x54, (char)0x28, (char)0x1b, (char)0xf7, (char)0x99, (char)0x06, (char)0xa2, (char)0xad, (char)0x04, (char)0x19, (char)0x9f, (char)0x2e, (char)0x34, (char)0xe6, (char)0xf0, (char)0xee, (char)0xeb, (char)0x93, (char)0x9a, (char)0x9c, (char)0x73, (char)0x86, (char)0x23, (char)0x6d, (char)0x5d, (char)0xae, (char)0x64, (char)0xec, (char)0x6f, (char)0xf9, (char)0x7c, (char)0xc7, (char)0x46, (char)0x96, (char)0xdb, (char)0x44, (char)0xf4, (char)0xab, (char)0xc9, (char)0x67, (char)0x61, (char)0xb8, (char)0xec, (char)0xf0, (char)0x99, (char)0xe0, (char)0x4d, (char)0x45, (char)0xed, (char)0xa3, (char)0x1c, (char)0xe9, (char)0x68, (char)0x31, (char)0x85, (char)0xa5, (char)0xa1, (char)0xba, (char)0x08, (char)0xdb, (char)0x3f, (char)0x84, (char)0x75, (char)0x70, (char)0x24, (char)0xcd, (char)0x49, (char)0xd4, (char)0x07, (char)0xa8, (char)0xaa, (char)0x52, (char)0xd9, (char)0x55, (char)0x68, (char)0x8f, (char)0x78, (char)0xd2, (char)0x5d, (char)0x46, (char)0x23, (char)0x60, (char)0x76, (char)0xe1, (char)0x22, (char)0xdc, (char)0x2a, (char)0xeb, (char)0xac, (char)0xbc, (char)0xeb, (char)0xd6, (char)0x4c, (char)0x0f, (char)0xb5, (char)0xcb, (char)0x47, (char)0xce, (char)0x43, (char)0x59, (char)0x1d, (char)0x3e, (char)0xfc, (char)0x7f, (char)0x7c, (char)0x93, (char)0x9e, (char)0xef, (char)0xcd, (char)0x79, (char)0x5c, (char)0x08, (char)0x8e, (char)0xeb, (char)0xa8, (char)0x98, (char)0x3e, (char)0x95, (char)0xd1, (char)0x36, (char)0x42, (char)0x57, (char)0xfd, (char)0x6d, (char)0xdc, (char)0xe0, (char)0xa3, (char)0x3f, (char)0x46, (char)0x32, (char)0xb7, (char)0xff, (char)0x00, (char)0x4f, (char)0x7b, (char)0x23, (char)0x4d, (char)0xd0, (char)0xe5, (char)0xdd, (char)0x40, (char)0xab, (char)0xb2, (char)0xcb, (char)0x45, (char)0x92, (char)0x76, (char)0x7c, (char)0x5b, (char)0x98, (char)0xc7, (char)0xc0, (char)0x54, (char)0x34, (char)0x94, (char)0x8e, (char)0xbb, (char)0x28, (char)0xcf, (char)0xba, (char)0xd9, (char)0xa0, (char)0xe6, (char)0xf3, (char)0x65, (char)0x61, (char)0xd7, (char)0x10, (char)0xd3, (char)0xeb, (char)0xce, (char)0x21, (char)0x6a, (char)0xca, (char)0x61, (char)0xe7, (char)0x81, (char)0x15, (char)0x18, (char)0x4e, (char)0x71, (char)0xb0, (char)0x99, (char)0x62, (char)0xd9, (char)0xeb, (char)0xd0, (char)0x8b, (char)0xe9, (char)0xdf, (char)0x6a, (char)0x6d, (char)0x59, (char)0x0b, (char)0x45, (char)0x93, (char)0x38, (char)0xfe, (char)0xe6, (char)0x6a, (char)0xd1, (char)0x5f, (char)0xb6, (char)0xe9, (char)0x86, (char)0x01, (char)0x38, (char)0xab, (char)0x59, (char)0x5c, (char)0xd7, (char)0xb7, (char)0xfa, (char)0x81, (char)0x8a, (char)0xbe, (char)0xdc, (char)0xeb, (char)0x50, (char)0x7d, (char)0x81, (char)0xfa, (char)0x1b, (char)0x8f, (char)0xce, (char)0x53, (char)0x38, (char)0xe4, (char)0x8a, (char)0x82, (char)0xbe, (char)0x7d, (char)0xdc, (char)0xd8, (char)0x57, (char)0x5a, (char)0x48, (char)0xa3, (char)0x38, (char)0x74, (char)0x8a, (char)0xac, (char)0xf2, (char)0xfd, (char)0xbf, (char)0xcc, (char)0xd8, (char)0x08, (char)0x4d, (char)0x3e, (char)0xae, (char)0xa9, (char)0x00, (char)0x66, (char)0x06, (char)0xcb, (char)0xf3, 
        (char)0x50, (char)0xcc, (char)0x52, (char)0xc7, (char)0x4b, (char)0x16, (char)0x33, (char)0xa5, (char)0xde, (char)0x20, (char)0xed, (char)0x6a, (char)0xa7, (char)0x58, (char)0x5e, (char)0x4e, (char)0x7e, (char)0x29, (char)0xab, (char)0xb9, (char)0x65, (char)0x9d, (char)0x17, (char)0xe0, (char)0x1e, (char)0x79, (char)0x77, (char)0xf6, (char)0x1e, (char)0xa0, (char)0xcb, (char)0x0c, (char)0xf7, (char)0xc0, (char)0xe4, (char)0xf6, (char)0x3b, (char)0x60, (char)0x81, (char)0xfe, (char)0xed, (char)0xd9, (char)0x42, (char)0xa9, (char)0x61, (char)0x9d, (char)0xa8, (char)0xd7, (char)0xe8, (char)0xaa, (char)0x97, (char)0xad, (char)0xbb, (char)0xba, (char)0x13, (char)0x6e, (char)0x05, (char)0xa5, (char)0xce, (char)0x7a, (char)0x65, (char)0x6f, (char)0x55, (char)0xe3, (char)0xcf, (char)0xbc, (char)0x67, (char)0x14, (char)0x64, (char)0x57, (char)0x9c, (char)0x46, (char)0x14, (char)0xd6, (char)0x1d, (char)0x39, (char)0x1c, (char)0xd3, (char)0xe8, (char)0x98, (char)0x20, (char)0x5a, (char)0x1a, (char)0x05, (char)0x3b, (char)0x27, (char)0xd5, (char)0x84, (char)0xca, (char)0xd4, (char)0x0b, (char)0xc4, (char)0x1e, (char)0xd8, (char)0x46, (char)0x29, (char)0x48, (char)0x95, (char)0xdb, (char)0xe5, (char)0x58, (char)0x8a, (char)0x51, (char)0xc7, (char)0x74, (char)0x7f, (char)0x53, (char)0xa8, (char)0xbb, (char)0x58, (char)0xc0, (char)0x5b, (char)0xe1, (char)0xa7, (char)0x27, (char)0x36, (char)0x6c, (char)0xa6, (char)0x70, (char)0xec, (char)0x88, (char)0xcd, (char)0x9a, (char)0x70, (char)0xe1, (char)0xa0, (char)0xc7, (char)0xdd, (char)0x60, (char)0x71, (char)0xf4, (char)0x2a, (char)0x51, (char)0x98, (char)0x8e, (char)0xab, (char)0xb8, (char)0x13, (char)0x03, (char)0x48, (char)0x5f, (char)0x44, (char)0xf8, (char)0x88, (char)0xd9, (char)0x7d, (char)0xd3, (char)0xf1, (char)0x5f, (char)0xc4, (char)0x2b, (char)0x44, (char)0x15, (char)0x57, (char)0x31, (char)0xa4, (char)0xa1, (char)0xdb, (char)0x6d, (char)0x2a, (char)0x5a, (char)0x5a, (char)0xf7, (char)0xde, (char)0xd5, (char)0x23, (char)0x38, (char)0x00, (char)0xe5, (char)0x5c, (char)0x55, (char)0xe7, (char)0x37, (char)0x9c, (char)0xcb, (char)0x8b, (char)0xc0, (char)0x33, (char)0x42, (char)0x68, (char)0x23, (char)0x84, (char)0x7d, (char)0x89, (char)0x9d, (char)0xae, (char)0x59, (char)0x18, (char)0xae, (char)0xea, (char)0x46, (char)0x3f, (char)0xac, (char)0x57, (char)0x0d, (char)0x5d, (char)0x49, (char)0x14, (char)0x50, (char)0xe5, (char)0x70, (char)0x17, (char)0x73, (char)0x09, (char)0x11, (char)0x93, (char)0x6b, (char)0x02, (char)0x22, (char)0xb7, (char)0x63, (char)0xc9, (char)0xe6, (char)0xa4, (char)0xe3, (char)0xb1, (char)0xf7, (char)0xa6, (char)0x58, (char)0x8d, (char)0x14, (char)0xa1, (char)0xda, (char)0x6a, (char)0xb9, (char)0x38, (char)0xf9, (char)0x20, (char)0x45, (char)0x8c, (char)0xe6, (char)0x32, (char)0x23, (char)0x9d, (char)0x5f, (char)0xba, (char)0xcb, (char)0xb4, (char)0x95, (char)0xf9, (char)0xa9, (char)0x5c, (char)0x60, (char)0x03, (char)0x5a, (char)0x8c, (char)0xa7, (char)0xb9, (char)0x65, (char)0xa8, (char)0x84, (char)0x38, (char)0xc0, (char)0x25, (char)0xe6, (char)0xa7, (char)0xc0, (char)0x3b, (char)0xbc, (char)0x11, (char)0xed, (char)0x0e, (char)0x9a, (char)0x6f, (char)0xfe, (char)0x61, (char)0x79, (char)0x86, (char)0x92, (char)0x3a, (char)0xce, (char)0xe0, (char)0xb7, (char)0x70, (char)0xad, (char)0xe0, (char)0xcc, (char)0x88, (char)0x47, (char)0xd9, (char)0x2a, (char)0x3d, (char)0x41, (char)0x06, (char)0x77, (char)0x41, (char)0xbe, (char)0x3f, (char)0x55, (char)0x31, (char)0x54, (char)0x10, (char)0x14, (char)0x5b, (char)0xdf, (char)0x88, (char)0xb2, (char)0x9f, (char)0xff, (char)0x11, (char)0xb8, (char)0x11, (char)0xdc, (char)0x5e, (char)0x64, (char)0xf9, (char)0x97, (char)0x8a, (char)0x26, (char)0x6a, (char)0x44, (char)0xb4, (char)0x83, (char)0x83, (char)0x9b, (char)0x81, (char)0xaa, (char)0xfd, (char)0xb5, (char)0x8b, (char)0x16, (char)0x18, (char)0x2e, (char)0x5c, (char)0xe4, (char)0x5b, (char)0x8f, (char)0xdd, (char)0x7c, (char)0x1f, (char)0x33, (char)0x2f, (char)0xef, (char)0x57, (char)0x8c, (char)0x6a, (char)0x3f, (char)0x3c, (char)0x19, (char)0x5e, (char)0x73, (char)0x64, (char)0xc5, (char)0xaf, (char)0x1d, (char)0xa1, (char)0xb4, (char)0x11, (char)0xee, (char)0x6b, (char)0x7e, (char)0x66, (char)0xfb, (char)0xaa, (char)0x03, (char)0x17, (char)0xe4, (char)0xc9, (char)0x90, (char)0x4b, (char)0xf2, (char)0x50, (char)0x55, (char)0x71, (char)0xad, (char)0x31, (char)0x71, (char)0x49, (char)0xd7, (char)0x80, (char)0xd1, (char)0xa5, (char)0x9f, (char)0x6d, (char)0x71, (char)0x28, (char)0x2b, (char)0x65, (char)0xcf, (char)0x8d, (char)0xb1, (char)0x2a, (char)0x33, (char)0xdc, (char)0x93, (char)0xff, (char)0x86, (char)0xd7, (char)0xa6, (char)0xd0, (char)0x46, (char)0x66, (char)0x32, (char)0x3d, (char)0x18, (char)0x8c, (char)0xd3, (char)0xda, (char)0xf6, (char)0x1b, (char)0xa0, (char)0x2d, (char)0x29, (char)0xfd, (char)0x8d, (char)0x57, (char)0x2c, (char)0x82, (char)0xed, (char)0x38, (char)0x4a, (char)0x6f, (char)0xc4, (char)0x3c, (char)0x9a, (char)0x61, (char)0xcb, (char)0xe5, (char)0xcf, (char)0xd3, (char)0x83, (char)0xa1, (char)0x91, (char)0x93, (char)0x0d, (char)0x75, (char)0xfd, (char)0x4e, (char)0x2c, (char)0x83, (char)0xa0, (char)0x85, (char)0x27, (char)0x13, (char)0x5a, (char)0x24, (char)0xbd, (char)0x08, (char)0x1e, (char)0xe9, (char)0xab, (char)0x92, (char)0x41, (char)0xc2, (char)0x3a, (char)0xa0, (char)0xe1, (char)0xfd, (char)0x00, (char)0xb9, (char)0xf8, (char)0xca, (char)0x0b, (char)0x1a, (char)0x8e, (char)0xf6, (char)0x27, (char)0x9f, (char)0x5a, (char)0xf0, (char)0x23, (char)0x07, (char)0xc8, (char)0xbf, (char)0xf6, (char)0x74, (char)0xe7, (char)0xf8, (char)0x67, (char)0xfc, (char)0x28, (char)0x4e, (char)0x6a, (char)0x6c, (char)0xc6, (char)0x83, (char)0xe3, (char)0xf0, (char)0x01, (char)0xe0, (char)0x0f, (char)0x2d, (char)0xdf, (char)0x9e, (char)0x4b, (char)0x8b, (char)0x06, (char)0x15, (char)0x4c, (char)0x9f, (char)0xdf, (char)0x55, (char)0x14, (char)0x44, (char)0xde, (char)0x34, (char)0x35, (char)0x5a, (char)0xcb, (char)0xe5, (char)0xa7, (char)0xb5, (char)0x7e, (char)0x00, (char)0x31, (char)0x98, (char)0x5f, (char)0x51, (char)0x11, (char)0x37, (char)0xe1, (char)0xd2, (char)0x99, (char)0x8f, (char)0x70, (char)0x13, (char)0x40, (char)0xa0, (char)0xbe, (char)0xf8, (char)0xde, (char)0xac, (char)0x37, (char)0x06, (char)0xb6, (char)0x26, (char)0xf3, (char)0xb1, (char)0x97, (char)0x0b, (char)0x85, (char)0x68, (char)0x09, (char)0xa4, (char)0xc8, (char)0x34, (char)0x0a, (char)0x41, (char)0x6e, (char)0xac, (char)0x1a, (char)0x5b, (char)0xe0, (char)0x91, (char)0x6f, (char)0xa3, (char)0x0a, (char)0xf6, (char)0x05, (char)0x37, (char)0x32, (char)0xe1, (char)0x8e, (char)0xd8, (char)0xed, (char)0x55, (char)0xa3, (char)0x54, (char)0x3f, (char)0x62, (char)0x95, (char)0x82, (char)0xcf, (char)0x0a, (char)0x19, (char)0xb4, (char)0x9f, (char)0x04, (char)0xcc, (char)0x86, (char)0x7e, (char)0xf1, (char)0xe5, (char)0x8b, (char)0x67, (char)0x73, (char)0xa2, (char)0x46, (char)0x4e, (char)0xf2, (char)0x98, (char)0x94, (char)0xb5, (char)0xeb, (char)0xa5, (char)0xbd, (char)0xcb, (char)0x66, (char)0x82, (char)0xe9, (char)0x87, (char)0xe9, (char)0xe3, (char)0x50, (char)0x55, (char)0x4b, (char)0xd6, (char)0x67, (char)0x30, (char)0xe1, (char)0x7c, (char)0x15, (char)0x77, (char)0x29, (char)0xfd, (char)0x85, (char)0x67, (char)0x5a, (char)0xc4, (char)0xd5, (char)0x69, (char)0xfa, (char)0xc7, (char)0x66, (char)0x66, (char)0x49, (char)0xf7, (char)0x5a, (char)0xcd, (char)0xd1, (char)0x81, (char)0x5c, (char)0x74, (char)0x8d, (char)0xbf, (char)0xc5, (char)0xc2, (char)0xff, (char)0x4d, (char)0x90, (char)0xe8, (char)0x8e, (char)0x05, (char)0x00, (char)0xff, (char)0x7a, (char)0xd7, (char)0xb2, (char)0x7a, (char)0xad, (char)0x8b, (char)0xd6, (char)0x4b, (char)0x52, (char)0x09, (char)0x50, (char)0x4b
    };
    
    SrsHandshakeBytes bytes;
    ASSERT_EQ(ERROR_SUCCESS, bytes.create_c0c1());
    memcpy(bytes.c0c1, c0c1, 1537);
    ASSERT_EQ(ERROR_SUCCESS, bytes.create_s0s1s2());
    memcpy(bytes.s0s1s2, s0s1s2, 3073);
    ASSERT_EQ(ERROR_SUCCESS, bytes.create_c2());
    memcpy(bytes.c2, c2, 1536);
    
    MockEmptyIO eio;
    
    SrsSimpleHandshake hs;
    EXPECT_EQ(ERROR_SUCCESS, hs.handshake_with_client(&bytes, &eio));
    EXPECT_EQ(ERROR_SUCCESS, hs.handshake_with_server(&bytes, &eio));
}

/**
* bytes equal utility
*/
VOID TEST(ProtocolHandshakeTest, BytesEqual)
{
    char a1[] = { (char)0x01 };
    char b1[] = { (char)0x02 };
    char a2[] = { (char)0x01, (char)0x02 };
    char b2[] = { (char)0x02, (char)0x03 };
    
    EXPECT_TRUE(srs_bytes_equals(NULL, NULL, 0));
    EXPECT_FALSE(srs_bytes_equals(a1, NULL, 1));
    EXPECT_FALSE(srs_bytes_equals(NULL, a1, 1));
    EXPECT_FALSE(srs_bytes_equals(a1, b1, 1));
    EXPECT_TRUE(srs_bytes_equals(a1, a1, 1));
    EXPECT_TRUE(srs_bytes_equals(a1, a2, 1));
    EXPECT_FALSE(srs_bytes_equals(a1, b2, 1));
}

/**
* resolve vhost from tcUrl.
*/
VOID TEST(ProtocolUtilityTest, VhostResolve)
{
    std::string vhost = "vhost";
    std::string app = "app";
    std::string param;
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("vhost", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());
    
    app = "app?vhost=changed";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());
    
    app = "app?vhost=changed1&&query=true";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed1", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());
    
    app = "app?other=true&&vhost=changed2&&query=true";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed2", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());
    
    app = "app...other...true...vhost...changed3...query...true";
    srs_vhost_resolve(vhost, app, param);
    EXPECT_STREQ("changed3", vhost.c_str());
    EXPECT_STREQ("app", app.c_str());
}

/**
* discovery tcUrl to schema/vhost/host/port/app
*/
VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
{
    std::string tcUrl; 
    std::string schema; std::string host; std::string vhost; 
    std::string app; std::string port; std::string param;
    
    tcUrl = "rtmp://127.0.0.1:1935/live";
    srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", host.c_str());
    EXPECT_STREQ("127.0.0.1", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("1935", port.c_str());
    
    tcUrl = "rtmp://127.0.0.1:19351/live";
    srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", host.c_str());
    EXPECT_STREQ("127.0.0.1", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("19351", port.c_str());
    
    tcUrl = "rtmp://127.0.0.1:19351/live?vhost=demo";
    srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", host.c_str());
    EXPECT_STREQ("demo", vhost.c_str());
    EXPECT_STREQ("live", app.c_str());
    EXPECT_STREQ("19351", port.c_str());
    
    tcUrl = "rtmp://127.0.0.1:19351/live/show?vhost=demo";
    srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
    EXPECT_STREQ("rtmp", schema.c_str());
    EXPECT_STREQ("127.0.0.1", host.c_str());
    EXPECT_STREQ("demo", vhost.c_str());
    EXPECT_STREQ("live/show", app.c_str());
    EXPECT_STREQ("19351", port.c_str());
}

/**
* generate tcUrl from ip/vhost/app/port
*/
VOID TEST(ProtocolUtilityTest, GenerateTcUrl)
{
    string ip; string vhost; string app; string port; string tcUrl; string param;
    
    ip = "127.0.0.1"; vhost = "__defaultVhost__"; app = "live"; port = "1935";
    tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
    EXPECT_STREQ("rtmp://127.0.0.1/live", tcUrl.c_str());
    
    ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "1935";
    tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
    EXPECT_STREQ("rtmp://demo/live", tcUrl.c_str());
    
    ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "19351";
    tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
    EXPECT_STREQ("rtmp://demo:19351/live", tcUrl.c_str());
}

/**
* shared ptr message array test
*/
VOID TEST(ProtocolMsgArrayTest, MessageArray)
{
    SrsMessageHeader header;
    SrsSharedPtrMessage msg;
    char* payload = new char[1024];
    EXPECT_TRUE(ERROR_SUCCESS == msg.create(&header, payload, 1024));
    EXPECT_EQ(0, msg.count());
    
    if (true) {
        SrsSharedPtrMessageArray arr(3);
        
        arr.msgs[0] = msg.copy();
        EXPECT_EQ(1, msg.count());
        
        arr.msgs[1] = msg.copy();
        EXPECT_EQ(2, msg.count());
        
        arr.msgs[2] = msg.copy();
        EXPECT_EQ(3, msg.count());
    }
    EXPECT_EQ(0, msg.count());
    
    if (true) {
        SrsSharedPtrMessageArray arr(3);
        
        arr.msgs[0] = msg.copy();
        EXPECT_EQ(1, msg.count());
        
        arr.msgs[2] = msg.copy();
        EXPECT_EQ(2, msg.count());
    }
    EXPECT_EQ(0, msg.count());
}

/**
* set/get timeout of protocol stack
*/
VOID TEST(ProtocolStackTest, ProtocolTimeout)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    EXPECT_TRUE((int64_t)ST_UTIME_NO_TIMEOUT == proto.get_recv_timeout());
    EXPECT_TRUE((int64_t)ST_UTIME_NO_TIMEOUT == proto.get_send_timeout());
    
    proto.set_recv_timeout(10);
    EXPECT_TRUE(10 == proto.get_recv_timeout());
    
    proto.set_send_timeout(10);
    EXPECT_TRUE(10 == proto.get_send_timeout());
}

/**
* get recv/send bytes of protocol stack.
*/
VOID TEST(ProtocolStackTest, ProtocolBytes)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    EXPECT_TRUE(0 == proto.get_recv_bytes());
    EXPECT_TRUE(0 == proto.get_send_bytes());
    
    SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    EXPECT_TRUE(0 < proto.get_send_bytes());
}

/**
* recv a SrsConnectAppPacket packet.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // packet is SrsConnectAppPacket
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0xa1, (char)0x14, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        (char)0xC3, /*next chunk.*/         (char)0x0d, (char)0x76, (char)0x69, (char)0x64,
        (char)0x65, (char)0x6f, (char)0x46, (char)0x75, (char)0x6e, (char)0x63, (char)0x74, (char)0x69, (char)0x6f, (char)0x6e, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x07, (char)0x70, (char)0x61, (char)0x67, (char)0x65, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x62, (char)0x68,
        (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73, (char)0x2e,
        (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x73,
        (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2e, (char)0x68, (char)0x74, (char)0x6d, (char)0x6c,
        (char)0x3f, (char)0x76, (char)0x68, (char)0x6f, (char)0x73, (char)0x74, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61,
        (char)0x6d, (char)0x3d, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x26, (char)0x73, (char)0x65, (char)0x72,
        (char)0x76, (char)0x65, (char)0x72, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x70, (char)0x6f, (char)0x72, (char)0x74, 
        (char)0xC3, /*next chunk.*/         (char)0x3d, (char)0x31, (char)0x39, (char)0x33,
        (char)0x35, (char)0x00, (char)0x0e, (char)0x6f, (char)0x62, (char)0x6a, (char)0x65, (char)0x63, (char)0x74, (char)0x45, (char)0x6e, (char)0x63, (char)0x6f, (char)0x64, (char)0x69, (char)0x6e,
        (char)0x67, (char)0x00, (char)0x40, (char)0x08, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    
    SrsPacket* pkt = NULL;
    EXPECT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
    SrsAutoFree(SrsPacket, pkt);
    
    SrsConnectAppPacket* spkt = dynamic_cast<SrsConnectAppPacket*>(pkt);
    ASSERT_TRUE(NULL != spkt);
}

// for librtmp, if ping, it will send a fresh stream with fmt=1,
// 0x42             where: fmt=1, cid=2, protocol contorl user-control message
// 0x00 0x00 0x00   where: timestamp=0
// 0x00 0x00 0x06   where: payload_length=6
// 0x04             where: message_type=4(protocol control user-control message)
// 0x00 0x06            where: event Ping(0x06)
// 0x00 0x00 0x0d 0x0f  where: event data 4bytes ping timestamp.
// @see: https://github.com/simple-rtmp-server/srs/issues/98
VOID TEST(ProtocolStackTest, ProtocolRecvMessageBug98)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // packet is SrsConnectAppPacket
    char data[] = {
        (char)0x42, // 1bytes chunk header
        (char)0x00, (char)0x00, (char)0x00, // timestamp=0
        (char)0x00, (char)0x00, (char)0x06, // payload_length=6
        (char)0x04, // message_type=4(protocol control user-control message)
        (char)0x00, (char)0x06, // event Ping(0x06)
        (char)0x00, (char)0x00, (char)0x0d, (char)0x0f // event data 4bytes ping timestamp.
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    
    SrsPacket* pkt = NULL;
    EXPECT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
    SrsAutoFree(SrsPacket, pkt);
    
    SrsUserControlPacket* spkt = dynamic_cast<SrsUserControlPacket*>(pkt);
    ASSERT_TRUE(NULL != spkt);
    EXPECT_EQ(SrcPCUCPingRequest, spkt->event_type);
    EXPECT_EQ(0x0d0f, spkt->event_data);
}

/**
* recv a SrsSetWindowAckSizePacket packet.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // packet is SrsSetWindowAckSizePacket
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x02, 
        (char)0x00, (char)0x00, (char)0x00, 
        (char)0x00, (char)0x00, (char)0x04, 
        (char)0x05, 
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    
    SrsPacket* pkt = NULL;
    EXPECT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
    SrsAutoFree(SrsPacket, pkt);
    
    SrsSetWindowAckSizePacket* spkt = dynamic_cast<SrsSetWindowAckSizePacket*>(pkt);
    ASSERT_TRUE(NULL != spkt);
    EXPECT_EQ(0x0763, spkt->ackowledgement_window_size);
}

/**
* recv a video message.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
}

/**
* recv a audio message.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvAMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // audio message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x08, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_audio());
}

/**
* recv a video message in 2 chunk packets.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVMessage2Trunk)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        (char)0xC3, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
}

/**
* recv video and audio, interlaced in chunks.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video and audio, interlaced in chunks.
* the continue chunks use fmt=1 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt1)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video and audio, interlaced in chunks.
* the continue chunks use fmt=2 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            // msg payload start
            /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video and audio, interlaced in chunks.
* the continue chunks use fmt=3 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt3)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x00, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3, 
            // msg payload start
            /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
    }
}

/**
* recv video, audio and video, interlaced in chunks.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio and video, interlaced in chunks.
* the continue chunks use fmt=1 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt1)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x12, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x22, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio and video, interlaced in chunks.
* the continue chunks use fmt=2 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83, 
            (char)0x00, (char)0x00, (char)0x12, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x22, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio and video, interlaced in chunks.
* the continue chunks use fmt=3 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt3)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3, 
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x30, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=2 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=3 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3, 
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0xC3, 
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x30, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=1 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=1 header,
* last video changed length
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x20, // length, 288
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=2 header
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83, 
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
}

/**
* recv video, audio, video and video, interlaced in chunks.
* the continue chunks use fmt=1, last video with fmt=2 header,
* last video changed length
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x03, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x10, // length, 272
            (char)0x09, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x04, 
            (char)0x00, (char)0x00, (char)0x15, // timestamp
            (char)0x00, (char)0x00, (char)0x90, // length, 144
            (char)0x08, // message_type
            (char)0x01, (char)0x00, (char)0x00, (char)0x00, // stream_id
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x43, 
            (char)0x00, (char)0x00, (char)0x10, // timestamp
            (char)0x00, (char)0x01, (char)0x20, // length, 288
            (char)0x09, // message_type
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // audio message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC4, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#1
    if (true) {
        char data[] = {
            // 12bytes header, 1byts chunk header, 11bytes msg heder
            (char)0x83, 
            (char)0x00, (char)0x00, (char)0x20, // timestamp
            // msg payload start
            (char)0x02, (char)0x00, (char)0x07, (char)0x63,
            (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
            (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
            (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
            (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
            (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
            (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
            (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
            (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#2
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
            (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
            (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
            (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
            (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
            (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
            (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    // video message, chunk#3
    if (true) {
        char data[] = {
            (char)0xC3, /*next chunk.*/
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
            (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
        };
        bio.in_buffer.append(data, sizeof(data));
    }
    
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x10, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
        EXPECT_EQ(0x110, msg->header.payload_length);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_audio());
        EXPECT_EQ(0x15, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x20, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
        EXPECT_EQ(0x120, msg->header.payload_length);
    }
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_video());
        EXPECT_EQ(0x40, msg->header.timestamp);
        EXPECT_EQ(0x01, msg->header.stream_id);
        EXPECT_EQ(0x120, msg->header.payload_length);
    }
}

/**
* recv video, with extended timestamp.
* small timestamp < 0xffffff
*/
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x00, (char)0x00, (char)0x00, (char)0x10, // extended timestamp
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    EXPECT_EQ(0x10, msg->header.timestamp);
}

/**
* recv video, with extended timestamp.
* big timestamp > 0xffffff
*/
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x7f, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    EXPECT_EQ(0x7f010203, msg->header.timestamp);
}

/**
* recv video, with extended timestamp.
* always use 31bits timestamp.
*/
// always use 31bits timestamp, for some server may use 32bits extended timestamp.
// @see https://github.com/simple-rtmp-server/srs/issues/111
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage3)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    /**
    * parse the message header.
    *   3bytes: timestamp delta,    fmt=0,1,2
    *   3bytes: payload length,     fmt=0,1
    *   1bytes: message type,       fmt=0,1
    *   4bytes: stream id,          fmt=0
    * where:
    *   fmt=0, 0x0X
    *   fmt=1, 0x4X
    *   fmt=2, 0x8X
    *   fmt=3, 0xCX
    */
    
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0xff, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // always use 31bits timestamp
    EXPECT_EQ(0x7f010203, msg->header.timestamp);
}

/**
* recv video, with extended timestamp, in 2 chunks packet.
* always send extended timestamp in 0xCX chunk packets.
*/
/**
* RTMP specification and ffmpeg/librtmp is false,
* but, adobe changed the specification, so flash/FMLE/FMS always true.
* default to true to support flash/FMLE/FMS.
* 
* ffmpeg/librtmp may donot send this filed, need to detect the value.
* @see also: http://blog.csdn.net/win_lin/article/details/13363699
* compare to the chunk timestamp, which is set by chunk message header
* type 0,1 or 2.
*
* @remark, nginx send the extended-timestamp in sequence-header,
* and timestamp delta in continue C1 chunks, and so compatible with ffmpeg,
* that is, there is no continue chunks and extended-timestamp in nginx-rtmp.
*
* @remark, srs always send the extended-timestamp, to keep simple,
* and compatible with adobe products.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC3,
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC3,
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 0xCX with extended timestamp.
    EXPECT_EQ(0x00010203, msg->header.timestamp);
}

/**
* recv video, with extended timestamp, in 2 chunks packet.
* never send extended timestamp in 0xCX chunk packets.
*/
// FFMPEG/librtmp, RTMP specification standard protocol.
VOID TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0xff, (char)0xff, (char)0xff, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC3,
        /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC3,
        /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 0xCX without extended timestamp.
    EXPECT_EQ(0x00010203, msg->header.timestamp);
}

/**
* a video message, in 2 chunks packet.
* use 1B chunk header, min chunk id is 2.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMin)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x02, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC2, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC2, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 1B cid(6bits), min is 2
    EXPECT_EQ(0x02, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 1B chunk header, cid in 2-63
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BNormal)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x09, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC9, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC9, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 1B cid(6bits), cid in 2-63
    EXPECT_EQ(0x09, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 1B chunk header, max chunk id is 63.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMax)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x3F, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xFF, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xFF, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 1B cid(6bits), max is 63
    EXPECT_EQ(0x3F, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, min chunk id is 64.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BMin)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC0, (char)0x00, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC0, (char)0x00, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(8bits), min is 64
    EXPECT_EQ(64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, cid in 64-319
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC0, (char)0x10, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC0, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(8bits), cid in 64-319
    EXPECT_EQ(0x10+64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, cid in 64-319
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0x11,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC0, (char)0x11, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC0, (char)0x11, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(8bits), cid in 64-319
    EXPECT_EQ(0x11+64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 2B chunk header, max chunk id is 319.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BMax)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x00, (char)0xFF, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC0, (char)0xFF, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC0, (char)0xFF, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(68bits), max is 319
    EXPECT_EQ(319, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, min chunk id is 64.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMin)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x00, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x00, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), min is 64
    EXPECT_EQ(64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x00, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x10, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC1, (char)0x00, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0x10*256+64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599, greater than 319
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal2)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x01, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC1, (char)0x01, (char)0x10, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC1, (char)0x01, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0x01 + (0x10*256) + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599, greater than 319
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal3)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0xFF, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0x10, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0xFF + (0x10*256) + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, cid in 64-65599, greater than 319
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal4)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0x02, (char)0x10,
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC1, (char)0x02, (char)0x10, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC1, (char)0x02, (char)0x10, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 3B cid(16bits), cid in 64-65599
    EXPECT_EQ(0x02 + (0x10*256) + 64, msg->header.perfer_cid);
}

/**
* a video message, in 2 chunks packet.
* use 3B chunk header, max chunk id is 65599.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMax)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x01, (char)0xFF, (char)0xFF, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0xFF, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // chunk #2
        (char)0xC1, (char)0xFF, (char)0xFF, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // 2B cid(16bits), max is 65599
    EXPECT_EQ(65599, msg->header.perfer_cid);
}

/**
* recv a zero length video message.
*/
VOID TEST(ProtocolStackTest, ProtocolRecvV0LenMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // video #1
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x00, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        
        // video #2
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x00, (char)0x04, // length
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x00, (char)0x00, (char)0x07, (char)0x63
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
    SrsAutoFree(SrsMessage, msg);
    EXPECT_TRUE(msg->header.is_video());
    // protocol stack will ignore the empty video message.
    EXPECT_EQ(4, msg->header.payload_length);
}

/**
* send a video message
*/
VOID TEST(ProtocolStackTest, ProtocolSendVMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    char data[] = {0x01, 0x02, 0x03, 0x04};
    
    SrsMessage* msg = new SrsCommonMessage();
    msg->size = sizeof(data);
    msg->payload = new char[msg->size];
    memcpy(msg->payload, data, msg->size);
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(msg, 0));
    EXPECT_EQ(16, bio.out_buffer.length());
}

/**
* send a SrsConnectAppPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsConnectAppPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
    pkt->command_object = SrsAmf0Any::object();
    pkt->args = SrsAmf0Any::object();
    
    pkt->command_object->set("version", SrsAmf0Any::str("1.0.0"));
    pkt->command_object->set("build", SrsAmf0Any::number(150));
    SrsAmf0Object* data = SrsAmf0Any::object();
    pkt->command_object->set("data", data);
    
    data->set("server", SrsAmf0Any::str("SRS"));
    data->set("signature", SrsAmf0Any::str("simple-rtmp-server"));
    
    pkt->args->set("info", SrsAmf0Any::str("NetStream.Status.Info"));
    pkt->args->set("desc", SrsAmf0Any::str("connected"));
    pkt->args->set("data", SrsAmf0Any::ecma_array());
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0xb2, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f,
        (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x07, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f,
        (char)0x6e, (char)0x02, (char)0x00, (char)0x05, (char)0x31, (char)0x2e, (char)0x30, (char)0x2e,
        (char)0x30, (char)0x00, (char)0x05, (char)0x62, (char)0x75, (char)0x69, (char)0x6c, (char)0x64,
        (char)0x00, (char)0x40, (char)0x62, (char)0xc0, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x04, (char)0x64, (char)0x61, (char)0x74, (char)0x61, (char)0x03,
        (char)0x00, (char)0x06, (char)0x73, (char)0x65, (char)0x72, (char)0x76, (char)0x65, (char)0x72,
        (char)0x02, (char)0x00, (char)0x03, (char)0x53, (char)0x52, (char)0x53, (char)0x00, (char)0x09,
        (char)0x73, (char)0x69, (char)0x67, (char)0x6e, (char)0x61, (char)0x74, (char)0x75, (char)0x72,
        (char)0x65, (char)0x02, (char)0x00, (char)0x12, (char)0x73, (char)0x69, (char)0x6d, (char)0x70,
        (char)0x6c, (char)0x65, (char)0x2d, (char)0x72, (char)0x74, (char)0x6d, (char)0x70, (char)0x2d,
        (char)0x73, (char)0x65, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x00, (char)0x00,
        (char)0x09, (char)0x00, (char)0x00, (char)0x09, (char)0x03, (char)0x00, (char)0x04, (char)0x69,
        (char)0x6e, (char)0x66, (char)0x6f, (char)0x02, (char)0x00, (char)0x15, (char)0x4e, (char)0x65,
        (char)0x74, (char)0x53, (char)0x74, (char)0x72, (char)0xc3, (char)0x65, (char)0x61, (char)0x6d,
        (char)0x2e, (char)0x53, (char)0x74, (char)0x61, (char)0x74, (char)0x75, (char)0x73, (char)0x2e,
        (char)0x49, (char)0x6e, (char)0x66, (char)0x6f, (char)0x00, (char)0x04, (char)0x64, (char)0x65,
        (char)0x73, (char)0x63, (char)0x02, (char)0x00, (char)0x09, (char)0x63, (char)0x6f, (char)0x6e,
        (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x65, (char)0x64, (char)0x00, (char)0x04,
        (char)0x64, (char)0x61, (char)0x74, (char)0x61, (char)0x08, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x09, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsConnectAppResPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsConnectAppResPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
    pkt->props = SrsAmf0Any::object();
    pkt->info = SrsAmf0Any::object();
    
    pkt->props->set("version", SrsAmf0Any::str("1.0.0"));
    pkt->props->set("build", SrsAmf0Any::number(150));
    SrsAmf0Object* data = SrsAmf0Any::object();
    pkt->props->set("data", data);
    
    data->set("server", SrsAmf0Any::str("SRS"));
    data->set("signature", SrsAmf0Any::str("simple-rtmp-server"));
    
    pkt->info->set("info", SrsAmf0Any::str("NetStream.Status.Info"));
    pkt->info->set("desc", SrsAmf0Any::str("connected"));
    pkt->info->set("data", SrsAmf0Any::ecma_array());
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0xb2, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x5f,
        (char)0x72, (char)0x65, (char)0x73, (char)0x75, (char)0x6c, (char)0x74, (char)0x00, (char)0x3f,
        (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x07, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f,
        (char)0x6e, (char)0x02, (char)0x00, (char)0x05, (char)0x31, (char)0x2e, (char)0x30, (char)0x2e,
        (char)0x30, (char)0x00, (char)0x05, (char)0x62, (char)0x75, (char)0x69, (char)0x6c, (char)0x64,
        (char)0x00, (char)0x40, (char)0x62, (char)0xc0, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x04, (char)0x64, (char)0x61, (char)0x74, (char)0x61, (char)0x03,
        (char)0x00, (char)0x06, (char)0x73, (char)0x65, (char)0x72, (char)0x76, (char)0x65, (char)0x72,
        (char)0x02, (char)0x00, (char)0x03, (char)0x53, (char)0x52, (char)0x53, (char)0x00, (char)0x09,
        (char)0x73, (char)0x69, (char)0x67, (char)0x6e, (char)0x61, (char)0x74, (char)0x75, (char)0x72,
        (char)0x65, (char)0x02, (char)0x00, (char)0x12, (char)0x73, (char)0x69, (char)0x6d, (char)0x70,
        (char)0x6c, (char)0x65, (char)0x2d, (char)0x72, (char)0x74, (char)0x6d, (char)0x70, (char)0x2d,
        (char)0x73, (char)0x65, (char)0x72, (char)0x76, (char)0x65, (char)0x72, (char)0x00, (char)0x00,
        (char)0x09, (char)0x00, (char)0x00, (char)0x09, (char)0x03, (char)0x00, (char)0x04, (char)0x69,
        (char)0x6e, (char)0x66, (char)0x6f, (char)0x02, (char)0x00, (char)0x15, (char)0x4e, (char)0x65,
        (char)0x74, (char)0x53, (char)0x74, (char)0x72, (char)0xc3, (char)0x65, (char)0x61, (char)0x6d,
        (char)0x2e, (char)0x53, (char)0x74, (char)0x61, (char)0x74, (char)0x75, (char)0x73, (char)0x2e,
        (char)0x49, (char)0x6e, (char)0x66, (char)0x6f, (char)0x00, (char)0x04, (char)0x64, (char)0x65,
        (char)0x73, (char)0x63, (char)0x02, (char)0x00, (char)0x09, (char)0x63, (char)0x6f, (char)0x6e,
        (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x65, (char)0x64, (char)0x00, (char)0x04,
        (char)0x64, (char)0x61, (char)0x74, (char)0x61, (char)0x08, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x09, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsCallPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsCallPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    SrsCallPacket* pkt = new SrsCallPacket();
    pkt->command_name = "my_call";
    pkt->command_object = SrsAmf0Any::null();
    pkt->arguments = args;
    
    args->set("video_id", SrsAmf0Any::number(100));
    args->set("url", SrsAmf0Any::str("http://ossrs.net/api/v1/videos/100"));
    args->set("date", SrsAmf0Any::str("2014-07-11 16:20:10.2984"));
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x76, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x6d,
        (char)0x79, (char)0x5f, (char)0x63, (char)0x61, (char)0x6c, (char)0x6c, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x03, (char)0x00, (char)0x08, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f,
        (char)0x5f, (char)0x69, (char)0x64, (char)0x00, (char)0x40, (char)0x59, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03, (char)0x75, (char)0x72,
        (char)0x6c, (char)0x02, (char)0x00, (char)0x22, (char)0x68, (char)0x74, (char)0x74, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73,
        (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x2f, (char)0x61, (char)0x70, (char)0x69,
        (char)0x2f, (char)0x76, (char)0x31, (char)0x2f, (char)0x76, (char)0x69, (char)0x64, (char)0x65,
        (char)0x6f, (char)0x73, (char)0x2f, (char)0x31, (char)0x30, (char)0x30, (char)0x00, (char)0x04,
        (char)0x64, (char)0x61, (char)0x74, (char)0x65, (char)0x02, (char)0x00, (char)0x18, (char)0x32,
        (char)0x30, (char)0x31, (char)0x34, (char)0x2d, (char)0x30, (char)0x37, (char)0x2d, (char)0x31,
        (char)0x31, (char)0x20, (char)0x31, (char)0x36, (char)0x3a, (char)0x32, (char)0x30, (char)0x3a,
        (char)0x31, (char)0x30, (char)0x2e, (char)0x32, (char)0x39, (char)0x38, (char)0x34, (char)0x00,
        (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsCallResPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsCallResPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    SrsCallResPacket* pkt = new SrsCallResPacket(0);
    pkt->command_name = "_result";
    pkt->command_object = SrsAmf0Any::null();
    pkt->response = args;
    
    args->set("video_id", SrsAmf0Any::number(100));
    args->set("url", SrsAmf0Any::str("http://ossrs.net/api/v1/videos/100"));
    args->set("date", SrsAmf0Any::str("2014-07-11 16:20:10.2984"));
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x76, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x5f,
        (char)0x72, (char)0x65, (char)0x73, (char)0x75, (char)0x6c, (char)0x74, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x03, (char)0x00, (char)0x08, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f,
        (char)0x5f, (char)0x69, (char)0x64, (char)0x00, (char)0x40, (char)0x59, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03, (char)0x75, (char)0x72,
        (char)0x6c, (char)0x02, (char)0x00, (char)0x22, (char)0x68, (char)0x74, (char)0x74, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73,
        (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x2f, (char)0x61, (char)0x70, (char)0x69,
        (char)0x2f, (char)0x76, (char)0x31, (char)0x2f, (char)0x76, (char)0x69, (char)0x64, (char)0x65,
        (char)0x6f, (char)0x73, (char)0x2f, (char)0x31, (char)0x30, (char)0x30, (char)0x00, (char)0x04,
        (char)0x64, (char)0x61, (char)0x74, (char)0x65, (char)0x02, (char)0x00, (char)0x18, (char)0x32,
        (char)0x30, (char)0x31, (char)0x34, (char)0x2d, (char)0x30, (char)0x37, (char)0x2d, (char)0x31,
        (char)0x31, (char)0x20, (char)0x31, (char)0x36, (char)0x3a, (char)0x32, (char)0x30, (char)0x3a,
        (char)0x31, (char)0x30, (char)0x2e, (char)0x32, (char)0x39, (char)0x38, (char)0x34, (char)0x00,
        (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsCreateStreamPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsCreateStreamPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();
    pkt->command_object = SrsAmf0Any::null();
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x19, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x0c, (char)0x63,
        (char)0x72, (char)0x65, (char)0x61, (char)0x74, (char)0x65, (char)0x53, (char)0x74, (char)0x72,
        (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x40, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsFMLEStartPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsFMLEStartPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsFMLEStartPacket* pkt = new SrsFMLEStartPacket();
    pkt->command_name = "FMLEStart";
    pkt->command_object = SrsAmf0Any::null();
    pkt->stream_name = "livestream";
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x23, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x09, (char)0x46,
        (char)0x4d, (char)0x4c, (char)0x45, (char)0x53, (char)0x74, (char)0x61, (char)0x72, (char)0x74,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x05, (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76,
        (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsFMLEStartResPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsFMLEStartResPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(1);
    pkt->command_name = "FMLEStart";
    pkt->command_object = SrsAmf0Any::null();
    pkt->args = args;
    
    args->set("stream" , SrsAmf0Any::str("livestream"));
    args->set("start" , SrsAmf0Any::number(0));
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x17, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x09, (char)0x46,
        (char)0x4d, (char)0x4c, (char)0x45, (char)0x53, (char)0x74, (char)0x61, (char)0x72, (char)0x74,
        (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x05, (char)0x06
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsPublishPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsPublishPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsPublishPacket* pkt = new SrsPublishPacket();
    pkt->command_name = "publish";
    pkt->command_object = SrsAmf0Any::null();
    pkt->stream_name = "livestream";
    pkt->type = "live";
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x28, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x70,
        (char)0x75, (char)0x62, (char)0x6c, (char)0x69, (char)0x73, (char)0x68, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73,
        (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x02, (char)0x00, (char)0x04,
        (char)0x6c, (char)0x69, (char)0x76, (char)0x65
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsPlayPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsPlayPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsPlayPacket* pkt = new SrsPlayPacket();
    pkt->command_name = "play";
    pkt->command_object = SrsAmf0Any::null();
    pkt->stream_name = "livestream";
    pkt->start = 0;
    pkt->duration = 0;
    pkt->reset = true;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x32, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x04, (char)0x70,
        (char)0x6c, (char)0x61, (char)0x79, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05, (char)0x02, (char)0x00, (char)0x0a,
        (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65,
        (char)0x61, (char)0x6d, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0x01
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsPlayResPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsPlayResPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    SrsPlayResPacket* pkt = new SrsPlayResPacket();
    pkt->command_name = "_result";
    pkt->command_object = SrsAmf0Any::null();
    pkt->desc = args;
    
    args->set("stream" , SrsAmf0Any::str("livestream"));
    args->set("start" , SrsAmf0Any::number(0));
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x3d, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x07, (char)0x5f,
        (char)0x72, (char)0x65, (char)0x73, (char)0x75, (char)0x6c, (char)0x74, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05,
        (char)0x03, (char)0x00, (char)0x06, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61,
        (char)0x6d, (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x05,
        (char)0x73, (char)0x74, (char)0x61, (char)0x72, (char)0x74, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnBWDonePacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsOnBWDonePacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();
    pkt->command_name = "onBWDone";
    pkt->args = SrsAmf0Any::null();
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x15, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x08, (char)0x6f,
        (char)0x6e, (char)0x42, (char)0x57, (char)0x44, (char)0x6f, (char)0x6e, (char)0x65, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x05
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnStatusCallPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsOnStatusCallPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    args->set("stream" , SrsAmf0Any::str("livestream"));
    args->set("start" , SrsAmf0Any::number(0));
    
    SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
    pkt->command_name = "onStatus";
    pkt->args = SrsAmf0Any::null();
    pkt->data = args;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x3e, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x08, (char)0x6f,
        (char)0x6e, (char)0x53, (char)0x74, (char)0x61, (char)0x74, (char)0x75, (char)0x73, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x05, (char)0x03, (char)0x00, (char)0x06, (char)0x73, (char)0x74, (char)0x72, (char)0x65,
        (char)0x61, (char)0x6d, (char)0x02, (char)0x00, (char)0x0a, (char)0x6c, (char)0x69, (char)0x76,
        (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x00,
        (char)0x05, (char)0x73, (char)0x74, (char)0x61, (char)0x72, (char)0x74, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsBandwidthPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsBandwidthPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    args->set("stream" , SrsAmf0Any::str("livestream"));
    args->set("start" , SrsAmf0Any::number(0));
    
    SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
    pkt->command_name = "startPublish";
    pkt->args = SrsAmf0Any::null();
    pkt->data = args;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x42, (char)0x14,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x0c, (char)0x73,
        (char)0x74, (char)0x61, (char)0x72, (char)0x74, (char)0x50, (char)0x75, (char)0x62, (char)0x6c,
        (char)0x69, (char)0x73, (char)0x68, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05, (char)0x03, (char)0x00, (char)0x06,
        (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x02, (char)0x00,
        (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72,
        (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x05, (char)0x73, (char)0x74, (char)0x61,
        (char)0x72, (char)0x74, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnStatusDataPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsOnStatusDataPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    args->set("stream" , SrsAmf0Any::str("livestream"));
    args->set("start" , SrsAmf0Any::number(0));
    
    SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();
    pkt->command_name = "onData";
    pkt->data = args;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x32, (char)0x12,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x06, (char)0x6f,
        (char)0x6e, (char)0x44, (char)0x61, (char)0x74, (char)0x61, (char)0x03, (char)0x00, (char)0x06,
        (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x02, (char)0x00,
        (char)0x0a, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72,
        (char)0x65, (char)0x61, (char)0x6d, (char)0x00, (char)0x05, (char)0x73, (char)0x74, (char)0x61,
        (char)0x72, (char)0x74, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSampleAccessPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsSampleAccessPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();
    pkt->command_name = "|RtmpSampleAccess";
    pkt->video_sample_access = true;
    pkt->audio_sample_access = true;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x05, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x18, (char)0x12,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x11, (char)0x7c,
        (char)0x52, (char)0x74, (char)0x6d, (char)0x70, (char)0x53, (char)0x61, (char)0x6d, (char)0x70,
        (char)0x6c, (char)0x65, (char)0x41, (char)0x63, (char)0x63, (char)0x65, (char)0x73, (char)0x73,
        (char)0x01, (char)0x01, (char)0x01, (char)0x01
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsOnMetaDataPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsOnMetaDataPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAmf0Object* args = SrsAmf0Any::object();
    
    args->set("width" , SrsAmf0Any::number(1024));
    args->set("height" , SrsAmf0Any::number(576));
    
    SrsOnMetaDataPacket* pkt = new SrsOnMetaDataPacket();
    pkt->name = "onMetaData";
    pkt->metadata = args;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x04, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x32, (char)0x12,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x02, (char)0x00, (char)0x0a, (char)0x6f,
        (char)0x6e, (char)0x4d, (char)0x65, (char)0x74, (char)0x61, (char)0x44, (char)0x61, (char)0x74,
        (char)0x61, (char)0x03, (char)0x00, (char)0x05, (char)0x77, (char)0x69, (char)0x64, (char)0x74,
        (char)0x68, (char)0x00, (char)0x40, (char)0x90, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x06, (char)0x68, (char)0x65, (char)0x69, (char)0x67,
        (char)0x68, (char)0x74, (char)0x00, (char)0x40, (char)0x82, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSetWindowAckSizePacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsSetWindowAckSizePacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
    pkt->ackowledgement_window_size = 102400;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x05,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0x90, (char)0x00
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsAcknowledgementPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsAcknowledgementPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsAcknowledgementPacket* pkt = new SrsAcknowledgementPacket();
    pkt->sequence_number = 1024;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x03,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x00
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSetChunkSizePacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsSetChunkSizePacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
    pkt->chunk_size = 1024;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x01,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x00
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsSetPeerBandwidthPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsSetPeerBandwidthPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();
    pkt->type = SrsPeerBandwidthSoft;
    pkt->bandwidth = 1024;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x05, (char)0x06, 
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x04, (char)0x00, 
        (char)0x01 
    };
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
}

/**
* send a SrsUserControlPacket packet
*/
VOID TEST(ProtocolStackTest, ProtocolSendSrsUserControlPacket)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    SrsUserControlPacket* pkt = new SrsUserControlPacket();
    pkt->event_type = SrcPCUCSetBufferLength;
    pkt->event_data = 0x01;
    pkt->extra_data = 0x10;
    
    EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    char buf[] = {
        (char)0x02, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0a, (char)0x04,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03, (char)0x00, (char)0x00,
        (char)0x00, (char)0x01, (char)0x00, (char)0x00, (char)0x00, (char)0x10
    };
    
    EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
    EXPECT_TRUE(true);
}

/**
* recv video message from multiple chunks,
* the next chunks must not be fmt=0 which means new msg.
*/
// when exists cache msg, means got an partial message,
// the fmt must not be type0 which means new message.
VOID TEST(ProtocolStackTest, ProtocolRecvVMessageFmtInvalid)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // video message
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, 
        (char)0x00, (char)0x00, (char)0x00, // timestamp
        (char)0x00, (char)0x01, (char)0x10, // length, 272
        (char)0x09, // message_type
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        (char)0x03, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        (char)0xC3, /*next chunk.*/
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    EXPECT_FALSE(ERROR_SUCCESS == proto.recv_message(&msg));
}

/**
* when recv bytes archive the ack-size, server must response a acked-size auto.
*/
VOID TEST(ProtocolStackTest, ProtocolAckSizeFlow)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    if (true) {
        SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
        pkt->ackowledgement_window_size = 512;
        
        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    }
    
    if (true) {
        SrsMessage* msg = new SrsCommonMessage();
        msg->header.payload_length = msg->size = 4096;
        msg->payload = new char[msg->size];
        
        msg->header.message_type = 9;
        EXPECT_TRUE(msg->header.is_video());

        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(msg, 1));
    }
    
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    
    // recv SrsSetWindowAckSizePacket
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        ASSERT_TRUE(msg->header.is_window_ackledgement_size());
    }
    // recv video
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        ASSERT_TRUE(msg->header.is_video());
    }
    
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv auto send acked size. #1
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        ASSERT_TRUE(msg->header.is_ackledgement());
    }
    
    // send again
    if (true) {
        SrsMessage* msg = new SrsCommonMessage();
        msg->header.payload_length = msg->size = 4096;
        msg->payload = new char[msg->size];
        
        msg->header.message_type = 9;
        EXPECT_TRUE(msg->header.is_video());

        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(msg, 1));
    }
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv video
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        ASSERT_TRUE(msg->header.is_video());
    }
    
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv auto send acked size. #2
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        ASSERT_TRUE(msg->header.is_ackledgement());
    }
}

/**
* when recv ping message, server will response it auto.
*/
VOID TEST(ProtocolStackTest, ProtocolPingFlow)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // ping request
    if (true) {
        SrsUserControlPacket* pkt = new SrsUserControlPacket();
        pkt->event_type = SrcPCUCPingRequest;
        pkt->event_data = 0x3456;
        EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
    }
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv ping
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        EXPECT_TRUE(msg->header.is_user_control_message());
    }
    
    // recv the server auto send ping response message
    // copy output to input
    if (true) {
        bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
        bio.out_buffer.erase(bio.out_buffer.length());
    }
    // recv ping
    if (true) {
        SrsMessage* msg = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
        SrsAutoFree(SrsMessage, msg);
        ASSERT_TRUE(msg->header.is_user_control_message());
        
        SrsPacket* pkt = NULL;
        ASSERT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
        SrsUserControlPacket* spkt = dynamic_cast<SrsUserControlPacket*>(pkt);
        ASSERT_TRUE(spkt != NULL);
        
        EXPECT_TRUE(SrcPCUCPingResponse == spkt->event_type);
        EXPECT_TRUE(0x3456 == spkt->event_data);
    }
}

/**
* expect specified message
*/
VOID TEST(ProtocolStackTest, ProtocolExcpectMessage)
{
    MockBufferIO bio;
    SrsProtocol proto(&bio);
    
    // packet is SrsConnectAppPacket
    char data[] = {
        // 12bytes header, 1byts chunk header, 11bytes msg heder
        (char)0x03, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x01, (char)0xa1, (char)0x14, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        // msg payload start
        (char)0x02, (char)0x00, (char)0x07, (char)0x63,
        (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
        (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
        (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
        (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
        (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
        (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
        (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
        (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, 
        (char)0xC3, /*next chunk.*/         (char)0x61, (char)0x79, (char)0x65, (char)0x72,
        (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
        (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
        (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
        (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
        (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
        (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
        (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 
        (char)0xC3, /*next chunk.*/         (char)0x0d, (char)0x76, (char)0x69, (char)0x64,
        (char)0x65, (char)0x6f, (char)0x46, (char)0x75, (char)0x6e, (char)0x63, (char)0x74, (char)0x69, (char)0x6f, (char)0x6e, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00,
        (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x07, (char)0x70, (char)0x61, (char)0x67, (char)0x65, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x62, (char)0x68,
        (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72, (char)0x73, (char)0x2e,
        (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x73,
        (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2e, (char)0x68, (char)0x74, (char)0x6d, (char)0x6c,
        (char)0x3f, (char)0x76, (char)0x68, (char)0x6f, (char)0x73, (char)0x74, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61,
        (char)0x6d, (char)0x3d, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x73, (char)0x74, (char)0x72, (char)0x65, (char)0x61, (char)0x6d, (char)0x26, (char)0x73, (char)0x65, (char)0x72,
        (char)0x76, (char)0x65, (char)0x72, (char)0x3d, (char)0x64, (char)0x65, (char)0x76, (char)0x26, (char)0x70, (char)0x6f, (char)0x72, (char)0x74, 
        (char)0xC3, /*next chunk.*/         (char)0x3d, (char)0x31, (char)0x39, (char)0x33,
        (char)0x35, (char)0x00, (char)0x0e, (char)0x6f, (char)0x62, (char)0x6a, (char)0x65, (char)0x63, (char)0x74, (char)0x45, (char)0x6e, (char)0x63, (char)0x6f, (char)0x64, (char)0x69, (char)0x6e,
        (char)0x67, (char)0x00, (char)0x40, (char)0x08, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x09
    };
    bio.in_buffer.append(data, sizeof(data));
    
    SrsMessage* msg = NULL;
    SrsConnectAppPacket* pkt = NULL;
    ASSERT_TRUE(ERROR_SUCCESS == proto.expect_message<SrsConnectAppPacket>(&msg, &pkt));
    SrsAutoFree(SrsMessage, msg);
    SrsAutoFree(SrsConnectAppPacket, pkt);
    ASSERT_TRUE(NULL != pkt);
}

VOID TEST(ProtocolRTMPTest, RTMPRequest)
{
    SrsRequest req;
    std::string param;
    
    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://std.ossrs.net/live", 
        req.schema, req.host, req.vhost, req.app, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());
    
    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://s td.os srs.n et/li v e", 
        req.schema, req.host, req.vhost, req.app, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());
    
    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://s\ntd.o\rssrs.ne\nt/li\nve", 
        req.schema, req.host, req.vhost, req.app, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());
    
    req.stream = "livestream";
    srs_discovery_tc_url("rtmp://std.ossrs.net/live ", 
        req.schema, req.host, req.vhost, req.app, req.port, param);
    req.strip();
    EXPECT_STREQ("rtmp", req.schema.c_str());
    EXPECT_STREQ("std.ossrs.net", req.host.c_str());
    EXPECT_STREQ("std.ossrs.net", req.vhost.c_str());
    EXPECT_STREQ("live", req.app.c_str());
    EXPECT_STREQ("1935", req.port.c_str());
    
    EXPECT_TRUE(NULL == req.args);
    SrsRequest req1;
    req1.args = SrsAmf0Any::object();
    req.update_auth(&req1);
    EXPECT_TRUE(NULL != req.args);
    EXPECT_TRUE(req1.args != req.args);
}

VOID TEST(ProtocolRTMPTest, RTMPHandshakeBytes)
{
    MockBufferIO bio;
    SrsHandshakeBytes bytes;
    
    char hs[3073];
    bio.in_buffer.append(hs, sizeof(hs));
    bio.in_buffer.append(hs, sizeof(hs));
    
    EXPECT_TRUE(ERROR_SUCCESS == bytes.read_c0c1(&bio));
    EXPECT_TRUE(bytes.c0c1 != NULL);
    
    EXPECT_TRUE(ERROR_SUCCESS == bytes.read_c2(&bio));
    EXPECT_TRUE(bytes.c2 != NULL);
    
    EXPECT_TRUE(ERROR_SUCCESS == bytes.read_s0s1s2(&bio));
    EXPECT_TRUE(bytes.s0s1s2 != NULL);
}

#endif

