Пример #1
0
void pyllbc_FacadeEvBuilder::SetAttr(PyObject *ev, PyObject *attr, const LLBC_String &val)
{
    PyObject *pyVal = PyString_FromStringAndSize(val.data(), val.size());
    PyObject_SetAttr(ev, attr, pyVal);
    
    Py_DECREF(pyVal);
}
Пример #2
0
LLBC_String LLBC_GetCacheDirectory(bool appendSlash)
{
 #if LLBC_TARGET_PLATFORM_NON_WIN32
    if (appendSlash)
    {
        return "/tmp/";
    }
    else
    {
        return "/tmp";
    }
 #else
    CHAR buf[MAX_PATH];
    memset(buf, 0, sizeof(CHAR) * MAX_PATH);
    if (::SHGetSpecialFolderPathA(NULL, buf, CSIDL_INTERNET_CACHE, FALSE) == FALSE)
    {
        LLBC_SetLastError(LLBC_ERROR_OSAPI);
        return "";
    }
    
    LLBC_String path = buf;
    if (appendSlash)
    {
        path.append(1, LLBC_BACKLASH_A);
    }

    return path;
 #endif
}
Пример #3
0
LLBC_String LLBC_SockAddr_IN::ToString() const
{
    LLBC_String desc;
    desc.format("%s:%d", GetIpAsString().c_str(), GetPort());

    return desc;
}
Пример #4
0
int pyllbc_Service::PreSubscribe(int opcode, PyObject *preHandler, int flags)
{
    if (_started)
    {
        pyllbc_SetError("service already started", LLBC_ERROR_INITED);
        return LLBC_RTN_FAILED;
    }
    else if (_llbcSvcType == LLBC_IService::Raw && opcode != 0)
    {
        pyllbc_SetError("RAW type service could not pre-subscribe opcode != 0's packet", LLBC_ERROR_INVALID);
        return LLBC_RTN_FAILED;
    }

    pyllbc_PacketHandler *wrapHandler = LLBC_New1(pyllbc_PacketHandler, opcode);
    if (wrapHandler->SetHandler(preHandler) != LLBC_RTN_OK)
    {
        LLBC_Delete(wrapHandler);
        return LLBC_RTN_FAILED;
    }

    if (!_preHandlers.insert(std::make_pair(opcode, wrapHandler)).second)
    {
        LLBC_Delete(wrapHandler);

        LLBC_String err;
        pyllbc_SetError(err.format(
            "repeat to pre-subscribe opcode: %d, the opcode already pre-subscribed", opcode), LLBC_ERROR_REPEAT);

        return LLBC_RTN_FAILED;
    }

    _llbcSvc->PreSubscribe(opcode, _cppFacade, &pyllbc_Facade::OnDataPreReceived);

    return LLBC_RTN_OK;
}
Пример #5
0
int pyllbc_Service::RegisterCodec(int opcode, PyObject *codec)
{
    if (_codec != This::BinaryCodec)
    {
        pyllbc_SetError("current codec strategy not BINARY, don't need register codec");
        return LLBC_RTN_FAILED;
    }
    else if (_llbcSvcType == LLBC_IService::Raw)
    {
        pyllbc_SetError("RAW type service don't need register codec");
        return LLBC_RTN_FAILED;
    }
    else if (!PyCallable_Check(codec))
    {
        pyllbc_SetError("codec not callable");
        return LLBC_RTN_FAILED;
    }

    if (!_codecs.insert(std::make_pair(opcode, codec)).second)
    {
        LLBC_String err;
        pyllbc_SetError(err.append_format(
            "repeat to register specify opcode's codec, opcode: %d", opcode));

        return LLBC_RTN_FAILED;
    }

    Py_INCREF(codec);

    return LLBC_RTN_OK;
}
Пример #6
0
__LLBC_NS_BEGIN

