Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions
nsFormHistory Class Reference

#include <nsFormHistory.h>

Inheritance diagram for nsFormHistory:
Inheritance graph
[legend]
Collaboration diagram for nsFormHistory:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIFORMHISTORY2
NS_DECL_NSIOBSERVER NS_IMETHOD 
Notify (nsIContent *formNode, nsIDOMWindowInternal *window, nsIURI *actionURL, PRBool *cancelSubmit)
 nsFormHistory ()
virtual ~nsFormHistory ()
nsresult Init ()
nsresult AutoCompleteSearch (const nsAString &aInputName, const nsAString &aInputValue, nsIAutoCompleteMdbResult2 *aPrevResult, nsIAutoCompleteResult **aNewResult)
NS_DECL_ISUPPORTS
NS_DECL_NSIFORMHISTORY2
NS_DECL_NSIOBSERVER NS_IMETHOD 
Notify (nsIContent *formNode, nsIDOMWindowInternal *window, nsIURI *actionURL, PRBool *cancelSubmit)
 nsFormHistory ()
nsresult Init ()
nsresult AutoCompleteSearch (const nsAString &aInputName, const nsAString &aInputValue, nsIAutoCompleteSimpleResult *aPrevResult, nsIAutoCompleteResult **aNewResult)
void addEntry (in AString name, in AString value)
 Adds a name and value pair to the form history.
void removeEntry (in AString name, in AString value)
 Removes a name and value pair from the form history.
void removeEntriesForName (in AString name)
 Removes all entries that are paired with a name.
void removeAllEntries ()
 Removes all entries in the entire form history.
boolean nameExists (in AString name)
 Returns true if there is no entry that is paired with a name.
boolean entryExists (in AString name, in AString value)
 Gets whether a name and value pair exists in the form history.
mozIStorageConnectionGetStorageConnection ()
void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.

Static Public Member Functions

static nsFormHistoryGetInstance ()
static nsFormHistoryGetInstance ()

Public Attributes

readonly attribute boolean hasEntries
 Returns true if the form history has any entries.

Static Public Attributes

static mdb_column kToken_ValueColumn = 0
static mdb_column kToken_NameColumn = 0

Protected Member Functions

