int TestCase_Core_Thread_ThreadMgr::Run(int argc, char *argv[])
{
    LLBC_PrintLine("core/thread/ThreadManager test:");

    LLBC_PrintLine("Create threads:");
    LLBC_Handle groupHandle = LLBC_ThreadManagerSingleton->CreateThreads(2, &ThreadProc);
    if(groupHandle == LLBC_INVALID_HANDLE)
    {
        LLBC_PrintLine("Create threads failed, reason: %s", LLBC_FormatLastError());
    }
    else
    {
        LLBC_ThreadManager::Sleep(1000);
        LLBC_PrintLine("Create successed, group handle: %d, join it.", groupHandle);
        if(LLBC_ThreadManagerSingleton->WaitGroup(groupHandle) != LLBC_RTN_OK)
        {
            LLBC_PrintLine("Wait group failed, reason: %s", LLBC_FormatLastError());
        }
        else
        {
            LLBC_PrintLine("Wait group successed");
        }
    }

    LLBC_PrintLine("Press any key to continue ...");
    getchar();

    return 0;
}
bool TestCase_Core_File_File::MoveFileTest()
{
    LLBC_PrintLine("Move file test:");

    const LLBC_String moveFileName = _testFileName + ".move";
    LLBC_File file(_testFileName, LLBC_FileMode::BinaryReadWrite);
    if (!file.IsOpened())
    {
        LLBC_PrintLine("Open test file[%s] failed, error: %s", _testFileName.c_str(), LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("test file[name: %s, will move] opened, write line string: Hello World!", _testFileName.c_str());
    file.WriteLine("Hello World");

    LLBC_PrintLine("Begin move(overlapped): %s ---> %s", _testFileName.c_str(), moveFileName.c_str());
    if (file.MoveFile(moveFileName, true) != LLBC_OK)
    {
        LLBC_PrintLine("Move file failed, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("Open the move file:");
    LLBC_File moveFile(moveFileName, LLBC_FileMode::BinaryRead);
    if (!moveFile.IsOpened())
    {
        LLBC_PrintLine("Failed to open move file, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("Move file opened, content: %s", moveFile.ReadToEnd().c_str());
    moveFile.Close();

    const LLBC_String copyFileName = _testFileName + ".copy";
    LLBC_File::CopyFile(moveFileName, copyFileName, true);
    LLBC_PrintLine("Copy move file and move again(don't overlapped): %s ---> %s", copyFileName.c_str(), copyFileName.c_str());
    if (LLBC_File::MoveFile(copyFileName, moveFileName, false) == LLBC_OK)
    {
        LLBC_PrintLine("Move success, failed. check your code!");
        LLBC_File::DeleteFile(copyFileName);
        LLBC_File::DeleteFile(moveFileName);

        return false;
    }
    else
    {
        LLBC_PrintLine("Move failed, error: %s, right!", LLBC_FormatLastError());
    }

    LLBC_PrintLine("Delete copy file and move file");
    LLBC_File::DeleteFile(copyFileName);
    LLBC_File::DeleteFile(moveFileName);

    LLBC_PrintLine("");

    return true;
}
示例#3
0
void LLBC_IocpPoller::HandleEv_AsyncConn(LLBC_PollerEvent &ev)
{
    bool succeed = true;
    LLBC_String reason = "Success";
    do {
        LLBC_SocketHandle handle = LLBC_CreateTcpSocketEx();
        if (handle == LLBC_INVALID_SOCKET_HANDLE)
        {
            succeed = false;
            reason = LLBC_FormatLastError();
            break;
        }

        LLBC_Socket *socket = LLBC_New1(LLBC_Socket, handle);

        socket->SetNonBlocking();
        socket->SetPollerType(LLBC_PollerType::IocpPoller);
        if (socket->AttachToIocp(_iocp) != LLBC_OK)
        {
            LLBC_Delete(socket);

            succeed = false;
            reason = LLBC_FormatLastError();
            break;
        }

        LLBC_POverlapped ol = LLBC_New(LLBC_Overlapped);
        ol->opcode = LLBC_OverlappedOpcode::Connect;
        ol->sock = handle;
        if (socket->ConnectEx(ev.peerAddr, ol) != LLBC_OK &&
                LLBC_GetLastError() != LLBC_ERROR_PENDING)
        {
            LLBC_Delete(ol);
            LLBC_Delete(socket);

            succeed = false;
            reason = LLBC_FormatLastError();
            break;
        }

        socket->InsertOverlapped(ol);

        LLBC_AsyncConnInfo asyncInfo;
        asyncInfo.socket = socket;
        asyncInfo.peerAddr = ev.peerAddr;
        asyncInfo.sessionId = ev.sessionId;

        _connecting.insert(std::make_pair(handle, asyncInfo));
    } while (false);

    if (!succeed)
        _svc->Push(LLBC_SvcEvUtil::
                BuildAsyncConnResultEv(succeed, reason, ev.peerAddr));
}
bool TestCase_Core_File_File::GetXXXMethodsTest()
{
    LLBC_PrintLine("GetXXXMethods test:");

    // Open file as BinaryWrite mode for test.
    LLBC_File file(_testFileName, LLBC_FileMode::BinaryWrite);
    if (!file.IsOpened())
    {
        LLBC_PrintLine("Open file to test failed, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("File %s opened", _testFileName.c_str());

    // GetFileNo():
    LLBC_PrintLine("LLBC_File::GetFileNo(): %d", file.GetFileNo());
    // GetFileHandle():
    LLBC_PrintLine("LLBC_File::GetFileHandle()(FILE *): %p", file.GetFileHandle());
    // GetFileMode():
    LLBC_PrintLine("LLBC_File::GetFileMode(): %s", LLBC_FileMode::GetFileModeDesc(file.GetFileMode()).c_str());

    LLBC_PrintLine("");

    return true;
}
示例#5
0
文件: OS_Iocp.cpp 项目: mr-kelly/llbc
int LLBC_AddSocketToIocp(LLBC_IocpHandle handle,
                         LLBC_SocketHandle sock,
                         void *completionKey)
{
    LLBC_IocpHandle ret = ::CreateIoCompletionPort((HANDLE)sock,
                                                   handle, 
                                                   (ULONG_PTR)completionKey, 
                                                   0);
    if (ret == LLBC_INVALID_IOCP_HANDLE)
    {
        LLBC_SetLastError(LLBC_ERROR_OSAPI);
        trace("LLBC_AddSocketToIocp() failed, reason: %s\n", LLBC_FormatLastError());
        return LLBC_RTN_FAILED;
    }

    return LLBC_RTN_OK;
}
bool TestCase_Core_File_File::OpenCloseTest()
{
    LLBC_PrintLine("Open/Close file test:");

    // Open/Close use BinaryRead mode.
    LLBC_String fileName = _testFileName;
    LLBC_PrintLine("Open file use constructor method(BinaryRead): %s", fileName.c_str());
    LLBC_File file(fileName, LLBC_FileMode::BinaryRead);
    if (file.IsOpened())
    {
        LLBC_PrintLine("File opened, test failed!!!");
        return false;
    }

    LLBC_PrintLine("File open failed, error: %s", LLBC_FormatLastError());

    // Open/Close use BinaryWrite mode.
    LLBC_PrintLine("Open file use constructor method(BinaryWrite): %s", fileName.c_str());
    LLBC_File file2(fileName, LLBC_FileMode::BinaryWrite);
    if (!file2.IsOpened())
    {
        LLBC_PrintLine("File not open, error: %s, test failed!!!", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("File open success, close it");
    file2.Close();

    // Open/Close file use Open method.
    LLBC_PrintLine("Open file use Open() method(BinaryRead): %s", fileName.c_str());
    LLBC_File file3;
    if (file3.Open(fileName, LLBC_FileMode::BinaryRead) != 0)
    {
        LLBC_PrintLine("File open failed, error: %s, test failed", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("Open successful, reopen it(LastestMode):");
    if (file3.ReOpen(LLBC_FileMode::LastestMode) != 0)
    {
        LLBC_PrintLine("Reopen file failed, error: %s", LLBC_FormatLastError());
        return false;
    }
    else
    {
        LLBC_PrintLine("Reopen success, mode: %s", LLBC_FileMode::GetFileModeDesc(file3.GetFileMode()).c_str());
    }

    LLBC_PrintLine("Reopen successful, reopen again(BinaryWrite):");
    if (file3.ReOpen(LLBC_FileMode::BinaryWrite) != 0)
    {
        LLBC_PrintLine("Reopen file failed, error: %s", LLBC_FormatLastError());
        return false;
    }

    file3.Close();

    // Final, delete test file.
    LLBC_PrintLine("Delete test file");
    if (LLBC_File::DeleteFile(fileName) != LLBC_OK)
    {
        LLBC_PrintLine("Delete file failed, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("");

    return true;
}
bool TestCase_Core_File_File::FileAttributeTest()
{
    LLBC_PrintLine("file attribute about test:");
    LLBC_File file(_testFileName, LLBC_FileMode::BinaryRead);
    if (!file.IsOpened())
    {
        LLBC_PrintLine("Open file to test failed, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_FileAttributes fileAttrs;
    if (file.GetFileAttributes(fileAttrs) != LLBC_OK)
    {
        LLBC_PrintLine("Failed to get file attributes, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("File %s attributes got, print it: ", _testFileName.c_str());
    PrintFileAttributes(fileAttrs);

    // Test directory attributes:
    if (LLBC_File::GetFileAttributes(".", fileAttrs) != LLBC_OK)
    {
        LLBC_PrintLine("Failed to get file attributes, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("File %s attributes got, print it: ", ".");
    PrintFileAttributes(fileAttrs);

    file.Close();

    LLBC_PrintLine("Touch file test, file: %s", _testFileName.c_str());
    LLBC_PrintLine("Touch all times to now:");
    if (LLBC_File::TouchFile(_testFileName, true, NULL, true, NULL) != LLBC_OK)
    {
        LLBC_PrintLine("Failed to touch file: %s, error: %s", _testFileName.c_str(), LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("Touched, attributes:");
    LLBC_File::GetFileAttributes(_testFileName, fileAttrs);
    PrintFileAttributes(fileAttrs);

    LLBC_PrintLine("Sleep 2 seconds...");
    LLBC_Sleep(2000);
    LLBC_PrintLine("Touch last access time to now");
    LLBC_File::TouchFile(_testFileName, true, NULL, false, NULL);
    LLBC_PrintLine("Touched, attributes:");
    LLBC_File::GetFileAttributes(_testFileName, fileAttrs);
    PrintFileAttributes(fileAttrs);

    LLBC_PrintLine("Sleep 2 seconds...");
    LLBC_Sleep(2000);
    LLBC_PrintLine("Touch last modify time to now");
    LLBC_File::TouchFile(_testFileName, false, NULL, true, NULL);
    LLBC_PrintLine("Touched, attributes:");
    LLBC_File::GetFileAttributes(_testFileName, fileAttrs);
    PrintFileAttributes(fileAttrs);

    LLBC_PrintLine("");

    return true;
}
bool TestCase_Core_File_File::ReadWriteTest()
{
    LLBC_PrintLine("Read/Write test:");
    // Open file as BinaryWrite mode for test.
    LLBC_File file(_testFileName, LLBC_FileMode::BinaryReadWrite);
    if (!file.IsOpened())
    {
        LLBC_PrintLine("Open file to test failed, error: %s", LLBC_FormatLastError());
        return false;
    }

    LLBC_PrintLine("File %s opened", _testFileName.c_str());

    // Write raw data:
    LLBC_PrintLine("Write (bool)true, (bool)false, (sint8)-8, (uint8)8, (sint16)-16, (uint16)16, "
        "(sint32)-32, (uint32)32, (sint64)-64, (uint64)64, (float)3.14, (double)1.618");
    file.Write(true), file.Write(false);
    file.Write(static_cast<sint8>(-8)); file.Write(static_cast<uint8>(8));
    file.Write(static_cast<sint16>(-16)); file.Write(static_cast<uint16>(16));
    file.Write(static_cast<sint32>(-32)); file.Write(static_cast<uint32>(32));
    file.Write(static_cast<sint64>(-64)); file.Write(static_cast<uint64>(64));
    file.Write(static_cast<float>(3.14)); file.Write(static_cast<double>(1.618));

    // Seek file pointer to file begin.
    LLBC_PrintLine("Seek file pointer to begin.");
    file.Seek(LLBC_FileSeekOrigin::Begin, 0);

    // Read it
    bool trueVal, falseVal;
    file.Read(trueVal); file.Read(falseVal);
    sint8 sint8Val; uint8 uint8Val;
    file.Read(sint8Val); file.Read(uint8Val);
    sint16 sint16Val; uint16 uint16Val;
    file.Read(sint16Val); file.Read(uint16Val);
    sint32 sint32Val; uint32 uint32Val;
    file.Read(sint32Val); file.Read(uint32Val);
    sint64 sint64Val; uint64 uint64Val;
    file.Read(sint64Val); file.Read(uint64Val);
    float floatVal; double doubleVal;
    file.Read(floatVal); file.Read(doubleVal);
    LLBC_PrintLine("Read it: %s, %s, %d, %u, %d, %u, %d, %u, %lld, %llu, %f, %f",
        trueVal ? "true" : "false", falseVal ? "true" : "false",
        sint8Val, uint8Val, sint16Val, uint16Val, sint32Val, uint32Val,
        sint64Val, uint64Val, floatVal, doubleVal);

    LLBC_PrintLine("Seek(Current, -sizeof(double)), and read again the double value:");
    file.Seek(LLBC_FileSeekOrigin::Current, -8);
    doubleVal = 0.0; file.Read(doubleVal);
    LLBC_PrintLine("The doubleVal: %f", doubleVal);

    LLBC_PrintLine("Seek(End, -sizeof(double)), and read again the double value:");
    file.Seek(LLBC_FileSeekOrigin::End, -8);
    doubleVal = 0.0; file.Read(doubleVal);
    LLBC_PrintLine("The doubleVal: %f", doubleVal);

    LLBC_PrintLine("Now file size: %ld, file pos: %ld", file.GetFileSize(), file.GetFilePosition());
    file.Seek(LLBC_FileSeekOrigin::Current, -16);
    LLBC_PrintLine("After Seek(Current, -16), file size: %ld, file pos: %ld", file.GetFileSize(), file.GetFilePosition());

    // Test ReadLine/WriteLine/ReadToEnd methods:
    LLBC_PrintLine("ReOpen file for test ReadLine/WriteLine/ReadToEnd methods:");
    file.ReOpen(LLBC_FileMode::BinaryReadWrite);

    LLBC_PrintLine("WriteLine(\"Hello World!\"):");
    file.WriteLine("Hello World!");
    LLBC_PrintLine("WriteLine(\"Hey, Judy!\"):");
    file.WriteLine("Hey, Judy!");

    file.SetFilePosition(0);
    LLBC_PrintLine("Read lines:");
    LLBC_PrintLine("First line: %s", file.ReadLine().c_str());
    LLBC_PrintLine("Second line: %s", file.ReadLine().c_str());
    const LLBC_String notExistLine = file.ReadLine();
    LLBC_PrintLine("Not exist line: %s, error: %s", notExistLine.c_str(), LLBC_FormatLastError());

    LLBC_PrintLine("");

    return true;
}
示例#9
0
int TestCase_Comm_Svc::Run(int argc, char *argv[])
{
    LLBC_PrintLine("Server/Client test:");
    if (argc < 5)
    {
        LLBC_PrintLine("argument error, eg: ./a [client/server] [normal/raw] ip port");
        return -1;
    }

    // Parse arguments.
    const char *ip = argv[3];
    const int port = LLBC_Str2Int32(argv[4]);
    const bool asClient = LLBC_String(argv[1]) == "client" ? true : false;
    LLBC_IService::Type svcType = 
        LLBC_String(argv[2]) == "normal" ? LLBC_IService::Normal : LLBC_IService::Raw;

    LLBC_PrintLine("Will start %s type service, service type: %s",
        asClient ? "CLIENT" : "SERVER",
        svcType == LLBC_IService::Normal ? "Normal" : "Raw");

    // Create service
    LLBC_IService *svc = LLBC_IService::Create(svcType);
    TestFacade *facade = LLBC_New(TestFacade);
    svc->RegisterFacade(facade);
    svc->Subscribe(OPCODE, facade, &TestFacade::OnDataArrival);
    svc->SuppressCoderNotFoundWarning();
    svc->Start(2);

    // Connect to server / Create listen session to wait client connect.
    int sessionId;
    if (!asClient)
    {
        LLBC_PrintLine("Will listening in %s:%d", ip, port);
        if ((sessionId = svc->Listen(ip, port)) == 0)
        {
            LLBC_PrintLine("Create session failed, reason: %s", LLBC_FormatLastError());
            LLBC_Delete(svc);

            return -1;
        }
    }
    else
    {
        // Client service, we create some clients to test service.
        int clientCount;
        const int pollerType = LLBC_PollerType::Str2Type(LLBC_CFG_COMM_POLLER_MODEL);
        if (pollerType == LLBC_PollerType::SelectPoller)
            clientCount = 50;
        else
            clientCount = 1024;

        LLBC_PrintLine("Create %d clients to test", clientCount);

        for (int i = 0; i < clientCount; i++)
        {
            const int sessionId = svc->Connect(ip, port);

            const int dataSize = 4096;
            char *data = LLBC_Malloc(char, dataSize);
            ::memset(data, 1, dataSize);

            LLBC_Packet *packet = LLBC_New(LLBC_Packet);
            packet->SetHeader(sessionId, OPCODE, 0);
            packet->Write(data, dataSize);

            LLBC_Free(data);

            svc->Send(packet);

            // Test unhandled packet(unsubscribe opcode).
            LLBC_Packet *unhandledPacket = LLBC_New(LLBC_Packet);
            unhandledPacket->SetHeader(sessionId, OPCODE + 10000, 0);
            unhandledPacket->Write("Hello World", 12);

            svc->Send(unhandledPacket);
        }
    }

    LLBC_PrintLine("Press any key to continue...");
    getchar();

    return 0;
}
示例#10
0
int TestCase_Core_Log::Run(int argc, char *argv[])
{
    LLBC_PrintLine("core/log test:");

#if LLBC_TARGET_PLATFORM_IPHONE
    const LLBC_Bundle *mainBundle = LLBC_Bundle::GetMainBundle();
    if(LLBC_LoggerManagerSingleton->Initialize(mainBundle->GetBundlePath() + "/" + "Logger_Cfg.cfg") != LLBC_OK)
#else

    if(LLBC_LoggerManagerSingleton->Initialize("Logger_Cfg.cfg") != LLBC_OK)
#endif
    {
        LLBC_FilePrintLine(stderr, "Initialize logger manager failed, err: %s", LLBC_FormatLastError());
        LLBC_FilePrintLine(stderr, "Forgot copy Logger_Cfg.cfg test config file to CWD?");
        return -1;
    }

    // Use root logger to test.
    LLBC_DEBUG_LOG("This is a debug log message.");
    LLBC_DEBUG_LOG2("test_tag", "This is a debug log message.");

#if LLBC_CFG_LOG_USING_WITH_STREAM
    LLBC_DEBUG_LOG("Message type test, char: " <<'a' <<", bool: " <<true <<", uint8: " <<(uint8)8
        <<", sint16: " <<(sint16)-16 << ", uint16: " <<(uint16)16 <<", sint32: " <<-32
        <<", uint32: " <<(uint32)32 <<", long: " <<(long)-1 <<", ulong: " <<(llbc::ulong)1
        <<", sint64: " <<(sint64)-64 <<", uint64: " <<(uint64)64 <<", float: " <<(float)1.0
        <<", double: " <<2.0 <<", ldouble: " <<(ldouble)3.0);

    std::string stdStr = "This is a std::string";
    LLBC_String llbcStr = "This is a LLBC_String";
    LLBC_DEBUG_LOG("std::string operator << test: " <<stdStr <<", LLBC_String operator << test: " <<llbcStr);

    LLBC_Time now;
    LLBC_TimeSpan span(-30);
    LLBC_DEBUG_LOG("Current time: " <<now <<", TimeSpan: " <<span);

    // Test precision.
    double f = 3.14159;
    LLBC_DEBUG_LOG(std::setprecision(5) <<f);
    LLBC_DEBUG_LOG(std::setprecision(9) <<f);
    LLBC_DEBUG_LOG(std::setprecision(5) <<std::fixed <<f);
    LLBC_DEBUG_LOG(std::setprecision(9) <<std::fixed <<f);
#endif // LLBC_CFG_LOG_USING_WITH_STREAM`

    LLBC_INFO_LOG("This is a info log message.");
    LLBC_INFO_LOG2("test_tag", "This is a info log message.");

    LLBC_WARN_LOG("This is a warn log message.");
    LLBC_WARN_LOG2("test_tag", "This is a warn log message.");

    LLBC_ERROR_LOG("This is a error log message.");
    LLBC_ERROR_LOG2("test_tag", "This is a error log message.");

    LLBC_FATAL_LOG("This is a fatal log message.");
    LLBC_FATAL_LOG2("test_tag", "This is a fatal log message.");

    // Use test logger to test.
    LLBC_DEBUG_LOG_SPEC("test", "This is a debug log message.");
    LLBC_DEBUG_LOG_SPEC2("test", "test_tag", "This is a debug log message.");

    LLBC_INFO_LOG_SPEC("test", "This is a info log message.");
    LLBC_INFO_LOG_SPEC2("test", "test_tag", "This is a info log message.");

    LLBC_WARN_LOG_SPEC("test", "This is a warn log message.");
    LLBC_WARN_LOG_SPEC2("test", "test_tag", "This is a warn log message.");

    LLBC_ERROR_LOG_SPEC("test", "This is a error log message.");
    LLBC_ERROR_LOG_SPEC2("test", "test_tag", "This is a error log message.");

    LLBC_FATAL_LOG_SPEC("test", "This is a fatal log message.");
    LLBC_FATAL_LOG_SPEC2("test", "test_tag", "This is a fatal log message.");

    // Log file delete test.
    for (int i = 0; i < 20; i++)
    {
        LLBC_DEBUG_LOG_SPEC("deltest", "This is a deltest logger message.");
        LLBC_ThreadManager::Sleep(1000);
    }

    // Peform performance test.
    LLBC_PrintLine("Perform preformance test:");
    LLBC_CPUTime begin = LLBC_CPUTime::Current();
    const int loopLmt = 500000;
    for (int i = 0; i < loopLmt; i++)
        LLBC_DEBUG_LOG_SPEC("perftest", "performance test msg");
    LLBC_LoggerManagerSingleton->Finalize();

    LLBC_CPUTime elapsed = LLBC_CPUTime::Current() - begin;
    LLBC_PrintLine("Performance test completed, "
        "log size:%d, elapsed time: %s", loopLmt, elapsed.ToString().c_str());

    LLBC_PrintLine("Press any key to continue ...");
    getchar();

    return 0;
}
示例#11
0
int TestCase_Comm_SendBytes::Run(int argc, char *argv[])
{
    LLBC_PrintLine("Servie send bytes test:");
    if (argc < 5)
    {
        LLBC_PrintLine("argument error, eg: ./a [client/server] [normal/raw] ip port");
        return LLBC_FAILED;
    }

    FetchArgs(argc, argv);
    LLBC_IService *svc = LLBC_IService::Create(_svcType);

    TestFacade *facade = LLBC_New(TestFacade);
    svc->RegisterFacade(facade);

    svc->Subscribe(OPCODE, facade, &TestFacade::OnRecv);

    int sid = 0;
    if (_asClient)
    {
        sid = svc->Connect(_runIp.c_str(), _runPort);
        if (sid == 0)
        {
            LLBC_FilePrintLine(stderr, "connect to %s:%d failed, err: %s",
                _runIp.c_str(), _runPort, LLBC_FormatLastError());
            LLBC_Delete(svc);

            return LLBC_FAILED;
        }

        LLBC_PrintLine("server connect to %s:%d success", _runIp.c_str(), _runPort);
    }
    else
    {
        sid = svc->Listen(_runIp.c_str(), _runPort);
        if (sid == 0)
        {
            LLBC_FilePrintLine(stderr, "failed to listen on %s:%d, err: %s",
                _runIp.c_str(), _runPort, LLBC_FormatLastError());
            LLBC_Delete(svc);

            return LLBC_FAILED;
        }

        LLBC_PrintLine("server listen on %s:%d", _runIp.c_str(), _runPort);
    }

    svc->Start();

    if (_asClient)
    {
        LLBC_Packet *pkt = LLBC_New(LLBC_Packet);
        pkt->SetHeader(sid, OPCODE, 0);
        pkt->Write("Hello, world");
        pkt->Write(0);

        svc->Send(pkt);
    }

    LLBC_PrintLine("Press any key to continue...");
    getchar();

    LLBC_Delete(svc);

    return LLBC_OK;
}
int TestCase_Core_Config_Config::Run(int argc, char *argv[])
{
    std::cout <<"LLBC_Config test: " <<std::endl;

#if LLBC_TARGET_PLATFORM_NON_IPHONE
    const char *file = "core/config/test_json.json";
#else
    const LLBC_Bundle *mainBundle = LLBC_Bundle::GetMainBundle();
    const char *file = mainBundle->GetResPath("test_json", "json").c_str();
    std::cout <<"json file path: " <<file <<std::endl;
#endif

    LLBC_Config config;
    if(config.AddFile(file) != LLBC_RTN_OK)
    {
        std::cerr <<"Add file to config failed, file: " <<file;
        std::cerr <<", error desc: " <<LLBC_FormatLastError() <<std::endl;
        return -1;
    }

    if(config.Initialize() != LLBC_RTN_OK)
    {
        std::cerr <<"Initialize config failed, error desc: ";
        std::cerr <<LLBC_FormatLastError() <<std::endl;
        return -1;
    }

    LLBC_JsonValue jsonValue = config.GetJsonValue(file, "json_value");
    std::cout <<"json_value: " <<std::endl;
    std::cout <<jsonValue.toStyledString() <<std::endl;

    LLBC_Variant intVal = config.GetVariantValue(file, "int_value.int_value");
    std::cout <<"int_value.int_value: " <<intVal <<std::endl;
    LLBC_Variant stringVal = config.GetVariantValue(file, "string_value");
    std::cout <<"string_value: " <<stringVal <<std::endl;

    std::vector<LLBC_JsonValue> jsonArray = config.GetJsonValueArray(file, "json_array");
    std::cout <<"json_array[count: " <<jsonArray.size() <<"]: " <<std::endl;
    for(size_t i = 0; i < jsonArray.size(); i ++)
    {
        std::cout <<jsonArray[i].toStyledString() <<std::endl;
    }

    std::map<int, LLBC_JsonValue> intJsonMap = config.GetIntJsonMap(file, "int_json_map");
    std::cout <<"int_json_map[count: " <<intJsonMap.size() <<"]: " <<std::endl;
    std::map<int, LLBC_JsonValue>::const_iterator intJsonMapIter = intJsonMap.begin();
    for(; intJsonMapIter != intJsonMap.end(); intJsonMapIter ++)
    {
        std::cout <<"key: " <<intJsonMapIter->first 
            <<"\nvalue: " <<intJsonMapIter->second.toStyledString() <<std::endl;
    }

    std::map<LLBC_String, LLBC_JsonValue> stringJsonMap = config.GetStringJsonMap(file, "string_json_map");
    std::cout <<"string_json_map[count: " <<stringJsonMap.size() <<"]: " <<std::endl;
    std::map<LLBC_String, LLBC_JsonValue>::const_iterator stringJsonMapIter = stringJsonMap.begin();
    for(; stringJsonMapIter != stringJsonMap.end(); stringJsonMapIter ++)
    {
        std::cout <<"key: " <<stringJsonMapIter->first
            <<"\nvalue: " <<stringJsonMapIter->second.toStyledString() <<std::endl;
    }

    std::vector<LLBC_Variant> variantArray = config.GetVariantValueArray(file, "variant_array");
    std::cout <<"variant_array[count: " <<variantArray.size() <<"]: " <<std::endl;
    for(size_t i = 0; i < variantArray.size(); i ++)
    {
        std::cout <<variantArray[i] <<std::endl;
    }

    std::map<int, LLBC_Variant> intVariantMap = config.GetIntVariantMap(file, "int_variant_map");
    std::cout <<"int_variant_map[count: " <<intVariantMap.size() <<"]: " <<std::endl;
    std::map<int, LLBC_Variant>::const_iterator intVariantMapIter = intVariantMap.begin();
    for(; intVariantMapIter != intVariantMap.end(); intVariantMapIter ++)
    {
        std::cout <<"key: " <<intVariantMapIter->first
            <<"\nvalue: " <<intVariantMapIter->second <<std::endl;
    }

    std::map<LLBC_String, LLBC_Variant> stringVariantMap = 
        config.GetStringVariantMap(file, "string_variant_map.string_variant_map");
    std::cout <<"string_variant_map.string_variant_map[count: " 
        <<stringVariantMap.size() <<"]: " <<std::endl;
    std::map<LLBC_String, LLBC_Variant>::const_iterator stringVariantMapIter = stringVariantMap.begin();
    for(; stringVariantMapIter != stringVariantMap.end(); stringVariantMapIter ++)
    {
        std::cout <<"key: " <<stringVariantMapIter->first
            <<"\nvalue: " <<stringVariantMapIter->second <<std::endl;
    }

    std::cout <<"Press any key to continue ... ..." <<std::endl;
    getchar();

    return 0;
}