LLBC_String LLBC_GetHomeDirectory(bool appendSlash)
{
#if LLBC_TARGET_PLATFORM_NON_WIN32
    char *valStr = getenv("HOME");
#else
    char *valStr = getenv("HOMEPATH");
#endif
    if (!valStr)
    {
        LLBC_SetLastError(LLBC_ERROR_CLIB);
        return "";
    }
    
    LLBC_String path = valStr;
    if (appendSlash)
    {
#if LLBC_TARGET_PLATFORM_NON_WIN32
    path.append(1, LLBC_SLASH_A);
#else
    path.append(1, LLBC_BACKLASH_A);
#endif
    }

    return path;
}
Пример #7
0
LLBC_String LLBC_GetTemporaryDirectory(bool appendSlash)
{
 #if LLBC_TARGET_PLATFORM_NON_WIN32
    if (appendSlash)
    {
        return "/tmp/";
    }
    else
    {
        return "/tmp";
    }
 #else
    DWORD bufLen = 0;
    bufLen = ::GetTempPathA(0, NULL);
    bufLen += 1;

    LPSTR buf = reinterpret_cast<LPSTR>(::malloc(sizeof(CHAR) * bufLen));
    if (::GetTempPathA(bufLen, buf) == 0)
    {
        LLBC_SetLastError(LLBC_ERROR_OSAPI);
        ::free(buf);
        return "";
    }

    LLBC_String path = buf;
    ::free(buf);
    
    if (!appendSlash)
    {
        path = path.substr(0, path.size() - 1);
    }
    
    return path;
 #endif
}
Пример #8
0
LLBC_String LLBC_Directory::TempDir()
{
#if LLBC_TARGET_PLATFORM_NON_WIN32
    return "/tmp";
#else // Win32
    DWORD bufLen = 0;
    bufLen = ::GetTempPathA(0, NULL);
    bufLen += 1;

    LPSTR buf = reinterpret_cast<LPSTR>(::malloc(sizeof(CHAR) * bufLen));
    if (::GetTempPathA(bufLen, buf) == 0)
    {
        LLBC_SetLastError(LLBC_ERROR_OSAPI);
        ::free(buf);
        return "";
    }

    LLBC_String path = buf;
    ::free(buf);

    if (path[path.length() - 1] == LLBC_BACKLASH_A)
        return path.substr(0, path.length() - 1);
    
    return path;
#endif // Non-Win32
}
Пример #9
0
void TestCase_Com_DataType::StringSplitTest(const LLBC_String &str, size_t maxSplit, const LLBC_String &sep)
{
    LLBC_PrintLine("Will split string(maxSplit: %ld, sep: %s): %s", maxSplit, sep.c_str(), str.c_str());
    std::vector<LLBC_String> splitted = str.split(sep, maxSplit);
    LLBC_PrintLine("Split use separator:., size: %ld", splitted.size());
    for (size_t i = 0; i < splitted.size(); i++)
        LLBC_PrintLine("    \"%s\"", splitted[i].c_str());
}
Пример #10
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;
}
Пример #11
0
void LLBC_LogTagToken::Format(const LLBC_LogData &data, LLBC_String &formattedData) const
{
    int index = static_cast<int>(formattedData.size());
    if (data.tagLen)
        formattedData.append(data.others + data.tagBeg, data.tagLen);

    LLBC_LogFormattingInfo *formatter = GetFormatter();
    formatter->Format(formattedData, index);
}
Пример #12
0
void LLBC_SockAddr_IN::SetIp(const LLBC_String &ip)
{
    if (ip.empty())
    {
        SetIp("127.0.0.1");
        return;
    }

    _ip = ::inet_addr(ip.c_str());
}
Пример #13
0
void TestCase_Com_DataType::StringBaseTest()
{
    LLBC_PrintLine("String base functions test:");

    LLBC_String testStr;
    testStr.format("%s", "hello world!");
    testStr.append_format("%s", "hello world!");
    LLBC_PrintLine("LLBC_String::format/append_format test: %s", testStr.c_str());

    LLBC_String testStr2;
    for(int i = 0; i < 1000; i++)
    {
        testStr.append("hello world!");
    }

    testStr2.append_format("%s", testStr.c_str());
    LLBC_PrintLine("LLBC_String:format large string test: %s", testStr2.c_str());

    // tolower/toupper test.
    testStr = "Hello WoRlD!";
    LLBC_PrintLine("'%s' to lower: '%s'", testStr.c_str(), testStr.tolower().c_str());
    LLBC_PrintLine("'%s' to upper: '%s'", testStr.c_str(), testStr.toupper().c_str());

    LLBC_PrintLine("\n");
}
Пример #14
0
LLBC_String LLBC_TrimRight(const LLBC_String &str, char target)
{
    if (UNLIKELY(str.empty()))
    {
        return LLBC_String();
    }

    const LLBC_String::size_type length = str.size();
    register LLBC_String::size_type rightPos = length - 1;
    for (; str[rightPos] == target && rightPos != 0; rightPos --);

    return str.substr(0, rightPos + 1);
}
Пример #15
0
int pyllbc_PackLemma_Top::Write(pyllbc_Stream *stream, PyObject *values)
{
    if (UNLIKELY(!this->IsDone()))
    {
        pyllbc_SetError("top-lemma not done, could not pack data");
        return LLBC_RTN_FAILED;
    }

    const bool valuesIsNone = pyllbc_TypeDetector::IsNone(values);
    if (valuesIsNone)
    {
        if (!_lemmas.empty())
        {
            pyllbc_SetError("not found any values to pack, but has been specified format character symbol");
            return LLBC_RTN_FAILED;
        }

        return LLBC_RTN_OK;
    }
    else if (!pyllbc_TypeDetector::IsSequence(values))
    {
        pyllbc_SetError("will pack data not iterable");
        return LLBC_RTN_FAILED;
    }
    
    const Py_ssize_t seqSize = PySequence_Size(values);
    if (seqSize != static_cast<Py_ssize_t>(_lemmas.size()))
    {
        LLBC_String errStr;
        pyllbc_SetError(errStr.format(
            "will pack data sequence size[%ld] not equal format character size[%d]", 
            seqSize, _lemmas.size()));

        return LLBC_RTN_FAILED;
    }

    for (Py_ssize_t i = 0; i < seqSize; i++)
    {
        Base *lemma = _lemmas.at(i);
        PyObject *obj = PySequence_GetItem(values, i);
        if (lemma->Write(stream, obj) != LLBC_RTN_OK)
        {
            Py_DECREF(obj);
            return LLBC_RTN_FAILED;
        }

        Py_DECREF(obj);
    }

    return LLBC_RTN_OK;
}
Пример #16
0
LLBC_BundleHandle LLBC_CreateBundle(const LLBC_String &path)
{
    LLBC_String realPath = LLBC_GetMainBundlePath();
    if (UNLIKELY(realPath.empty()))
        return LLBC_INVALID_BUNDLE_HANDLE;

    // Main bundle-path + /(\\) + path.
    // Trim right(/(\\)).
    if (!path.empty())
    {
#if LLBC_TARGET_PLATFORM_NON_WIN32
        realPath.append(1, LLBC_SLASH_A);
#else
        realPath.append(1, LLBC_BACKLASH_A);
#endif

        realPath.append(path);

        const LLBC_String::size_type len = realPath.length();
        if (realPath[len - 1] == LLBC_SLASH_A || realPath[len - 1] == LLBC_BACKLASH_A)
            realPath.erase(len - 1, 1);
    }

    // Check path.
    if (!LLBC_DirectoryExist(realPath))
        return LLBC_INVALID_BUNDLE_HANDLE;

    return new LLBC_String(realPath);
}
Пример #17
0
int pyllbc_Service::Post(PyObject *callable)
{
    if (!PyCallable_Check(callable))
    {
        const LLBC_String objDesc = pyllbc_ObjUtil::GetObjStr(callable);
        pyllbc_SetError(LLBC_String().format("frame callable object not callable: %s", objDesc.c_str()));

        return LLBC_RTN_FAILED;
    }

    if (_handlingBeforeFrameCallables &&
        _handlingAfterFrameCallables)
    {
        pyllbc_SetError("could not push callable object to service, internal error!");
        return LLBC_RTN_FAILED;
    }

    if (_beforeFrameCallables.find(callable) != _beforeFrameCallables.end() ||
        _afterFrameCallables.find(callable) != _afterFrameCallables.end())
    {
        const LLBC_String objDesc = pyllbc_ObjUtil::GetObjStr(callable);
        pyllbc_SetError(LLBC_String().format(
            "repeat to add callable to service, callable: %s", objDesc.c_str()));

        return LLBC_RTN_FAILED;
    }

    Py_INCREF(callable);
    if (_handlingBeforeFrameCallables)
    {
        _afterFrameCallables.insert(callable);
    }
    else
    {
        if (!_handledBeforeFrameCallables)
        {
            _beforeFrameCallables.insert(callable);
        }
        else
        {
            if (!_handlingAfterFrameCallables)
                _afterFrameCallables.insert(callable);
            else
                _beforeFrameCallables.insert(callable);
        }
    }

    return LLBC_RTN_OK;
}
Пример #18
0
LLBC_String LLBC_BaseName(const LLBC_String &path, bool incExtension)
{
    if (UNLIKELY(path.empty()))
    {
        return LLBC_String();
    }

    LLBC_String baseName;
#if LLBC_TARGET_PLATFORM_NON_WIN32
    baseName = ::basename(const_cast<char *>(path.c_str()));
#else
    LLBC_String::size_type slashPos = path.rfind(LLBC_SLASH_A);
    LLBC_String::size_type backlashPos = path.rfind(LLBC_BACKLASH_A);

    if (slashPos == LLBC_String::npos)
    {
        if (backlashPos == LLBC_String::npos)
        {
            baseName = path;
        }
        else
        {
            baseName = path.substr(backlashPos + 1);
        }
    }
    else
    {
        if (backlashPos == LLBC_String::npos)
        {
            baseName = path.substr(slashPos + 1);
        }
        else
        {
            baseName = path.substr(MAX(slashPos, backlashPos) + 1);
        }
    }
#endif

    if (!incExtension)
    {
        LLBC_String::size_type dotPos = baseName.rfind('.');
        if (dotPos != LLBC_String::npos && dotPos != 0)
        {
            baseName.erase(dotPos);
        }
    }

    return baseName;
}
Пример #19
0
void TestCase_Com_DataType::StringBaseTest()
{
    LLBC_PrintLine("String base functions test:");

    LLBC_String testStr;
    testStr.format("%s", "hello world!");
    testStr.append_format("%s", "hello world!");
    LLBC_PrintLine("LLBC_String::format/append_format test: %s", testStr.c_str());

    LLBC_String testStr2;
    for(int i = 0; i < 1000; i++)
    {
        testStr.append("hello world!");
    }

    testStr2.append_format("%s", testStr.c_str());
    LLBC_PrintLine("LLBC_String:format large string test: %s", testStr2.c_str());

    // tolower/toupper test.
    testStr = "Hello WoRlD!";
    LLBC_PrintLine("'%s' to lower: '%s'", testStr.c_str(), testStr.tolower().c_str());
    LLBC_PrintLine("'%s' to upper: '%s'", testStr.c_str(), testStr.toupper().c_str());

    // isalpha/isupper/islower.
    LLBC_String str("HELLO");
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "hello";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "HeLlO";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "hello123";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "HELLO123";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "Hello123";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "H";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "h";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());
    str = "3";
    LLBC_PrintLine("%s islower?%d, isupper?%d, isalpha?%d", 
        str.c_str(), str.islower(), str.isupper(), str.isalpha());

    LLBC_PrintLine("\n");
}
Пример #20
0
LLBC_String LLBC_ExtensionName(const LLBC_String &path)
{
    LLBC_String basename = LLBC_BaseName(path);
    if (UNLIKELY(basename.empty()))
    {
        return LLBC_String();
    }

    LLBC_String::size_type pos = basename.rfind(".");
    if (pos == LLBC_String::npos)
    {
        return LLBC_String();
    }

    return basename.substr(pos + 1);
}
Пример #21
0
int TestCase_Com_Compiler::Run(int argc, char *argv[])
{
    LLBC_PrintLine("common/compiler test:");

    LLBC_String compInfo;
    compInfo.append_format("  Compiler Type: %d\n", LLBC_CUR_COMP)
        .append_format("  Compiler Version: %d\n", LLBC_COMP_VER)
        .append_format("  Major Version: %d\n", LLBC_COMP_MAJOR_VER)
        .append_format("  Minor Version: %d\n", LLBC_COMP_MINOR_VER)
        .append_format("  Patch Level: %d\n", LLBC_COMP_PATCH_LEVEL);

    LLBC_PrintLine("%s", compInfo.c_str());

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

    return LLBC_RTN_OK;
}
Пример #22
0
int pyllbc_Service::RegisterFacade(PyObject *facade)
{
    if (!_facades.insert(facade).second)
    {
        PyObject *pyFacadeStr = PyObject_Str(facade);
        LLBC_String facadeStr = PyString_AsString(pyFacadeStr);
        Py_DECREF(pyFacadeStr);

        LLBC_String errStr;
        pyllbc_SetError(errStr.format("repeat to register facade: %s", facadeStr.c_str()), LLBC_ERROR_REPEAT);

        return LLBC_RTN_FAILED;
    }

    Py_INCREF(facade);

    return LLBC_RTN_OK;
}
Пример #23
0
LLBC_String LLBC_Trim(const LLBC_String &str, const char *targets)
{
    if (UNLIKELY(str.empty()))
    {
        return LLBC_String();
    }

    return LLBC_TrimRight(LLBC_TrimLeft(str, targets), targets);
}
Пример #24
0
LLBC_String LLBC_Trim(const LLBC_String &str)
{
    if (UNLIKELY(str.empty()))
    {
        return LLBC_String(); 
    }

    return LLBC_TrimRight(LLBC_TrimLeft(str));
}
Пример #25
0
LLBC_String LLBC_TrimLeft(const LLBC_String &str, char target)
{
    if (UNLIKELY(str.empty()))
    {
        return LLBC_String();
    }

    const LLBC_String::size_type length = str.size();
    register LLBC_String::size_type leftPos = 0;
    for (; str[leftPos] == target && leftPos < length; leftPos ++);

    if (leftPos >= length)
    {
        return LLBC_String();
    }

    return str.substr(leftPos, LLBC_String::npos);
}
Пример #26
0
LLBC_Dictionary::Iter LLBC_Dictionary::Find(const LLBC_String &key)
{
    LLBC_KeyHashAlgorithm *hashAlgo = LLBC_KeyHashAlgorithmSingleton;
    const LLBC_KeyHashAlgorithm::HashBase &hashFun = 
        *hashAlgo->GetAlgorithm(LLBC_CFG_OBJBASE_DICT_KEY_HASH_ALGO);

    uint32 hash = hashFun(key.c_str(), key.size()) % _bucketSize;
    LLBC_DictionaryElem *elem = _bucket[hash];
    for (; elem != NULL; elem = elem->GetBucketElemNext())
    {
        if (elem->IsStrKey() && *elem->GetStrKey() == key)
        {
            return Iter(elem);
        }
    }

    LLBC_SetLastError(LLBC_ERROR_NOT_FOUND);
    return this->End();
}
Пример #27
0
LLBC_String LLBC_GetDocumentDirectory(bool appendSlash)
{
 #if LLBC_TARGET_PLATFORM_NON_WIN32
    return LLBC_GetHomeDirectory(appendSlash);
 #else
    CHAR buf[MAX_PATH];
    memset(buf, 0, sizeof(CHAR) * MAX_PATH);
    if (::SHGetSpecialFolderPathA(NULL, buf, CSIDL_COMMON_DOCUMENTS, FALSE) == FALSE)
    {
        LLBC_SetLastError(LLBC_ERROR_OSAPI);
        return "";
    }

    LLBC_String path = buf;
    if (appendSlash)
    {
        path.append(1, LLBC_BACKLASH_A);
    }
    
    return path;
 #endif
}
Пример #28
0
void TestCase_Com_DataType::StringStripTest()
{
    LLBC_PrintLine("Strip test:");
    LLBC_String str = "\t \t Hello World! \t \t";
    LLBC_PrintLine("Before strip, str: %s, len: %ld", str.c_str(), str.length());

    str.strip();
    LLBC_PrintLine("After strip, str: %s, len: %ld", str.c_str(), str.length());
}
Пример #29
0
int LLBC_LogConsoleAppender::Output(const LLBC_LogData &data)
{
    LLBC_LogTokenChain *chain = NULL;
    if (!(chain = GetTokenChain()))
    {
        LLBC_SetLastError(LLBC_ERROR_NOT_INIT);
        return LLBC_FAILED;
    }

    const int logLevel = data.level;
    FILE * const out = logLevel >= _LogLevel::Warn ? stderr : stdout;

    int oldOutputColor = 0;
    if (_colourfulOutput)
    {
        oldOutputColor = LLBC_GetConsoleColor(out);

        const int outputColor = DetermineLogTextColor(logLevel);
        LLBC_SetConsoleColor(out, outputColor);
    }

    LLBC_String formattedData;
    chain->Format(data, formattedData);

    LLBC_FilePrint(out, "%s", formattedData.c_str());

#if LLBC_CFG_LOG_DIRECT_FLUSH_TO_CONSOLE
    if (logLevel < _LogLevel::Warn) 
        LLBC_FlushFile(stdout);
#endif

    if (_colourfulOutput)
        LLBC_SetConsoleColor(out, oldOutputColor);

    return LLBC_OK;
}
Пример #30
0
int LLBC_SamplerGroup::AddSampler(int type, const LLBC_String &name)
{
    if (!LLBC_SamplerType::IsValid(type) || name.empty())
    {
        LLBC_SetLastError(LLBC_ERROR_ARG);
        return LLBC_RTN_FAILED;
    }

    if (_samplers->find(name) != _samplers->end())
    {
        LLBC_SetLastError(LLBC_ERROR_EXIST);
        return LLBC_RTN_FAILED;
    }

    LLBC_ISampler *sampler = NULL;
    switch (type)
    {
    case LLBC_SamplerType::CountSampler:
        sampler = new LLBC_CountSampler;
        break;

    case LLBC_SamplerType::LimitSampler:
        sampler = new LLBC_LimitSampler;
        break;

    case LLBC_SamplerType::IntervalSampler:
        sampler = new LLBC_IntervalSampler;
        break;

    default:
        ASSERT(false && "llbc library internal error, unknown sampler type!");
        break;
    }

    _samplers->insert(std::make_pair(name, sampler));

    return true;
}