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

StringCompressor.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "StringCompressor.h"
00009 #include "DS_HuffmanEncodingTree.h"
00010 #include "BitStream.h"
00011 #include "RakString.h"
00012 #include "RakAssert.h"
00013 #include <string.h>
00014 #if !defined(_PS3) && !defined(__PS3__) && !defined(SN_TARGET_PS3)
00015 #include <memory.h>
00016 #endif
00017 #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00018                         
00019 #endif
00020 
00021 using namespace RakNet;
00022 
00023 StringCompressor* StringCompressor::instance=0;
00024 int StringCompressor::referenceCount=0;
00025 
00026 void StringCompressor::AddReference(void)
00027 {
00028         if (++referenceCount==1)
00029         {
00030                 instance = RakNet::OP_NEW<StringCompressor>( __FILE__, __LINE__ );
00031         }
00032 }
00033 void StringCompressor::RemoveReference(void)
00034 {
00035         RakAssert(referenceCount > 0);
00036 
00037         if (referenceCount > 0)
00038         {
00039                 if (--referenceCount==0)
00040                 {
00041                         RakNet::OP_DELETE(instance, __FILE__, __LINE__);
00042                         instance=0;
00043                 }
00044         }
00045 }
00046 
00047 StringCompressor* StringCompressor::Instance(void)
00048 {
00049         return instance;
00050 }
00051 
00052 unsigned int englishCharacterFrequencies[ 256 ] =
00053 {
00054         0,
00055                 0,
00056                 0,
00057                 0,
00058                 0,
00059                 0,
00060                 0,
00061                 0,
00062                 0,
00063                 0,
00064                 722,
00065                 0,
00066                 0,
00067                 2,
00068                 0,
00069                 0,
00070                 0,
00071                 0,
00072                 0,
00073                 0,
00074                 0,
00075                 0,
00076                 0,
00077                 0,
00078                 0,
00079                 0,
00080                 0,
00081                 0,
00082                 0,
00083                 0,
00084                 0,
00085                 0,
00086                 11084,
00087                 58,
00088                 63,
00089                 1,
00090                 0,
00091                 31,
00092                 0,
00093                 317,
00094                 64,
00095                 64,
00096                 44,
00097                 0,
00098                 695,
00099                 62,
00100                 980,
00101                 266,
00102                 69,
00103                 67,
00104                 56,
00105                 7,
00106                 73,
00107                 3,
00108                 14,
00109                 2,
00110                 69,
00111                 1,
00112                 167,
00113                 9,
00114                 1,
00115                 2,
00116                 25,
00117                 94,
00118                 0,
00119                 195,
00120                 139,
00121                 34,
00122                 96,
00123                 48,
00124                 103,
00125                 56,
00126                 125,
00127                 653,
00128                 21,
00129                 5,
00130                 23,
00131                 64,
00132                 85,
00133                 44,
00134                 34,
00135                 7,
00136                 92,
00137                 76,
00138                 147,
00139                 12,
00140                 14,
00141                 57,
00142                 15,
00143                 39,
00144                 15,
00145                 1,
00146                 1,
00147                 1,
00148                 2,
00149                 3,
00150                 0,
00151                 3611,
00152                 845,
00153                 1077,
00154                 1884,
00155                 5870,
00156                 841,
00157                 1057,
00158                 2501,
00159                 3212,
00160                 164,
00161                 531,
00162                 2019,
00163                 1330,
00164                 3056,
00165                 4037,
00166                 848,
00167                 47,
00168                 2586,
00169                 2919,
00170                 4771,
00171                 1707,
00172                 535,
00173                 1106,
00174                 152,
00175                 1243,
00176                 100,
00177                 0,
00178                 2,
00179                 0,
00180                 10,
00181                 0,
00182                 0,
00183                 0,
00184                 0,
00185                 0,
00186                 0,
00187                 0,
00188                 0,
00189                 0,
00190                 0,
00191                 0,
00192                 0,
00193                 0,
00194                 0,
00195                 0,
00196                 0,
00197                 0,
00198                 0,
00199                 0,
00200                 0,
00201                 0,
00202                 0,
00203                 0,
00204                 0,
00205                 0,
00206                 0,
00207                 0,
00208                 0,
00209                 0,
00210                 0,
00211                 0,
00212                 0,
00213                 0,
00214                 0,
00215                 0,
00216                 0,
00217                 0,
00218                 0,
00219                 0,
00220                 0,
00221                 0,
00222                 0,
00223                 0,
00224                 0,
00225                 0,
00226                 0,
00227                 0,
00228                 0,
00229                 0,
00230                 0,
00231                 0,
00232                 0,
00233                 0,
00234                 0,
00235                 0,
00236                 0,
00237                 0,
00238                 0,
00239                 0,
00240                 0,
00241                 0,
00242                 0,
00243                 0,
00244                 0,
00245                 0,
00246                 0,
00247                 0,
00248                 0,
00249                 0,
00250                 0,
00251                 0,
00252                 0,
00253                 0,
00254                 0,
00255                 0,
00256                 0,
00257                 0,
00258                 0,
00259                 0,
00260                 0,
00261                 0,
00262                 0,
00263                 0,
00264                 0,
00265                 0,
00266                 0,
00267                 0,
00268                 0,
00269                 0,
00270                 0,
00271                 0,
00272                 0,
00273                 0,
00274                 0,
00275                 0,
00276                 0,
00277                 0,
00278                 0,
00279                 0,
00280                 0,
00281                 0,
00282                 0,
00283                 0,
00284                 0,
00285                 0,
00286                 0,
00287                 0,
00288                 0,
00289                 0,
00290                 0,
00291                 0,
00292                 0,
00293                 0,
00294                 0,
00295                 0,
00296                 0,
00297                 0,
00298                 0,
00299                 0,
00300                 0,
00301                 0,
00302                 0,
00303                 0,
00304                 0,
00305                 0,
00306                 0,
00307                 0,
00308                 0,
00309                 0
00310 };
00311 
00312 StringCompressor::StringCompressor()
00313 {
00314         DataStructures::Map<int, HuffmanEncodingTree *>::IMPLEMENT_DEFAULT_COMPARISON();
00315 
00316         // Make a default tree immediately, since this is used for RPC possibly from multiple threads at the same time
00317         HuffmanEncodingTree *huffmanEncodingTree = RakNet::OP_NEW<HuffmanEncodingTree>( __FILE__, __LINE__ );
00318         huffmanEncodingTree->GenerateFromFrequencyTable( englishCharacterFrequencies );
00319 
00320         huffmanEncodingTrees.Set(0, huffmanEncodingTree);
00321 }
00322 void StringCompressor::GenerateTreeFromStrings( unsigned char *input, unsigned inputLength, int languageID )
00323 {
00324         HuffmanEncodingTree *huffmanEncodingTree;
00325         if (huffmanEncodingTrees.Has(languageID))
00326         {
00327                 huffmanEncodingTree = huffmanEncodingTrees.Get(languageID);
00328                 RakNet::OP_DELETE(huffmanEncodingTree, __FILE__, __LINE__);
00329         }
00330 
00331         unsigned index;
00332         unsigned int frequencyTable[ 256 ];
00333 
00334         if ( inputLength == 0 )
00335                 return ;
00336 
00337         // Zero out the frequency table
00338         memset( frequencyTable, 0, sizeof( frequencyTable ) );
00339 
00340         // Generate the frequency table from the strings
00341         for ( index = 0; index < inputLength; index++ )
00342                 frequencyTable[ input[ index ] ] ++;
00343 
00344         // Build the tree
00345         huffmanEncodingTree = RakNet::OP_NEW<HuffmanEncodingTree>( __FILE__, __LINE__ );
00346         huffmanEncodingTree->GenerateFromFrequencyTable( frequencyTable );
00347         huffmanEncodingTrees.Set(languageID, huffmanEncodingTree);
00348 }
00349 
00350 StringCompressor::~StringCompressor()
00351 {
00352         for (unsigned i=0; i < huffmanEncodingTrees.Size(); i++)
00353                 RakNet::OP_DELETE(huffmanEncodingTrees[i], __FILE__, __LINE__);
00354 }
00355 
00356 void StringCompressor::EncodeString( const char *input, int maxCharsToWrite, RakNet::BitStream *output, int languageID )
00357 {
00358         HuffmanEncodingTree *huffmanEncodingTree;
00359         if (huffmanEncodingTrees.Has(languageID)==false)
00360                 return;
00361         huffmanEncodingTree=huffmanEncodingTrees.Get(languageID);
00362 
00363         if ( input == 0 )
00364         {
00365                 output->WriteCompressed( (unsigned int) 0 );
00366                 return ;
00367         }
00368 
00369         RakNet::BitStream encodedBitStream;
00370 
00371         unsigned int stringBitLength;
00372 
00373         int charsToWrite;
00374 
00375         if ( maxCharsToWrite<=0 || ( int ) strlen( input ) < maxCharsToWrite )
00376                 charsToWrite = ( int ) strlen( input );
00377         else
00378                 charsToWrite = maxCharsToWrite - 1;
00379 
00380         huffmanEncodingTree->EncodeArray( ( unsigned char* ) input, charsToWrite, &encodedBitStream );
00381 
00382         stringBitLength = (unsigned int) encodedBitStream.GetNumberOfBitsUsed();
00383 
00384         output->WriteCompressed( stringBitLength );
00385 
00386         output->WriteBits( encodedBitStream.GetData(), stringBitLength );
00387 }
00388 
00389 bool StringCompressor::DecodeString( char *output, int maxCharsToWrite, RakNet::BitStream *input, int languageID )
00390 {
00391         HuffmanEncodingTree *huffmanEncodingTree;
00392         if (huffmanEncodingTrees.Has(languageID)==false)
00393                 return false;
00394         if (maxCharsToWrite<=0)
00395                 return false;
00396         huffmanEncodingTree=huffmanEncodingTrees.Get(languageID);
00397 
00398         unsigned int stringBitLength;
00399         int bytesInStream;
00400 
00401         output[ 0 ] = 0;
00402 
00403         if ( input->ReadCompressed( stringBitLength ) == false )
00404                 return false;
00405 
00406         if ( (unsigned) input->GetNumberOfUnreadBits() < stringBitLength )
00407                 return false;
00408 
00409         bytesInStream = huffmanEncodingTree->DecodeArray( input, stringBitLength, maxCharsToWrite, ( unsigned char* ) output );
00410 
00411         if ( bytesInStream < maxCharsToWrite )
00412                 output[ bytesInStream ] = 0;
00413         else
00414                 output[ maxCharsToWrite - 1 ] = 0;
00415 
00416         return true;
00417 }
00418 #ifdef _CSTRING_COMPRESSOR
00419 void StringCompressor::EncodeString( const CString &input, int maxCharsToWrite, RakNet::BitStream *output )
00420 {
00421         LPTSTR p = input;
00422         EncodeString(p, maxCharsToWrite*sizeof(TCHAR), output, languageID);
00423 }
00424 bool StringCompressor::DecodeString( CString &output, int maxCharsToWrite, RakNet::BitStream *input, int languageID )
00425 {
00426         LPSTR p = output.GetBuffer(maxCharsToWrite*sizeof(TCHAR));
00427         DecodeString(p,maxCharsToWrite*sizeof(TCHAR), input, languageID);
00428         output.ReleaseBuffer(0)
00429 
00430 }
00431 #endif
00432 #ifdef _STD_STRING_COMPRESSOR
00433 void StringCompressor::EncodeString( const std::string &input, int maxCharsToWrite, RakNet::BitStream *output, int languageID )
00434 {
00435         EncodeString(input.c_str(), maxCharsToWrite, output, languageID);
00436 }
00437 bool StringCompressor::DecodeString( std::string *output, int maxCharsToWrite, RakNet::BitStream *input, int languageID )
00438 {
00439         if (maxCharsToWrite <= 0)
00440         {
00441                 output->clear();
00442                 return true;
00443         }
00444 
00445         char *destinationBlock;
00446         bool out;
00447 
00448 #if !defined(_XBOX) && !defined(_X360)
00449         if (maxCharsToWrite < MAX_ALLOCA_STACK_ALLOCATION)
00450         {
00451                 destinationBlock = (char*) alloca(maxCharsToWrite);
00452                 out=DecodeString(destinationBlock, maxCharsToWrite, input, languageID);
00453                 *output=destinationBlock;
00454         }
00455         else
00456 #endif
00457         {
00458                 destinationBlock = (char*) rakMalloc_Ex( maxCharsToWrite, __FILE__, __LINE__ );
00459                 out=DecodeString(destinationBlock, maxCharsToWrite, input, languageID);
00460                 *output=destinationBlock;
00461                 rakFree_Ex(destinationBlock, __FILE__, __LINE__ );
00462         }
00463 
00464         return out;
00465 }
00466 #endif
00467 void StringCompressor::EncodeString( const RakString *input, int maxCharsToWrite, RakNet::BitStream *output, int languageID )
00468 {
00469         EncodeString(input->C_String(), maxCharsToWrite, output, languageID);
00470 }
00471 bool StringCompressor::DecodeString( RakString *output, int maxCharsToWrite, RakNet::BitStream *input, int languageID )
00472 {
00473         if (maxCharsToWrite <= 0)
00474         {
00475                 output->Clear();
00476                 return true;
00477         }
00478 
00479         char *destinationBlock;
00480         bool out;
00481 
00482 #if !defined(_XBOX) && !defined(_X360)
00483         if (maxCharsToWrite < MAX_ALLOCA_STACK_ALLOCATION)
00484         {
00485                 destinationBlock = (char*) alloca(maxCharsToWrite);
00486                 out=DecodeString(destinationBlock, maxCharsToWrite, input, languageID);
00487                 *output=destinationBlock;
00488         }
00489         else
00490 #endif
00491         {
00492                 destinationBlock = (char*) rakMalloc_Ex( maxCharsToWrite, __FILE__, __LINE__ );
00493                 out=DecodeString(destinationBlock, maxCharsToWrite, input, languageID);
00494                 *output=destinationBlock;
00495                 rakFree_Ex(destinationBlock, __FILE__, __LINE__ );
00496         }
00497 
00498         return out;
00499 }

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