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
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
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
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
00125
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 }