⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpleini.h

📁 iContact v0.75 iContact is designed to be an all-inclusive finger-friendly contact manager for Wind
💻 H
📖 第 1 页 / 共 5 页
字号:
#if __STDC_WANT_SECURE_LIB__
    fopen_s(&fp, a_pszFile, "rb");
#else
    fp = fopen(a_pszFile, "rb");
#endif
    if (!fp) {
        return SI_FILE;
    }
    SI_Error rc = LoadFile(fp);
    fclose(fp);
    return rc;
}

#ifdef SI_HAS_WIDE_FILE
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
    const SI_WCHAR_T * a_pwszFile
    )
{
#ifdef _WIN32
    FILE * fp = NULL;
#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
    _wfopen_s(&fp, a_pwszFile, L"rb");
#else
    fp = _wfopen(a_pwszFile, L"rb");
#endif
    if (!fp) return SI_FILE;
    SI_Error rc = LoadFile(fp);
    fclose(fp);
    return rc;
#else // SI_CONVERT_ICU
    char szFile[256];
    u_austrncpy(szFile, a_pwszFile, sizeof(szFile));
    return LoadFile(szFile);
#endif
}
#endif // SI_HAS_WIDE_FILE

template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
    FILE * a_fpFile
    )
{
    // load the raw file data
    int retval = fseek(a_fpFile, 0, SEEK_END);
    if (retval != 0) {
        return SI_FILE;
    }
    long lSize = ftell(a_fpFile);
    if (lSize < 0) {
        return SI_FILE;
    }
    if (lSize == 0) {
        return SI_OK;
    }
    char * pData = new char[lSize];
    if (!pData) {
        return SI_NOMEM;
    }
    fseek(a_fpFile, 0, SEEK_SET);
    size_t uRead = fread(pData, sizeof(char), lSize, a_fpFile);
    if (uRead != (size_t) lSize) {
        delete[] pData;
        return SI_FILE;
    }

    // convert the raw data to unicode
    SI_Error rc = Load(pData, uRead);
    delete[] pData;
    return rc;
}

template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Load(
    const char *    a_pData,
    size_t          a_uDataLen
    )
{
    SI_CONVERTER converter(m_bStoreIsUtf8);

    if (a_uDataLen == 0) {
        return SI_OK;
    }

    // consume the UTF-8 BOM if it exists
    if (m_bStoreIsUtf8 && a_uDataLen >= 3) {
        if (memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) {
            a_pData    += 3;
            a_uDataLen -= 3;
        }
    }

    // determine the length of the converted data
    size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen);
    if (uLen == (size_t)(-1)) {
        return SI_FAIL;
    }

    // allocate memory for the data, ensure that there is a NULL
    // terminator wherever the converted data ends
    SI_CHAR * pData = new SI_CHAR[uLen+1];
    if (!pData) {
        return SI_NOMEM;
    }
    memset(pData, 0, sizeof(SI_CHAR)*(uLen+1));

    // convert the data
    if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) {
        delete[] pData;
        return SI_FAIL;
    }

    // parse it
    const static SI_CHAR empty = 0;
    SI_CHAR * pWork = pData;
    const SI_CHAR * pSection = &empty;
    const SI_CHAR * pItem = NULL;
    const SI_CHAR * pVal = NULL;
    const SI_CHAR * pComment = NULL;

    // We copy the strings if we are loading data into this class when we
    // already have stored some.
    bool bCopyStrings = (m_pData != NULL);

    // find a file comment if it exists, this is a comment that starts at the
    // beginning of the file and continues until the first blank line.
    SI_Error rc = FindFileComment(pWork, bCopyStrings);
    if (rc < 0) return rc;

    // add every entry in the file to the data table
    while (FindEntry(pWork, pSection, pItem, pVal, pComment)) {
        rc = AddEntry(pSection, pItem, pVal, pComment, bCopyStrings);
        if (rc < 0) return rc;
    }

    // store these strings if we didn't copy them
    if (bCopyStrings) {
        delete[] pData;
    }
    else {
        m_pData = pData;
        m_uDataLen = uLen+1;
    }

    return SI_OK;
}

#ifdef SI_SUPPORT_IOSTREAMS
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Load(
    std::istream & a_istream
    )
{
    std::string strData;
    char szBuf[512];
    do {
        a_istream.get(szBuf, sizeof(szBuf), '\0');
        strData.append(szBuf);
    }
    while (a_istream.good());
    return Load(strData);
}
#endif // SI_SUPPORT_IOSTREAMS

