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

TableSerializer.cpp

Go to the documentation of this file.
00001 #include "TableSerializer.h"
00002 #include "DS_Table.h"
00003 #include "BitStream.h"
00004 #include "StringCompressor.h"
00005 #include "RakAssert.h"
00006 
00007 void TableSerializer::SerializeTable(DataStructures::Table *in, RakNet::BitStream *out)
00008 {
00009         DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur = in->GetRows().GetListHead();
00010         const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns();
00011         SerializeColumns(in, out);
00012         out->Write((unsigned)in->GetRows().Size());
00013         unsigned rowIndex;
00014         while (cur)
00015         {
00016                 for (rowIndex=0; rowIndex < (unsigned)cur->size; rowIndex++)
00017                 {
00018                         SerializeRow(cur->data[rowIndex], cur->keys[rowIndex], columns, out);
00019                 }
00020                 cur=cur->next;
00021         }
00022 }
00023 void TableSerializer::SerializeColumns(DataStructures::Table *in, RakNet::BitStream *out)
00024 {
00025         const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns();
00026         out->Write((unsigned)columns.Size());
00027         unsigned i;
00028         for (i=0; i<columns.Size(); i++)
00029         {
00030                 stringCompressor->EncodeString(columns[i].columnName, _TABLE_MAX_COLUMN_NAME_LENGTH, out);
00031                 out->Write((unsigned char)columns[i].columnType);
00032         }
00033 }
00034 void TableSerializer::SerializeColumns(DataStructures::Table *in, RakNet::BitStream *out, DataStructures::List<int> &skipColumnIndices)
00035 {
00036         const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns();
00037         out->Write((unsigned)columns.Size()-skipColumnIndices.Size());
00038         unsigned i;
00039         for (i=0; i<columns.Size(); i++)
00040         {
00041                 if (skipColumnIndices.GetIndexOf(i)==(unsigned)-1)
00042                 {
00043                         stringCompressor->EncodeString(columns[i].columnName, _TABLE_MAX_COLUMN_NAME_LENGTH, out);
00044                         out->Write((unsigned char)columns[i].columnType);
00045                 }               
00046         }
00047 }
00048 bool TableSerializer::DeserializeTable(unsigned char *serializedTable, unsigned int dataLength, DataStructures::Table *out)
00049 {
00050         RakNet::BitStream in((unsigned char*) serializedTable, dataLength, false);
00051         return DeserializeTable(&in, out);
00052 }
00053 bool TableSerializer::DeserializeTable(RakNet::BitStream *in, DataStructures::Table *out)
00054 {
00055         unsigned rowSize;
00056         DeserializeColumns(in,out);
00057         if (in->Read(rowSize)==false || rowSize>100000)
00058         {
00059                 RakAssert(0);
00060                 return false; // Hacker crash prevention
00061         }
00062 
00063         unsigned rowIndex;
00064         for (rowIndex=0; rowIndex < rowSize; rowIndex++)
00065         {
00066                 if (DeserializeRow(in, out)==false)
00067                         return false;
00068         }
00069         return true;
00070 }
00071 bool TableSerializer::DeserializeColumns(RakNet::BitStream *in, DataStructures::Table *out)
00072 {
00073         unsigned columnSize;
00074         unsigned char columnType;
00075         char columnName[_TABLE_MAX_COLUMN_NAME_LENGTH];
00076         if (in->Read(columnSize)==false || columnSize > 10000)
00077                 return false; // Hacker crash prevention
00078 
00079         out->Clear();
00080         unsigned i;
00081         for (i=0; i<columnSize; i++)
00082         {
00083                 stringCompressor->DecodeString(columnName, 32, in);
00084                 in->Read(columnType);
00085                 out->AddColumn(columnName, (DataStructures::Table::ColumnType)columnType);
00086         }
00087         return true;
00088 }
00089 void TableSerializer::SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, RakNet::BitStream *out)
00090 {
00091         unsigned cellIndex;
00092         out->Write(keyIn);
00093         unsigned int columnsSize = columns.Size();
00094         out->Write(columnsSize);
00095         for (cellIndex=0; cellIndex<columns.Size(); cellIndex++)
00096         {
00097                 out->Write(cellIndex);
00098                 SerializeCell(out, in->cells[cellIndex], columns[cellIndex].columnType);
00099         }
00100 }
00101 void TableSerializer::SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, RakNet::BitStream *out, DataStructures::List<int> &skipColumnIndices)
00102 {
00103         unsigned cellIndex;
00104         out->Write(keyIn);
00105         unsigned int numEntries=0;
00106         for (cellIndex=0; cellIndex<columns.Size(); cellIndex++)
00107         {
00108                 if (skipColumnIndices.GetIndexOf(cellIndex)==(unsigned)-1)
00109                 {
00110                         numEntries++;
00111                 }
00112         }
00113         out->Write(numEntries);
00114 
00115         for (cellIndex=0; cellIndex<columns.Size(); cellIndex++)
00116         {
00117                 if (skipColumnIndices.GetIndexOf(cellIndex)==(unsigned)-1)
00118                 {
00119                         out->Write(cellIndex);
00120                         SerializeCell(out, in->cells[cellIndex], columns[cellIndex].columnType);
00121                 }
00122         }
00123 }
00124 bool TableSerializer::DeserializeRow(RakNet::BitStream *in, DataStructures::Table *out)
00125 {
00126         const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=out->GetColumns();
00127         unsigned numEntries;
00128         DataStructures::Table::Row *row;
00129         unsigned key;
00130         if (in->Read(key)==false)
00131                 return false;
00132         row=out->AddRow(key);
00133         unsigned int cnt;
00134         in->Read(numEntries);
00135         for (cnt=0; cnt<numEntries; cnt++)
00136         {
00137                 unsigned cellIndex;
00138                 in->Read(cellIndex);
00139                 if (DeserializeCell(in, row->cells[cellIndex], columns[cellIndex].columnType)==false)
00140                 {
00141                         out->RemoveRow(key);
00142                         return false;
00143                 }
00144         }
00145         return true;
00146 }
00147 void TableSerializer::SerializeCell(RakNet::BitStream *out, DataStructures::Table::Cell *cell, DataStructures::Table::ColumnType columnType)
00148 {
00149         out->Write(cell->isEmpty);
00150         if (cell->isEmpty==false)
00151         {
00152                 if (columnType==DataStructures::Table::NUMERIC)
00153                 {
00154                         out->Write(cell->i);
00155                 }
00156                 else if (columnType==DataStructures::Table::STRING)
00157                 {
00158                         stringCompressor->EncodeString(cell->c, 65535, out);
00159                 }
00160                 else if (columnType==DataStructures::Table::POINTER)
00161                 {
00162                         out->Write(cell->ptr);
00163                 }
00164                 else
00165                 {
00166                         // Binary
00167                         RakAssert(columnType==DataStructures::Table::BINARY);
00168                         RakAssert(cell->i>0);
00169                         unsigned binaryLength;
00170                         binaryLength=(unsigned)cell->i;
00171                         out->Write(binaryLength);
00172                         out->WriteAlignedBytes((const unsigned char*) cell->c, (const unsigned int) cell->i);
00173                 }
00174         }
00175 }
00176 bool TableSerializer::DeserializeCell(RakNet::BitStream *in, DataStructures::Table::Cell *cell, DataStructures::Table::ColumnType columnType)
00177 {
00178         bool isEmpty;
00179         double value;
00180         void *ptr;
00181         char tempString[65535];
00182         cell->Clear();
00183 
00184         if (in->Read(isEmpty)==false)
00185                 return false;
00186         if (isEmpty==false)
00187         {
00188                 if (columnType==DataStructures::Table::NUMERIC)
00189                 {
00190                         if (in->Read(value)==false)
00191                                 return false;
00192                         cell->Set(value);
00193                 }
00194                 else if (columnType==DataStructures::Table::STRING)
00195                 {
00196                         if (stringCompressor->DecodeString(tempString, 65535, in)==false)
00197                                 return false;
00198                         cell->Set(tempString);
00199                 }
00200                 else if (columnType==DataStructures::Table::POINTER)
00201                 {
00202                         if (in->Read(ptr)==false)
00203                                 return false;
00204                         cell->SetPtr(ptr);
00205                 }
00206                 else
00207                 {
00208                         unsigned binaryLength;
00209                         // Binary
00210                         RakAssert(columnType==DataStructures::Table::BINARY);
00211                         if (in->Read(binaryLength)==false || binaryLength > 10000000)
00212                                 return false; // Sanity check to max binary cell of 10 megabytes
00213                         in->AlignReadToByteBoundary();
00214                         if (BITS_TO_BYTES(in->GetNumberOfUnreadBits())<(BitSize_t)binaryLength)
00215                                 return false;
00216                         cell->Set((char*) in->GetData()+BITS_TO_BYTES(in->GetReadOffset()), (int) binaryLength);
00217                         in->IgnoreBits(BYTES_TO_BITS((int) binaryLength));
00218                 }
00219         }
00220         return true;
00221 }
00222 void TableSerializer::SerializeFilterQuery(RakNet::BitStream *in, DataStructures::Table::FilterQuery *query)
00223 {
00224         stringCompressor->EncodeString(query->columnName,_TABLE_MAX_COLUMN_NAME_LENGTH,in,0);
00225         in->WriteCompressed(query->columnIndex);
00226         in->Write((unsigned char) query->operation);
00227         in->Write(query->cellValue->isEmpty);
00228         if (query->cellValue->isEmpty==false)
00229         {
00230                 in->Write(query->cellValue->i);
00231                 in->WriteAlignedBytesSafe((const char*)query->cellValue->c,(const unsigned int)query->cellValue->i,10000000); // Sanity check to max binary cell of 10 megabytes
00232                 in->Write(query->cellValue->ptr);
00233 
00234         }
00235 }
00236 bool TableSerializer::DeserializeFilterQuery(RakNet::BitStream *out, DataStructures::Table::FilterQuery *query)
00237 {
00238         bool b;
00239         RakAssert(query->cellValue);
00240         stringCompressor->DecodeString(query->columnName,_TABLE_MAX_COLUMN_NAME_LENGTH,out,0);
00241         out->ReadCompressed(query->columnIndex);
00242         unsigned char op;
00243         out->Read(op);
00244         query->operation=(DataStructures::Table::FilterQueryType) op;
00245         query->cellValue->Clear();
00246         b=out->Read(query->cellValue->isEmpty);
00247         if (query->cellValue->isEmpty==false)
00248         {
00249                 // HACK - cellValue->i is used for integer, character, and binary data. However, for character and binary c will be 0. So use that to determine if the data was integer or not.
00250                 out->Read(query->cellValue->i);
00251                 unsigned int inputLength;
00252                 out->ReadAlignedBytesSafeAlloc(&query->cellValue->c,inputLength,10000000); // Sanity check to max binary cell of 10 megabytes
00253                 if (query->cellValue->c)
00254                         query->cellValue->i=inputLength;
00255                 b=out->Read(query->cellValue->ptr);
00256         }
00257         return b;
00258 }
00259 void TableSerializer::SerializeFilterQueryList(RakNet::BitStream *in, DataStructures::Table::FilterQuery *query, unsigned int numQueries, unsigned int maxQueries)
00260 {
00261         (void) maxQueries;
00262         in->Write((bool)(query && numQueries>0));
00263         if (query==0 || numQueries<=0)
00264                 return;
00265 
00266         RakAssert(numQueries<=maxQueries);
00267         in->WriteCompressed(numQueries);
00268         unsigned i;
00269         for (i=0; i < numQueries; i++)
00270         {
00271                 SerializeFilterQuery(in, query);
00272         }
00273 }
00274 bool TableSerializer::DeserializeFilterQueryList(RakNet::BitStream *out, DataStructures::Table::FilterQuery **query, unsigned int *numQueries, unsigned int maxQueries, int allocateExtraQueries)
00275 {
00276         bool b, anyQueries=false;
00277         out->Read(anyQueries);
00278         if (anyQueries==false)
00279         {
00280                 if (allocateExtraQueries<=0)
00281                         *query=0;
00282                 else
00283                         *query=new DataStructures::Table::FilterQuery[allocateExtraQueries];
00284 
00285                 *numQueries=0;
00286                 return true;
00287         }
00288         b=out->ReadCompressed(*numQueries);
00289         if (*numQueries>maxQueries)
00290         {
00291                 RakAssert(0);
00292                 *numQueries=maxQueries;
00293         }
00294         if (*numQueries==0)
00295                 return b;
00296 
00297         *query=new DataStructures::Table::FilterQuery[*numQueries+allocateExtraQueries];
00298         DataStructures::Table::FilterQuery *queryPtr = *query;
00299 
00300         unsigned i;
00301         for (i=0; i < *numQueries; i++)
00302         {
00303                 queryPtr[i].cellValue=new DataStructures::Table::Cell;
00304                 b=DeserializeFilterQuery(out, queryPtr+i);
00305         }
00306 
00307         return b;
00308 }
00309 void TableSerializer::DeallocateQueryList(DataStructures::Table::FilterQuery *query, unsigned int numQueries)
00310 {
00311         if (query==0 || numQueries==0)
00312                 return;
00313 
00314         unsigned i;
00315         for (i=0; i < numQueries; i++)
00316                 RakNet::OP_DELETE(query[i].cellValue, __FILE__, __LINE__);
00317         RakNet::OP_DELETE_ARRAY(query, __FILE__, __LINE__);
00318 }

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