//************************************************************************** //** //** ## ## ## ## ## #### #### ### ### //** ## ## ## ## ## ## ## ## ## ## #### #### //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## //** ## ## ######## ## ## ## ## ## ## ## ### ## //** ### ## ## ### ## ## ## ## ## ## //** # ## ## # #### #### ## ## //** //** $Id: name.cpp 1583 2006-06-27 19:05:42Z dj_jl $ //** //** Copyright (C) 1999-2006 Jānis Legzdiņš //** //** This program is free software; you can redistribute it and/or //** modify it under the terms of the GNU General Public License //** as published by the Free Software Foundation; either version 2 //** of the License, or (at your option) any later version. //** //** This program is distributed in the hope that it will be useful, //** but WITHOUT ANY WARRANTY; without even the implied warranty of //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //** GNU General Public License for more details. //** //************************************************************************** // HEADER FILES ------------------------------------------------------------ #include "vcc.h" // MACROS ------------------------------------------------------------------ // TYPES ------------------------------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // EXTERNAL DATA DECLARATIONS ---------------------------------------------- // PUBLIC DATA DEFINITIONS ------------------------------------------------- TArray VName::Names; VNameEntry* VName::HashTable[4096]; bool VName::Initialised; #define REGISTER_NAME(name) { NULL, NAME_##name, #name }, static VNameEntry AutoNames[] = { #include "names.h" }; // PRIVATE DATA DEFINITIONS ------------------------------------------------ // CODE -------------------------------------------------------------------- //========================================================================== // // GetTypeHash // //========================================================================== inline vuint32 GetTypeHash(const char *S) { return ((vuint8*)S)[0] | ((vuint8*)S)[1]; } //========================================================================== // // operator VStream << VNameEntry // //========================================================================== VStream& operator<<(VStream& Strm, VNameEntry& E) { guard(operator VStream << VNameEntry); vuint8 Size; if (Strm.IsSaving()) { Size = strlen(E.Name) + 1; } Strm << Size; Strm.Serialise(E.Name, Size); return Strm; unguard; } //========================================================================== // // AllocateNameEntry // //========================================================================== VNameEntry* AllocateNameEntry(const char* Name, vint32 Index, VNameEntry* HashNext) { guard(AllocateNameEntry); int Size = sizeof(VNameEntry) - NAME_SIZE + strlen(Name) + 1; VNameEntry* E = (VNameEntry*)Z_Malloc(Size); memset(E, 0, Size); strcpy(E->Name, Name); E->Index = Index; E->HashNext = HashNext; return E; unguard; } //========================================================================== // // VName::VName // //========================================================================== VName::VName(const char* Name, ENameFindType FindType) { guard(VName::VName); char NameBuf[NAME_SIZE]; Index = NAME_None; // Make sure name is valid. if (!Name || !*Name) { return; } // Copy name localy, make sure it's not longer than 64 characters. if (FindType == AddLower8) { for (int i = 0; i < 8; i++) { NameBuf[i] = tolower(Name[i]); } NameBuf[8] = 0; } else { strncpy(NameBuf, Name, NAME_SIZE); NameBuf[NAME_SIZE - 1] = 0; } // Search in cache. int HashIndex = GetTypeHash(NameBuf) & 4095; VNameEntry* TempHash = HashTable[HashIndex]; while (TempHash) { if (!strcmp(NameBuf, TempHash->Name)) { Index = TempHash->Index; break; } TempHash = TempHash->HashNext; } // Add new name if not found. if (!TempHash && (FindType == Add || FindType == AddLower8)) { Index = Names.Num(); Names.Append(AllocateNameEntry(NameBuf, Index, HashTable[HashIndex])); HashTable[HashIndex] = Names[Index]; } unguard; } //========================================================================== // // VName::StaticInit // //========================================================================== void VName::StaticInit() { guard(VName::StaticInit); // Register hardcoded names. for (int i = 0; i < (int)ARRAY_COUNT(AutoNames); i++) { Names.Append(&AutoNames[i]); int HashIndex = GetTypeHash(AutoNames[i].Name) & 4095; AutoNames[i].HashNext = HashTable[HashIndex]; HashTable[HashIndex] = &AutoNames[i]; } // We are now initialised. Initialised = true; unguard; } //========================================================================== // // VName::StaticExit // //========================================================================== void VName::StaticExit() { guard(VName::StaticExit); for (int i = NUM_HARDCODED_NAMES; i < Names.Num(); i++) { Z_Free(Names[i]); } Names.Clear(); Initialised = false; unguard; }