nsresult OpenDatabase ()
nsresult OpenExistingFile (const char *aPath)
nsresult CreateNewFile (const char *aPath)
nsresult CloseDatabase ()
nsresult CreateTokens ()
nsresult Flush ()
nsresult CopyRowsFromTable (nsIMdbTable *sourceTable)
mdb_err UseThumb (nsIMdbThumb *aThumb, PRBool *aDone)
nsresult AppendRow (const nsAString &aValue, const nsAString &aName, nsIMdbRow **aResult)
nsresult SetRowValue (nsIMdbRow *aRow, mdb_column aCol, const nsAString &aValue)
nsresult GetRowValue (nsIMdbRow *aRow, mdb_column aCol, nsAString &aValue)
PRBool RowMatch (nsIMdbRow *aRow, const nsAString &aInputName, const nsAString &aInputValue, PRUnichar **aValue)
 PR_STATIC_CALLBACK (int) SortComparison(const void *v1
nsresult EntriesExistInternal (const nsAString *aName, const nsAString *aValue, PRBool *_retval)
nsresult RemoveEntriesInternal (const nsAString *aName)
nsresult InitByteOrder (PRBool aForce)
nsresult GetByteOrder (nsAString &aByteOrder)
nsresult SaveByteOrder (const nsAString &aByteOrder)
nsresult OpenDatabase ()
nsresult CloseDatabase ()
nsresult GetDatabaseFile (nsIFile **aFile)
nsresult StartCache ()
nsresult StopCache ()

Static Protected Member Functions

static PRBool FormHistoryEnabled ()
static PRBool FormHistoryEnabled ()

Protected Attributes

const voidv2
const void voidclosureVoid
nsCOMPtr< nsIMdbFactorymMdbFactory
nsCOMPtr< nsIPrefBranchmPrefBranch
nsIMdbEnvmEnv
nsIMdbStoremStore
nsIMdbTablemTable
PRInt64 mFileSizeOnDisk
nsCOMPtr< nsIMdbRowmMetaRow
PRPackedBool mReverseByteOrder
mdb_scope kToken_RowScope
mdb_kind kToken_Kind
mdb_column kToken_ByteOrder
nsCOMPtr< mozIStorageServicemStorageService
nsCOMPtr< mozIStorageStatementmDBGetMatchingField
nsCOMPtr< mozIStorageStatementmDBFindEntry
nsCOMPtr< mozIStorageStatementmDBFindEntryByName
nsCOMPtr< mozIStorageStatementmDBSelectEntries
nsCOMPtr< mozIStorageStatementmDBInsertNameValue
nsCOMPtr< mozIStorageConnectionmDummyConnection
nsCOMPtr< mozIStorageStatementmDummyStatement
nsCOMPtr< mozIStorageConnectionmDBConn

Static Protected Attributes

static nsFormHistorygFormHistory = nsnull
static PRBool gFormHistoryEnabled = PR_FALSE
static PRBool gPrefsInitialized = PR_FALSE

Private Member Functions

 ~nsFormHistory ()

Detailed Description

Definition at line 53 of file nsFormHistory.h.


Constructor & Destructor Documentation

Definition at line 99 of file nsFormHistory.cpp.

                             :
  mEnv(nsnull),
  mStore(nsnull),
  mTable(nsnull),
  mReverseByteOrder(PR_FALSE)
{
  NS_ASSERTION(!gFormHistory, "nsFormHistory must be used as a service");
  gFormHistory = this;
}

Definition at line 109 of file nsFormHistory.cpp.

{
  NS_ASSERTION(gFormHistory == this,
               "nsFormHistory must be used as a service");
  CloseDatabase();
  gFormHistory = nsnull;
}

Here is the call graph for this function:


Member Function Documentation

void nsIFormHistory2::addEntry ( in AString  name,
in AString  value 
) [inherited]

Adds a name and value pair to the form history.

nsresult nsFormHistory::AppendRow ( const nsAString &  aValue,
const nsAString &  aName,
nsIMdbRow **  aResult 
) [protected]

Definition at line 628 of file nsFormHistory.cpp.

{  
  if (!mTable)
    return NS_ERROR_NOT_INITIALIZED;

  if (aName.Length() > FORMFILL_NAME_MAX_LEN ||
      aValue.Length() > FORMFILL_VALUE_MAX_LEN)
    return NS_ERROR_INVALID_ARG;

  PRBool exists = PR_TRUE;
  EntryExists(aName, aValue, &exists);
  if (exists)
    return NS_OK;

  mdbOid rowId;
  rowId.mOid_Scope = kToken_RowScope;
  rowId.mOid_Id = mdb_id(-1);

  nsCOMPtr<nsIMdbRow> row;
  mdb_err err = mTable->NewRow(mEnv, &rowId, getter_AddRefs(row));
  if (err != 0)
    return NS_ERROR_FAILURE;

  SetRowValue(row, kToken_NameColumn, aName);
  SetRowValue(row, kToken_ValueColumn, aValue);

  if (aResult) {
    *aResult = row;
    NS_ADDREF(*aResult);
  }
  
  return NS_OK;  
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::AutoCompleteSearch ( const nsAString &  aInputName,
const nsAString &  aInputValue,
nsIAutoCompleteMdbResult2 aPrevResult,
nsIAutoCompleteResult **  aNewResult 
)

Definition at line 722 of file nsFormHistory.cpp.

{
  if (!FormHistoryEnabled())
    return NS_OK;

  nsresult rv = OpenDatabase(); // lazily ensure that the database is open
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIAutoCompleteMdbResult2> result;
  
  if (aPrevResult) {
    result = aPrevResult;
    
    PRUint32 rowCount;
    result->GetMatchCount(&rowCount);
    
    for (PRInt32 i = rowCount-1; i >= 0; --i) {
      nsIMdbRow *row;
      result->GetRowAt(i, &row);
      if (!RowMatch(row, aInputName, aInputValue, nsnull))
        result->RemoveValueAt(i, PR_FALSE);
    }
  } else {
    result = do_CreateInstance("@mozilla.org/autocomplete/mdb-result;1");

    result->SetSearchString(aInputValue);
    result->Init(mEnv, mTable);
    result->SetTokens(kToken_ValueColumn, nsIAutoCompleteMdbResult2::kUnicharType, nsnull, nsIAutoCompleteMdbResult2::kUnicharType);
    result->SetReverseByteOrder(mReverseByteOrder);

    // Get a cursor to iterate through all rows in the database
    nsCOMPtr<nsIMdbTableRowCursor> rowCursor;
    mdb_err err = mTable->GetTableRowCursor(mEnv, -1, getter_AddRefs(rowCursor));
    NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
    
    // Store only the matching values
    nsAutoVoidArray matchingValues;
    nsCOMArray<nsIMdbRow> matchingRows;

    nsCOMPtr<nsIMdbRow> row;
    mdb_pos pos;
    do {
      rowCursor->NextRow(mEnv, getter_AddRefs(row), &pos);
      if (!row)
        break;

      PRUnichar *value = 0; // We will own the allocated string value
      if (RowMatch(row, aInputName, aInputValue, &value)) {
        matchingRows.AppendObject(row);
        matchingValues.AppendElement(value);
      }
    } while (row);

    // Turn auto array into flat array for quick sort, now that we
    // know how many items there are
    PRUint32 count = matchingRows.Count();

    if (count > 0) {
      PRUint32* items = new PRUint32[count];
      PRUint32 i;
      for (i = 0; i < count; ++i)
        items[i] = i;

      NS_QuickSort(items, count, sizeof(PRUint32),
                   SortComparison, &matchingValues);

      for (i = 0; i < count; ++i) {
        // Place the sorted result into the autocomplete result
        result->AddRow(matchingRows[items[i]]);

        // Free up these strings we owned.
        NS_Free(matchingValues[i]);
      }

      delete[] items;
    }

    PRUint32 matchCount;
    result->GetMatchCount(&matchCount);
    if (matchCount > 0) {
      result->SetSearchResult(nsIAutoCompleteResult::RESULT_SUCCESS);
      result->SetDefaultIndex(0);
    } else {
      result->SetSearchResult(nsIAutoCompleteResult::RESULT_NOMATCH);
      result->SetDefaultIndex(-1);
    }
  }
  
  *aResult = result;
  NS_IF_ADDREF(*aResult);

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsFormHistory::AutoCompleteSearch ( const nsAString &  aInputName,
const nsAString &  aInputValue,
nsIAutoCompleteSimpleResult aPrevResult,
nsIAutoCompleteResult **  aNewResult 
)

Definition at line 562 of file nsStorageFormHistory.cpp.

{
  if (!FormHistoryEnabled())
    return NS_OK;

  nsCOMPtr<nsIAutoCompleteSimpleResult> result;

  if (aPrevResult) {
    result = aPrevResult;

    PRUint32 matchCount;
    result->GetMatchCount(&matchCount);

    for (PRInt32 i = matchCount - 1; i >= 0; --i) {
      nsAutoString match;
      result->GetValueAt(i, match);
      if (!StringBeginsWith(match, aInputValue,
                            nsCaseInsensitiveStringComparator())) {
        result->RemoveValueAt(i, PR_FALSE);
      }
    }
  } else {
    nsCOMPtr<nsFormHistoryResult> fhResult =
      new nsFormHistoryResult(aInputName);
    NS_ENSURE_TRUE(fhResult, NS_ERROR_OUT_OF_MEMORY);
    nsresult rv = fhResult->Init();
    NS_ENSURE_SUCCESS(rv, rv);
    NS_REINTERPRET_CAST(nsCOMPtr<nsIAutoCompleteSimpleResult>*, &fhResult)->swap(result);

    result->SetSearchString(aInputValue);

    // generates query string             
    mozStorageStatementScoper scope(mDBGetMatchingField);
    rv = mDBGetMatchingField->BindStringParameter(0, aInputName);
    NS_ENSURE_SUCCESS(rv,rv);

    PRBool hasMore = PR_FALSE;
    PRUint32 count = 0;
    while (NS_SUCCEEDED(mDBGetMatchingField->ExecuteStep(&hasMore)) &&
           hasMore) {
      nsAutoString entryString;
      mDBGetMatchingField->GetString(0, entryString);
      // filters out irrelevant results
      if(StringBeginsWith(entryString, aInputValue,
                          nsCaseInsensitiveStringComparator())) {
        result->AppendMatch(entryString, EmptyString());
        ++count;
      }
    }
    if (count > 0) {
      result->SetSearchResult(nsIAutoCompleteResult::RESULT_SUCCESS);
      result->SetDefaultIndex(0);
    } else {
      result->SetSearchResult(nsIAutoCompleteResult::RESULT_NOMATCH);
      result->SetDefaultIndex(-1);
    }
  }

  *aResult = result;
  NS_IF_ADDREF(*aResult);
  return NS_OK;
}

Here is the call graph for this function:

Definition at line 517 of file nsFormHistory.cpp.

{
  Flush();

  mMetaRow = nsnull;

  if (mTable)
    mTable->Release();

  if (mStore)
    mStore->Release();

  if (mEnv)
    mEnv->Release();

  mTable = nsnull;
  mEnv = nsnull;
  mStore = nsnull;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::CopyRowsFromTable ( nsIMdbTable sourceTable) [protected]

Definition at line 602 of file nsFormHistory.cpp.

{
  nsCOMPtr<nsIMdbTableRowCursor> rowCursor;
  mdb_err err = sourceTable->GetTableRowCursor(mEnv, -1, getter_AddRefs(rowCursor));
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
  
  nsCOMPtr<nsIMdbRow> row;
  mdb_pos pos;
  do {
    rowCursor->NextRow(mEnv, getter_AddRefs(row), &pos);
    if (!row)
      break;

    mdbOid rowId;
    rowId.mOid_Scope = kToken_RowScope;
    rowId.mOid_Id = mdb_id(-1);

    nsCOMPtr<nsIMdbRow> newRow;
    mTable->NewRow(mEnv, &rowId, getter_AddRefs(newRow));
    newRow->SetRow(mEnv, row);
    mTable->AddRow(mEnv, newRow);
  } while (row);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::CreateNewFile ( const char *  aPath) [protected]

Definition at line 473 of file nsFormHistory.cpp.

{
  nsIMdbHeap* dbHeap = 0;
  nsCOMPtr<nsIMdbFile> newFile;
  mdb_err err = mMdbFactory->CreateNewFile(mEnv, dbHeap, aPath, getter_AddRefs(newFile));
  NS_ENSURE_TRUE(!err && newFile, NS_ERROR_FAILURE);

  nsCOMPtr <nsIMdbTable> oldTable = mTable;;
  nsCOMPtr <nsIMdbStore> oldStore = mStore;
  mdbOpenPolicy policy = {{0, 0}, 0, 0};
  err = mMdbFactory->CreateNewFileStore(mEnv, dbHeap, newFile, &policy, &mStore);
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
  
  nsresult rv = CreateTokens();
  NS_ENSURE_SUCCESS(rv, rv);

  // Create the one and only table in the database
  err = mStore->NewTable(mEnv, kToken_RowScope, kToken_Kind, PR_TRUE, nsnull, &mTable);
  NS_ENSURE_TRUE(!err && mTable, NS_ERROR_FAILURE);

  mdbOid oid = {kToken_RowScope, 1};
  err = mTable->GetMetaRow(mEnv, &oid, nsnull, getter_AddRefs(mMetaRow));
  if (err) {
    NS_WARNING("Could not get meta row");
    return NS_ERROR_FAILURE;
  }

   // oldTable will only be set if we detected a corrupt db, and are 
   // trying to restore data from it.
  if (oldTable)
    CopyRowsFromTable(oldTable);

  // Force a commit now to get it written out.
  nsCOMPtr<nsIMdbThumb> thumb;
  err = mStore->CompressCommit(mEnv, getter_AddRefs(thumb));
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);

  PRBool done;
  err = UseThumb(thumb, &done);

  return err || !done ? NS_ERROR_FAILURE : NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 540 of file nsFormHistory.cpp.

{
  mdb_err err;

  if (!mStore)
    return NS_ERROR_NOT_INITIALIZED;

  err = mStore->StringToToken(mEnv, "ns:formhistory:db:row:scope:formhistory:all", &kToken_RowScope);
  if (err != 0) return NS_ERROR_FAILURE;
  
  err = mStore->StringToToken(mEnv, "ns:formhistory:db:table:kind:formhistory", &kToken_Kind);
  if (err != 0) return NS_ERROR_FAILURE;
  
  err = mStore->StringToToken(mEnv, "Value", &kToken_ValueColumn);
  if (err != 0) return NS_ERROR_FAILURE;

  err = mStore->StringToToken(mEnv, "Name", &kToken_NameColumn);
  if (err != 0) return NS_ERROR_FAILURE;

  err = mStore->StringToToken(mEnv, "ByteOrder", &kToken_ByteOrder);
  if (err != 0) return NS_ERROR_FAILURE;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::EntriesExistInternal ( const nsAString *  aName,
const nsAString *  aValue,
PRBool _retval 
) [protected]

Definition at line 852 of file nsFormHistory.cpp.

{
  // Unfortunately we have to do a brute force search through the database
  // because mork didn't bother to implement any indexing functionality
  
  *_retval = PR_FALSE;
  
  nsresult rv = OpenDatabase(); // lazily ensure that the database is open
  NS_ENSURE_SUCCESS(rv, rv);

  // Get a cursor to iterate through all rows in the database
  nsCOMPtr<nsIMdbTableRowCursor> rowCursor;
  mdb_err err = mTable->GetTableRowCursor(mEnv, -1, getter_AddRefs(rowCursor));
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
  
  nsCOMPtr<nsIMdbRow> row;
  mdb_pos pos;
  do {
    rowCursor->NextRow(mEnv, getter_AddRefs(row), &pos);
    if (!row)
      break;

    // Check if the name and value combination match this row
    nsAutoString name;
    GetRowValue(row, kToken_NameColumn, name);

    if (Compare(name, *aName, nsCaseInsensitiveStringComparator()) == 0) {
      nsAutoString value;
      GetRowValue(row, kToken_ValueColumn, value);
      if (!aValue || Compare(value, *aValue, nsCaseInsensitiveStringComparator()) == 0) {
        *_retval = PR_TRUE;
        break;
      }
    }
  } while (1);
  
  return NS_OK;
}

Here is the call graph for this function:

boolean nsIFormHistory2::entryExists ( in AString  name,
in AString  value 
) [inherited]

Gets whether a name and value pair exists in the form history.

nsresult nsFormHistory::Flush ( void  ) [protected]

Definition at line 566 of file nsFormHistory.cpp.

{
  if (!mStore || !mTable)
    return NS_OK;

  mdb_err err;

  nsCOMPtr<nsIMdbThumb> thumb;
  err = mStore->CompressCommit(mEnv, getter_AddRefs(thumb));

  if (err == 0)
    err = UseThumb(thumb, nsnull);
  
  return err ? NS_ERROR_FAILURE : NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsFormHistory::FormHistoryEnabled ( ) [static, protected]

Definition at line 130 of file nsFormHistory.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool nsFormHistory::FormHistoryEnabled ( ) [static, protected]
nsresult nsFormHistory::GetByteOrder ( nsAString &  aByteOrder) [protected]

Definition at line 1001 of file nsFormHistory.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::GetDatabaseFile ( nsIFile **  aFile) [protected]

Definition at line 456 of file nsStorageFormHistory.cpp.

{
  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, aFile);
  NS_ENSURE_SUCCESS(rv, rv);
  return (*aFile)->Append(NS_LITERAL_STRING("formhistory.sqlite"));
}

Here is the call graph for this function:

static nsFormHistory* nsFormHistory::GetInstance ( void  ) [inline, static]

Definition at line 70 of file nsFormHistory.h.

Here is the call graph for this function:

Here is the caller graph for this function:

static nsFormHistory* nsFormHistory::GetInstance ( void  ) [inline, static]

Definition at line 104 of file nsStorageFormHistory.h.

Here is the call graph for this function:

nsresult nsFormHistory::GetRowValue ( nsIMdbRow aRow,
mdb_column  aCol,
nsAString &  aValue 
) [protected]

Definition at line 688 of file nsFormHistory.cpp.

{
  mdbYarn yarn;
  mdb_err err = aRow->AliasCellYarn(mEnv, aCol, &yarn);
  if (err != 0)
    return NS_ERROR_FAILURE;

  aValue.Truncate(0);
  if (!yarn.mYarn_Fill)
    return NS_OK;
  
  switch (yarn.mYarn_Form) {
    case 0: { // unicode
      PRUint32 len = yarn.mYarn_Fill / sizeof(PRUnichar);
      if (mReverseByteOrder) {
        PRUnichar *swapval = new PRUnichar[len];
        if (!swapval)
          return NS_ERROR_OUT_OF_MEMORY;
        SwapBytes(swapval, (const PRUnichar*)yarn.mYarn_Buf, len);
        aValue.Assign(swapval, len);
        delete swapval;
      }
      else
        aValue.Assign((const PRUnichar *)yarn.mYarn_Buf, len);
      break;
    }
    default:
      return NS_ERROR_UNEXPECTED;
  }
  
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 77 of file nsStorageFormHistory.h.

{ return mDBConn; }

Definition at line 118 of file nsFormHistory.cpp.

{
  nsCOMPtr<nsIObserverService> service = do_GetService("@mozilla.org/observer-service;1");
  if (service)
    service->AddObserver(this, NS_EARLYFORMSUBMIT_SUBJECT, PR_TRUE);
  
  return NS_OK;
}

Here is the call graph for this function:

nsresult nsFormHistory::InitByteOrder ( PRBool  aForce) [protected]

Definition at line 952 of file nsFormHistory.cpp.

{
  // bigEndian and littleEndian are endianness markers that are stored in
  // the formhistory db as UTF-16.  Define them to be strings easily
  // recognized in either endianness.
  nsAutoString bigEndianByteOrder((PRUnichar*)"BBBB", 2);
  nsAutoString littleEndianByteOrder((PRUnichar*)"llll", 2);
#ifdef IS_BIG_ENDIAN
  nsAutoString nativeByteOrder(bigEndianByteOrder);
#else
  nsAutoString nativeByteOrder(littleEndianByteOrder);
#endif

  nsAutoString fileByteOrder;
  nsresult rv = NS_OK;

  if (!aForce)
    rv = GetByteOrder(fileByteOrder);

  if (aForce || NS_FAILED(rv) ||
      !(fileByteOrder.Equals(bigEndianByteOrder) ||
        fileByteOrder.Equals(littleEndianByteOrder))) {
#if defined(XP_MACOSX) && defined(IS_LITTLE_ENDIAN)
    // The formhistory db did not carry endiannes information until the
    // initial x86 Mac release.  There are a lot of users out there who
    // will be switching from ppc versions to x86, and their unmarked
    // formhistory files are big-endian.  On x86 Macs, unless aForce is set
    // (indicating formhistory reset or a brand-new db), use big-endian byte
    // ordering and turn swapping on.
    if (aForce) {
      mReverseByteOrder = PR_FALSE;
      rv = SaveByteOrder(nativeByteOrder);
    }
    else {
      mReverseByteOrder = PR_TRUE;
      rv = SaveByteOrder(bigEndianByteOrder);
    }
#else
    mReverseByteOrder = PR_FALSE;
    rv = SaveByteOrder(nativeByteOrder);
#endif
  }
  else
    mReverseByteOrder = !fileByteOrder.Equals(nativeByteOrder);

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean nsIFormHistory2::nameExists ( in AString  name) [inherited]

Returns true if there is no entry that is paired with a name.

NS_IMETHODIMP nsFormHistory::Notify ( nsIContent formNode,
nsIDOMWindowInternal window,
nsIURI actionURL,
PRBool cancelSubmit 
) [virtual]

Implements nsIFormSubmitObserver.

Definition at line 236 of file nsFormHistory.cpp.

{
  if (!FormHistoryEnabled())
    return NS_OK;

  nsresult rv = OpenDatabase(); // lazily ensure that the database is open
  NS_ENSURE_SUCCESS(rv, rv);
  
  nsCOMPtr<nsIDOMHTMLFormElement> formElt = do_QueryInterface(aFormNode);
  NS_ENSURE_TRUE(formElt, NS_ERROR_FAILURE);

  NS_NAMED_LITERAL_STRING(kAutoComplete, "autocomplete");
  nsAutoString autocomplete;
  formElt->GetAttribute(kAutoComplete, autocomplete);
  if (autocomplete.LowerCaseEqualsLiteral("off"))
    return NS_OK;

  nsCOMPtr<nsIDOMHTMLCollection> elts;
  formElt->GetElements(getter_AddRefs(elts));

  PRUint32 length;
  elts->GetLength(&length);
  for (PRUint32 i = 0; i < length; ++i) {
    nsCOMPtr<nsIDOMNode> node;
    elts->Item(i, getter_AddRefs(node));
    nsCOMPtr<nsIDOMHTMLInputElement> inputElt = do_QueryInterface(node);
    if (inputElt) {
      // Filter only inputs that are of type "text" without autocomplete="off"
      nsAutoString type;
      inputElt->GetType(type);
      if (!type.LowerCaseEqualsLiteral("text"))
        continue;

      nsAutoString autocomplete;
      inputElt->GetAttribute(kAutoComplete, autocomplete);
      if (!autocomplete.LowerCaseEqualsLiteral("off")) {
        // If this input has a name/id and value, add it to the database
        nsAutoString value;
        inputElt->GetValue(value);
        if (!value.IsEmpty()) {
          nsAutoString name;
          inputElt->GetName(name);
          if (name.IsEmpty())
            inputElt->GetId(name);
          if (!name.IsEmpty())
            AppendRow(name, value, nsnull);
        }
      }
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

NS_DECL_ISUPPORTS NS_DECL_NSIFORMHISTORY2 NS_DECL_NSIOBSERVER NS_IMETHOD nsFormHistory::Notify ( nsIContent formNode,
nsIDOMWindowInternal window,
nsIURI actionURL,
PRBool cancelSubmit 
) [virtual]

Implements nsIFormSubmitObserver.

void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.

Definition at line 353 of file nsFormHistory.cpp.

{
  if (mStore)
    return NS_OK;
  
  // Get a handle to the database file
  nsCOMPtr <nsIFile> historyFile;
  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(historyFile));
  NS_ENSURE_SUCCESS(rv, rv);
  historyFile->Append(NS_ConvertUTF8toUCS2(kFormHistoryFileName));

  // Get an Mdb Factory
  static NS_DEFINE_CID(kMorkCID, NS_MORK_CID);
  nsCOMPtr<nsIMdbFactoryFactory> mdbFactory = do_CreateInstance(kMorkCID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = mdbFactory->GetMdbFactory(getter_AddRefs(mMdbFactory));
  NS_ENSURE_SUCCESS(rv, rv);

  // Create the Mdb environment
  mdb_err err = mMdbFactory->MakeEnv(nsnull, &mEnv);
  NS_ASSERTION(err == 0, "ERROR: Unable to create Form History mdb");
  mEnv->SetAutoClear(PR_TRUE);
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
  mEnv->SetErrorHook(new SatchelErrorHook());

  nsCAutoString filePath;
  historyFile->GetNativePath(filePath);
  PRBool exists = PR_TRUE;
  historyFile->Exists(&exists);

  PRBool createdNew = PR_FALSE;
  
  if (!exists || NS_FAILED(rv = OpenExistingFile(filePath.get()))) {
    // If the file doesn't exist, or we fail trying to open it,
    // then make sure it is deleted and then create an empty database file
    historyFile->Remove(PR_FALSE);
    rv = CreateNewFile(filePath.get());
    createdNew = PR_TRUE;
  }
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the initial size of the file, needed later for Commit
  historyFile->GetFileSize(&mFileSizeOnDisk);

  rv = InitByteOrder(createdNew);

  /* // TESTING: Add a row to the database
  nsAutoString foopy;
  foopy.AssignWithConversion("foopy");
  nsAutoString oogly;
  oogly.AssignWithConversion("oogly");
  AppendRow(foopy, oogly, nsnull);
  Flush(); */
  
  /* // TESTING: Dump the contents of the database
  PRUint32 count = 0;
  mdb_err err = mTable->GetCount(mEnv, &count);
  printf("%d rows in form history\n", count);

  for (mdb_pos pos = count - 1; pos >= 0; --pos) {
    nsCOMPtr<nsIMdbRow> row;
    err = mTable->PosToRow(mEnv, pos, getter_AddRefs(row));
    
    nsAutoString name;
    GetRowValue(row, kToken_NameColumn, name);
    nsAutoString value;
    GetRowValue(row, kToken_ValueColumn, value);
    printf("ROW: %s - %s\n", ToNewCString(name), ToNewCString(value));
  } */

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::OpenExistingFile ( const char *  aPath) [protected]

Definition at line 427 of file nsFormHistory.cpp.

{
  nsCOMPtr<nsIMdbFile> oldFile;
  nsIMdbHeap* dbHeap = 0;
  mdb_err err = mMdbFactory->OpenOldFile(mEnv, dbHeap, aPath, mdbBool_kFalse, getter_AddRefs(oldFile));
  NS_ENSURE_TRUE(!err && oldFile, NS_ERROR_FAILURE);

  mdb_bool canOpen = 0;
  mdbYarn outFormat = {nsnull, 0, 0, 0, 0, nsnull};
  err = mMdbFactory->CanOpenFilePort(mEnv, oldFile, &canOpen, &outFormat);
  NS_ENSURE_TRUE(!err && canOpen, NS_ERROR_FAILURE);

  nsCOMPtr<nsIMdbThumb> thumb;
  mdbOpenPolicy policy = {{0, 0}, 0, 0};
  err = mMdbFactory->OpenFileStore(mEnv, dbHeap, oldFile, &policy, getter_AddRefs(thumb));
  NS_ENSURE_TRUE(!err && thumb, NS_ERROR_FAILURE);

  PRBool done;
  mdb_err thumbErr = UseThumb(thumb, &done);

  if (err == 0 && done)
    err = mMdbFactory->ThumbToOpenStore(mEnv, thumb, &mStore);
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);

  nsresult rv = CreateTokens();
  NS_ENSURE_SUCCESS(rv, rv);

  mdbOid oid = {kToken_RowScope, 1};
  err = mStore->GetTable(mEnv, &oid, &mTable);
  NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
  if (!mTable) {
    NS_WARNING("ERROR: Form history file is corrupt, now deleting it.");
    return NS_ERROR_FAILURE;
  }

  err = mTable->GetMetaRow(mEnv, &oid, nsnull, getter_AddRefs(mMetaRow));
  if (err)
    NS_WARNING("Could not get meta row");

  if (NS_FAILED(thumbErr))
    err = thumbErr;

  return err ? NS_ERROR_FAILURE : NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFormHistory::PR_STATIC_CALLBACK ( int  ) const [protected]

Removes all entries in the entire form history.

void nsIFormHistory2::removeEntriesForName ( in AString  name) [inherited]

Removes all entries that are paired with a name.

nsresult nsFormHistory::RemoveEntriesInternal ( const nsAString *  aName) [protected]

Definition at line 892 of file nsFormHistory.cpp.

{
  nsresult rv = OpenDatabase(); // lazily ensure that the database is open
  NS_ENSURE_SUCCESS(rv, rv);

  if (!mTable) return NS_OK;

  mdb_err err;
  mdb_count count;
  nsAutoString name;
  err = mTable->GetCount(mEnv, &count);
  if (err != 0) return NS_ERROR_FAILURE;

  // Begin the batch.
  int marker;
  err = mTable->StartBatchChangeHint(mEnv, &marker);
  NS_ASSERTION(err == 0, "unable to start batch");
  if (err != 0) return NS_ERROR_FAILURE;

  for (mdb_pos pos = count - 1; pos >= 0; --pos) {
    nsCOMPtr<nsIMdbRow> row;
    err = mTable->PosToRow(mEnv, pos, getter_AddRefs(row));
    NS_ASSERTION(err == 0, "unable to get row");
    if (err != 0)
      break;

    NS_ASSERTION(row != nsnull, "no row");
    if (! row)
      continue;

    // Check if the name matches this row
    GetRowValue(row, kToken_NameColumn, name);
    
    if (!aName || Compare(name, *aName, nsCaseInsensitiveStringComparator()) == 0) {

      // Officially cut the row *now*, before notifying any observers:
      // that way, any re-entrant calls won't find the row.
      err = mTable->CutRow(mEnv, row);
      NS_ASSERTION(err == 0, "couldn't cut row");
      if (err != 0)
        continue;
  
      // possibly avoid leakage
      err = row->CutAllColumns(mEnv);
      NS_ASSERTION(err == 0, "couldn't cut all columns");
      // we'll notify regardless of whether we could successfully
      // CutAllColumns or not.
    }

  }
  
  // Finish the batch.
  err = mTable->EndBatchChangeHint(mEnv, &marker);
  NS_ASSERTION(err == 0, "error ending batch");

  return (err == 0) ? NS_OK : NS_ERROR_FAILURE;

}

Here is the call graph for this function:

void nsIFormHistory2::removeEntry ( in AString  name,
in AString  value 
) [inherited]

Removes a name and value pair from the form history.

PRBool nsFormHistory::RowMatch ( nsIMdbRow aRow,
const nsAString &  aInputName,
const nsAString &  aInputValue,
PRUnichar **  aValue 
) [protected]

Definition at line 833 of file nsFormHistory.cpp.

{
  nsAutoString name;
  GetRowValue(aRow, kToken_NameColumn, name);

  if (name.Equals(aInputName)) {
    nsAutoString value;
    GetRowValue(aRow, kToken_ValueColumn, value);
    if (Compare(Substring(value, 0, aInputValue.Length()), aInputValue, nsCaseInsensitiveStringComparator()) == 0) {
      if (aValue)
        *aValue = ToNewUnicode(value);
      return PR_TRUE;
    }
  }
  
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::SaveByteOrder ( const nsAString &  aByteOrder) [protected]

Definition at line 1012 of file nsFormHistory.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFormHistory::SetRowValue ( nsIMdbRow aRow,
mdb_column  aCol,
const nsAString &  aValue 
) [protected]

Definition at line 663 of file nsFormHistory.cpp.

{
  PRInt32 len = aValue.Length() * sizeof(PRUnichar);
  PRUnichar *swapval = nsnull;
  mdbYarn yarn = {nsnull, len, len, 0, 0, nsnull};
  const nsPromiseFlatString& buffer = PromiseFlatString(aValue);

  if (mReverseByteOrder) {
    swapval = new PRUnichar[aValue.Length()];
    if (!swapval)
      return NS_ERROR_OUT_OF_MEMORY;
    SwapBytes(swapval, buffer.get(), aValue.Length());
    yarn.mYarn_Buf = swapval;
  }
  else
    yarn.mYarn_Buf = (void*)buffer.get();

  mdb_err err = aRow->AddColumn(mEnv, aCol, &yarn);

  delete swapval;
  
  return err ? NS_ERROR_FAILURE : NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 483 of file nsStorageFormHistory.cpp.

{
  // do nothing if the dummy statement is already running
  if (mDummyStatement)
    return NS_OK;

  // dummy database connection
  nsCOMPtr<nsIFile> formHistoryFile;
  nsresult rv = GetDatabaseFile(getter_AddRefs(formHistoryFile));
  NS_ENSURE_SUCCESS(rv, rv);
  rv = mStorageService->OpenDatabase(formHistoryFile,
                                     getter_AddRefs(mDummyConnection));
  NS_ENSURE_SUCCESS(rv, rv);

  // Make sure the dummy table exists
  PRBool tableExists;
  rv = mDummyConnection->TableExists(NS_LITERAL_CSTRING("moz_dummy_table"), &tableExists);
  NS_ENSURE_SUCCESS(rv, rv);
  if (! tableExists) {
    rv = mDummyConnection->ExecuteSimpleSQL(
        NS_LITERAL_CSTRING("CREATE TABLE moz_dummy_table (id INTEGER PRIMARY KEY)"));
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // This table is guaranteed to have something in it and will keep the dummy
  // statement open. If the table is empty, it won't hold the statement open.
  // the PRIMARY KEY value on ID means that it is unique. The OR IGNORE means
  // that if there is already a value of 1 there, this insert will be ignored,
  // which is what we want so as to avoid growing the table infinitely.
  rv = mDummyConnection->ExecuteSimpleSQL(
      NS_LITERAL_CSTRING("INSERT OR IGNORE INTO moz_dummy_table VALUES (1)"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = mDummyConnection->CreateStatement(NS_LITERAL_CSTRING(
      "SELECT id FROM moz_dummy_table LIMIT 1"),
    getter_AddRefs(mDummyStatement));
  NS_ENSURE_SUCCESS(rv, rv);

  // we have to step the dummy statement so that it will hold a lock on the DB
  PRBool dummyHasResults;
  rv = mDummyStatement->ExecuteStep(&dummyHasResults);
  NS_ENSURE_SUCCESS(rv, rv);

  // Set the cache size
  nsCAutoString cacheSizePragma("PRAGMA cache_size=");
  cacheSizePragma.AppendInt(DATABASE_CACHE_PAGES);
  rv = mDummyConnection->ExecuteSimpleSQL(cacheSizePragma);
  NS_ENSURE_SUCCESS(rv, rv);

  // preload the cache
  rv = mDummyConnection->Preload();
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}

Here is the call graph for this function:

Definition at line 547 of file nsStorageFormHistory.cpp.

{
  // do nothing if the dummy statement isn't running
  if (! mDummyStatement)
    return NS_OK;

  nsresult rv = mDummyStatement->Reset();
  NS_ENSURE_SUCCESS(rv, rv);

  mDummyStatement = nsnull;
  return NS_OK;
}
mdb_err nsFormHistory::UseThumb ( nsIMdbThumb aThumb,
PRBool aDone 
) [protected]

Definition at line 583 of file nsFormHistory.cpp.

{
  mdb_count total;
  mdb_count current;
  mdb_bool done;
  mdb_bool broken;
  mdb_err err;
  
  do {
    err = aThumb->DoMore(mEnv, &total, &current, &done, &broken);
  } while ((err == 0) && !broken && !done);
  
  if (aDone)
    *aDone = done;
  
  return err ? NS_ERROR_FAILURE : NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 102 of file nsFormHistory.h.

static nsFormHistory * nsFormHistory::gFormHistory = nsnull [static, protected]

Definition at line 114 of file nsFormHistory.h.

static PRBool nsFormHistory::gFormHistoryEnabled = PR_FALSE [static, protected]

Definition at line 116 of file nsFormHistory.h.

static PRBool nsFormHistory::gPrefsInitialized = PR_FALSE [static, protected]

Definition at line 117 of file nsFormHistory.h.

Returns true if the form history has any entries.

Definition at line 58 of file nsIFormHistory.idl.

Definition at line 131 of file nsFormHistory.h.

Definition at line 130 of file nsFormHistory.h.

Definition at line 82 of file nsFormHistory.h.

Definition at line 129 of file nsFormHistory.h.

Definition at line 81 of file nsFormHistory.h.

Definition at line 80 of file nsStorageFormHistory.h.

Definition at line 134 of file nsStorageFormHistory.h.

Definition at line 135 of file nsStorageFormHistory.h.

Definition at line 133 of file nsStorageFormHistory.h.

Definition at line 137 of file nsStorageFormHistory.h.

Definition at line 136 of file nsStorageFormHistory.h.

Definition at line 142 of file nsStorageFormHistory.h.

Definition at line 143 of file nsStorageFormHistory.h.

Definition at line 121 of file nsFormHistory.h.

Definition at line 124 of file nsFormHistory.h.

Definition at line 119 of file nsFormHistory.h.

Definition at line 125 of file nsFormHistory.h.

Definition at line 120 of file nsFormHistory.h.

Definition at line 126 of file nsFormHistory.h.

Definition at line 132 of file nsStorageFormHistory.h.

Definition at line 122 of file nsFormHistory.h.

Definition at line 123 of file nsFormHistory.h.

Definition at line 102 of file nsFormHistory.h.


The documentation for this class was generated from the following files: