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

📄 beosprefs.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

            if (p > buffer)
                AppendToString(&entry->prefix, buffer, p - buffer);

            if (*p)
            {
                char *end;
                // char *out;
                int32 length;
                
                entry->key = ReadQuotableString(p, (const char **)&end, ":#");
                if (entry->key && entry->key[0] == '/')
                    continue;
                else if (entry->key && !m_ht.Value(entry->key))
                    m_ht.Insert(entry->key, entry);
                else if (!m_errorLineNumber)
                    m_errorLineNumber = lineNumber;
                p = end;
                
                while (*p && (*p == ' ' || *p == '\t'))
                    p++;
                if (*p == ':')
                    p++;
                else if (!m_errorLineNumber)
                    m_errorLineNumber = lineNumber;
                while (*p && (*p == ' ' || *p == '\t'))
                    p++;
                
                AppendToString(&entry->separator, end, p - end);
                
                entry->value = ReadQuotableString(p, (const char **)&end, "#");
                if (!entry->value && !m_errorLineNumber)
                    m_errorLineNumber = lineNumber;
                p = end;
                length = strlen(p);
                if (p[length - 1] != '\n')
                {
                    p[length++] = '\n';
                    p[length] = '\0';
                }
                AppendToString(&entry->suffix, p, length);
                
                m_entries.push_back(entry);
                entry = new BeOSPrefEntry;
            }
        }

        if (entry->prefix)
            m_entries.push_back(entry);
        else
            delete entry;
        
        if (m_errorLineNumber)
            m_saveEnable = false;
        
        fclose(prefsFile);
    }

    SetDefaults();
    Save();

    // Test(this);
}

BeOSPrefs::
~BeOSPrefs()
{
    Save();

    delete[] m_prefsFilePath;
}

Error
BeOSPrefs::
SetDefaults()
{
    char buf[1024];
    uint32 size;
    
    // set install directory value
    size = sizeof(buf);
    if (GetPrefString(kInstallDirPref, buf, &size) == kError_NoPrefValue)
        SetPrefString(kInstallDirPref, "Dummy");

    // set default freeamp library path value
    size = sizeof(buf);
    if (GetPrefString(kLibraryPathPref, buf, &size) == kError_NoPrefValue)
        SetPrefString(kLibraryPathPref, kDefaultLibraryPath);
    
    // set default ui value
    size = sizeof(buf);
    if (GetPrefString(kUIPref, buf, &size) == kError_NoPrefValue)
        SetPrefString(kUIPref, kDefaultUI);
    
    // set default text ui value
    size = sizeof(buf);
    if (GetPrefString(kTextUIPref, buf, &size) == kError_NoPrefValue)
        SetPrefString(kTextUIPref, kDefaultTextUI);
    
    // set default pmo value
    size = sizeof(buf);
    if (GetPrefString(kPMOPref, buf, &size) == kError_NoPrefValue)
        SetPrefString(kPMOPref, kDefaultPMO);
    
    size = sizeof(buf);
    if (GetPrefString(kDatabaseDirPref, buf, &size) == kError_NoPrefValue) {
        string tempdir = FreeampDir(NULL);
        tempdir += "/db";
        SetPrefString(kDatabaseDirPref, tempdir.c_str());
    }

    size = sizeof(buf);
    if (GetPrefString(kSaveMusicDirPref, buf, &size) == kError_NoPrefValue) {
        string tempdir = FreeampDir(NULL);
        tempdir += "/MyMusic";
        SetPrefString(kSaveMusicDirPref, tempdir.c_str());
    }

    size = sizeof(buf);
    if (GetPrefString(kWatchThisDirectoryPref, buf, &size) == kError_NoPrefValue)
    {
        string tempdir = FreeampDir(NULL);
        tempdir += "/MyMusic";
        SetPrefString(kWatchThisDirectoryPref, tempdir.c_str());
    }

    Preferences::SetDefaults();

    return kError_NoErr;
}

Error
BeOSPrefs::
Save()
{
    if (!m_saveEnable || !m_changed)
        return kError_NoErr;

    // XXX: We should check the modification date of the file,
    //      and refuse to save if it's been modified since we
    //      read it.

    m_changed = false;

    const char *tmpSuffix = ".tmp";
    char *tmpFilePath = new char[strlen(m_prefsFilePath) +
                                 strlen(tmpSuffix) + 1];
    strcpy(tmpFilePath, m_prefsFilePath);
    strcat(tmpFilePath, tmpSuffix);

    const char *bakSuffix = ".bak";
    char *bakFilePath = new char[strlen(m_prefsFilePath) +
                                 strlen(bakSuffix) + 1];
    strcpy(bakFilePath, m_prefsFilePath);
    strcat(bakFilePath, bakSuffix);

    {
        FILE *prefsFile = fopen(tmpFilePath, "w");
        if (!prefsFile)
        {
            delete[] tmpFilePath;
            delete[] bakFilePath;
            return kError_UnknownErr; // XXX: Be more informative
        }

        m_mutex.Acquire();
                
        int32 numEntries = m_entries.size();
        int32 i;
        BeOSPrefEntry *entry;
        
        for (i = 0; i < numEntries; i++)
        {
            entry = m_entries[i];
            if (entry->prefix)
                fputs(entry->prefix, prefsFile);
            if (entry->key && entry->separator && entry->value)
            {
                char *outStr;
                
                outStr = WriteQuotableString(entry->key, ":#");
                fputs(outStr, prefsFile);
                delete[] outStr;

                fputs(entry->separator, prefsFile);

                outStr = WriteQuotableString(entry->value, "#");
                fputs(outStr, prefsFile);
                delete[] outStr;
            }
            if (entry->suffix)
                fputs(entry->suffix, prefsFile);
        }
        
        m_mutex.Release();

        if (ferror(prefsFile))
        {
            fclose(prefsFile);
            delete[] tmpFilePath;
            delete[] bakFilePath;
            return kError_UnknownErr; // XXX: Be more informative
        }
        
        fclose(prefsFile);
    }

    if (rename(m_prefsFilePath, bakFilePath) && errno != ENOENT)
    {
        delete[] tmpFilePath;
        delete[] bakFilePath;
        return kError_UnknownErr; // XXX: Be more informative
    }

    if (rename(tmpFilePath, m_prefsFilePath))
        rename(bakFilePath, m_prefsFilePath);

    delete[] tmpFilePath;
    delete[] bakFilePath;
    return kError_NoErr;
}

