LCOV - code coverage report
Current view: directory - dom/src/storage - nsDOMStorageMemoryDB.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 187 22 11.8 %
Date: 2012-06-02 Functions: 22 4 18.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Mozilla Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Neil Deakin <enndeakin@sympatico.ca>
      24                 :  *   Honza Bambas <honzab@firemni.cz>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsCOMPtr.h"
      41                 : #include "nsDOMError.h"
      42                 : #include "nsDOMStorage.h"
      43                 : #include "nsDOMStorageMemoryDB.h"
      44                 : #include "nsNetUtil.h"
      45                 : 
      46                 : nsresult
      47              78 : nsDOMStorageMemoryDB::Init(nsDOMStoragePersistentDB* aPreloadDB)
      48                 : {
      49              78 :   if (!mData.Init(20))
      50               0 :     return NS_ERROR_OUT_OF_MEMORY;
      51                 : 
      52              78 :   mPreloadDB = aPreloadDB;
      53              78 :   return NS_OK;
      54                 : }
      55                 : 
      56                 : static PLDHashOperator
      57               0 : AllKeyEnum(nsSessionStorageEntry* aEntry, void* userArg)
      58                 : {
      59                 :   nsDOMStorageMemoryDB::nsStorageItemsTable *target =
      60               0 :       (nsDOMStorageMemoryDB::nsStorageItemsTable *)userArg;
      61                 : 
      62                 :   nsDOMStorageMemoryDB::nsInMemoryItem* item =
      63               0 :       new nsDOMStorageMemoryDB::nsInMemoryItem();
      64               0 :   if (!item)
      65               0 :     return PL_DHASH_STOP;
      66                 : 
      67               0 :   aEntry->mItem->GetValue(item->mValue);
      68               0 :   nsresult rv = aEntry->mItem->GetSecure(&item->mSecure);
      69               0 :   if (NS_FAILED(rv))
      70               0 :     item->mSecure = false;
      71                 : 
      72               0 :   target->Put(aEntry->GetKey(), item);
      73               0 :   return PL_DHASH_NEXT;
      74                 : }
      75                 : 
      76                 : nsresult
      77               0 : nsDOMStorageMemoryDB::GetItemsTable(DOMStorageImpl* aStorage,
      78                 :                                     nsInMemoryStorage** aMemoryStorage)
      79                 : {
      80               0 :   if (mData.Get(aStorage->GetScopeDBKey(), aMemoryStorage))
      81               0 :     return NS_OK;
      82                 : 
      83               0 :   *aMemoryStorage = nsnull;
      84                 : 
      85               0 :   nsInMemoryStorage* storageData = new nsInMemoryStorage();
      86               0 :   if (!storageData)
      87               0 :     return NS_ERROR_OUT_OF_MEMORY;
      88                 : 
      89               0 :   if (!storageData->mTable.Init()) {
      90               0 :     delete storageData;
      91               0 :     return NS_ERROR_OUT_OF_MEMORY;
      92                 :   }
      93                 : 
      94               0 :   if (mPreloadDB) {
      95                 :     nsresult rv;
      96                 : 
      97               0 :     nsTHashtable<nsSessionStorageEntry> keys;
      98               0 :     keys.Init();
      99                 : 
     100               0 :     rv = mPreloadDB->GetAllKeys(aStorage, &keys);
     101               0 :     NS_ENSURE_SUCCESS(rv, rv);
     102                 : 
     103               0 :     mPreloading = true;
     104               0 :     keys.EnumerateEntries(AllKeyEnum, &storageData->mTable);
     105               0 :     mPreloading = false;
     106                 :   }
     107                 : 
     108               0 :   mData.Put(aStorage->GetScopeDBKey(), storageData);
     109               0 :   *aMemoryStorage = storageData;
     110                 : 
     111               0 :   return NS_OK;
     112                 : }
     113                 : 
     114                 : struct GetAllKeysEnumStruc
     115                 : {
     116                 :   nsTHashtable<nsSessionStorageEntry>* mTarget;
     117                 :   DOMStorageImpl* mStorage;
     118                 : };
     119                 : 
     120                 : static PLDHashOperator
     121               0 : GetAllKeysEnum(const nsAString& keyname,
     122                 :                nsDOMStorageMemoryDB::nsInMemoryItem* item,
     123                 :                void *closure)
     124                 : {
     125               0 :   GetAllKeysEnumStruc* struc = (GetAllKeysEnumStruc*)closure;
     126                 : 
     127               0 :   nsSessionStorageEntry* entry = struc->mTarget->PutEntry(keyname);
     128               0 :   if (!entry)
     129               0 :     return PL_DHASH_STOP;
     130                 : 
     131                 :   entry->mItem = new nsDOMStorageItem(struc->mStorage,
     132                 :                                       keyname,
     133               0 :                                       EmptyString(),
     134               0 :                                       item->mSecure);
     135               0 :   if (!entry->mItem)
     136               0 :     return PL_DHASH_STOP;
     137                 : 
     138               0 :   return PL_DHASH_NEXT;
     139                 : }
     140                 : 
     141                 : nsresult
     142               0 : nsDOMStorageMemoryDB::GetAllKeys(DOMStorageImpl* aStorage,
     143                 :                                  nsTHashtable<nsSessionStorageEntry>* aKeys)
     144                 : {
     145                 :   nsresult rv;
     146                 : 
     147                 :   nsInMemoryStorage* storage;
     148               0 :   rv = GetItemsTable(aStorage, &storage);
     149               0 :   NS_ENSURE_SUCCESS(rv, rv);
     150                 : 
     151                 :   GetAllKeysEnumStruc struc;
     152               0 :   struc.mTarget = aKeys;
     153               0 :   struc.mStorage = aStorage;
     154               0 :   storage->mTable.EnumerateRead(GetAllKeysEnum, &struc);
     155                 : 
     156               0 :   return NS_OK;
     157                 : }
     158                 : 
     159                 : nsresult
     160               0 : nsDOMStorageMemoryDB::GetKeyValue(DOMStorageImpl* aStorage,
     161                 :                                   const nsAString& aKey,
     162                 :                                   nsAString& aValue,
     163                 :                                   bool* aSecure)
     164                 : {
     165               0 :   if (mPreloading) {
     166               0 :     NS_PRECONDITION(mPreloadDB, "Must have a preload DB set when preloading");
     167               0 :     return mPreloadDB->GetKeyValue(aStorage, aKey, aValue, aSecure);
     168                 :   }
     169                 : 
     170                 :   nsresult rv;
     171                 : 
     172                 :   nsInMemoryStorage* storage;
     173               0 :   rv = GetItemsTable(aStorage, &storage);
     174               0 :   NS_ENSURE_SUCCESS(rv, rv);
     175                 : 
     176                 :   nsInMemoryItem* item;
     177               0 :   if (!storage->mTable.Get(aKey, &item))
     178               0 :     return NS_ERROR_DOM_NOT_FOUND_ERR;
     179                 : 
     180               0 :   aValue = item->mValue;
     181               0 :   *aSecure = item->mSecure;
     182               0 :   return NS_OK;
     183                 : }
     184                 : 
     185                 : nsresult
     186               0 : nsDOMStorageMemoryDB::SetKey(DOMStorageImpl* aStorage,
     187                 :                              const nsAString& aKey,
     188                 :                              const nsAString& aValue,
     189                 :                              bool aSecure,
     190                 :                              PRInt32 aQuota,
     191                 :                              bool aExcludeOfflineFromUsage,
     192                 :                              PRInt32 *aNewUsage)
     193                 : {
     194                 :   nsresult rv;
     195                 : 
     196                 :   nsInMemoryStorage* storage;
     197               0 :   rv = GetItemsTable(aStorage, &storage);
     198               0 :   NS_ENSURE_SUCCESS(rv, rv);
     199                 : 
     200               0 :   PRInt32 usage = 0;
     201               0 :   if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
     202               0 :     rv = GetUsage(aStorage, aExcludeOfflineFromUsage, &usage);
     203               0 :     NS_ENSURE_SUCCESS(rv, rv);
     204                 :   }
     205                 : 
     206               0 :   usage += aKey.Length() + aValue.Length();
     207                 : 
     208                 :   nsInMemoryItem* item;
     209               0 :   if (!storage->mTable.Get(aKey, &item)) {
     210               0 :     if (usage > aQuota) {
     211               0 :       return NS_ERROR_DOM_QUOTA_REACHED;
     212                 :     }
     213                 : 
     214               0 :     item = new nsInMemoryItem();
     215               0 :     if (!item)
     216               0 :       return NS_ERROR_OUT_OF_MEMORY;
     217                 : 
     218               0 :     storage->mTable.Put(aKey, item);
     219               0 :     storage->mUsageDelta += aKey.Length();
     220                 :   }
     221                 :   else
     222                 :   {
     223               0 :     if (!aSecure && item->mSecure)
     224               0 :       return NS_ERROR_DOM_SECURITY_ERR;
     225               0 :     usage -= aKey.Length() + item->mValue.Length();
     226               0 :     if (usage > aQuota) {
     227               0 :       return NS_ERROR_DOM_QUOTA_REACHED;
     228                 :     }
     229                 :   }
     230                 : 
     231               0 :   storage->mUsageDelta += aValue.Length() - item->mValue.Length();
     232                 : 
     233               0 :   item->mValue = aValue;
     234               0 :   item->mSecure = aSecure;
     235                 : 
     236               0 :   *aNewUsage = usage;
     237                 : 
     238               0 :   MarkScopeDirty(aStorage);
     239                 : 
     240               0 :   return NS_OK;
     241                 : }
     242                 : 
     243                 : nsresult
     244               0 : nsDOMStorageMemoryDB::SetSecure(DOMStorageImpl* aStorage,
     245                 :                                 const nsAString& aKey,
     246                 :                                 const bool aSecure)
     247                 : {
     248                 :   nsresult rv;
     249                 : 
     250                 :   nsInMemoryStorage* storage;
     251               0 :   rv = GetItemsTable(aStorage, &storage);
     252               0 :   NS_ENSURE_SUCCESS(rv, rv);
     253                 : 
     254                 :   nsInMemoryItem* item;
     255               0 :   if (!storage->mTable.Get(aKey, &item))
     256               0 :     return NS_ERROR_DOM_NOT_FOUND_ERR;
     257                 : 
     258               0 :   item->mSecure = aSecure;
     259                 : 
     260               0 :   MarkScopeDirty(aStorage);
     261                 : 
     262               0 :   return NS_OK;
     263                 : }
     264                 : 
     265                 : nsresult
     266               0 : nsDOMStorageMemoryDB::RemoveKey(DOMStorageImpl* aStorage,
     267                 :                                 const nsAString& aKey,
     268                 :                                 bool aExcludeOfflineFromUsage,
     269                 :                                 PRInt32 aKeyUsage)
     270                 : {
     271                 :   nsresult rv;
     272                 : 
     273                 :   nsInMemoryStorage* storage;
     274               0 :   rv = GetItemsTable(aStorage, &storage);
     275               0 :   NS_ENSURE_SUCCESS(rv, rv);
     276                 : 
     277                 :   nsInMemoryItem* item;
     278               0 :   if (!storage->mTable.Get(aKey, &item))
     279               0 :     return NS_ERROR_DOM_NOT_FOUND_ERR;
     280                 : 
     281               0 :   storage->mUsageDelta -= aKey.Length() + item->mValue.Length();
     282               0 :   storage->mTable.Remove(aKey);
     283                 : 
     284               0 :   MarkScopeDirty(aStorage);
     285                 : 
     286               0 :   return NS_OK;
     287                 : }
     288                 : 
     289                 : static PLDHashOperator
     290               0 : RemoveAllKeysEnum(const nsAString& keyname,
     291                 :                   nsAutoPtr<nsDOMStorageMemoryDB::nsInMemoryItem>& item,
     292                 :                   void *closure)
     293                 : {
     294                 :   nsDOMStorageMemoryDB::nsInMemoryStorage* storage =
     295               0 :       (nsDOMStorageMemoryDB::nsInMemoryStorage*)closure;
     296                 : 
     297               0 :   storage->mUsageDelta -= keyname.Length() + item->mValue.Length();
     298               0 :   return PL_DHASH_REMOVE;
     299                 : }
     300                 : 
     301                 : nsresult
     302               0 : nsDOMStorageMemoryDB::ClearStorage(DOMStorageImpl* aStorage)
     303                 : {
     304                 :   nsresult rv;
     305                 : 
     306                 :   nsInMemoryStorage* storage;
     307               0 :   rv = GetItemsTable(aStorage, &storage);
     308               0 :   NS_ENSURE_SUCCESS(rv, rv);
     309                 : 
     310               0 :   storage->mTable.Enumerate(RemoveAllKeysEnum, storage);
     311                 : 
     312               0 :   MarkScopeDirty(aStorage);
     313                 : 
     314               0 :   return NS_OK;
     315                 : }
     316                 : 
     317                 : nsresult
     318               0 : nsDOMStorageMemoryDB::DropStorage(DOMStorageImpl* aStorage)
     319                 : {
     320               0 :   mData.Remove(aStorage->GetScopeDBKey());
     321               0 :   MarkScopeDirty(aStorage);
     322               0 :   return NS_OK;
     323                 : }
     324                 : 
     325                 : struct RemoveOwnersStruc
     326                 : {
     327                 :   nsCString* mSubDomain;
     328                 :   bool mMatch;
     329                 : };
     330                 : 
     331                 : static PLDHashOperator
     332               0 : RemoveOwnersEnum(const nsACString& key,
     333                 :                  nsAutoPtr<nsDOMStorageMemoryDB::nsInMemoryStorage>& storage,
     334                 :                  void *closure)
     335                 : {
     336               0 :   RemoveOwnersStruc* struc = (RemoveOwnersStruc*)closure;
     337                 : 
     338               0 :   if (StringBeginsWith(key, *(struc->mSubDomain)) == struc->mMatch)
     339               0 :     return PL_DHASH_REMOVE;
     340                 : 
     341               0 :   return PL_DHASH_NEXT;
     342                 : }
     343                 : 
     344                 : nsresult
     345              96 : nsDOMStorageMemoryDB::RemoveOwner(const nsACString& aOwner,
     346                 :                                   bool aIncludeSubDomains)
     347                 : {
     348             192 :   nsCAutoString subdomainsDBKey;
     349              96 :   nsDOMStorageDBWrapper::CreateDomainScopeDBKey(aOwner, subdomainsDBKey);
     350                 : 
     351              96 :   if (!aIncludeSubDomains)
     352               0 :     subdomainsDBKey.AppendLiteral(":");
     353                 : 
     354                 :   RemoveOwnersStruc struc;
     355              96 :   struc.mSubDomain = &subdomainsDBKey;
     356              96 :   struc.mMatch = true;
     357              96 :   mData.Enumerate(RemoveOwnersEnum, &struc);
     358                 : 
     359              96 :   MarkAllScopesDirty();
     360                 : 
     361              96 :   return NS_OK;
     362                 : }
     363                 : 
     364                 : 
     365                 : nsresult
     366              25 : nsDOMStorageMemoryDB::RemoveOwners(const nsTArray<nsString> &aOwners,
     367                 :                                    bool aIncludeSubDomains,
     368                 :                                    bool aMatch)
     369                 : {
     370              25 :   if (aOwners.Length() == 0) {
     371              25 :     if (aMatch) {
     372               2 :       return NS_OK;
     373                 :     }
     374                 : 
     375              23 :     return RemoveAll();
     376                 :   }
     377                 : 
     378               0 :   for (PRUint32 i = 0; i < aOwners.Length(); i++) {
     379               0 :     nsCAutoString quotaKey;
     380                 :     nsresult rv;
     381                 :     rv = nsDOMStorageDBWrapper::CreateDomainScopeDBKey(
     382               0 :       NS_ConvertUTF16toUTF8(aOwners[i]), quotaKey);
     383                 : 
     384               0 :     if (!aIncludeSubDomains)
     385               0 :       quotaKey.AppendLiteral(":");
     386                 : 
     387                 :     RemoveOwnersStruc struc;
     388               0 :     struc.mSubDomain = &quotaKey;
     389               0 :     struc.mMatch = aMatch;
     390               0 :     mData.Enumerate(RemoveOwnersEnum, &struc);
     391                 :   }
     392                 : 
     393               0 :   MarkAllScopesDirty();
     394                 : 
     395               0 :   return NS_OK;
     396                 : }
     397                 : 
     398                 : nsresult
     399             160 : nsDOMStorageMemoryDB::RemoveAll()
     400                 : {
     401             160 :   mData.Clear(); // XXX Check this releases all instances
     402                 : 
     403             160 :   MarkAllScopesDirty();
     404                 : 
     405             160 :   return NS_OK;
     406                 : }
     407                 : 
     408                 : nsresult
     409               0 : nsDOMStorageMemoryDB::GetUsage(DOMStorageImpl* aStorage,
     410                 :                                bool aExcludeOfflineFromUsage, PRInt32 *aUsage)
     411                 : {
     412               0 :   return GetUsageInternal(aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage),
     413               0 :                           aExcludeOfflineFromUsage, aUsage);
     414                 : }
     415                 : 
     416                 : nsresult
     417               0 : nsDOMStorageMemoryDB::GetUsage(const nsACString& aDomain,
     418                 :                                bool aIncludeSubDomains,
     419                 :                                PRInt32 *aUsage)
     420                 : {
     421                 :   nsresult rv;
     422                 : 
     423               0 :   nsCAutoString quotadomainDBKey;
     424                 :   rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomain,
     425                 :                                                      aIncludeSubDomains,
     426                 :                                                      false,
     427               0 :                                                      quotadomainDBKey);
     428               0 :   NS_ENSURE_SUCCESS(rv, rv);
     429                 : 
     430               0 :   return GetUsageInternal(quotadomainDBKey, false, aUsage);
     431                 : }
     432                 : 
     433                 : struct GetUsageEnumStruc
     434               0 : {
     435                 :   PRInt32 mUsage;
     436                 :   PRInt32 mExcludeOfflineFromUsage;
     437                 :   nsCString mSubdomain;
     438                 : };
     439                 : 
     440                 : static PLDHashOperator
     441               0 : GetUsageEnum(const nsACString& key,
     442                 :              nsDOMStorageMemoryDB::nsInMemoryStorage* storageData,
     443                 :              void *closure)
     444                 : {
     445               0 :   GetUsageEnumStruc* struc = (GetUsageEnumStruc*)closure;
     446                 : 
     447               0 :   if (StringBeginsWith(key, struc->mSubdomain)) {
     448               0 :     if (struc->mExcludeOfflineFromUsage) {
     449               0 :       nsCAutoString domain;
     450               0 :       nsresult rv = nsDOMStorageDBWrapper::GetDomainFromScopeKey(key, domain);
     451               0 :       if (NS_SUCCEEDED(rv) && IsOfflineAllowed(domain))
     452               0 :         return PL_DHASH_NEXT;
     453                 :     }
     454                 : 
     455               0 :     struc->mUsage += storageData->mUsageDelta;
     456                 :   }
     457                 : 
     458               0 :   return PL_DHASH_NEXT;
     459                 : }
     460                 : 
     461                 : nsresult
     462               0 : nsDOMStorageMemoryDB::GetUsageInternal(const nsACString& aQuotaDomainDBKey,
     463                 :                                        bool aExcludeOfflineFromUsage,
     464                 :                                        PRInt32 *aUsage)
     465                 : {
     466               0 :   GetUsageEnumStruc struc;
     467               0 :   struc.mUsage = 0;
     468               0 :   struc.mExcludeOfflineFromUsage = aExcludeOfflineFromUsage;
     469               0 :   struc.mSubdomain = aQuotaDomainDBKey;
     470                 : 
     471               0 :   if (mPreloadDB) {
     472                 :     nsresult rv;
     473                 : 
     474                 :     rv = mPreloadDB->GetUsageInternal(aQuotaDomainDBKey,
     475               0 :                                       aExcludeOfflineFromUsage, &struc.mUsage);
     476               0 :     NS_ENSURE_SUCCESS(rv, rv);
     477                 :   }
     478                 : 
     479               0 :   mData.EnumerateRead(GetUsageEnum, &struc);
     480                 : 
     481               0 :   *aUsage = struc.mUsage;
     482               0 :   return NS_OK;
     483                 : }

Generated by: LCOV version 1.7