static const char *GetRawString(BencDict *dict, const char *key) { BencString *string = dict->GetString(key); if (string) return string->RawValue(); return NULL; }
BencDict *BencDict::Decode(const char *bytes, size_t *lenOut) { if (!bytes || *bytes != 'd') return NULL; BencDict *dict = new BencDict(); size_t ix = 1; while (bytes[ix] != 'e') { size_t len; BencString *key = BencString::Decode(bytes + ix, &len); if (!key || key->Type() != BT_STRING) { delete key; delete dict; return NULL; } ix += len; BencObj *obj = BencObj::Decode(bytes + ix, &len); if (!obj) { delete key; delete dict; return NULL; } ix += len; dict->Add(key->RawValue(), obj); delete key; } if (lenOut) *lenOut = ix + 1; return dict; }
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"); }
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 }
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; } } }