SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TableSerializer.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #include "slikenet/TableSerializer.h"
17 #include "slikenet/DS_Table.h"
18 #include "slikenet/BitStream.h"
19 #include "slikenet/StringCompressor.h"
20 #include "slikenet/assert.h"
21
22 using namespace SLNet;
23
24 void TableSerializer::SerializeTable(DataStructures::Table *in, SLNet::BitStream *out)
25 {
26 DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur = in->GetRows().GetListHead();
27 const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns();
28 SerializeColumns(in, out);
29 out->Write((unsigned)in->GetRows().Size());
30 unsigned rowIndex;
31 while (cur)
32 {
33 for (rowIndex=0; rowIndex < (unsigned)cur->size; rowIndex++)
34 {
35 SerializeRow(cur->data[rowIndex], cur->keys[rowIndex], columns, out);
36 }
37 cur=cur->next;
38 }
39 }
40 void TableSerializer::SerializeColumns(DataStructures::Table *in, SLNet::BitStream *out)
41 {
42 const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns();
43 out->Write((unsigned)columns.Size());
44 unsigned i;
45 for (i=0; i<columns.Size(); i++)
46 {
47 StringCompressor::Instance()->EncodeString(columns[i].columnName, _TABLE_MAX_COLUMN_NAME_LENGTH, out);
48 out->Write((unsigned char)columns[i].columnType);
49 }
50 }
51 void TableSerializer::SerializeColumns(DataStructures::Table *in, SLNet::BitStream *out, DataStructures::List<int> &skipColumnIndices)
52 {
53 const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns();
54 out->Write((unsigned)columns.Size()-skipColumnIndices.Size());
55 unsigned i;
56 for (i=0; i<columns.Size(); i++)
57 {
58 if (skipColumnIndices.GetIndexOf(i)==(unsigned)-1)
59 {
60 StringCompressor::Instance()->EncodeString(columns[i].columnName, _TABLE_MAX_COLUMN_NAME_LENGTH, out);
61 out->Write((unsigned char)columns[i].columnType);
62 }
63 }
64 }
65 bool TableSerializer::DeserializeTable(unsigned char *serializedTable, unsigned int dataLength, DataStructures::Table *out)
66 {
67 SLNet::BitStream in((unsigned char*) serializedTable, dataLength, false);
68 return DeserializeTable(&in, out);
69 }
70 bool TableSerializer::DeserializeTable(SLNet::BitStream *in, DataStructures::Table *out)
71 {
72 unsigned rowSize;
73 DeserializeColumns(in,out);
74 if (in->Read(rowSize)==false || rowSize>100000)
75 {
76 RakAssert(0);
77 return false; // Hacker crash prevention
78 }
79
80 unsigned rowIndex;
81 for (rowIndex=0; rowIndex < rowSize; rowIndex++)
82 {
83 if (DeserializeRow(in, out)==false)
84 return false;
85 }
86 return true;
87 }
88 bool TableSerializer::DeserializeColumns(SLNet::BitStream *in, DataStructures::Table *out)
89 {
90 unsigned columnSize;
91 unsigned char columnType;
92 char columnName[_TABLE_MAX_COLUMN_NAME_LENGTH];
93 if (in->Read(columnSize)==false || columnSize > 10000)
94 return false; // Hacker crash prevention
95
96 out->Clear();
97 unsigned i;
98 for (i=0; i<columnSize; i++)
99 {
100 StringCompressor::Instance()->DecodeString(columnName, 32, in);
101 in->Read(columnType);
102 out->AddColumn(columnName, (DataStructures::Table::ColumnType)columnType);
103 }
104 return true;
105 }
106 void TableSerializer::SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, SLNet::BitStream *out)
107 {
108 unsigned cellIndex;
109 out->Write(keyIn);
110 unsigned int columnsSize = columns.Size();
111 out->Write(columnsSize);
112 for (cellIndex=0; cellIndex<columns.Size(); cellIndex++)
113 {
114 out->Write(cellIndex);
115 SerializeCell(out, in->cells[cellIndex], columns[cellIndex].columnType);
116 }
117 }
118 void TableSerializer::SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, SLNet::BitStream *out, DataStructures::List<int> &skipColumnIndices)
119 {
120 unsigned cellIndex;
121 out->Write(keyIn);
122 unsigned int numEntries=0;
123 for (cellIndex=0; cellIndex<columns.Size(); cellIndex++)
124 {
125 if (skipColumnIndices.GetIndexOf(cellIndex)==(unsigned)-1)
126 {
127 numEntries++;
128 }
129 }
130 out->Write(numEntries);
131
132 for (cellIndex=0; cellIndex<columns.Size(); cellIndex++)
133 {
134 if (skipColumnIndices.GetIndexOf(cellIndex)==(unsigned)-1)
135 {
136 out->Write(cellIndex);
137 SerializeCell(out, in->cells[cellIndex], columns[cellIndex].columnType);
138 }
139 }
140 }
141 bool TableSerializer::DeserializeRow(SLNet::BitStream *in, DataStructures::Table *out)
142 {
143 const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=out->GetColumns();
144 unsigned numEntries;
145 DataStructures::Table::Row *row;
146 unsigned key;
147 if (in->Read(key)==false)
148 return false;
149 row=out->AddRow(key);
150 unsigned int cnt;
151 in->Read(numEntries);
152 for (cnt=0; cnt<numEntries; cnt++)
153 {
154 unsigned cellIndex;
155 in->Read(cellIndex);
156 if (DeserializeCell(in, row->cells[cellIndex], columns[cellIndex].columnType)==false)
157 {
158 out->RemoveRow(key);
159 return false;
160 }
161 }
162 return true;
163 }
164 void TableSerializer::SerializeCell(SLNet::BitStream *out, DataStructures::Table::Cell *cell, DataStructures::Table::ColumnType columnType)
165 {
166 out->Write(cell->isEmpty);
167 if (cell->isEmpty==false)
168 {
169 if (columnType==DataStructures::Table::NUMERIC)
170 {
171 out->Write(cell->i);
172 }
173 else if (columnType==DataStructures::Table::STRING)
174 {
175 StringCompressor::Instance()->EncodeString(cell->c, 65535, out);
176 }
177 else if (columnType==DataStructures::Table::POINTER)
178 {
179 out->Write(cell->ptr);
180 }
181 else
182 {
183 // Binary
184 RakAssert(columnType==DataStructures::Table::BINARY);
185 RakAssert(cell->i>0);
186 unsigned binaryLength;
187 binaryLength=(unsigned)cell->i;
188 out->Write(binaryLength);
189 out->WriteAlignedBytes((const unsigned char*) cell->c, (const unsigned int) cell->i);
190 }
191 }
192 }
193 bool TableSerializer::DeserializeCell(SLNet::BitStream *in, DataStructures::Table::Cell *cell, DataStructures::Table::ColumnType columnType)
194 {
195 bool isEmpty=false;
196 double value;
197 void *ptr;
198 char tempString[65535];
199 cell->Clear();
200
201 if (in->Read(isEmpty)==false)
202 return false;
203 if (isEmpty==false)
204 {
205 if (columnType==DataStructures::Table::NUMERIC)
206 {
207 if (in->Read(value)==false)
208 return false;
209 cell->Set(value);
210 }
211 else if (columnType==DataStructures::Table::STRING)
212 {
213 if (StringCompressor::Instance()->DecodeString(tempString, 65535, in)==false)
214 return false;
215 cell->Set(tempString);
216 }
217 else if (columnType==DataStructures::Table::POINTER)
218 {
219 if (in->Read(ptr)==false)
220 return false;
221 cell->SetPtr(ptr);
222 }
223 else
224 {
225 unsigned binaryLength;
226 // Binary
227 RakAssert(columnType==DataStructures::Table::BINARY);
228 if (in->Read(binaryLength)==false || binaryLength > 10000000)
229 return false; // Sanity check to max binary cell of 10 megabytes
230 in->AlignReadToByteBoundary();
231 if (BITS_TO_BYTES(in->GetNumberOfUnreadBits())<(BitSize_t)binaryLength)
232 return false;
233 cell->Set((char*) in->GetData()+BITS_TO_BYTES(in->GetReadOffset()), (int) binaryLength);
234 in->IgnoreBits(BYTES_TO_BITS((int) binaryLength));
235 }
236 }
237 return true;
238 }
239 void TableSerializer::SerializeFilterQuery(SLNet::BitStream *in, DataStructures::Table::FilterQuery *query)
240 {
241 StringCompressor::Instance()->EncodeString(query->columnName,_TABLE_MAX_COLUMN_NAME_LENGTH,in,0);
242 in->WriteCompressed(query->columnIndex);
243 in->Write((unsigned char) query->operation);
244 in->Write(query->cellValue->isEmpty);
245 if (query->cellValue->isEmpty==false)
246 {
247 in->Write(query->cellValue->i);
248 in->WriteAlignedBytesSafe((const char*)query->cellValue->c,(const unsigned int)query->cellValue->i,10000000); // Sanity check to max binary cell of 10 megabytes
249 in->Write(query->cellValue->ptr);
250
251 }
252 }
253 bool TableSerializer::DeserializeFilterQuery(SLNet::BitStream *out, DataStructures::Table::FilterQuery *query)
254 {
255 bool b;
256 RakAssert(query->cellValue);
257 StringCompressor::Instance()->DecodeString(query->columnName,_TABLE_MAX_COLUMN_NAME_LENGTH,out,0);
258 out->ReadCompressed(query->columnIndex);
259 unsigned char op;
260 out->Read(op);
261 query->operation=(DataStructures::Table::FilterQueryType) op;
262 query->cellValue->Clear();
263 b=out->Read(query->cellValue->isEmpty);
264 if (query->cellValue->isEmpty==false)
265 {
266 // 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.
267 out->Read(query->cellValue->i);
268 unsigned int inputLength;
269 out->ReadAlignedBytesSafeAlloc(&query->cellValue->c,inputLength,10000000); // Sanity check to max binary cell of 10 megabytes
270 if (query->cellValue->c)
271 query->cellValue->i=inputLength;
272 b=out->Read(query->cellValue->ptr);
273 }
274 return b;
275 }
276 void TableSerializer::SerializeFilterQueryList(SLNet::BitStream *in, DataStructures::Table::FilterQuery *query, unsigned int numQueries, unsigned int maxQueries)
277 {
278 (void) maxQueries;
279 in->Write((bool)(query && numQueries>0));
280 if (query==0 || numQueries<=0)
281 return;
282
283 RakAssert(numQueries<=maxQueries);
284 in->WriteCompressed(numQueries);
285 unsigned i;
286 for (i=0; i < numQueries; i++)
287 {
288 SerializeFilterQuery(in, query);
289 }
290 }
291 bool TableSerializer::DeserializeFilterQueryList(SLNet::BitStream *out, DataStructures::Table::FilterQuery **query, unsigned int *numQueries, unsigned int maxQueries, int allocateExtraQueries)
292 {
293 bool b, anyQueries=false;
294 out->Read(anyQueries);
295 if (anyQueries==false)
296 {
297 if (allocateExtraQueries<=0)
298 *query=0;
299 else
300 *query=new DataStructures::Table::FilterQuery[allocateExtraQueries];
301
302 *numQueries=0;
303 return true;
304 }
305 b=out->ReadCompressed(*numQueries);
306 if (*numQueries>maxQueries)
307 {
308 RakAssert(0);
309 *numQueries=maxQueries;
310 }
311 if (*numQueries==0)
312 return b;
313
314 *query=new DataStructures::Table::FilterQuery[*numQueries+allocateExtraQueries];
315 DataStructures::Table::FilterQuery *queryPtr = *query;
316
317 unsigned i;
318 for (i=0; i < *numQueries; i++)
319 {
320 queryPtr[i].cellValue=new DataStructures::Table::Cell;
321 b=DeserializeFilterQuery(out, queryPtr+i);
322 }
323
324 return b;
325 }
326 void TableSerializer::DeallocateQueryList(DataStructures::Table::FilterQuery *query, unsigned int numQueries)
327 {
328 if (query==0 || numQueries==0)
329 return;
330
331 unsigned i;
332 for (i=0; i < numQueries; i++)
333 SLNet::OP_DELETE(query[i].cellValue, _FILE_AND_LINE_);
334 SLNet::OP_DELETE_ARRAY(query, _FILE_AND_LINE_);
335 }