1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
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
15
* The Original Code is Mozilla Communicator client code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the NPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the NPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
43
#include "nsIOutputStream.h"
47
typedef struct _SerializedHashTable {
52
} SerializedHashTable;
54
typedef SerializedHashTable* SHT;
56
typedef struct _SHTEntry {
62
typedef SHTEntry* SHTE;
65
dumpHashItem (SHT table, char* key, size_t keyLen, void* value, size_t valueSize) {
66
fprintf(table->file, "A %i\n%s\n%i\n", keyLen, key, valueSize);
67
fwrite(value, 1, valueSize, table->file);
68
fprintf(table->file, "\n");
72
readNextItem(FILE *file, char** key, char** value, size_t *valueSize, PRBool *ignorep,
78
*offset = ftell(file);
79
if (!fgets((char*)tbuff, 10, file)) return 0;
80
if (tbuff[0] == 'X') return 0;
81
sscanf(tbuff, "%c %i", &ignoreChar, &keySize);
82
xkey = (char*) PR_Malloc(keySize + 1);
83
if (!fgets(xkey, keySize+1, file)) return 0;
84
fread(tbuff, 1, 1, file);
85
memset(tbuff, '\0', 10);
86
if (!fgets((char*)tbuff, 10, file)) return 0;
87
sscanf(tbuff, "%i", valueSize);
88
xvalue = (char*) PR_Malloc(*valueSize + 1);
89
xvalue[*valueSize] = '\0';
90
if (!fread(xvalue, *valueSize, 1, file)) return 0;
91
fread(tbuff, 1, 1, file);
92
if (ignoreChar == 'D') {
93
PR_Free((void*)xvalue);
107
SHTFlusher(PLHashEntry *he, PRIntn index, void *arg) {
108
SHT table = (SHT)arg;
109
SHTE entry = (SHTE)he->value;
110
char* key = (char*)he->key;
111
char* v1 = (char*)entry->value;
112
dumpHashItem(table, key, strlen(key), entry->value, entry->size);
113
return HT_ENUMERATE_NEXT;
117
FlushSHT (SHT table) {
119
table->buffer = (char*)PR_Malloc(table->maxEntrySize + 256);
120
fseek(table->file, 0, SEEK_SET);
121
PL_HashTableEnumerateEntries(table->table, SHTFlusher, table);
122
fwrite("X", 1, 1, table->file);
124
PR_Free(table->buffer);
128
SHTAddInt (PLHashTable* table, size_t valueSize, void* value, char* key, int offset) {
129
SHTE ve = (SHTE) PR_Malloc(sizeof(SHTEntry));
131
ve->size = valueSize;
133
return PL_HashTableAdd(table, key, ve);
137
MakeSerializedHash (FILE* file, PRUint32 numBuckets, PLHashFunction keyHash,
138
PLHashComparator keyCompare, PLHashComparator valueCompare,
139
const PLHashAllocOps *allocOps, void *allocPriv) {
140
SHT table = (SHT)PR_Malloc(sizeof(SerializedHashTable));
146
table->table = PL_NewHashTable(numBuckets, keyHash,
147
keyCompare, valueCompare,
148
allocOps, allocPriv);
150
table->maxEntrySize = 1024;
151
while (readNextItem(file, &key, &value, &valueSize, &ignorep, &offset)) {
152
SHTAddInt(table->table, valueSize, value, key, offset);
158
SHTAdd(SHT table, char *key, void *value, size_t valueSize) {
159
fseek(table->file, 0, SEEK_END);
160
SHTFlusher(SHTAddInt(table->table,valueSize, value, key, ftell(table->file)), 0, table);
165
SHTRemove(SHT table, char* key) {
166
SHTE entry = (SHTE)PL_HashTableLookup(table->table, (void*) key);
168
fseek(table->file, entry->offset, SEEK_SET);
169
fwrite("D", 1, 1, table->file);
171
PL_HashTableRemove(table->table, key);
177
SHTLookup(SHT ht, const char *key) {
178
SHTE entry = (SHTE)PL_HashTableLookup(ht->table, (void*) key);
185
MakeOrOpenFile (char* name) {
187
ans = fopen(name, "r+");
189
ans = fopen(name, "w");
191
return fopen(name, "r+");
195
FILE *f = MakeOrOpenFile("test");
196
SHT table = MakeSerializedHash(f, 100, PL_HashString, PL_CompareStrings,
197
PL_CompareValues, NULL, NULL);
200
while (fgets(buffer, 1023, stdin)) {
201
if (strncmp(buffer, "x", 1) == 0) {
205
if (strncmp(buffer, "a", 1) ==0) {
206
char key[100], value[100];
208
sscanf(buffer, "a %s %s", key, value);
209
xkey = (char*)PR_Malloc(strlen(key)+1);
210
xvalue = (char*)PR_Malloc(strlen(value)+1);
211
memset(xkey, '\0', strlen(key)+1);
212
memset(xvalue, '\0', strlen(value)+1);
213
memcpy(xkey, key, strlen(key));
214
memcpy(xvalue, value, strlen(value));
215
SHTAdd(table, xkey, xvalue, strlen(xvalue));
217
if (strncmp(buffer, "q", 1) ==0) {
220
sscanf(buffer, "q %s", key);
221
ans = (char*)SHTLookup(table, (char*)key);
222
printf("-> %s\n", (ans ? ans : "null"));
224
if (strncmp(buffer, "r", 1) == 0) {
226
sscanf(buffer, "r %s", key);
227
SHTRemove(table, key);