コード例 #1
0
static BencArray *SerializeFileHistory(FileHistory& fileHistory, bool globalPrefsOnly)
{
    BencArray *arr = new BencArray();

    // Don't save more file entries than will be useful
    int minOpenCount = 0;
    if (globalPrefsOnly) {
        Vec<DisplayState *> frequencyList;
        fileHistory.GetFrequencyOrder(frequencyList);
        if (frequencyList.Count() > FILE_HISTORY_MAX_RECENT)
            minOpenCount = frequencyList.At(FILE_HISTORY_MAX_FREQUENT)->openCount / 2;
    }

    DisplayState *state;
    for (int index = 0; (state = fileHistory.Get(index)); index++) {
        // never forget pinned documents and documents we've remembered a password for
        bool forceSave = state->isPinned || state->decryptionKey != NULL;
        if (index >= MAX_REMEMBERED_FILES && !forceSave)
            continue;
        if (state->openCount < minOpenCount && index > FILE_HISTORY_MAX_RECENT && !forceSave)
            continue;
        BencDict *obj = DisplayState_Serialize(state, globalPrefsOnly);
        if (!obj)
            goto Error;
        arr->Add(obj);
    }
    return arr;

Error:
    delete arr;
    return NULL;
}
コード例 #2
0
// for simplicity, favorites are serialized as an array. Element 2*i is
// a name of the file, for favorite i, element 2*i+1 is an array of
// page number integer/name string pairs
static BencArray *SerializeFavorites(Favorites *favs)
{
    BencArray *res = new BencArray();
    for (size_t i = 0; i < favs->favs.Count(); i++) {
        FileFavs *fav = favs->favs.At(i);
        res->Add(fav->filePath);
        res->Add(SerializeFavData(fav));
    }
    return res;
}
コード例 #3
0
static BencArray *SerializeFavData(FileFavs *fav)
{
    BencArray *res = new BencArray();
    for (size_t i = 0; i < fav->favNames.Count(); i++) {
        FavName *fn = fav->favNames.At(i);
        res->Add(fn->pageNo);
        res->Add(NullToEmpty(fn->name));
    }
    return res;
}
コード例 #4
0
ファイル: AppPrefs.cpp プロジェクト: shienme/sumatrapdf
static BencDict *SerializeStruct(PrefInfo *info, size_t count, const void *structBase, BencDict *prefs=NULL, uint32_t bitmask=-1)
{
    if (!prefs)
        prefs = new BencDict();
    const char *base = (const char *)structBase;
    for (size_t i = 0; i < count; i++) {
        PrefInfo& meta = info[i];
        if ((meta.bitfield & bitmask) != meta.bitfield)
            continue;
        switch (meta.type) {
        case Pref_Bool:
            prefs->Add(meta.name, (int64_t)*(bool *)(base + meta.offset));
            break;
        case Pref_Int:
            prefs->Add(meta.name, (int64_t)*(int *)(base + meta.offset));
            break;
        case Pref_Str:
        case Pref_UILang:
            if (*(const char **)(base + meta.offset))
                prefs->AddRaw(meta.name, *(const char **)(base + meta.offset));
            else
                delete prefs->Remove(meta.name);
            break;
        case Pref_WStr:
            if (*(const WCHAR **)(base + meta.offset))
                prefs->Add(meta.name, *(const WCHAR **)(base + meta.offset));
            else
                delete prefs->Remove(meta.name);
            break;
        case Pref_DisplayMode:
            prefs->Add(meta.name, DisplayModeConv::NameFromEnum(*(DisplayMode *)(base + meta.offset)));
            break;
        case Pref_Float:
            prefs->AddRaw(meta.name, ScopedMem<char>(str::Format("%.4f", *(float *)(base + meta.offset))));
            break;
        case Pref_IntVec:
            Vec<int> *intVec = *(Vec<int> **)(base + meta.offset);
            if (intVec) {
                BencArray *array = new BencArray();
                for (size_t idx = 0; idx < intVec->Count(); idx++) {
                    array->Add(intVec->At(idx));
                }
                prefs->Add(meta.name, array);
            }
            else
                delete prefs->Remove(meta.name);
            break;
        }
    }
    return prefs;
}
コード例 #5
0
static void DeserializeToc(BencDict *dict, DisplayState *ds)
{
    BencArray *tocState = dict->GetArray(TOC_STATE_STR);
    if (!tocState)
        return;
    size_t len = tocState->Length();
    ds->tocState = new Vec<int>(len);
    if (!ds->tocState)
        return;

    for (size_t i = 0; i < len; i++) {
        BencInt *intObj = tocState->GetInt(i);
        if (intObj)
            ds->tocState->Append((int)intObj->Value());
    }
}
コード例 #6
0
ファイル: BencUtil_ut.cpp プロジェクト: aarjones55/sumatrapdf
static void BencTestArrayAppend()
{
    BencArray *array = new BencArray();
    for (size_t i = 1; i <= ITERATION_COUNT; i++) {
        array->Add(i);
        assert(array->Length() == i);
    }
    array->Add(new BencDict());
    for (size_t i = 1; i <= ITERATION_COUNT; i++) {
        BencInt *obj = array->GetInt(i - 1);
        assert(obj && obj->Type() == BT_INT);
        assert(obj->Value() == i);
        assert(!array->GetString(i - 1));
        assert(!array->GetArray(i - 1));
        assert(!array->GetDict(i - 1));
    }
    assert(!array->GetInt(ITERATION_COUNT));
    assert(array->GetDict(ITERATION_COUNT));
    BencTestRoundtrip(array);
    delete array;
}
コード例 #7
0
ファイル: BencUtil_ut.cpp プロジェクト: aarjones55/sumatrapdf
static void BencTestParseRawStrings()
{
    BencArray array;
    array.AddRaw("a\x82");
    array.AddRaw("a\x82", 1);
    BencString *raw = array.GetString(0);
    assert(raw && str::Eq(raw->RawValue(), "a\x82"));
    BencTestSerialization(raw, "2:a\x82");
    raw = array.GetString(1);
    assert(raw && str::Eq(raw->RawValue(), "a"));
    BencTestSerialization(raw, "1:a");

    BencDict dict;
    dict.AddRaw("1", "a\x82");
    dict.AddRaw("2", "a\x82", 1);
    raw = dict.GetString("1");
    assert(raw && str::Eq(raw->RawValue(), "a\x82"));
    BencTestSerialization(raw, "2:a\x82");
    raw = dict.GetString("2");
    assert(raw && str::Eq(raw->RawValue(), "a"));
    BencTestSerialization(raw, "1:a");
}
コード例 #8
0
ファイル: BencUtil.cpp プロジェクト: aarjones55/sumatrapdf
BencArray *BencArray::Decode(const char *bytes, size_t *lenOut)
{
    if (!bytes || *bytes != 'l')
        return NULL;

    BencArray *list = new BencArray();
    size_t ix = 1;
    while (bytes[ix] != 'e') {
        size_t len;
        BencObj *obj = BencObj::Decode(bytes + ix, &len);
        if (!obj) {
            delete list;
            return NULL;
        }
        ix += len;
        list->Add(obj);
    }

    if (lenOut)
        *lenOut = ix + 1;
    return list;
}
コード例 #9
0
ファイル: BencUtil_ut.cpp プロジェクト: aarjones55/sumatrapdf
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;
}
コード例 #10
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;
}
コード例 #11
0
static BencDict *DisplayState_Serialize(DisplayState *ds, bool globalPrefsOnly)
{
    BencDict *prefs = new BencDict();
    if (!prefs)
        return NULL;

    prefs->Add(FILE_STR, ds->filePath);
    if (ds->decryptionKey)
        prefs->AddRaw(DECRYPTION_KEY_STR, ds->decryptionKey);

    prefs->Add(OPEN_COUNT_STR, ds->openCount);
    prefs->Add(IS_PINNED_STR, ds->isPinned);
    if (globalPrefsOnly || ds->useGlobalValues) {
        prefs->Add(USE_GLOBAL_VALUES_STR, TRUE);
        return prefs;
    }

    const WCHAR *mode = DisplayModeConv::NameFromEnum(ds->displayMode);
    prefs->Add(DISPLAY_MODE_STR, mode);
    prefs->Add(PAGE_NO_STR, ds->pageNo);
    prefs->Add(REPARSE_IDX_STR, ds->reparseIdx);
    prefs->Add(ROTATION_STR, ds->rotation);
    prefs->Add(SCROLL_X_STR, ds->scrollPos.x);
    prefs->Add(SCROLL_Y_STR, ds->scrollPos.y);
    prefs->Add(WINDOW_STATE_STR, ds->windowState);
    prefs->Add(WINDOW_X_STR, ds->windowPos.x);
    prefs->Add(WINDOW_Y_STR, ds->windowPos.y);
    prefs->Add(WINDOW_DX_STR, ds->windowPos.dx);
    prefs->Add(WINDOW_DY_STR, ds->windowPos.dy);

    prefs->Add(TOC_VISIBLE_STR, ds->tocVisible);
    prefs->Add(SIDEBAR_DX_STR, ds->sidebarDx);

    // BUG: 2140
    if (!IsValidZoom(ds->zoomVirtual)) {
        CrashLogFmt("Invalid ds->zoomVirtual: %.4f\n", ds->zoomVirtual);
        const WCHAR *ext = str::FindCharLast(ds->filePath, L'.');
        if (ext) {
            ScopedMem<char> extA(str::conv::ToUtf8(ext));
            CrashLogFmt("File type: %s\n", extA.Get());
        }
        CrashLogFmt("DisplayMode: %d\n", ds->displayMode);
        CrashLogFmt("PageNo: %d\n", ds->pageNo);
    }

    CrashIf(!IsValidZoom(ds->zoomVirtual));
    ScopedMem<char> zoom(str::Format("%.4f", ds->zoomVirtual));
    prefs->AddRaw(ZOOM_VIRTUAL_STR, zoom);

    if (ds->tocState && ds->tocState->Count() > 0) {
        BencArray *tocState = new BencArray();
        if (tocState) {
            for (size_t i = 0; i < ds->tocState->Count(); i++) {
                tocState->Add(ds->tocState->At(i));
            }
            prefs->Add(TOC_STATE_STR, tocState);
        }
    }

    return prefs;
}
コード例 #12
0
ファイル: AppPrefs.cpp プロジェクト: shienme/sumatrapdf
static void DeserializeStruct(PrefInfo *info, size_t count, void *structBase, BencDict *prefs)
{
    char *base = (char *)structBase;
    BencInt *intObj;
    BencString *strObj;
    BencArray *arrObj;

    for (size_t i = 0; i < count; i++) {
        PrefInfo& meta = info[i];
        switch (meta.type) {
        case Pref_Bool:
            if ((intObj = prefs->GetInt(meta.name)))
                *(bool *)(base + meta.offset) = intObj->Value() != 0;
            break;
        case Pref_Int:
            if ((intObj = prefs->GetInt(meta.name)))
                *(int *)(base + meta.offset) = (int)intObj->Value();
            break;
        case Pref_Str:
            if ((strObj = prefs->GetString(meta.name)))
                str::ReplacePtr((char **)(base + meta.offset), strObj->RawValue());
            break;
        case Pref_WStr:
            if ((strObj = prefs->GetString(meta.name))) {
                ScopedMem<WCHAR> str(strObj->Value());
                if (str)
                    str::ReplacePtr((WCHAR **)(base + meta.offset), str);
            }
            break;
        case Pref_DisplayMode:
            if ((strObj = prefs->GetString(meta.name))) {
                ScopedMem<WCHAR> mode(strObj->Value());
                if (mode)
                    DisplayModeConv::EnumFromName(mode, (DisplayMode *)(base + meta.offset));
            }
            break;
        case Pref_Float:
            if ((strObj = prefs->GetString(meta.name))) {
                // note: this might round the value for files produced with versions
                //       prior to 1.6 and on a system where the decimal mark isn't a '.'
                //       (the difference should be hardly notable, though)
                *(float *)(base + meta.offset) = (float)atof(strObj->RawValue());
            }
            break;
        case Pref_IntVec:
            if ((arrObj = prefs->GetArray(meta.name))) {
                size_t len = arrObj->Length();
                Vec<int> *intVec = new Vec<int>(len);
                if (intVec) {
                    for (size_t idx = 0; idx < len; idx++) {
                        if ((intObj = arrObj->GetInt(idx)))
                            intVec->Append((int)intObj->Value());
                    }
                    delete *(Vec<int> **)(base + meta.offset);
                    *(Vec<int> **)(base + meta.offset) = intVec;
                }
            }
            break;
        case Pref_UILang:
            if ((strObj = prefs->GetString(meta.name))) {
                // ensure language code is valid
                const char *langCode = trans::ValidateLangCode(strObj->RawValue());
                if (langCode)
                    *(const char **)(base + meta.offset) = langCode;
            }
            break;
        }
    }
}
コード例 #13
0
ファイル: AppPrefs.cpp プロジェクト: shienme/sumatrapdf
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;
}