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;
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;
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
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
00210 RakAssert(columnType==DataStructures::Table::BINARY);
00211 if (in->Read(binaryLength)==false || binaryLength > 10000000)
00212 return false;
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);
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
00250 out->Read(query->cellValue->i);
00251 unsigned int inputLength;
00252 out->ReadAlignedBytesSafeAlloc(&query->cellValue->c,inputLength,10000000);
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 }