• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

StringTable.cpp

Go to the documentation of this file.
00001 #include "StringTable.h"
00002 #include <string.h>
00003 #include "RakAssert.h"
00004 #include <stdio.h>
00005 #include "BitStream.h"
00006 #include "StringCompressor.h"
00007 using namespace RakNet;
00008 
00009 StringTable* StringTable::instance=0;
00010 int StringTable::referenceCount=0;
00011 
00012 
00013 int StrAndBoolComp( char *const &key, const StrAndBool &data )
00014 {
00015         return strcmp(key,(const char*)data.str);
00016 }
00017 
00018 StringTable::StringTable()
00019 {
00020         
00021 }
00022 
00023 StringTable::~StringTable()
00024 {
00025         unsigned i;
00026         for (i=0; i < orderedStringList.Size(); i++)
00027         {
00028                 if (orderedStringList[i].b)
00029                         rakFree_Ex(orderedStringList[i].str, __FILE__, __LINE__ );
00030         }
00031 }
00032 
00033 void StringTable::AddReference(void)
00034 {
00035         if (++referenceCount==1)
00036         {
00037                 instance = RakNet::OP_NEW<StringTable>( __FILE__, __LINE__ );
00038         }
00039 }
00040 void StringTable::RemoveReference(void)
00041 {
00042         RakAssert(referenceCount > 0);
00043 
00044         if (referenceCount > 0)
00045         {
00046                 if (--referenceCount==0)
00047                 {
00048                         RakNet::OP_DELETE(instance, __FILE__, __LINE__);
00049                         instance=0;
00050                 }
00051         }
00052 }
00053 
00054 StringTable* StringTable::Instance(void)
00055 {
00056         return instance;
00057 }
00058 
00059 void StringTable::AddString(const char *str, bool copyString)
00060 {
00061         StrAndBool sab;
00062         sab.b=copyString;
00063         if (copyString)
00064         {
00065                 sab.str = (char*) rakMalloc_Ex( strlen(str)+1, __FILE__, __LINE__ );
00066                 strcpy(sab.str, str);
00067         }
00068         else
00069         {
00070                 sab.str=(char*)str;
00071         }
00072 
00073         // If it asserts inside here you are adding duplicate strings.
00074         if (orderedStringList.Insert(sab.str,sab, true, __FILE__,__LINE__)!=(unsigned)-1)
00075         {
00076                 if (copyString)
00077                         RakNet::OP_DELETE(sab.str, __FILE__, __LINE__);
00078         }
00079 
00080         // If this assert hits you need to increase the range of StringTableType
00081         RakAssert(orderedStringList.Size() < (StringTableType)-1);      
00082         
00083 }
00084 void StringTable::EncodeString( const char *input, int maxCharsToWrite, RakNet::BitStream *output )
00085 {
00086         unsigned index;
00087         bool objectExists;
00088         // This is fast because the list is kept ordered.
00089         index=orderedStringList.GetIndexFromKey((char*)input, &objectExists);
00090         if (objectExists)
00091         {
00092                 output->Write(true);
00093                 output->Write((StringTableType)index);
00094         }
00095         else
00096         {
00097                 LogStringNotFound(input);
00098                 output->Write(false);
00099                 stringCompressor->EncodeString(input, maxCharsToWrite, output);
00100         }
00101 }
00102 
00103 bool StringTable::DecodeString( char *output, int maxCharsToWrite, RakNet::BitStream *input )
00104 {
00105         bool hasIndex;
00106         RakAssert(maxCharsToWrite>0);
00107 
00108         if (maxCharsToWrite==0)
00109                 return false;
00110         if (!input->Read(hasIndex))
00111                 return false;
00112         if (hasIndex==false)
00113         {
00114                 stringCompressor->DecodeString(output, maxCharsToWrite, input);
00115         }
00116         else
00117         {
00118                 StringTableType index;
00119                 if (!input->Read(index))
00120                         return false;
00121                 if (index >= orderedStringList.Size())
00122                 {
00123 #ifdef _DEBUG
00124                         // Critical error - got a string index out of range, which means AddString was called more times on the remote system than on this system.
00125                         // All systems must call AddString the same number of types, with the same strings in the same order.
00126                         RakAssert(0);
00127 #endif
00128                         return false;
00129                 }
00130                 
00131                 strncpy(output, orderedStringList[index].str, maxCharsToWrite);
00132                 output[maxCharsToWrite-1]=0;
00133         }
00134 
00135         return true;
00136 }
00137 void StringTable::LogStringNotFound(const char *strName)
00138 {
00139         (void) strName;
00140 
00141 #ifdef _DEBUG
00142         RAKNET_DEBUG_PRINTF("Efficiency Warning! Unregistered String %s sent to StringTable.\n", strName);
00143 #endif
00144 }

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1