Preferences *
BeOSPrefs::
ComponentPrefs(const char *componentName)
{
    return new PrefixPrefs(this, componentName);
}

Error
BeOSPrefs::
GetPrefString(const char* pref, char* buf, uint32* len)
{
    BeOSPrefEntry *entry;
    // int32 index;

    m_mutex.Acquire();

    buf[0] = '\0';
    entry = m_ht.Value(pref);
    if (!entry || !entry->value)
    {
        *len = 0;
        m_mutex.Release();
        return kError_NoPrefValue;
    }
    char *value = entry->value;
    uint32 value_len = strlen(value) + 1;

    if (value_len > *len)
    {
        *len = value_len;
        m_mutex.Release();
        return kError_BufferTooSmall;
    }

    strncpy(buf, value, value_len);
    *len = value_len;
    m_mutex.Release();
    return kError_NoErr;
}

Error
BeOSPrefs::
SetPrefString(const char* pref, const char* buf)
{
    BeOSPrefEntry *entry;

    m_mutex.Acquire();

    entry = m_ht.Value(pref);
    if (entry)
    {
        delete[] entry->value;
        entry->value = 0;
    }
    else
    {
        entry = new BeOSPrefEntry;
        AppendToString(&entry->key, pref, strlen(pref));
        AppendToString(&entry->separator, ": ", 2);
        AppendToString(&entry->suffix, "\n", 1);
        m_entries.push_back(entry);
        m_ht.Insert(pref, entry);
    }
    AppendToString(&entry->value, buf, strlen(buf));

    m_changed = true;

    m_mutex.Release();
    return kError_NoErr;
}

char *BeOSPrefs::m_libDirs = 0;

const char *
BeOSPrefs::
GetLibDirs()
{
    if (!m_libDirs) {
        uint32 size = 1024;
        m_libDirs = new char[size];

        GetPrefString(kLibraryPathPref, m_libDirs, &size);
    }
    return m_libDirs;
}

LibDirFindHandle *
BeOSPrefs::
GetFirstLibDir(char *path, uint32 *len)
{
    // if no FREEAMP_PATH, use kLibraryPathPref
    // if FREEAMP_PATH, then its FREEAMP_PATH
    char *pEnv = getenv(FREEAMP_PATH_ENV);
    char *pPath = NULL;
    if (pEnv) {
//      cout << "Using env: " << pEnv << endl;
        pPath = strdup_new(pEnv);
    } else {
        pPath = strdup_new(GetLibDirs());
    }
    pEnv = pPath;
    LibDirFindHandle *hLibDirFind = new LibDirFindHandle();
    hLibDirFind->m_pLibDirs = new vector<char *>();
    hLibDirFind->m_current = 0;

    char *pCol = (char *)1;
    char *pPart = pPath;
    while (pCol) {
        pCol = strchr(pPart,':');
        if (pCol) *pCol = '\0';
        char *pFoo = strdup_new(pPart);
        hLibDirFind->m_pLibDirs->push_back(pFoo);
        pPart = pCol + sizeof(char);
    }

    if (hLibDirFind->m_pLibDirs->size() > 0) {
        pPath = (*hLibDirFind->m_pLibDirs)[0];
        strncpy(path,pPath,*len);
        *len = strlen(pPath);
    } else {
        *path = '\0';
        *len = 0;
        delete hLibDirFind->m_pLibDirs;
        delete hLibDirFind;
        hLibDirFind = 0;
    }

    if (pEnv) delete pEnv;
    //cout << "returning " << path << endl;
    return hLibDirFind;
}

Error
BeOSPrefs::
GetNextLibDir(LibDirFindHandle *hLibDirFind, char *path, uint32 *len)
{
    if (hLibDirFind) {
        if (++hLibDirFind->m_current < (int32)hLibDirFind->m_pLibDirs->size()) {
            char *pPath = (*hLibDirFind->m_pLibDirs)[hLibDirFind->m_current];
            strncpy(path,pPath,*len);
            *len = strlen(pPath);
//          cout << "returning next: " << path << endl;
            return kError_NoErr;
        }
        *path = '\0';
        *len = 0;
//      cout << "returning no next " << path << endl;
    }
    return kError_NoMoreLibDirs;
}

Error
BeOSPrefs::
GetLibDirClose(LibDirFindHandle *hLibDirFind)
{
    if (hLibDirFind) {
        while (hLibDirFind->m_pLibDirs->size() > 0)
        {
            delete (*(hLibDirFind->m_pLibDirs))[0];
            hLibDirFind->m_pLibDirs->erase(hLibDirFind->m_pLibDirs->begin());
        }
        delete hLibDirFind->m_pLibDirs;
        delete hLibDirFind;
    }
    return kError_NoErr;
}

⌨️ 快捷键说明

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