template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindFileComment(
    SI_CHAR *&      a_pData,
    bool            a_bCopyStrings
    )
{
    // there can only be a single file comment
    if (m_pFileComment) {
        return SI_OK;
    }

    // Load the file comment as multi-line text, this will modify all of
    // the newline characters to be single \n chars
    if (!LoadMultiLineText(a_pData, m_pFileComment, NULL, false)) {
        return SI_OK;
    }

    // copy the string if necessary
    if (a_bCopyStrings) {
        SI_Error rc = CopyString(m_pFileComment);
        if (rc < 0) return rc;
    }

    return SI_OK;
}

template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
    SI_CHAR *&        a_pData,
    const SI_CHAR *&  a_pSection,
    const SI_CHAR *&  a_pKey,
    const SI_CHAR *&  a_pVal,
    const SI_CHAR *&  a_pComment
    ) const
{
    a_pComment = NULL;

    SI_CHAR * pTrail = NULL;
    while (*a_pData) {
        // skip spaces and empty lines
        while (*a_pData && IsSpace(*a_pData)) {
            ++a_pData;
        }
        if (!*a_pData) {
            break;
        }

        // skip processing of comment lines but keep a pointer to
        // the start of the comment.
        if (IsComment(*a_pData)) {
            LoadMultiLineText(a_pData, a_pComment, NULL, true);
            continue;
        }

        // process section names
        if (*a_pData == '[') {
            // skip leading spaces
            ++a_pData;
            while (*a_pData && IsSpace(*a_pData)) {
                ++a_pData;
            }

            // find the end of the section name (it may contain spaces)
            // and convert it to lowercase as necessary
            a_pSection = a_pData;
            while (*a_pData && *a_pData != ']' && !IsNewLineChar(*a_pData)) {
                ++a_pData;
            }

            // if it's an invalid line, just skip it
            if (*a_pData != ']') {
                continue;
            }

            // remove trailing spaces from the section
            pTrail = a_pData - 1;
            while (pTrail >= a_pSection && IsSpace(*pTrail)) {
                --pTrail;
            }
            ++pTrail;
            *pTrail = 0;

            // skip to the end of the line
            ++a_pData;  // safe as checked that it == ']' above
            while (*a_pData && !IsNewLineChar(*a_pData)) {
                ++a_pData;
            }

            a_pKey = NULL;
            a_pVal = NULL;
            return true;
        }

        // find the end of the key name (it may contain spaces)
        // and convert it to lowercase as necessary
        a_pKey = a_pData;
        while (*a_pData && *a_pData != '=' && !IsNewLineChar(*a_pData)) {
            ++a_pData;
        }

        // if it's an invalid line, just skip it
        if (*a_pData != '=') {
            continue;
        }

        // empty keys are invalid
        if (a_pKey == a_pData) {
            while (*a_pData && !IsNewLineChar(*a_pData)) {
                ++a_pData;
            }
            continue;
        }

        // remove trailing spaces from the key
        pTrail = a_pData - 1;
        while (pTrail >= a_pKey && IsSpace(*pTrail)) {
            --pTrail;
        }
        ++pTrail;
        *pTrail = 0;

        // skip leading whitespace on the value
        ++a_pData;  // safe as checked that it == '=' above
        while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) {
            ++a_pData;
        }

        // find the end of the value which is the end of this line
        a_pVal = a_pData;
        while (*a_pData && !IsNewLineChar(*a_pData)) {
            ++a_pData;
        }

        // remove trailing spaces from the value
        pTrail = a_pData - 1;
        if (*a_pData) { // prepare for the next round
            SkipNewLine(a_pData);
        }
        while (pTrail >= a_pVal && IsSpace(*pTrail)) {
            --pTrail;
        }
        ++pTrail;
        *pTrail = 0;

        // check for multi-line entries
        if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) {
            // skip the "<<<" to get the tag that will end the multiline
            const SI_CHAR * pTagName = a_pVal + 3;
            return LoadMultiLineText(a_pData, a_pVal, pTagName);
        }

        // return the standard entry
        return true;
    }

    return false;
}

template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::IsMultiLineTag(
    const SI_CHAR * a_pVal
    ) const
{
    // check for the "<<<" prefix for a multi-line entry
    if (*a_pVal++ != '<') return false;
    if (*a_pVal++ != '<') return false;
    if (*a_pVal++ != '<') return false;
    return true;
}

template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::IsMultiLineData(
    const SI_CHAR * a_pData
    ) const
{
    // data is multi-line if it has any of the following features:
    //  * whitespace prefix
    //  * embedded newlines
    //  * whitespace suffix

    // empty string
    if (!*a_pData) {
        return false;
    }

    // check for prefix
    if (IsSpace(*a_pData)) {
        return true;
    }

    // embedded newlines
    while (*a_pData) {
        if (IsNewLineChar(*a_pData)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -