/* */
/* */
/* */
-/* (C) 2003 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2003-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* A string pool is used to store identifiers and other strings. Each string
* stored in the pool has a unique id, which may be used to access the string
- * in the pool. Identical strings are only stored once in the pool and have
+ * in the pool. Identical strings are stored only once in the pool and have
* identical ids. This means that instead of comparing strings, just the
* string pool ids must be compared.
*/
StringPoolEntry* Next; /* Pointer to next entry in hash chain */
unsigned Hash; /* Full hash value */
unsigned Id; /* The numeric string id */
- unsigned Len; /* Length of the string (excluding terminator) */
- char S[1]; /* The string itself */
+ StrBuf Buf; /* The string itself */
};
-static StringPoolEntry* NewStringPoolEntry (const char* S, unsigned Hash, unsigned Id)
+static StringPoolEntry* NewStringPoolEntry (const StrBuf* S, unsigned Hash, unsigned Id)
/* Create a new string pool entry and return it. */
{
- /* Get the length of the string */
- unsigned Len = strlen (S);
-
/* Allocate memory */
- StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry) + Len);
+ StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry));
/* Initialize the fields */
E->Next = 0;
E->Hash = Hash;
E->Id = Id;
- E->Len = Len;
- memcpy (E->S, S, Len+1);
+ E->Buf = AUTO_STRBUF_INITIALIZER;
+ SB_Copy (&E->Buf, S);
+
+ /* Always zero terminate the string */
+ SB_Terminate (&E->Buf);
/* Return the new entry */
return E;
/* Free all entries and clear the entry collection */
for (I = 0; I < CollCount (&P->Entries); ++I) {
- xfree (CollAtUnchecked (&P->Entries, I));
+
+ /* Get a pointer to the entry */
+ StringPoolEntry* E = CollAtUnchecked (&P->Entries, I);
+
+ /* Free string buffer memory */
+ SB_Done (&E->Buf);
+
+ /* Free the memory for the entry itself */
+ xfree (E);
}
CollDeleteAll (&P->Entries);
-const char* SP_Get (const StringPool* P, unsigned Index)
+const StrBuf* SP_Get (const StringPool* P, unsigned Index)
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */
{
/* Get the collection entry */
const StringPoolEntry* E = CollConstAt (&P->Entries, Index);
/* Return the string from the entry */
- return E->S;
+ return &E->Buf;
}
-unsigned SP_Add (StringPool* P, const char* S)
-/* Add a string to the buffer and return the index. If the string does already
- * exist in the pool, SP_Add will just return the index of the existing string.
+unsigned SP_Add (StringPool* P, const StrBuf* S)
+/* Add a string buffer to the buffer and return the index. If the string does
+ * already exist in the pool, SP_AddBuf will just return the index of the
+ * existing string.
*/
{
/* Calculate the string hash */
- unsigned Hash = HashStr (S);
+ unsigned Hash = HashBuf (S);
/* Calculate the reduced string hash */
unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0]));
/* Search for an existing entry */
StringPoolEntry* E = P->Tab[RHash];
while (E) {
- if (E->Hash == Hash && strcmp (E->S, S) == 0) {
+ if (E->Hash == Hash && SB_Compare (&E->Buf, S) == 0) {
/* Found, return the id of the existing string */
return E->Id;
}
E->Next = P->Tab[RHash];
P->Tab[RHash] = E;
- /* Add up the string size (plus terminator) */
- P->TotalSize += E->Len + 1;
+ /* Add up the string size */
+ P->TotalSize += SB_GetLen (&E->Buf);
/* Return the id of the entry */
return E->Id;
+unsigned SP_AddStr (StringPool* P, const char* S)
+/* Add a string to the buffer and return the index. If the string does already
+ * exist in the pool, SP_Add will just return the index of the existing string.
+ */
+{
+ unsigned Id;
+
+ /* First make a string buffer, then add it. This is some overhead, but the
+ * routine will probably go.
+ */
+ StrBuf Buf;
+ Id = SP_Add (P, SB_InitFromString (&Buf, S));
+
+ /* Return the id of the new entry */
+ return Id;
+}
+
+
+