nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, PRUint32 flags) { if (!gHashTable.ops) return NS_ERROR_OUT_OF_MEMORY; PrefHashEntry* pref = static_cast<PrefHashEntry*>(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD)); if (!pref) return NS_ERROR_OUT_OF_MEMORY; // new entry, better intialize if (!pref->key) { // initialize the pref entry pref->flags = type; pref->key = ArenaStrDup(key, &gPrefNameArena); memset(&pref->defaultPref, 0, sizeof(pref->defaultPref)); memset(&pref->userPref, 0, sizeof(pref->userPref)); } else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) != (type & PREF_VALUETYPE_MASK)) { NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get()); return NS_ERROR_UNEXPECTED; } bool valueChanged = false; if (flags & kPrefSetDefault) { if (!PREF_IS_LOCKED(pref)) { /* ?? change of semantics? */ if (pref_ValueChanged(pref->defaultPref, value, type) || !(pref->flags & PREF_HAS_DEFAULT)) { pref_SetValue(&pref->defaultPref, value, type); pref->flags |= PREF_HAS_DEFAULT; if (!PREF_HAS_USER_VALUE(pref)) valueChanged = true; } } } else { /* If new value is same as the default value, then un-set the user value. Otherwise, set the user value only if it has changed */ if (!pref_ValueChanged(pref->defaultPref, value, type) && (pref->flags & PREF_HAS_DEFAULT) && !(flags & kPrefForceSet)) { if (PREF_HAS_USER_VALUE(pref)) { pref->flags &= ~PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = true; } } else if ( !PREF_HAS_USER_VALUE(pref) || pref_ValueChanged(pref->userPref, value, type) ) { pref_SetValue(&pref->userPref, value, type); pref->flags |= PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = true; } } nsresult rv = NS_OK; if (valueChanged) { gDirty = true; nsresult rv2 = pref_DoCallback(key); if (NS_FAILED(rv2)) rv = rv2; } return rv; }
nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, PRBool set_default) { if (!gHashTable.ops) return NS_ERROR_OUT_OF_MEMORY; PrefHashEntry* pref = static_cast<PrefHashEntry*>(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD)); if (!pref) return NS_ERROR_OUT_OF_MEMORY; // new entry, better intialize if (!pref->key) { // initialize the pref entry pref->flags = type; pref->key = ArenaStrDup(key, &gPrefNameArena); memset(&pref->defaultPref, 0, sizeof(pref->defaultPref)); memset(&pref->userPref, 0, sizeof(pref->userPref)); /* ugly hack -- define it to a default that no pref will ever default to this should really get fixed right by some out of band data */ if (pref->flags & PREF_BOOL) pref->defaultPref.boolVal = (PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE; if (pref->flags & PREF_INT) pref->defaultPref.intVal = (PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE; } else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) != (type & PREF_VALUETYPE_MASK)) { NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get()); return NS_ERROR_UNEXPECTED; } PRBool valueChanged = PR_FALSE; if (set_default) { if (!PREF_IS_LOCKED(pref)) { /* ?? change of semantics? */ if (pref_ValueChanged(pref->defaultPref, value, type)) { pref_SetValue(&pref->defaultPref, value, type); if (!PREF_HAS_USER_VALUE(pref)) valueChanged = PR_TRUE; } } } else { /* If new value is same as the default value, then un-set the user value. Otherwise, set the user value only if it has changed */ if ( !pref_ValueChanged(pref->defaultPref, value, type) ) { if (PREF_HAS_USER_VALUE(pref)) { pref->flags &= ~PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = PR_TRUE; } } else if ( !PREF_HAS_USER_VALUE(pref) || pref_ValueChanged(pref->userPref, value, type) ) { pref_SetValue(&pref->userPref, value, type); pref->flags |= PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = PR_TRUE; } } nsresult rv = NS_OK; if (valueChanged) { gDirty = PR_TRUE; if (gCallbacksEnabled) { nsresult rv2 = pref_DoCallback(key); if (NS_FAILED(rv2)) rv = rv2; } #ifdef MOZ_PROFILESHARING if (gSharedPrefHandler) gSharedPrefHandler->OnPrefChanged(set_default, pref, value); #endif } return rv; }