Exemple #1
0
static void DeserializePrefs(const char *prefsTxt, SerializableGlobalPrefs& globalPrefs,
    FileHistory& fh, Favorites *favs)
{
    BencObj *obj = BencObj::Decode(prefsTxt);
    if (!obj || obj->Type() != BT_DICT)
        goto Exit;
    BencDict *prefs = static_cast<BencDict *>(obj);
    BencDict *global = prefs->GetDict(GLOBAL_PREFS_STR);
    if (!global)
        goto Exit;

    DeserializeStruct(gGlobalPrefInfo, dimof(gGlobalPrefInfo), &globalPrefs, global);

    free(globalPrefs.prevSerialization);
    globalPrefs.prevSerialization = global->Encode();

    int weekDiff = GetWeekCount() - globalPrefs.openCountWeek;
    globalPrefs.openCountWeek = GetWeekCount();

    BencArray *fileHistory = prefs->GetArray(FILE_HISTORY_STR);
    if (!fileHistory)
        goto Exit;
    size_t dlen = fileHistory->Length();
    for (size_t i = 0; i < dlen; i++) {
        BencDict *dict = fileHistory->GetDict(i);
        assert(dict);
        if (!dict) continue;
        DisplayState *state = DeserializeDisplayState(dict, globalPrefs.globalPrefsOnly);
        if (state) {
            // "age" openCount statistics (cut in in half after every week)
            state->openCount >>= weekDiff;
            fh.Append(state);
        }
    }

    BencArray *favsArr = prefs->GetArray(FAVS_STR);
    if (!favsArr)
        goto Exit;
    for (size_t i = 0; i < favsArr->Length(); i += 2) {
        BencString *filePathBenc = favsArr->GetString(i);
        BencArray *favData = favsArr->GetArray(i+1);
        if (!filePathBenc || !favData)
            break;
        ScopedMem<WCHAR> filePath(filePathBenc->Value());
        for (size_t j = 0; j < favData->Length(); j += 2) {
            // we're lenient about errors
            BencInt *pageNoBenc = favData->GetInt(j);
            BencString *nameBenc = favData->GetString(j + 1);
            if (!pageNoBenc || !nameBenc)
                break;
            int pageNo = (int)pageNoBenc->Value();
            ScopedMem<WCHAR> name(nameBenc->Value());
            favs->AddOrReplace(filePath, pageNo, EmptyToNull(name));
        }
    }

Exit:
    delete obj;
}
static void BencTestParseDict(const char *benc, size_t expectedLen)
{
    BencObj *obj = BencObj::Decode(benc);
    assert(obj);
    assert(obj->Type() == BT_DICT);
    assert(static_cast<BencDict *>(obj)->Length() == expectedLen);
    BencTestSerialization(obj, benc);
    delete obj;
}
Exemple #3
0
static void BencTestParseArray(const char *benc, size_t expectedLen)
{
    BencObj *obj = BencObj::Decode(benc);
    utassert(obj);
    utassert(obj->Type() == BT_ARRAY);
    utassert(static_cast<BencArray *>(obj)->Length() == expectedLen);
    BencTestSerialization(obj, benc);
    delete obj;
}
static void BencTestParseInt()
{
    struct {
        const char *    benc;
        bool            valid;
        int64_t         value;
    } testData[] = {
        { NULL, false },
        { "", false },
        { "a", false },
        { "0", false },
        { "i", false },
        { "ie", false },
        { "i0", false },
        { "i1", false },
        { "i23", false },
        { "i-", false },
        { "i-e", false },
        { "i-0e", false },
        { "i23f", false },
        { "i2-3e", false },
        { "i23-e", false },
        { "i041e", false },
        { "i9223372036854775808e", false },
        { "i-9223372036854775809e", false },

        { "i0e", true, 0 },
        { "i1e", true, 1 },
        { "i9823e", true, 9823 },
        { "i-1e", true, -1 },
        { "i-53e", true, -53 },
        { "i123e", true, 123 },
        { "i2147483647e", true, INT_MAX },
        { "i2147483648e", true, (int64_t)INT_MAX + 1 },
        { "i-2147483648e", true, INT_MIN },
        { "i-2147483649e", true, (int64_t)INT_MIN - 1 },
        { "i9223372036854775807e", true, _I64_MAX },
        { "i-9223372036854775808e", true, _I64_MIN },
    };

    for (int i = 0; i < dimof(testData); i++) {
        BencObj *obj = BencObj::Decode(testData[i].benc);
        if (testData[i].valid) {
            assert(obj);
            assert(obj->Type() == BT_INT);
            assert(static_cast<BencInt *>(obj)->Value() == testData[i].value);
            BencTestSerialization(obj, testData[i].benc);
            delete obj;
        } else {
            assert(!obj);
        }
    }
}
Exemple #5
0
char *BencArray::Encode() const
{
    str::Str<char> bytes(256);
    bytes.Append('l');
    for (size_t i = 0; i < Length(); i++) {
        BencObj *val = value.At(i);
        if (val)
            bytes.AppendAndFree(val->Encode());
    }
    bytes.Append('e');
    return bytes.StealData();
}
Exemple #6
0
char *BencDict::Encode() const
{
    str::Str<char> bytes(256);
    bytes.Append('d');
    for (size_t i = 0; i < Length(); i++) {
        char *key = keys.At(i);
        BencObj *val = values.At(i);
        if (key && val) {
            bytes.AppendFmt("%" PRIuPTR ":%s", str::Len(key), key);
            bytes.AppendAndFree(val->Encode());
        }
    }
    bytes.Append('e');
    return bytes.StealData();
}
static void BencTestParseString()
{
    struct {
        const char *    benc;
        WCHAR *         value;
    } testData[] = {
        { NULL, NULL },
        { "", NULL },
        { "0", NULL },
        { "1234", NULL },
        { "a", NULL },
        { ":", NULL },
        { ":z", NULL },
        { "1:ab", NULL },
        { "3:ab", NULL },
        { "-2:ab", NULL },
        { "2e:ab", NULL },

        { "0:", L"" },
        { "1:a", L"a" },
        { "2::a", L":a" },
        { "4:spam", L"spam" },
        { "4:i23e", L"i23e" },
        { "5:\xC3\xA4\xE2\x82\xAC", L"\u00E4\u20AC" },
    };

    for (int i = 0; i < dimof(testData); i++) {
        BencObj *obj = BencObj::Decode(testData[i].benc);
        if (testData[i].value) {
            assert(obj);
            assert(obj->Type() == BT_STRING);
            ScopedMem<WCHAR> value(static_cast<BencString *>(obj)->Value());
            assert(str::Eq(value, testData[i].value));
            BencTestSerialization(obj, testData[i].benc);
            delete obj;
        } else {
            assert(!obj);
        }
    }
}
static void BencTestStress()
{
    char key[64];
    char val[64];
    WCHAR tval[64];
    Vec<BencObj*> stack(29);
    BencDict *startDict = new BencDict();
    BencDict *d = startDict;
    BencArray *a = NULL;
    srand((unsigned int)time(NULL));
    // generate new dict or array with 5% probability each, close an array or
    // dict with 8% probability (less than 10% probability of opening one, to
    // encourage nesting), generate int, string or raw strings uniformly
    // across the remaining 72% probability
    for (int i = 0; i < 10000; i++)
    {
        int n = rand() % 100;
        if (n < 5) {
            BencDict *nd = new BencDict();
            if (a) {
                a->Add(nd);
            } else {
                GenRandStr(key, dimof(key));
                d->Add(key, nd);
            }
            stack.Push(nd);
            d = nd;
            a = NULL;
        } else if (n < 10) {
            BencArray *na = new BencArray();
            if (a) {
                a->Add(na);
            } else {
                GenRandStr(key, dimof(key));
                d->Add(key, na);
            }
            stack.Push(na);
            d = NULL;
            a = na;
        } else if (n < 18) {
            if (stack.Count() > 0) {
                n = rand() % 100;
                stack.Pop();
                BencObj *o = startDict;
                if (stack.Count() > 0) {
                    o = stack.Last();
                }
                a = NULL; d = NULL;
                if (BT_ARRAY == o->Type()) {
                    a = static_cast<BencArray *>(o);
                } else {
                    d = static_cast<BencDict *>(o);
                }
            }
        } else if (n < (18 + 24)) {
            int64_t v = rand();
            if (a) {
                a->Add(v);
            } else {
                GenRandStr(key, dimof(key));
                d->Add(key, v);
            }
        } else if (n < (18 + 24 + 24)) {
            GenRandStr(val, dimof(val));
            if (a) {
                a->AddRaw((const char*)val);
            } else {
                GenRandStr(key, dimof(key));
                d->AddRaw((const char*)key, val);
            }
        } else {
            GenRandTStr(tval, dimof(tval));
            if (a) {
                a->Add(tval);
            } else {
                GenRandStr(key, dimof(key));
                d->Add((const char*)key, (const WCHAR *)val);
            }
        }
    }

    char *s = startDict->Encode();
    free(s);
    delete startDict;
}
Exemple #9
0
static void DeserializePrefs(const char *prefsTxt, SerializableGlobalPrefs& globalPrefs,
    FileHistory& fh, Favorites *favs)
{
    BencObj *obj = BencObj::Decode(prefsTxt);
    if (!obj || obj->Type() != BT_DICT)
        goto Exit;
    BencDict *prefs = static_cast<BencDict *>(obj);
    BencDict *global = prefs->GetDict(GLOBAL_PREFS_STR);
    if (!global)
        goto Exit;

    Retrieve(global, TOOLBAR_VISIBLE_STR, globalPrefs.toolbarVisible);
    Retrieve(global, TOC_VISIBLE_STR, globalPrefs.tocVisible);
    Retrieve(global, FAV_VISIBLE_STR, globalPrefs.favVisible);

    Retrieve(global, SIDEBAR_DX_STR, globalPrefs.sidebarDx);
    Retrieve(global, TOC_DY_STR, globalPrefs.tocDy);
    Retrieve(global, PDF_ASSOCIATE_DONT_ASK_STR, globalPrefs.pdfAssociateDontAskAgain);
    Retrieve(global, PDF_ASSOCIATE_ASSOCIATE_STR, globalPrefs.pdfAssociateShouldAssociate);
    Retrieve(global, ESC_TO_EXIT_STR, globalPrefs.escToExit);
    Retrieve(global, USE_SYS_COLORS_STR, globalPrefs.useSysColors);
    Retrieve(global, BG_COLOR_STR, globalPrefs.bgColor);
    Retrieve(global, ENABLE_AUTO_UPDATE_STR, globalPrefs.enableAutoUpdate);
    Retrieve(global, REMEMBER_OPENED_FILES_STR, globalPrefs.rememberOpenedFiles);
    Retrieve(global, GLOBAL_PREFS_ONLY_STR, globalPrefs.globalPrefsOnly);
    Retrieve(global, SHOW_RECENT_FILES_STR, globalPrefs.showStartPage);

    Retrieve(global, DISPLAY_MODE_STR, globalPrefs.defaultDisplayMode);
    Retrieve(global, ZOOM_VIRTUAL_STR, globalPrefs.defaultZoom);
    Retrieve(global, WINDOW_STATE_STR, globalPrefs.windowState);

    Retrieve(global, WINDOW_X_STR, globalPrefs.windowPos.x);
    Retrieve(global, WINDOW_Y_STR, globalPrefs.windowPos.y);
    Retrieve(global, WINDOW_DX_STR, globalPrefs.windowPos.dx);
    Retrieve(global, WINDOW_DY_STR, globalPrefs.windowPos.dy);

    Retrieve(global, INVERSE_SEARCH_COMMANDLINE, globalPrefs.inverseSearchCmdLine);
    Retrieve(global, ENABLE_TEX_ENHANCEMENTS_STR, globalPrefs.enableTeXEnhancements);
    Retrieve(global, VERSION_TO_SKIP_STR, globalPrefs.versionToSkip);
    RetrieveRaw(global, LAST_UPDATE_STR, globalPrefs.lastUpdateTime);

    const char *lang = GetRawString(global, UI_LANGUAGE_STR);
    const char *langCode = trans::ValidateLanguageCode(lang);
    if (langCode)
        globalPrefs.currentLanguage = langCode;

    Retrieve(global, FWDSEARCH_OFFSET, globalPrefs.fwdSearch.offset);
    Retrieve(global, FWDSEARCH_COLOR, globalPrefs.fwdSearch.color);
    Retrieve(global, FWDSEARCH_WIDTH, globalPrefs.fwdSearch.width);
    Retrieve(global, FWDSEARCH_PERMANENT, globalPrefs.fwdSearch.permanent);

    Retrieve(global, CBX_RIGHT2LEFT, globalPrefs.cbxR2L);

    Retrieve(global, OPEN_COUNT_WEEK_STR, globalPrefs.openCountWeek);
    int weekDiff = GetWeekCount() - globalPrefs.openCountWeek;
    globalPrefs.openCountWeek = GetWeekCount();

    BencArray *fileHistory = prefs->GetArray(FILE_HISTORY_STR);
    if (!fileHistory)
        goto Exit;
    size_t dlen = fileHistory->Length();
    for (size_t i = 0; i < dlen; i++) {
        BencDict *dict = fileHistory->GetDict(i);
        assert(dict);
        if (!dict) continue;
        DisplayState *state = DeserializeDisplayState(dict, globalPrefs.globalPrefsOnly);
        if (state) {
            // "age" openCount statistics (cut in in half after every week)
            state->openCount >>= weekDiff;
            fh.Append(state);
        }
    }

    BencArray *favsArr = prefs->GetArray(FAVS_STR);
    if (!favsArr)
        goto Exit;
    for (size_t i = 0; i < favsArr->Length(); i += 2) {
        BencString *filePathBenc = favsArr->GetString(i);
        BencArray *favData = favsArr->GetArray(i+1);
        if (!filePathBenc || !favData)
            break;
        ScopedMem<WCHAR> filePath(filePathBenc->Value());
        for (size_t j = 0; j < favData->Length(); j += 2) {
            // we're lenient about errors
            BencInt *pageNoBenc = favData->GetInt(j);
            BencString *nameBenc = favData->GetString(j + 1);
            if (!pageNoBenc || !nameBenc)
                break;
            int pageNo = (int)pageNoBenc->Value();
            ScopedMem<WCHAR> name(nameBenc->Value());
            favs->AddOrReplace(filePath, pageNo, EmptyToNull(name));
        }
    }

Exit:
    delete obj;
}
void SelectTranslation(const WCHAR *exePath=NULL)
{
    LANGID langId = GetUserDefaultUILanguage();
    int idx = GetLanguageIndex(langId);
    if (-1 == idx) {
        // try a neutral language if the specific sublanguage isn't available
        langId = MAKELANGID(PRIMARYLANGID(langId), SUBLANG_NEUTRAL);
        idx = GetLanguageIndex(langId);
    }
    if (-1 != idx) {
        gTranslationIdx = idx;
        plogf("sp: Detected language %s (%d)", gLanguages[idx / gTranslationsCount], idx);
    }

    // try to extract the language used by SumatraPDF
    ScopedMem<WCHAR> path;
    if (exePath) {
        path.Set(path::GetDir(exePath));
        path.Set(path::Join(path, PREFS_FILE_NAME));
    }
    if (!file::Exists(path)) {
        path.Set(GetSpecialFolder(CSIDL_APPDATA));
        path.Set(path::Join(path, L"SumatraPDF\\" PREFS_FILE_NAME));
    }
    if (!file::Exists(path))
        return;
    plogf("sp: Found preferences at %S", path);
#ifndef USE_INI_SETTINGS
    ScopedMem<char> data(file::ReadAll(path, NULL));
    if (data) {
        BencObj *root = BencObj::Decode(data);
        if (root && root->Type() == BT_DICT) {
            BencDict *global = static_cast<BencDict *>(root)->GetDict("gp");
            BencString *string = global ? global->GetString("UILanguage") : NULL;
            if (string) {
                plogf("sp: UILanguage from preferences: %s", string->RawValue());
                for (int i = 0; gLanguages[i]; i++) {
                    if (str::Eq(gLanguages[i], string->RawValue())) {
                        gTranslationIdx = i * gTranslationsCount;
                        break;
                    }
                }
            }
        }
        delete root;
    }
#else
    IniFile ini(path);
    IniSection *section = ini.FindSection(NULL);
    IniLine *line = section ? section->FindLine("CurrLangCode") : NULL;
    if (line) {
        plogf("sp: UILanguage from preferences: %s", line->value);
        for (int i = 0; gLanguages[i]; i++) {
            if (str::Eq(gLanguages[i], line->value)) {
                gTranslationIdx = i * gTranslationsCount;
                break;
            }
        }
    }
#endif
}