SLikeNet  0.1.3
 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 
17 #include "slikenet/DS_Table.h"
18 #include "slikenet/BitStream.h"
20 #include "slikenet/assert.h"
21 
22 using namespace SLNet;
23 
25 {
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 }
41 {
43  out->Write((unsigned)columns.Size());
44  unsigned i;
45  for (i=0; i<columns.Size(); i++)
46  {
48  out->Write((unsigned char)columns[i].columnType);
49  }
50 }
52 {
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  {
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 }
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 }
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 }
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 }
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 }
142 {
144  unsigned numEntries;
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 }
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
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 }
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
228  if (in->Read(binaryLength)==false || binaryLength > 10000000)
229  return false; // Sanity check to max binary cell of 10 megabytes
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 }
240 {
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 }
254 {
255  bool b;
256  RakAssert(query->cellValue);
258  out->ReadCompressed(query->columnIndex);
259  unsigned char op;
260  out->Read(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 }
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_);
335 }