2001-02-23 13:18:01 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is nsCacheMetaData.cpp, released February 22, 2001.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
|
|
* Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 2001 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Gordon Sheridan, 22-February-2001
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nsCacheMetaData.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* nsCacheClientHashTable
|
|
|
|
*/
|
|
|
|
|
|
|
|
PLDHashTableOps
|
|
|
|
nsCacheMetaData::ops =
|
|
|
|
{
|
|
|
|
PL_DHashAllocTable,
|
|
|
|
PL_DHashFreeTable,
|
|
|
|
GetKey,
|
|
|
|
HashKey,
|
|
|
|
MatchEntry,
|
|
|
|
MoveEntry,
|
|
|
|
ClearEntry,
|
|
|
|
Finalize
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
nsCacheMetaData::nsCacheMetaData()
|
2001-03-29 05:54:58 +00:00
|
|
|
: initialized(PR_FALSE)
|
2001-02-23 13:18:01 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCacheMetaData::~nsCacheMetaData()
|
|
|
|
{
|
2001-03-29 05:54:58 +00:00
|
|
|
if (initialized)
|
|
|
|
PL_DHashTableFinish(&table);
|
2001-02-23 13:18:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCacheMetaData::Init()
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
initialized = PL_DHashTableInit(&table, &ops, nsnull,
|
|
|
|
sizeof(nsCacheMetaDataHashTableEntry), 16);
|
|
|
|
|
|
|
|
if (!initialized) rv = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-02 01:51:41 +00:00
|
|
|
nsCacheMetaData *
|
|
|
|
nsCacheMetaData::Create()
|
|
|
|
{
|
|
|
|
nsCacheMetaData * metaData = new nsCacheMetaData();
|
|
|
|
if (!metaData)
|
|
|
|
return nsnull;
|
|
|
|
|
|
|
|
nsresult rv = metaData->Init();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
delete metaData;
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return metaData;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-23 13:18:01 +00:00
|
|
|
nsAReadableCString *
|
|
|
|
nsCacheMetaData::GetElement(const nsAReadableCString * key)
|
|
|
|
{
|
|
|
|
PLDHashEntryHdr * hashEntry;
|
|
|
|
nsCString * result = nsnull;
|
|
|
|
|
2001-03-04 00:11:30 +00:00
|
|
|
// XXX need to copy string until we have scc's new flat string abstract class
|
|
|
|
// XXX see nsCacheMetaData::HashKey below (bug 70075)
|
2001-03-02 01:51:41 +00:00
|
|
|
nsCString * tempKey = new nsCString(*key);
|
|
|
|
if (!tempKey) return result;
|
|
|
|
|
2001-02-23 13:18:01 +00:00
|
|
|
NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized");
|
2001-03-02 01:51:41 +00:00
|
|
|
hashEntry = PL_DHashTableOperate(&table, tempKey, PL_DHASH_LOOKUP);
|
2001-02-23 13:18:01 +00:00
|
|
|
if (PL_DHASH_ENTRY_IS_BUSY(hashEntry)) {
|
|
|
|
result = ((nsCacheMetaDataHashTableEntry *)hashEntry)->value;
|
|
|
|
}
|
2001-03-02 01:51:41 +00:00
|
|
|
|
|
|
|
delete tempKey;
|
2001-02-23 13:18:01 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
2001-03-01 20:06:16 +00:00
|
|
|
nsCacheMetaData::SetElement(const nsAReadableCString& key,
|
|
|
|
const nsAReadableCString& value)
|
2001-02-23 13:18:01 +00:00
|
|
|
{
|
2001-03-02 01:51:41 +00:00
|
|
|
nsCacheMetaDataHashTableEntry * metaEntry;
|
2001-03-13 15:43:17 +00:00
|
|
|
nsresult rv = NS_ERROR_OUT_OF_MEMORY; // presume the worst
|
2001-02-23 13:18:01 +00:00
|
|
|
|
2001-03-02 01:51:41 +00:00
|
|
|
NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized");
|
2001-02-23 13:18:01 +00:00
|
|
|
|
2001-03-04 00:11:30 +00:00
|
|
|
// XXX need to copy string until we have scc's new flat string abstract class
|
|
|
|
// XXX see nsCacheMetaData::HashKey below (bug 70075)
|
2001-03-02 01:51:41 +00:00
|
|
|
nsCString * tempKey = new nsCString(key);
|
2001-03-13 15:43:17 +00:00
|
|
|
if (!tempKey) return rv;
|
2001-03-02 01:51:41 +00:00
|
|
|
|
2001-03-04 00:11:30 +00:00
|
|
|
// XXX should empty value remove the key?
|
2001-03-02 01:51:41 +00:00
|
|
|
|
|
|
|
metaEntry = (nsCacheMetaDataHashTableEntry *)
|
|
|
|
PL_DHashTableOperate(&table, tempKey, PL_DHASH_ADD);
|
2001-03-13 15:43:17 +00:00
|
|
|
if (!metaEntry) goto error_exit;
|
|
|
|
|
|
|
|
|
2001-03-02 01:51:41 +00:00
|
|
|
if (metaEntry->key == nsnull) {
|
|
|
|
metaEntry->key = new nsCString(key);
|
|
|
|
if (metaEntry->key == nsnull) {
|
2001-03-13 15:43:17 +00:00
|
|
|
goto error_exit;
|
2001-03-02 01:51:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (metaEntry->value != nsnull)
|
2001-03-13 15:43:17 +00:00
|
|
|
delete metaEntry->value; // clear the old value
|
2001-03-02 01:51:41 +00:00
|
|
|
|
|
|
|
metaEntry->value = new nsCString(value);
|
|
|
|
if (metaEntry->value == nsnull) {
|
2001-03-04 00:11:30 +00:00
|
|
|
// XXX remove key?
|
2001-03-13 15:43:17 +00:00
|
|
|
goto error_exit;
|
2001-03-02 01:51:41 +00:00
|
|
|
}
|
2001-02-23 13:18:01 +00:00
|
|
|
|
2001-03-13 15:43:17 +00:00
|
|
|
rv = NS_OK;
|
|
|
|
error_exit:
|
2001-03-02 01:51:41 +00:00
|
|
|
delete tempKey;
|
2001-03-13 15:43:17 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRUint32
|
|
|
|
nsCacheMetaData::Size(void)
|
|
|
|
{
|
|
|
|
PRUint32 size = 0;
|
|
|
|
(void) PL_DHashTableEnumerate(&table, CalculateSize, &size);
|
|
|
|
return size;
|
2001-02-23 13:18:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-28 07:13:32 +00:00
|
|
|
nsresult
|
2001-03-02 04:09:01 +00:00
|
|
|
nsCacheMetaData::FlattenMetaData(char ** data, PRUint32 * size)
|
2001-02-28 07:13:32 +00:00
|
|
|
{
|
2001-03-02 04:09:01 +00:00
|
|
|
*size = 0;
|
2001-02-28 07:13:32 +00:00
|
|
|
|
2001-03-02 04:09:01 +00:00
|
|
|
if (PL_DHashTableEnumerate(&table, CalculateSize, size) != 0 && data) {
|
|
|
|
*data = new char[*size];
|
|
|
|
if (*data == nsnull) return NS_ERROR_OUT_OF_MEMORY;
|
2001-03-02 04:54:27 +00:00
|
|
|
char* state = *data;
|
|
|
|
PL_DHashTableEnumerate(&table, AccumulateElements, &state);
|
2001-02-28 07:13:32 +00:00
|
|
|
}
|
|
|
|
|
2001-03-02 04:09:01 +00:00
|
|
|
return NS_OK;
|
2001-02-28 07:13:32 +00:00
|
|
|
}
|
2001-02-23 13:18:01 +00:00
|
|
|
|
2001-03-02 04:09:01 +00:00
|
|
|
nsresult
|
|
|
|
nsCacheMetaData::UnflattenMetaData(char * data, PRUint32 size)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
|
|
|
char* limit = data + size;
|
|
|
|
while (data < limit) {
|
|
|
|
const char* name = data;
|
|
|
|
PRUint32 nameSize = nsCRT::strlen(name);
|
|
|
|
data += 1 + nameSize;
|
|
|
|
if (data < limit) {
|
|
|
|
const char* value = data;
|
|
|
|
PRUint32 valueSize = nsCRT::strlen(value);
|
|
|
|
data += 1 + valueSize;
|
2001-04-02 23:11:04 +00:00
|
|
|
rv = SetElement(nsLocalCString(name, nameSize),
|
|
|
|
nsLocalCString(value, valueSize));
|
2001-03-02 04:09:01 +00:00
|
|
|
if (NS_FAILED(rv)) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
2001-02-23 13:18:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* hash table operation callback functions
|
|
|
|
*/
|
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
const void * PR_CALLBACK
|
2001-02-26 14:46:54 +00:00
|
|
|
nsCacheMetaData::GetKey( PLDHashTable * /* table */, PLDHashEntryHdr *hashEntry)
|
2001-02-23 13:18:01 +00:00
|
|
|
{
|
|
|
|
return ((nsCacheMetaDataHashTableEntry *)hashEntry)->key;
|
|
|
|
}
|
|
|
|
|
2001-03-02 01:51:41 +00:00
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
PLDHashNumber PR_CALLBACK
|
2001-02-27 05:35:53 +00:00
|
|
|
nsCacheMetaData::HashKey( PLDHashTable * table, const void *key)
|
2001-02-26 14:46:54 +00:00
|
|
|
{
|
2001-03-04 00:11:30 +00:00
|
|
|
// XXX need scc's new flat string abstract class here (bug 70075)
|
2001-02-27 05:35:53 +00:00
|
|
|
return PL_DHashStringKey(table, ((nsCString *)key)->get());
|
2001-02-26 14:46:54 +00:00
|
|
|
}
|
|
|
|
|
2001-03-02 01:51:41 +00:00
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
PRBool PR_CALLBACK
|
2001-02-23 13:18:01 +00:00
|
|
|
nsCacheMetaData::MatchEntry(PLDHashTable * /* table */,
|
|
|
|
const PLDHashEntryHdr * hashEntry,
|
|
|
|
const void * key)
|
|
|
|
{
|
2001-03-13 15:43:17 +00:00
|
|
|
NS_ASSERTION(key != nsnull, "### nsCacheMetaDataHashTable::MatchEntry : null key");
|
2001-02-23 13:18:01 +00:00
|
|
|
nsCString * entryKey = ((nsCacheMetaDataHashTableEntry *)hashEntry)->key;
|
2001-03-13 15:43:17 +00:00
|
|
|
NS_ASSERTION(entryKey, "### hashEntry->key == nsnull");
|
2001-03-02 01:51:41 +00:00
|
|
|
|
|
|
|
return entryKey->Equals(*NS_STATIC_CAST(const nsAReadableCString*,key));
|
2001-02-23 13:18:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
void PR_CALLBACK
|
2001-02-23 13:18:01 +00:00
|
|
|
nsCacheMetaData::MoveEntry(PLDHashTable * /* table */,
|
|
|
|
const PLDHashEntryHdr *from,
|
|
|
|
PLDHashEntryHdr *to)
|
|
|
|
{
|
|
|
|
to->keyHash = from->keyHash;
|
|
|
|
((nsCacheMetaDataHashTableEntry *)to)->key =
|
|
|
|
((nsCacheMetaDataHashTableEntry *)from)->key;
|
|
|
|
((nsCacheMetaDataHashTableEntry *)to)->value =
|
|
|
|
((nsCacheMetaDataHashTableEntry *)from)->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
void PR_CALLBACK
|
2001-02-23 13:18:01 +00:00
|
|
|
nsCacheMetaData::ClearEntry(PLDHashTable * /* table */,
|
2001-02-28 07:13:32 +00:00
|
|
|
PLDHashEntryHdr * hashEntry)
|
2001-02-23 13:18:01 +00:00
|
|
|
{
|
|
|
|
((nsCacheMetaDataHashTableEntry *)hashEntry)->keyHash = 0;
|
|
|
|
((nsCacheMetaDataHashTableEntry *)hashEntry)->key = 0;
|
|
|
|
((nsCacheMetaDataHashTableEntry *)hashEntry)->value = 0;
|
|
|
|
}
|
|
|
|
|
2001-02-28 07:13:32 +00:00
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
void PR_CALLBACK
|
2001-02-28 07:13:32 +00:00
|
|
|
nsCacheMetaData::Finalize(PLDHashTable * table)
|
|
|
|
{
|
|
|
|
(void) PL_DHashTableEnumerate(table, FreeElements, nsnull);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* hash table enumeration callback functions
|
|
|
|
*/
|
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
PLDHashOperator PR_CALLBACK
|
2001-03-02 04:09:01 +00:00
|
|
|
nsCacheMetaData::CalculateSize(PLDHashTable *table,
|
2001-02-28 07:13:32 +00:00
|
|
|
PLDHashEntryHdr *hdr,
|
|
|
|
PRUint32 number,
|
|
|
|
void *arg)
|
2001-02-23 13:18:01 +00:00
|
|
|
{
|
2001-03-02 04:09:01 +00:00
|
|
|
nsCacheMetaDataHashTableEntry* hashEntry = (nsCacheMetaDataHashTableEntry *)hdr;
|
2001-03-02 04:54:27 +00:00
|
|
|
*(PRUint32*)arg += (2 + hashEntry->key->Length() + hashEntry->value->Length());
|
2001-02-28 07:13:32 +00:00
|
|
|
return PL_DHASH_NEXT;
|
2001-02-23 13:18:01 +00:00
|
|
|
}
|
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
PLDHashOperator PR_CALLBACK
|
2001-02-28 07:13:32 +00:00
|
|
|
nsCacheMetaData::AccumulateElements(PLDHashTable *table,
|
2001-03-02 04:09:01 +00:00
|
|
|
PLDHashEntryHdr *hdr,
|
|
|
|
PRUint32 number,
|
|
|
|
void *arg)
|
2001-02-28 07:13:32 +00:00
|
|
|
{
|
2001-03-02 04:09:01 +00:00
|
|
|
char** bufferPtr = (char**) arg;
|
|
|
|
nsCacheMetaDataHashTableEntry* hashEntry = (nsCacheMetaDataHashTableEntry *)hdr;
|
|
|
|
PRUint32 size = 1 + hashEntry->key->Length();
|
|
|
|
nsCRT::memcpy(*bufferPtr, hashEntry->key->get(), size);
|
|
|
|
*bufferPtr += size;
|
|
|
|
size = 1 + hashEntry->value->Length();
|
|
|
|
nsCRT::memcpy(*bufferPtr, hashEntry->value->get(), size);
|
|
|
|
*bufferPtr += size;
|
2001-02-28 07:13:32 +00:00
|
|
|
return PL_DHASH_NEXT;
|
|
|
|
}
|
|
|
|
|
2001-03-26 23:21:53 +00:00
|
|
|
PLDHashOperator PR_CALLBACK
|
2001-02-28 07:13:32 +00:00
|
|
|
nsCacheMetaData::FreeElements(PLDHashTable *table,
|
|
|
|
PLDHashEntryHdr *hdr,
|
|
|
|
PRUint32 number,
|
|
|
|
void *arg)
|
|
|
|
{
|
|
|
|
nsCacheMetaDataHashTableEntry *entry = (nsCacheMetaDataHashTableEntry *)hdr;
|
|
|
|
delete entry->key;
|
|
|
|
delete entry->value;
|
|
|
|
return PL_DHASH_NEXT;
|
|
|
|
}
|